Commit 40568fec authored by Akira Hatanaka's avatar Akira Hatanaka
Browse files

[CodeGen] Emit destructor calls to destruct compound literals

Fix a bug in IRGen where it wasn't destructing compound literals in C
that are ObjC pointer arrays or non-trivial structs. Also diagnose jumps
that enter or exit the lifetime of the compound literals.

rdar://problem/51867864

Differential Revision: https://reviews.llvm.org/D64464
parent ddfcda02
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

#include "clang/AST/DeclBase.h"
#include "clang/AST/DeclarationName.h"
#include "clang/AST/ExprCXX.h"
#include "clang/AST/NestedNameSpecifier.h"
#include "clang/AST/TemplateName.h"
#include "clang/AST/Type.h"
@@ -349,6 +350,10 @@ class TypeSourceInfo;
      return ToOrErr.takeError();
    }

    /// Import cleanup objects owned by ExprWithCleanup.
    llvm::Expected<ExprWithCleanups::CleanupObject>
    Import(ExprWithCleanups::CleanupObject From);

    /// Import the given type from the "from" context into the "to"
    /// context. A null type is imported as a null type (no error).
    ///
+7 −5
Original line number Diff line number Diff line
@@ -3321,13 +3321,15 @@ public:
/// literal is the extent of the enclosing scope.
class ExprWithCleanups final
    : public FullExpr,
      private llvm::TrailingObjects<ExprWithCleanups, BlockDecl *> {
      private llvm::TrailingObjects<
          ExprWithCleanups,
          llvm::PointerUnion<BlockDecl *, CompoundLiteralExpr *>> {
public:
  /// The type of objects that are kept in the cleanup.
  /// It's useful to remember the set of blocks;  we could also
  /// remember the set of temporaries, but there's currently
  /// no need.
  using CleanupObject = BlockDecl *;
  /// It's useful to remember the set of blocks and block-scoped compound
  /// literals; we could also remember the set of temporaries, but there's
  /// currently no need.
  using CleanupObject = llvm::PointerUnion<BlockDecl *, CompoundLiteralExpr *>;

private:
  friend class ASTStmtReader;
+1 −0
Original line number Diff line number Diff line
@@ -184,6 +184,7 @@ public:
  void dumpBareDeclRef(const Decl *D);
  void dumpName(const NamedDecl *ND);
  void dumpAccessSpecifier(AccessSpecifier AS);
  void dumpCleanupObject(const ExprWithCleanups::CleanupObject &C);

  void dumpDeclRef(const Decl *D, StringRef Label = {});

+4 −0
Original line number Diff line number Diff line
@@ -5543,6 +5543,8 @@ def note_enters_block_captures_weak : Note<
def note_enters_block_captures_non_trivial_c_struct : Note<
  "jump enters lifetime of block which captures a C struct that is non-trivial "
  "to destroy">;
def note_enters_compound_literal_scope : Note<
  "jump enters lifetime of a compound literal that is non-trivial to destruct">;
def note_exits_cleanup : Note<
  "jump exits scope of variable with __attribute__((cleanup))">;
@@ -5586,6 +5588,8 @@ def note_exits_block_captures_weak : Note<
def note_exits_block_captures_non_trivial_c_struct : Note<
  "jump exits lifetime of block which captures a C struct that is non-trivial "
  "to destroy">;
def note_exits_compound_literal_scope : Note<
  "jump exits lifetime of a compound literal that is non-trivial to destruct">;
def err_func_returning_qualified_void : ExtWarn<
  "function cannot return qualified void type %0">,
+2 −3
Original line number Diff line number Diff line
@@ -613,9 +613,8 @@ public:
  CleanupInfo Cleanup;
  /// ExprCleanupObjects - This is the stack of objects requiring
  /// cleanup that are created by the current full expression.  The
  /// element type here is ExprWithCleanups::Object.
  SmallVector<BlockDecl*, 8> ExprCleanupObjects;
  /// cleanup that are created by the current full expression.
  SmallVector<ExprWithCleanups::CleanupObject, 8> ExprCleanupObjects;
  /// Store a set of either DeclRefExprs or MemberExprs that contain a reference
  /// to a variable (constant) that may or may not be odr-used in this Expr, and
Loading