This is an archive of the discontinued LLVM Phabricator instance.

[OpenCL] Fix overloading ranking rules to work correctly for address space conversions
ClosedPublic

Authored by Anastasia on Jan 15 2019, 11:00 AM.

Diff Detail

Repository
rL LLVM

Event Timeline

Anastasia created this revision.Jan 15 2019, 11:00 AM

Is there a reason not to just do T1.getQualifiers() == T2.getQualifiers()?

Is there a reason not to just do T1.getQualifiers() == T2.getQualifiers()?

I tried this but it causes ObjC test to fail test/SemaObjCXX/arc-overloading.mm.

38 // Simple overloading
39 int &f2(id __strong const *); // expected-note{{candidate function}}
40 float &f2(id __autoreleasing const *); // expected-note{{candidate function}}
41 
42 void test_f2() {
43   id __strong *sip;
44   id __strong const *csip;
45   id __weak *wip;
46   id __autoreleasing *aip;
47   id __unsafe_unretained *uip;
48 
49   // Prefer non-ownership conversions to ownership conversions.
50   int &ir1 = f2(sip);
51   int &ir2 = f2(csip);
52   float &fr1 = f2(aip);
53 
54   f2(uip); // expected-error{{call to 'f2' is ambiguous}}
55 }

Clang fails to resolve the overloads:

error: 'error' diagnostics seen but not expected: 
  File /data/llvm/llvm/tools/clang/test/SemaObjCXX/arc-overloading.mm Line 50: call to 'f2' is ambiguous
  File /data/llvm/llvm/tools/clang/test/SemaObjCXX/arc-overloading.mm Line 52: call to 'f2' is ambiguous
error: 'note' diagnostics seen but not expected: 
  File /data/llvm/llvm/tools/clang/test/SemaObjCXX/arc-overloading.mm Line 39: candidate function
  File /data/llvm/llvm/tools/clang/test/SemaObjCXX/arc-overloading.mm Line 40: candidate function
  File /data/llvm/llvm/tools/clang/test/SemaObjCXX/arc-overloading.mm Line 39: candidate function
  File /data/llvm/llvm/tools/clang/test/SemaObjCXX/arc-overloading.mm Line 40: candidate function

Since CVR quals for both overloads of f2 are the same it didn't continue ranking the other qualifiers before. But now when it continues looking at the other qualifiers it finds that __strong and __autoreleasing are disjoint and exits at the following return statement in CompareQualificationConversions:

} else {
  // Qualifiers are disjoint.
  return ImplicitConversionSequence::Indistinguishable;
}

I feel the logic here doesn't apply to this case because it doesn't take into account that for the passed in function argument there is no ownership qualification conversion for one of the overloads. But I don't have a good idea how to fix this easily other than just keep fast pathing ObjC qual here.

May be if we add a separate qualification conversion for ObjC ownership qualification only we will end up with more conversion steps for one overload and therefore it will be possible to resolve the ambiguity? Do you have any other suggestions or do you think someone else could help?

Anastasia retitled this revision from [OpenCL] Fix overloading ranking rules to work correctly for address space coversions to [OpenCL] Fix overloading ranking rules to work correctly for address space conversions .Jan 16 2019, 4:43 AM

Is there a reason not to just do T1.getQualifiers() == T2.getQualifiers()?

I tried this but it causes ObjC test to fail test/SemaObjCXX/arc-overloading.mm.

38 // Simple overloading
39 int &f2(id __strong const *); // expected-note{{candidate function}}
40 float &f2(id __autoreleasing const *); // expected-note{{candidate function}}
41 
42 void test_f2() {
43   id __strong *sip;
44   id __strong const *csip;
45   id __weak *wip;
46   id __autoreleasing *aip;
47   id __unsafe_unretained *uip;
48 
49   // Prefer non-ownership conversions to ownership conversions.
50   int &ir1 = f2(sip);
51   int &ir2 = f2(csip);
52   float &fr1 = f2(aip);
53 
54   f2(uip); // expected-error{{call to 'f2' is ambiguous}}
55 }

Clang fails to resolve the overloads:

error: 'error' diagnostics seen but not expected: 
  File /data/llvm/llvm/tools/clang/test/SemaObjCXX/arc-overloading.mm Line 50: call to 'f2' is ambiguous
  File /data/llvm/llvm/tools/clang/test/SemaObjCXX/arc-overloading.mm Line 52: call to 'f2' is ambiguous
error: 'note' diagnostics seen but not expected: 
  File /data/llvm/llvm/tools/clang/test/SemaObjCXX/arc-overloading.mm Line 39: candidate function
  File /data/llvm/llvm/tools/clang/test/SemaObjCXX/arc-overloading.mm Line 40: candidate function
  File /data/llvm/llvm/tools/clang/test/SemaObjCXX/arc-overloading.mm Line 39: candidate function
  File /data/llvm/llvm/tools/clang/test/SemaObjCXX/arc-overloading.mm Line 40: candidate function

Since CVR quals for both overloads of f2 are the same it didn't continue ranking the other qualifiers before. But now when it continues looking at the other qualifiers it finds that __strong and __autoreleasing are disjoint and exits at the following return statement in CompareQualificationConversions:

} else {
  // Qualifiers are disjoint.
  return ImplicitConversionSequence::Indistinguishable;
}

I feel the logic here doesn't apply to this case because it doesn't take into account that for the passed in function argument there is no ownership qualification conversion for one of the overloads. But I don't have a good idea how to fix this easily other than just keep fast pathing ObjC qual here.

May be if we add a separate qualification conversion for ObjC ownership qualification only we will end up with more conversion steps for one overload and therefore it will be possible to resolve the ambiguity? Do you have any other suggestions or do you think someone else could help?

For now, let's just remove the ownership qualifiers before comparing and leave a comment explaining that considering them here seems to interfere with the ARC overload rule.

Anastasia updated this revision to Diff 182084.Jan 16 2019, 9:52 AM
  • Changed the condition to use all qualifiers except for ObjC ownership ones.

Thanks, LGTM.

Well, actually, could you improve the test case to verify that the right overload is called? This should be easy because C++ type-checking is bottom-up: just make the functions return something distinguishable, e.g. structs that declare different members.

Anastasia updated this revision to Diff 182245.Jan 17 2019, 3:37 AM

Improved test.

rjmccall accepted this revision.Jan 17 2019, 5:45 PM

Thanks!

This revision is now accepted and ready to land.Jan 17 2019, 5:45 PM
This revision was automatically updated to reflect the committed changes.