r191150 - PR17295: Do not allow explicit conversion functions to be used in cases where

Eli Friedman eli.friedman at gmail.com
Mon Sep 23 11:06:22 PDT 2013


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());
>    }
>

?

-Eli
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20130923/64a9ab4c/attachment.html>


More information about the cfe-commits mailing list