r191150 - PR17295: Do not allow explicit conversion functions to be used in cases where
Richard Smith
richard at metafoo.co.uk
Mon Sep 23 16:15:30 PDT 2013
On Mon, Sep 23, 2013 at 11:06 AM, Eli Friedman <eli.friedman at gmail.com>wrote:
> On Sat, Sep 21, 2013 at 2:55 PM, Richard Smith <richard-llvm at metafoo.co.uk
> > 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.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20130923/6d3c04d4/attachment.html>
More information about the cfe-commits
mailing list