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