forked from OSchip/llvm-project
Implement a FIXME for conversion sequence distinction. Should fix PR12092.
llvm-svn: 151577
This commit is contained in:
parent
7b4646184b
commit
aa6feaa7ea
|
@ -401,11 +401,15 @@ namespace clang {
|
|||
};
|
||||
|
||||
/// ConversionKind - The kind of implicit conversion sequence.
|
||||
unsigned ConversionKind : 31;
|
||||
unsigned ConversionKind : 30;
|
||||
|
||||
/// \brief Whether the argument is an initializer list.
|
||||
bool ListInitializationSequence : 1;
|
||||
|
||||
/// \brief Whether the target is really a std::initializer_list, and the
|
||||
/// sequence only represents the worst element conversion.
|
||||
bool StdInitializerListElement : 1;
|
||||
|
||||
void setKind(Kind K) {
|
||||
destruct();
|
||||
ConversionKind = K;
|
||||
|
@ -435,13 +439,16 @@ namespace clang {
|
|||
};
|
||||
|
||||
ImplicitConversionSequence()
|
||||
: ConversionKind(Uninitialized), ListInitializationSequence(false) {}
|
||||
: ConversionKind(Uninitialized), ListInitializationSequence(false),
|
||||
StdInitializerListElement(false)
|
||||
{}
|
||||
~ImplicitConversionSequence() {
|
||||
destruct();
|
||||
}
|
||||
ImplicitConversionSequence(const ImplicitConversionSequence &Other)
|
||||
: ConversionKind(Other.ConversionKind),
|
||||
ListInitializationSequence(Other.ListInitializationSequence)
|
||||
ListInitializationSequence(Other.ListInitializationSequence),
|
||||
StdInitializerListElement(Other.StdInitializerListElement)
|
||||
{
|
||||
switch (ConversionKind) {
|
||||
case Uninitialized: break;
|
||||
|
@ -536,6 +543,16 @@ namespace clang {
|
|||
ListInitializationSequence = true;
|
||||
}
|
||||
|
||||
/// \brief Whether the target is really a std::initializer_list, and the
|
||||
/// sequence only represents the worst element conversion.
|
||||
bool isStdInitializerListElement() const {
|
||||
return StdInitializerListElement;
|
||||
}
|
||||
|
||||
void setStdInitializerListElement(bool V = true) {
|
||||
StdInitializerListElement = V;
|
||||
}
|
||||
|
||||
// The result of a comparison between implicit conversion
|
||||
// sequences. Use Sema::CompareImplicitConversionSequences to
|
||||
// actually perform the comparison.
|
||||
|
|
|
@ -3163,9 +3163,15 @@ CompareImplicitConversionSequences(Sema &S,
|
|||
// list-initialization sequence L2 if L1 converts to std::initializer_list<X>
|
||||
// for some X and L2 does not.
|
||||
if (Result == ImplicitConversionSequence::Indistinguishable &&
|
||||
!ICS1.isBad() &&
|
||||
ICS1.isListInitializationSequence() &&
|
||||
ICS2.isListInitializationSequence()) {
|
||||
// FIXME: Find out if ICS1 converts to initializer_list and ICS2 doesn't.
|
||||
if (ICS1.isStdInitializerListElement() &&
|
||||
!ICS2.isStdInitializerListElement())
|
||||
return ImplicitConversionSequence::Better;
|
||||
if (!ICS1.isStdInitializerListElement() &&
|
||||
ICS2.isStdInitializerListElement())
|
||||
return ImplicitConversionSequence::Worse;
|
||||
}
|
||||
|
||||
return Result;
|
||||
|
@ -4241,11 +4247,12 @@ TryListConversion(Sema &S, InitListExpr *From, QualType ToType,
|
|||
// all the elements can be implicitly converted to X, the implicit
|
||||
// conversion sequence is the worst conversion necessary to convert an
|
||||
// element of the list to X.
|
||||
bool toStdInitializerList = false;
|
||||
QualType X;
|
||||
if (ToType->isArrayType())
|
||||
X = S.Context.getBaseElementType(ToType);
|
||||
else
|
||||
(void)S.isStdInitializerList(ToType, &X);
|
||||
toStdInitializerList = S.isStdInitializerList(ToType, &X);
|
||||
if (!X.isNull()) {
|
||||
for (unsigned i = 0, e = From->getNumInits(); i < e; ++i) {
|
||||
Expr *Init = From->getInit(i);
|
||||
|
@ -4265,6 +4272,7 @@ TryListConversion(Sema &S, InitListExpr *From, QualType ToType,
|
|||
Result = ICS;
|
||||
}
|
||||
Result.setListInitializationSequence();
|
||||
Result.setStdInitializerListElement(toStdInitializerList);
|
||||
return Result;
|
||||
}
|
||||
|
||||
|
|
|
@ -194,3 +194,21 @@ namespace objects {
|
|||
H h4 = {1, 1}; // expected-error {{no matching constructor}}
|
||||
};
|
||||
}
|
||||
|
||||
namespace PR12092 {
|
||||
|
||||
struct S {
|
||||
S(const char*);
|
||||
};
|
||||
struct V {
|
||||
template<typename T> V(T, T);
|
||||
void f(std::initializer_list<S>);
|
||||
void f(const V &);
|
||||
};
|
||||
|
||||
void g() {
|
||||
extern V s;
|
||||
s.f({"foo", "bar"});
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue