[cfe-commits] r153523 - in /cfe/trunk: lib/Sema/SemaOverload.cpp test/SemaCXX/cxx0x-initializer-constructor.cpp

Sebastian Redl sebastian.redl at getdesigned.at
Tue Mar 27 11:33:03 PDT 2012


Author: cornedbee
Date: Tue Mar 27 13:33:03 2012
New Revision: 153523

URL: http://llvm.org/viewvc/llvm-project?rev=153523&view=rev
Log:
Even more careful consideration of C++11 13.3.3.1p4. Fixes PR12241.

Modified:
    cfe/trunk/lib/Sema/SemaOverload.cpp
    cfe/trunk/test/SemaCXX/cxx0x-initializer-constructor.cpp

Modified: cfe/trunk/lib/Sema/SemaOverload.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=153523&r1=153522&r2=153523&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaOverload.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOverload.cpp Tue Mar 27 13:33:03 2012
@@ -2758,6 +2758,19 @@
   return UnwrappedAnyPointer && Context.hasSameUnqualifiedType(FromType,ToType);
 }
 
+static bool isFirstArgumentCompatibleWithType(ASTContext &Context,
+                                              CXXConstructorDecl *Constructor,
+                                              QualType Type) {
+  const FunctionProtoType *CtorType =
+      Constructor->getType()->getAs<FunctionProtoType>();
+  if (CtorType->getNumArgs() > 0) {
+    QualType FirstArg = CtorType->getArgType(0);
+    if (Context.hasSameUnqualifiedType(Type, FirstArg.getNonReferenceType()))
+      return true;
+  }
+  return false;
+}
+
 static OverloadingResult
 IsInitializerListConstructorConversion(Sema &S, Expr *From, QualType ToType,
                                        CXXRecordDecl *To,
@@ -2784,15 +2797,19 @@
                   S.isInitListConstructor(Constructor) &&
                   (AllowExplicit || !Constructor->isExplicit());
     if (Usable) {
+      // If the first argument is (a reference to) the target type,
+      // suppress conversions.
+      bool SuppressUserConversions =
+          isFirstArgumentCompatibleWithType(S.Context, Constructor, ToType);
       if (ConstructorTmpl)
         S.AddTemplateOverloadCandidate(ConstructorTmpl, FoundDecl,
                                        /*ExplicitArgs*/ 0,
                                        From, CandidateSet,
-                                       /*SuppressUserConversions=*/true);
+                                       SuppressUserConversions);
       else
         S.AddOverloadCandidate(Constructor, FoundDecl,
                                From, CandidateSet,
-                               /*SuppressUserConversions=*/true);
+                               SuppressUserConversions);
     }
   }
 
@@ -2918,15 +2935,8 @@
             if (NumArgs == 1) {
               // If the first argument is (a reference to) the target type,
               // suppress conversions.
-              const FunctionProtoType *CtorType =
-                  Constructor->getType()->getAs<FunctionProtoType>();
-              if (CtorType->getNumArgs() > 0) {
-                QualType FirstArg = CtorType->getArgType(0);
-                if (S.Context.hasSameUnqualifiedType(ToType,
-                                              FirstArg.getNonReferenceType())) {
-                  SuppressUserConversions = true;
-                }
-              }
+              SuppressUserConversions = isFirstArgumentCompatibleWithType(
+                                                S.Context, Constructor, ToType);
             }
           }
           if (ConstructorTmpl)

Modified: cfe/trunk/test/SemaCXX/cxx0x-initializer-constructor.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx0x-initializer-constructor.cpp?rev=153523&r1=153522&r2=153523&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/cxx0x-initializer-constructor.cpp (original)
+++ cfe/trunk/test/SemaCXX/cxx0x-initializer-constructor.cpp Tue Mar 27 13:33:03 2012
@@ -237,7 +237,7 @@
   bool s = f(string<1>());
 }
 
-namespace PR12257 {
+namespace PR12257_PR12241 {
   struct command_pair
   {
     command_pair(int, int);
@@ -253,14 +253,9 @@
     generator_pair(const command_map);
   };
 
-  const std::initializer_list<generator_pair> x =
-  {
-    {
-      {
-        {
-          {3, 4}
-        }
-      }
-    }
-  };
+  // 5 levels: init list, gen_pair, command_map, init list, command_pair
+  const std::initializer_list<generator_pair> x = {{{{{3, 4}}}}};
+
+  // 4 levels: init list, gen_pair, command_map via init list, command_pair
+  const std::initializer_list<generator_pair> y = {{{{1, 2}}}};
 }





More information about the cfe-commits mailing list