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