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