[clang] 5e12002 - Revert "[clang][Interp] Support destructors"

Timm Bäder via cfe-commits cfe-commits at lists.llvm.org
Sun Mar 5 04:18:40 PST 2023


Author: Timm Bäder
Date: 2023-03-05T13:18:13+01:00
New Revision: 5e12002c6cea7601073888c2281525131caa77e3

URL: https://github.com/llvm/llvm-project/commit/5e12002c6cea7601073888c2281525131caa77e3
DIFF: https://github.com/llvm/llvm-project/commit/5e12002c6cea7601073888c2281525131caa77e3.diff

LOG: Revert "[clang][Interp] Support destructors"

This reverts commit 78e4237460bf58f3d6b75f275e0424f38e3b1d04.

This breaks the memory sanitizer builder:
https://lab.llvm.org/buildbot/#/builders/5/builds/31959

Added: 
    

Modified: 
    clang/lib/AST/Interp/ByteCodeExprGen.cpp
    clang/lib/AST/Interp/ByteCodeExprGen.h
    clang/lib/AST/Interp/ByteCodeStmtGen.cpp
    clang/test/AST/Interp/cxx20.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
index 488d07e09d9b5..bc682c92c143f 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -26,10 +26,10 @@ namespace clang {
 namespace interp {
 
 /// Scope used to handle temporaries in toplevel variable declarations.
-template <class Emitter> class DeclScope final : public VariableScope<Emitter> {
+template <class Emitter> class DeclScope final : public LocalScope<Emitter> {
 public:
   DeclScope(ByteCodeExprGen<Emitter> *Ctx, const ValueDecl *VD)
-      : VariableScope<Emitter>(Ctx), Scope(Ctx->P, VD) {}
+      : LocalScope<Emitter>(Ctx), Scope(Ctx->P, VD) {}
 
   void addExtended(const Scope::Local &Local) override {
     return this->addLocal(Local);
@@ -1857,80 +1857,6 @@ void ByteCodeExprGen<Emitter>::emitCleanup() {
     C->emitDestruction();
 }
 
-/// When calling this, we have a pointer of the local-to-destroy
-/// on the stack.
-/// Emit destruction of record types (or arrays of record types).
-/// FIXME: Handle virtual destructors.
-template <class Emitter>
-bool ByteCodeExprGen<Emitter>::emitRecordDestruction(const Descriptor *Desc) {
-  assert(Desc);
-  assert(!Desc->isPrimitive());
-  assert(!Desc->isPrimitiveArray());
-
-  // Arrays.
-  if (Desc->isArray()) {
-    const Descriptor *ElemDesc = Desc->ElemDesc;
-    const Record *ElemRecord = ElemDesc->ElemRecord;
-    assert(ElemRecord); // This is not a primitive array.
-
-    if (const CXXDestructorDecl *Dtor = ElemRecord->getDestructor();
-        Dtor && !Dtor->isTrivial()) {
-      for (ssize_t I = Desc->getNumElems() - 1; I >= 0; --I) {
-        if (!this->emitConstUint64(I, SourceInfo{}))
-          return false;
-        if (!this->emitArrayElemPtrUint64(SourceInfo{}))
-          return false;
-        if (!this->emitRecordDestruction(Desc->ElemDesc))
-          return false;
-      }
-    }
-    return this->emitPopPtr(SourceInfo{});
-  }
-
-  const Record *R = Desc->ElemRecord;
-  assert(R);
-  // First, destroy all fields.
-  for (const Record::Field &Field : llvm::reverse(R->fields())) {
-    const Descriptor *D = Field.Desc;
-    if (!D->isPrimitive() && !D->isPrimitiveArray()) {
-      if (!this->emitDupPtr(SourceInfo{}))
-        return false;
-      if (!this->emitGetPtrField(Field.Offset, SourceInfo{}))
-        return false;
-      if (!this->emitRecordDestruction(D))
-        return false;
-    }
-  }
-
-  // FIXME: Unions need to be handled 
diff erently here. We don't want to
-  //   call the destructor of its members.
-
-  // Now emit the destructor and recurse into base classes.
-  if (const CXXDestructorDecl *Dtor = R->getDestructor();
-      Dtor && !Dtor->isTrivial()) {
-    const Function *DtorFunc = getFunction(Dtor);
-    if (DtorFunc && DtorFunc->isConstexpr()) {
-      assert(DtorFunc->hasThisPointer());
-      assert(DtorFunc->getNumParams() == 1);
-      if (!this->emitDupPtr(SourceInfo{}))
-        return false;
-      if (!this->emitCall(DtorFunc, SourceInfo{}))
-        return false;
-    }
-  }
-
-  for (const Record::Base &Base : llvm::reverse(R->bases())) {
-    if (!this->emitGetPtrBase(Base.Offset, SourceInfo{}))
-      return false;
-    if (!this->emitRecordDestruction(Base.Desc))
-      return false;
-  }
-  // FIXME: Virtual bases.
-
-  // Remove the instance pointer.
-  return this->emitPopPtr(SourceInfo{});
-}
-
 namespace clang {
 namespace interp {
 

diff  --git a/clang/lib/AST/Interp/ByteCodeExprGen.h b/clang/lib/AST/Interp/ByteCodeExprGen.h
index 4d929278f29c8..231f39ff8bd6d 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.h
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.h
@@ -256,8 +256,6 @@ class ByteCodeExprGen : public ConstStmtVisitor<ByteCodeExprGen<Emitter>, bool>,
     return FPO.getRoundingMode();
   }
 
-  bool emitRecordDestruction(const Descriptor *Desc);
-
 protected:
   /// Variable to storage mapping.
   llvm::DenseMap<const ValueDecl *, Scope::Local> Locals;
@@ -335,20 +333,9 @@ template <class Emitter> class LocalScope : public VariableScope<Emitter> {
     this->Ctx->Descriptors[*Idx].emplace_back(Local);
   }
 
-  /// Emit destruction of the local variable. This includes
-  /// object destructors.
   void emitDestruction() override {
     if (!Idx)
       return;
-    // Emit destructor calls for local variables of record
-    // type with a destructor.
-    for (Scope::Local &Local : this->Ctx->Descriptors[*Idx]) {
-      if (!Local.Desc->isPrimitive() && !Local.Desc->isPrimitiveArray()) {
-        this->Ctx->emitGetPtrLocal(Local.Offset, SourceInfo{});
-        this->Ctx->emitRecordDestruction(Local.Desc);
-      }
-    }
-
     this->Ctx->emitDestroy(*Idx, SourceInfo{});
   }
 

diff  --git a/clang/lib/AST/Interp/ByteCodeStmtGen.cpp b/clang/lib/AST/Interp/ByteCodeStmtGen.cpp
index 547a24e5b19d3..a4be86c0e0639 100644
--- a/clang/lib/AST/Interp/ByteCodeStmtGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeStmtGen.cpp
@@ -428,7 +428,6 @@ bool ByteCodeStmtGen<Emitter>::visitBreakStmt(const BreakStmt *S) {
   if (!BreakLabel)
     return false;
 
-  this->emitCleanup();
   return this->jump(*BreakLabel);
 }
 
@@ -437,7 +436,6 @@ bool ByteCodeStmtGen<Emitter>::visitContinueStmt(const ContinueStmt *S) {
   if (!ContinueLabel)
     return false;
 
-  this->emitCleanup();
   return this->jump(*ContinueLabel);
 }
 

diff  --git a/clang/test/AST/Interp/cxx20.cpp b/clang/test/AST/Interp/cxx20.cpp
index 480d6e8e9a8a2..cc37722730fc2 100644
--- a/clang/test/AST/Interp/cxx20.cpp
+++ b/clang/test/AST/Interp/cxx20.cpp
@@ -271,250 +271,3 @@ namespace ConstThis {
                                        // ref-error {{must have constant destruction}} \
                                        // ref-note {{in call to}}
 };
-
-namespace Destructors {
-
-  class Inc final {
-  public:
-    int &I;
-    constexpr Inc(int &I) : I(I) {}
-    constexpr ~Inc() {
-      I++;
-    }
-  };
-
-  class Dec final {
-  public:
-    int &I;
-    constexpr Dec(int &I) : I(I) {}
-    constexpr ~Dec() {
-      I--;
-    }
-  };
-
-
-
-  constexpr int m() {
-    int i = 0;
-    {
-      Inc f1(i);
-      Inc f2(i);
-      Inc f3(i);
-    }
-    return i;
-  }
-  static_assert(m() == 3, "");
-
-
-  constexpr int C() {
-    int i = 0;
-
-    while (i < 10) {
-      Inc inc(i);
-      continue;
-      Dec dec(i);
-    }
-    return i;
-  }
-  static_assert(C() == 10, "");
-
-
-  constexpr int D() {
-    int i = 0;
-
-    {
-      Inc i1(i);
-      {
-        Inc i2(i);
-        return i;
-      }
-    }
-
-    return i;
-  }
-  static_assert(D() == 0, "");
-
-  constexpr int E() {
-    int i = 0;
-
-    for(;;) {
-      Inc i1(i);
-      break;
-    }
-    return i;
-  }
-  static_assert(E() == 1, "");
-
-
-  /// FIXME: This should be rejected, since we call the destructor
-  ///   twice. However, GCC doesn't care either.
-  constexpr int ManualDtor() {
-    int i = 0;
-    {
-      Inc I(i); // ref-note {{destroying object 'I' whose lifetime has already ended}}
-      I.~Inc();
-    }
-    return i;
-  }
-  static_assert(ManualDtor() == 1, ""); // expected-error {{static assertion failed}} \
-                                        // expected-note {{evaluates to '2 == 1'}} \
-                                        // ref-error {{not an integral constant expression}} \
-                                        // ref-note {{in call to 'ManualDtor()'}}
-
-  constexpr void doInc(int &i) {
-    Inc I(i);
-    return;
-  }
-  constexpr int testInc() {
-    int i = 0;
-    doInc(i);
-    return i;
-  }
-  static_assert(testInc() == 1, "");
-  constexpr void doInc2(int &i) {
-    Inc I(i);
-    // No return statement.
-  }
-   constexpr int testInc2() {
-    int i = 0;
-    doInc2(i);
-    return i;
-  }
-  static_assert(testInc2() == 1, "");
-
-
-  namespace DtorOrder {
-    class A {
-      public:
-      int &I;
-      constexpr A(int &I) : I(I) {}
-      constexpr ~A() {
-        I = 1337;
-      }
-    };
-
-    class B : public A {
-      public:
-      constexpr B(int &I) : A(I) {}
-      constexpr ~B() {
-        I = 42;
-      }
-    };
-
-    constexpr int foo() {
-      int i = 0;
-      {
-        B b(i);
-      }
-      return i;
-    }
-
-    static_assert(foo() == 1337);
-  }
-
-  class FieldDtor1 {
-  public:
-    Inc I1;
-    Inc I2;
-    constexpr FieldDtor1(int &I) : I1(I), I2(I){}
-  };
-
-  constexpr int foo2() {
-    int i = 0;
-    {
-      FieldDtor1 FD1(i);
-    }
-    return i;
-  }
-
-  static_assert(foo2() == 2);
-
-  class FieldDtor2 {
-  public:
-    Inc Incs[3];
-    constexpr FieldDtor2(int &I)  : Incs{Inc(I), Inc(I), Inc(I)} {}
-  };
-
-  constexpr int foo3() {
-    int i = 0;
-    {
-      FieldDtor2 FD2(i);
-    }
-    return i;
-  }
-
-  static_assert(foo3() == 3);
-
-  struct ArrD {
-    int index;
-    int *arr;
-    int &p;
-    constexpr ~ArrD() {
-      arr[p] = index;
-      ++p;
-    }
-  };
-  constexpr bool ArrayOrder() {
-    int order[3] = {0, 0, 0};
-    int p = 0;
-    {
-      ArrD ds[3] = {
-        {1, order, p},
-        {2, order, p},
-        {3, order, p},
-      };
-      // ds will be destroyed.
-    }
-    return order[0] == 3 && order[1] == 2 && order[2] == 1;
-  }
-  static_assert(ArrayOrder());
-
-
-  // Static members aren't destroyed.
-  class Dec2 {
-  public:
-    int A = 0;
-    constexpr ~Dec2() {
-      A++;
-    }
-  };
-  class Foo {
-  public:
-    static constexpr Dec2 a;
-    static Dec2 b;
-  };
-  static_assert(Foo::a.A == 0);
-  constexpr bool f() {
-    Foo f;
-    return true;
-  }
-  static_assert(Foo::a.A == 0);
-  static_assert(f());
-  static_assert(Foo::a.A == 0);
-
-
-  struct NotConstexpr {
-    NotConstexpr() {}
-    ~NotConstexpr() {}
-  };
-
-  struct Outer {
-    constexpr Outer() = default;
-    constexpr ~Outer();
-
-    constexpr int foo() {
-      return 12;
-    }
-
-    constexpr int bar()const  {
-      return Outer{}.foo();
-    }
-
-    static NotConstexpr Val;
-  };
-
-  constexpr Outer::~Outer() {}
-
-  constexpr Outer O;
-  static_assert(O.bar() == 12);
-}


        


More information about the cfe-commits mailing list