This is an archive of the discontinued LLVM Phabricator instance.

[C++4OpenCL] Fix overloading resolution of addrspace constructors
ClosedPublic

Authored by olestrohm on May 20 2021, 8:55 AM.

Details

Summary

This fixes the prioritization of address spaces when choosing a constructor,
stopping them from being considered equally good, which made the construction
of types that could be constructed by more than one of the constructors.

It does this by preferring the most specific address space, which is decided by seeing
if one of the address spaces is a superset of the other, and preferring the other.

Fixes: PR50329

Diff Detail

Event Timeline

olestrohm created this revision.May 20 2021, 8:55 AM
olestrohm requested review of this revision.May 20 2021, 8:55 AM
olestrohm retitled this revision from [C++4OpenCL] Allow address space conversion in reinterpret_cast to [C++4OpenCL] Fix overloading resolution of addrspace constructors.May 21 2021, 1:22 AM
Anastasia added inline comments.May 21 2021, 8:29 AM
clang/lib/Sema/SemaOverload.cpp
9870

I think we should remove the OpenCL check since it is not OpenCL specific rule and you are using common helpers indeed!

I also wonder if this should be applied to all member functions not only ctors since isBetterOverloadCandidate should be used for everything?

However it seems that other members are already handled somehow https://godbolt.org/z/MrWKPKed7. Do you know where this handling comes from?

clang/test/CodeGenOpenCLCXX/addrspace-constructors.clcpp
14

Let's add a CHECK to make sure that the overload with the specific address space is used.

olestrohm added inline comments.May 24 2021, 3:36 AM
clang/lib/Sema/SemaOverload.cpp
9870

It's handled in SemaOverload.cpp:10000 in OverloadCandidateSet::BestViableFunction which checks if the given function is viable or not. For member functions the address space they're defined in and the address space of the variable have to match. Therefore only one of them is valid at a time and they never get checked against each other in isBetterOverloadCandidate.

Anastasia added inline comments.May 24 2021, 4:11 AM
clang/lib/Sema/SemaOverload.cpp
9870

I am quite sure that for the example above both __private and __generic overloads are viable. In fact, if you remove the __private overload the __generic one gets picked.

So I think the logic should be checking for compatibility rather than the exact match i.e. using isAddressSpaceSupersetOf although it might not be calling that helper directly but through the other Qualifier logic.

olestrohm added inline comments.May 24 2021, 5:35 AM
clang/lib/Sema/SemaOverload.cpp
9870

Ah, I think I checked it wrong last time. Going through it again it's actually determined by QualType::isMoreQualifiedThan in the end. I'll look into it more.

olestrohm updated this revision to Diff 347872.May 26 2021, 3:00 AM

Made the check more general, it's no longer OpenCL specific and no longer restricted to just constructors, since the check only requires them to be methods.

Also added more Sema tests, including using FileCheck to check that the constructors that should be used are actually used.

Anastasia added inline comments.May 26 2021, 3:36 AM
clang/lib/Sema/SemaOverload.cpp
9870

So did you happen to find where the address space ranking for the members is currently happening for this test case https://godbolt.org/z/MrWKPKed7?

I just want to make sure we don't add any redundant checks... so if let's say we already have a similar logic elsewhere it would be better if we attempt to generalize it or move it entirely here if it's doable. In general, we should try to use general qualifier logic if it works instead of specializing for address spaces.

olestrohm added inline comments.May 26 2021, 3:58 AM
clang/lib/Sema/SemaOverload.cpp
9870

It's handled on line 9661 with a call to CompareImplicitConversionSequences, which then goes through a couple of checks and discovers that the return type of one of the functions is more specialized than the other. However this uses the Conversions part of the candidates, which the constructors don't have.

I did attempt to generalize this further than address spaces, but that caused some tests to fail, so I think it makes sense to only check address spaces here.

Anastasia added inline comments.Jun 1 2021, 9:38 AM
clang/lib/Sema/SemaOverload.cpp
9870

Ah I see. Is it because the object parameter is not added implicitly in the ctors?

If this is only working for ctors I wonder if we should cast to CXXConstructorDecl instead of CXXMethodDecl or/and also add a comment explaining that?

olestrohm updated this revision to Diff 350561.Jun 8 2021, 3:20 AM

I've reverted to using Constructors and prioritizing based on which constructor is the most qualified.

Anastasia added inline comments.Jun 9 2021, 4:36 AM
clang/lib/Sema/SemaOverload.cpp
9870

ok, let's also add a comment explaining that ctors are handled separately from the other members because they don't have an object parameter created explicitly (if that is the reason).

olestrohm updated this revision to Diff 351165.Jun 10 2021, 7:25 AM

Added a comment explaining what the check is meant for.

Also added a CHECK-NOT: used to properly test that the __generic constructor is not used.

Anastasia accepted this revision.Jun 10 2021, 10:00 AM

LGTM! Thanks! Please, amend the comment as suggested in the final commit

clang/lib/Sema/SemaOverload.cpp
9870

Method -> General member function

This revision is now accepted and ready to land.Jun 10 2021, 10:00 AM