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