Even more careful consideration of C++11 13.3.3.1p4. Fixes PR12241.
llvm-svn: 153523
This commit is contained in:
parent
41ab2899b2
commit
e541716286
|
@ -2758,6 +2758,19 @@ Sema::IsQualificationConversion(QualType FromType, QualType ToType,
|
||||||
return UnwrappedAnyPointer && Context.hasSameUnqualifiedType(FromType,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
|
static OverloadingResult
|
||||||
IsInitializerListConstructorConversion(Sema &S, Expr *From, QualType ToType,
|
IsInitializerListConstructorConversion(Sema &S, Expr *From, QualType ToType,
|
||||||
CXXRecordDecl *To,
|
CXXRecordDecl *To,
|
||||||
|
@ -2784,15 +2797,19 @@ IsInitializerListConstructorConversion(Sema &S, Expr *From, QualType ToType,
|
||||||
S.isInitListConstructor(Constructor) &&
|
S.isInitListConstructor(Constructor) &&
|
||||||
(AllowExplicit || !Constructor->isExplicit());
|
(AllowExplicit || !Constructor->isExplicit());
|
||||||
if (Usable) {
|
if (Usable) {
|
||||||
|
// If the first argument is (a reference to) the target type,
|
||||||
|
// suppress conversions.
|
||||||
|
bool SuppressUserConversions =
|
||||||
|
isFirstArgumentCompatibleWithType(S.Context, Constructor, ToType);
|
||||||
if (ConstructorTmpl)
|
if (ConstructorTmpl)
|
||||||
S.AddTemplateOverloadCandidate(ConstructorTmpl, FoundDecl,
|
S.AddTemplateOverloadCandidate(ConstructorTmpl, FoundDecl,
|
||||||
/*ExplicitArgs*/ 0,
|
/*ExplicitArgs*/ 0,
|
||||||
From, CandidateSet,
|
From, CandidateSet,
|
||||||
/*SuppressUserConversions=*/true);
|
SuppressUserConversions);
|
||||||
else
|
else
|
||||||
S.AddOverloadCandidate(Constructor, FoundDecl,
|
S.AddOverloadCandidate(Constructor, FoundDecl,
|
||||||
From, CandidateSet,
|
From, CandidateSet,
|
||||||
/*SuppressUserConversions=*/true);
|
SuppressUserConversions);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2918,15 +2935,8 @@ IsUserDefinedConversion(Sema &S, Expr *From, QualType ToType,
|
||||||
if (NumArgs == 1) {
|
if (NumArgs == 1) {
|
||||||
// If the first argument is (a reference to) the target type,
|
// If the first argument is (a reference to) the target type,
|
||||||
// suppress conversions.
|
// suppress conversions.
|
||||||
const FunctionProtoType *CtorType =
|
SuppressUserConversions = isFirstArgumentCompatibleWithType(
|
||||||
Constructor->getType()->getAs<FunctionProtoType>();
|
S.Context, Constructor, ToType);
|
||||||
if (CtorType->getNumArgs() > 0) {
|
|
||||||
QualType FirstArg = CtorType->getArgType(0);
|
|
||||||
if (S.Context.hasSameUnqualifiedType(ToType,
|
|
||||||
FirstArg.getNonReferenceType())) {
|
|
||||||
SuppressUserConversions = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (ConstructorTmpl)
|
if (ConstructorTmpl)
|
||||||
|
|
|
@ -237,7 +237,7 @@ namespace PR12167 {
|
||||||
bool s = f(string<1>());
|
bool s = f(string<1>());
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace PR12257 {
|
namespace PR12257_PR12241 {
|
||||||
struct command_pair
|
struct command_pair
|
||||||
{
|
{
|
||||||
command_pair(int, int);
|
command_pair(int, int);
|
||||||
|
@ -253,14 +253,9 @@ namespace PR12257 {
|
||||||
generator_pair(const command_map);
|
generator_pair(const command_map);
|
||||||
};
|
};
|
||||||
|
|
||||||
const std::initializer_list<generator_pair> x =
|
// 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}}}};
|
||||||
{3, 4}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue