From 1cd89c4d60d7a458de733a4ea81d5580df82a652 Mon Sep 17 00:00:00 2001 From: Sebastian Redl Date: Tue, 20 Mar 2012 21:24:14 +0000 Subject: [PATCH] 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 --- lib/Sema/SemaOverload.cpp | 26 ++++++++++++----- .../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(); + 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); + }; + + struct generator_pair + { + generator_pair(const command_map); + }; + + const std::initializer_list x = + { + { + { + { + {3, 4} + } + } + } + }; +} -- 2.40.0