More careful consideration of C++11 13.3.3.1p4. Fixes PR12257.

llvm-svn: 153130
This commit is contained in:
Sebastian Redl 2012-03-20 21:24:14 +00:00
parent 6db0b1bfed
commit d9170b09e6
2 changed files with 47 additions and 7 deletions

View File

@ -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);
}
}
}

View File

@ -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}
}
}
}
};
}