]> granicus.if.org Git - clang/commitdiff
More fixes for isBetterOverloadCandidate not being a strict weak ordering. The
authorRichard Smith <richard-llvm@metafoo.co.uk>
Sat, 17 May 2014 04:36:39 +0000 (04:36 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Sat, 17 May 2014 04:36:39 +0000 (04:36 +0000)
bug was obvious from inspection, figuring out a way to test it was... less so.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@209060 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaOverload.cpp
test/CXX/expr/expr.prim/expr.prim.lambda/blocks.mm

index 8d03404e7a7d06d42c07b76b9f99c324379705e7..af7aeae30329c25b1daf1a20dba02bbd48f9cc5f 100644 (file)
@@ -8250,26 +8250,15 @@ isBetterOverloadCandidate(Sema &S,
     // other. This only distinguishes the results in non-standard, extension
     // cases such as the conversion from a lambda closure type to a function
     // pointer or block.
-    ImplicitConversionSequence::CompareKind FuncResult
-      = compareConversionFunctions(S, Cand1.Function, Cand2.Function);
-    if (FuncResult != ImplicitConversionSequence::Indistinguishable)
-      return FuncResult;
-
-    switch (CompareStandardConversionSequences(S,
-                                               Cand1.FinalConversion,
-                                               Cand2.FinalConversion)) {
-    case ImplicitConversionSequence::Better:
-      // Cand1 has a better conversion sequence.
-      return true;
-
-    case ImplicitConversionSequence::Worse:
-      // Cand1 can't be better than Cand2.
-      return false;
+    ImplicitConversionSequence::CompareKind Result =
+        compareConversionFunctions(S, Cand1.Function, Cand2.Function);
+    if (Result == ImplicitConversionSequence::Indistinguishable)
+      Result = CompareStandardConversionSequences(S,
+                                                  Cand1.FinalConversion,
+                                                  Cand2.FinalConversion);
 
-    case ImplicitConversionSequence::Indistinguishable:
-      // Do nothing
-      break;
-    }
+    if (Result != ImplicitConversionSequence::Indistinguishable)
+      return Result == ImplicitConversionSequence::Better;
 
     // FIXME: Compare kind of reference binding if conversion functions
     // convert to a reference type used in direct reference binding, per
index 345ea9bb2d63d6eb79674a87022cdbfe47448be2..96e8fcd8d37179bf43afcaf4f8cc2b16d2bbba46 100644 (file)
@@ -85,6 +85,24 @@ namespace overloading {
   void call_with_lambda() {
     int &ir = accept_lambda_conv([](int x) { return x + 1; });
   }
+
+  template<typename T> using id = T;
+
+  auto a = [](){};
+  struct C : decltype(a) {
+    using decltype(a)::operator id<void(*)()>;
+  private:
+    using decltype(a)::operator id<void(^)()>;
+  } extern c;
+
+  struct D : decltype(a) {
+    using decltype(a)::operator id<void(^)()>;
+  private:
+    using decltype(a)::operator id<void(*)()>; // expected-note {{here}}
+  } extern d;
+
+  bool r1 = c;
+  bool r2 = d; // expected-error {{private}}
 }
 
 namespace PR13117 {