r183283 - Model temporary lifetime-extension explicitly in the AST. Use this model to
Timur Iskhodzhanov
timurrrr at google.com
Wed Jun 5 04:43:12 PDT 2013
2013/6/5 Richard Smith <richard-llvm at metafoo.co.uk>:
> +/// Determine the declaration which an initialized entity ultimately refers to,
> +/// for the purpose of lifetime-extending a temporary bound to a reference in
> +/// the initialization of \p Entity.
> +static const ValueDecl *
> +getDeclForTemporaryLifetimeExtension(const InitializedEntity &Entity,
> + const ValueDecl *FallbackDecl = 0) {
> + // C++11 [class.temporary]p5:
> + switch (Entity.getKind()) {
> + case InitializedEntity::EK_Variable:
> + // The temporary [...] persists for the lifetime of the reference
> + return Entity.getDecl();
> +
> + case InitializedEntity::EK_Member:
> + // For subobjects, we look at the complete object.
> + if (Entity.getParent())
> + return getDeclForTemporaryLifetimeExtension(*Entity.getParent(),
> + Entity.getDecl());
> +
> + // except:
> + // -- A temporary bound to a reference member in a constructor's
> + // ctor-initializer persists until the constructor exits.
> + return Entity.getDecl();
> +
> + case InitializedEntity::EK_Parameter:
> + // -- A temporary bound to a reference parameter in a function call
> + // persists until the completion of the full-expression containing
> + // the call.
> + case InitializedEntity::EK_Result:
> + // -- The lifetime of a temporary bound to the returned value in a
> + // function return statement is not extended; the temporary is
> + // destroyed at the end of the full-expression in the return statement.
> + case InitializedEntity::EK_New:
> + // -- A temporary bound to a reference in a new-initializer persists
> + // until the completion of the full-expression containing the
> + // new-initializer.
> + return 0;
> +
> + case InitializedEntity::EK_Temporary:
> + case InitializedEntity::EK_CompoundLiteralInit:
> + // We don't yet know the storage duration of the surrounding temporary.
> + // Assume it's got full-expression duration for now, it will patch up our
> + // storage duration if that's not correct.
> + return 0;
> +
> + case InitializedEntity::EK_ArrayElement:
> + // For subobjects, we look at the complete object.
> + return getDeclForTemporaryLifetimeExtension(*Entity.getParent(),
> + FallbackDecl);
> +
> + case InitializedEntity::EK_Base:
> + case InitializedEntity::EK_Delegating:
> + // We can reach this case for aggregate initialization in a constructor:
> + // struct A { int &&r; };
> + // struct B : A { B() : A{0} {} };
> + // In this case, use the innermost field decl as the context.
> + return FallbackDecl;
> +
> + case InitializedEntity::EK_BlockElement:
> + case InitializedEntity::EK_LambdaCapture:
> + case InitializedEntity::EK_Exception:
> + case InitializedEntity::EK_VectorElement:
> + case InitializedEntity::EK_ComplexElement:
> + llvm_unreachable("should not materialize a temporary to initialize this");
> + }
> +}
gcc 4.6.3 gives the following warning on this code:
In function ‘const clang::ValueDecl*
getDeclForTemporaryLifetimeExtension(const clang::InitializedEntity&,
const clang::ValueDecl*)’:
tools/clang/lib/Sema/SemaInit.cpp:5196:1: warning: control reaches end
of non-void function [-Wreturn-type]
More information about the cfe-commits
mailing list