diff options
author | Sebastian Redl <sebastian.redl@getdesigned.at> | 2012-03-20 21:24:14 +0000 |
---|---|---|
committer | Sebastian Redl <sebastian.redl@getdesigned.at> | 2012-03-20 21:24:14 +0000 |
commit | 1cd89c4d60d7a458de733a4ea81d5580df82a652 (patch) | |
tree | a98162aff857d203484b9088bb1f1d79e31dee90 | |
parent | ca8937111cccdbf7d17c349487a332d6c7c97f91 (diff) |
More careful consideration of C++11 13.3.3.1p4. Fixes PR12257.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@153130 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Sema/SemaOverload.cpp | 26 | ||||
-rw-r--r-- | test/SemaCXX/cxx0x-initializer-constructor.cpp | 28 |
2 files changed, 47 insertions, 7 deletions
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp index b93fb093fa..ff227eee6e 100644 --- a/lib/Sema/SemaOverload.cpp +++ b/lib/Sema/SemaOverload.cpp @@ -2904,22 +2904,34 @@ IsUserDefinedConversion(Sema &S, Expr *From, QualType ToType, else Usable = Usable &&Constructor->isConvertingConstructor(AllowExplicit); if (Usable) { + bool SuppressUserConversions = !ConstructorsOnly; + if (SuppressUserConversions && ListInitializing) { + SuppressUserConversions = false; + 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; + } + } + } + } if (ConstructorTmpl) S.AddTemplateOverloadCandidate(ConstructorTmpl, FoundDecl, /*ExplicitArgs*/ 0, llvm::makeArrayRef(Args, NumArgs), - CandidateSet, - /*SuppressUserConversions=*/ - !ConstructorsOnly && - !ListInitializing); + CandidateSet, SuppressUserConversions); else // Allow one user-defined conversion when user specifies a // From->ToType conversion via an static cast (c-style, etc). S.AddOverloadCandidate(Constructor, FoundDecl, llvm::makeArrayRef(Args, NumArgs), - CandidateSet, - /*SuppressUserConversions=*/ - !ConstructorsOnly && !ListInitializing); + CandidateSet, SuppressUserConversions); } } } diff --git a/test/SemaCXX/cxx0x-initializer-constructor.cpp b/test/SemaCXX/cxx0x-initializer-constructor.cpp index fdc882e049..a14283ce7c 100644 --- a/test/SemaCXX/cxx0x-initializer-constructor.cpp +++ b/test/SemaCXX/cxx0x-initializer-constructor.cpp @@ -236,3 +236,31 @@ namespace PR12167 { bool s = f(string<1>()); } + +namespace PR12257 { + struct command_pair + { + command_pair(int, int); + }; + + struct command_map + { + command_map(std::initializer_list<command_pair>); + }; + + struct generator_pair + { + generator_pair(const command_map); + }; + + const std::initializer_list<generator_pair> x = + { + { + { + { + {3, 4} + } + } + } + }; +} |