[cfe-commits] r151577 - in /cfe/trunk: include/clang/Sema/Overload.h lib/Sema/SemaOverload.cpp test/SemaCXX/cxx0x-initializer-constructor.cpp
Sebastian Redl
sebastian.redl at getdesigned.at
Mon Feb 27 14:38:27 PST 2012
Author: cornedbee
Date: Mon Feb 27 16:38:26 2012
New Revision: 151577
URL: http://llvm.org/viewvc/llvm-project?rev=151577&view=rev
Log:
Implement a FIXME for conversion sequence distinction. Should fix PR12092.
Modified:
cfe/trunk/include/clang/Sema/Overload.h
cfe/trunk/lib/Sema/SemaOverload.cpp
cfe/trunk/test/SemaCXX/cxx0x-initializer-constructor.cpp
Modified: cfe/trunk/include/clang/Sema/Overload.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Overload.h?rev=151577&r1=151576&r2=151577&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Overload.h (original)
+++ cfe/trunk/include/clang/Sema/Overload.h Mon Feb 27 16:38:26 2012
@@ -401,11 +401,15 @@
};
/// 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 @@
};
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 @@
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.
Modified: cfe/trunk/lib/Sema/SemaOverload.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=151577&r1=151576&r2=151577&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaOverload.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOverload.cpp Mon Feb 27 16:38:26 2012
@@ -3163,9 +3163,15 @@
// 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 @@
// 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 @@
Result = ICS;
}
Result.setListInitializationSequence();
+ Result.setStdInitializerListElement(toStdInitializerList);
return Result;
}
Modified: cfe/trunk/test/SemaCXX/cxx0x-initializer-constructor.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx0x-initializer-constructor.cpp?rev=151577&r1=151576&r2=151577&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/cxx0x-initializer-constructor.cpp (original)
+++ cfe/trunk/test/SemaCXX/cxx0x-initializer-constructor.cpp Mon Feb 27 16:38:26 2012
@@ -194,3 +194,21 @@
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"});
+ }
+
+}
More information about the cfe-commits
mailing list