diff options
-rw-r--r-- | lib/Sema/SemaOverload.cpp | 32 | ||||
-rw-r--r-- | test/SemaCXX/cxx0x-initializer-constructor.cpp | 17 |
2 files changed, 27 insertions, 22 deletions
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp index be0243403b..661f589099 100644 --- a/lib/Sema/SemaOverload.cpp +++ b/lib/Sema/SemaOverload.cpp @@ -2758,6 +2758,19 @@ Sema::IsQualificationConversion(QualType FromType, QualType ToType, 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 @@ IsInitializerListConstructorConversion(Sema &S, Expr *From, QualType ToType, 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 @@ IsUserDefinedConversion(Sema &S, Expr *From, QualType ToType, 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) diff --git a/test/SemaCXX/cxx0x-initializer-constructor.cpp b/test/SemaCXX/cxx0x-initializer-constructor.cpp index a14283ce7c..da10189257 100644 --- a/test/SemaCXX/cxx0x-initializer-constructor.cpp +++ b/test/SemaCXX/cxx0x-initializer-constructor.cpp @@ -237,7 +237,7 @@ namespace PR12167 { bool s = f(string<1>()); } -namespace PR12257 { +namespace PR12257_PR12241 { struct command_pair { command_pair(int, int); @@ -253,14 +253,9 @@ namespace PR12257 { 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}}}}; } |