<div dir="ltr">On Mon, Sep 23, 2013 at 11:06 AM, Eli Friedman <span dir="ltr"><<a href="mailto:eli.friedman@gmail.com" target="_blank">eli.friedman@gmail.com</a>></span> wrote:<br><div class="gmail_extra"><div class="gmail_quote">
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div><div class="h5">On Sat, Sep 21, 2013 at 2:55 PM, Richard Smith <span dir="ltr"><<a href="mailto:richard-llvm@metafoo.co.uk" target="_blank">richard-llvm@metafoo.co.uk</a>></span> wrote:<br>
</div></div><div class="gmail_extra"><div class="gmail_quote"><div><div class="h5">
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: rsmith<br>
Date: Sat Sep 21 16:55:46 2013<br>
New Revision: 191150<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=191150&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=191150&view=rev</a><br>
Log:<br>
PR17295: Do not allow explicit conversion functions to be used in cases where<br>
an additional conversion (other than a qualification conversion) would be<br>
required after the explicit conversion.<br>
<br>
Conversely, do allow explicit conversion functions to be used when initializing<br>
a temporary for a reference binding in direct-list-initialization.<br>
<br>
Modified:<br>
cfe/trunk/include/clang/Sema/Initialization.h<br>
cfe/trunk/lib/Sema/SemaInit.cpp<br>
cfe/trunk/lib/Sema/SemaOverload.cpp<br>
cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp<br>
cfe/trunk/test/SemaCXX/explicit.cpp<br>
<br>
Modified: cfe/trunk/include/clang/Sema/Initialization.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Initialization.h?rev=191150&r1=191149&r2=191150&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Initialization.h?rev=191150&r1=191149&r2=191150&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/Sema/Initialization.h (original)<br>
+++ cfe/trunk/include/clang/Sema/Initialization.h Sat Sep 21 16:55:46 2013<br>
@@ -853,6 +853,10 @@ public:<br>
const InitializationKind &Kind,<br>
MultiExprArg Args,<br>
bool InInitList = false);<br>
+ void InitializeFrom(Sema &S, const InitializedEntity &Entity,<br>
+ const InitializationKind &Kind, MultiExprArg Args,<br>
+ bool InInitList);<br>
+<br>
~InitializationSequence();<br>
<br>
/// \brief Perform the actual initialization of the given entity based on<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaInit.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaInit.cpp?rev=191150&r1=191149&r2=191150&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaInit.cpp?rev=191150&r1=191149&r2=191150&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Sema/SemaInit.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaInit.cpp Sat Sep 21 16:55:46 2013<br>
@@ -3346,6 +3346,33 @@ static void TryListInitialization(Sema &<br>
return;<br>
}<br>
}<br>
+ if (S.getLangOpts().CPlusPlus && !DestType->isAggregateType() &&<br>
+ InitList->getNumInits() == 1 &&<br>
+ InitList->getInit(0)->getType()->isRecordType()) {<br>
+ // - Otherwise, if the initializer list has a single element of type E<br>
+ // [...references are handled above...], the object or reference is<br>
+ // initialized from that element; if a narrowing conversion is required<br>
+ // to convert the element to T, the program is ill-formed.<br>
+ //<br>
+ // Per core-24034, this is direct-initialization if we were performing<br>
+ // direct-list-initialization and copy-initialization otherwise.<br>
+ // We can't use InitListChecker for this, because it always performs<br>
+ // copy-initialization. This only matters if we might use an 'explicit'<br>
+ // conversion operator, so we only need to handle the cases where the source<br>
+ // is of record type.<br>
+ InitializationKind SubKind =<br>
+ Kind.getKind() == InitializationKind::IK_DirectList<br>
+ ? InitializationKind::CreateDirect(Kind.getLocation(),<br>
+ InitList->getLBraceLoc(),<br>
+ InitList->getRBraceLoc())<br>
+ : Kind;<br>
+ Expr *SubInit[1] = { InitList->getInit(0) };<br>
+ Sequence.InitializeFrom(S, Entity, SubKind, SubInit,<br>
+ /*TopLevelOfInitList*/true);<br>
+ if (Sequence)<br>
+ Sequence.RewrapReferenceInitList(Entity.getType(), InitList);<br>
+ return;<br>
+ }<br>
<br>
InitListChecker CheckInitList(S, Entity, InitList,<br>
DestType, /*VerifyOnly=*/true);<br>
@@ -4366,6 +4393,14 @@ InitializationSequence::InitializationSe<br>
MultiExprArg Args,<br>
bool TopLevelOfInitList)<br>
: FailedCandidateSet(Kind.getLocation()) {<br>
+ InitializeFrom(S, Entity, Kind, Args, TopLevelOfInitList);<br>
+}<br>
+<br>
+void InitializationSequence::InitializeFrom(Sema &S,<br>
+ const InitializedEntity &Entity,<br>
+ const InitializationKind &Kind,<br>
+ MultiExprArg Args,<br>
+ bool TopLevelOfInitList) {<br>
ASTContext &Context = S.Context;<br>
<br>
// Eliminate non-overload placeholder types in the arguments. We<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaOverload.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=191150&r1=191149&r2=191150&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=191150&r1=191149&r2=191150&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Sema/SemaOverload.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaOverload.cpp Sat Sep 21 16:55:46 2013<br>
@@ -5829,6 +5829,17 @@ Sema::AddConversionCandidate(CXXConversi<br>
ConvType = Conversion->getConversionType().getNonReferenceType();<br>
}<br>
<br>
+ // Per C++ [over.match.conv]p1, [over.match.ref]p1, an explicit conversion<br>
+ // operator is only a candidate if its return type is the target type or<br>
+ // can be converted to the target type with a qualification conversion.<br>
+ bool ObjCLifetimeConversion;<br>
+ QualType ToNonRefType = ToType.getNonReferenceType();<br>
+ if (Conversion->isExplicit() &&<br>
+ !Context.hasSameUnqualifiedType(ConvType, ToNonRefType) &&<br>
+ !IsQualificationConversion(ConvType, ToNonRefType, /*CStyle*/false,<br>
+ ObjCLifetimeConversion))<br>
+ return;<br>
+<br>
// Overload resolution is always an unevaluated context.<br>
EnterExpressionEvaluationContext Unevaluated(*this, Sema::Unevaluated);<br>
<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=191150&r1=191149&r2=191150&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=191150&r1=191149&r2=191150&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Sat Sep 21 16:55:46 2013<br>
@@ -3372,7 +3372,9 @@ void Sema::BuildVariableInstantiation(<br>
OldVar->isPreviousDeclInSameBlockScope());<br>
NewVar->setAccess(OldVar->getAccess());<br>
<br>
- if (!OldVar->isStaticDataMember()) {<br>
+ // For local variables, inherit the 'used' and 'referenced' flags from the<br>
+ // primary template.<br>
+ if (OldVar->getLexicalDeclContext()->isFunctionOrMethod()) {<br>
NewVar->setIsUsed(OldVar->isUsed(false));<br>
NewVar->setReferenced(OldVar->isReferenced());<br>
}<br></blockquote></div></div><div><br>?</div></div></div></div></blockquote><div><br></div><div>Whoops, that should not have been part of this commit. Reverted in r191237.</div></div></div></div>