]> granicus.if.org Git - clang/commitdiff
When attempting reference binding to an overloaded function, also
authorDouglas Gregor <dgregor@apple.com>
Mon, 8 Nov 2010 15:20:28 +0000 (15:20 +0000)
committerDouglas Gregor <dgregor@apple.com>
Mon, 8 Nov 2010 15:20:28 +0000 (15:20 +0000)
consider that we might be trying to bind a reference to a class type,
which involves a constructor call. Fixes PR7425.

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

lib/Sema/SemaInit.cpp
test/SemaCXX/addr-of-overloaded-function.cpp

index bee2ba46a8764b31c99bd290e5854cf583ad6c22..f45893df86de94ea37ea917fba7445dee37bc134 100644 (file)
@@ -2511,18 +2511,17 @@ static void TryReferenceInitialization(Sema &S,
   // type of the resulting function.
   if (S.Context.getCanonicalType(T2) == S.Context.OverloadTy) {
     DeclAccessPair Found;
-    FunctionDecl *Fn = S.ResolveAddressOfOverloadedFunction(Initializer, 
-                                                            T1,
-                                                            false,
-                                                            Found);
-    if (!Fn) {
+    if (FunctionDecl *Fn = S.ResolveAddressOfOverloadedFunction(Initializer, 
+                                                                T1,
+                                                                false,
+                                                                Found)) {
+      Sequence.AddAddressOverloadResolutionStep(Fn, Found);
+      cv2T2 = Fn->getType();
+      T2 = cv2T2.getUnqualifiedType();
+    } else if (!T1->isRecordType()) {
       Sequence.SetFailed(InitializationSequence::FK_AddressOfOverloadFailed);
       return;
     }
-
-    Sequence.AddAddressOverloadResolutionStep(Fn, Found);
-    cv2T2 = Fn->getType();
-    T2 = cv2T2.getUnqualifiedType();
   }
 
   // Compute some basic properties of the types and the initializer.
@@ -2604,7 +2603,9 @@ static void TryReferenceInitialization(Sema &S,
   // We handled the function type stuff above.
   if (!((isLValueRef && T1Quals.hasConst() && !T1Quals.hasVolatile()) ||
         (isRValueRef && InitCategory.isRValue()))) {
-    if (ConvOvlResult && !Sequence.getFailedCandidateSet().empty())
+    if (S.Context.getCanonicalType(T2) == S.Context.OverloadTy)
+      Sequence.SetFailed(InitializationSequence::FK_AddressOfOverloadFailed);
+    else if (ConvOvlResult && !Sequence.getFailedCandidateSet().empty())
       Sequence.SetOverloadFailure(
                         InitializationSequence::FK_ReferenceInitOverloadFailed,
                                   ConvOvlResult);
@@ -2706,6 +2707,8 @@ static void TryReferenceInitialization(Sema &S,
       Sequence.SetOverloadFailure(
                         InitializationSequence::FK_ReferenceInitOverloadFailed,
                                   ConvOvlResult);
+    else if (S.Context.getCanonicalType(T2) == S.Context.OverloadTy)
+      Sequence.SetFailed(InitializationSequence::FK_AddressOfOverloadFailed);
     else
       Sequence.SetFailed(InitializationSequence::FK_ReferenceInitFailed);
     return;
index c095e946c8b71c9cac6794abd587652526e5e766..00d91043e4e12d7e565373d5e7b4eeb204e5e196 100644 (file)
@@ -116,3 +116,32 @@ namespace PR8196 {
     add_property(&wrap_mean); // expected-error{{no matching function for call to 'add_property'}}
   }
 }
+
+namespace PR7425 {
+  template<typename T>
+  void foo()
+  {
+  }
+
+  struct B
+  {
+    template<typename T>
+    B(const T&)
+    {
+    }
+  };
+
+  void bar(const B& b)
+  {
+  }
+
+  void bar2(const B& b = foo<int>)
+  {
+  }
+
+  void test(int argc, char** argv)
+  {
+    bar(foo<int>);
+    bar2();
+  }
+}