[clang] Use pushFullExprCleanup for deferred destroy (PR #88670)

Utkarsh Saxena via cfe-commits cfe-commits at lists.llvm.org
Mon Apr 15 12:27:59 PDT 2024


https://github.com/usx95 updated https://github.com/llvm/llvm-project/pull/88670

>From 599283c1845a25afe90163a5f0a7a809c622a521 Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena <usx at google.com>
Date: Sun, 14 Apr 2024 21:21:21 +0000
Subject: [PATCH 1/4] Use pushFullExprCleanup for deferred destroy

---
 clang/lib/CodeGen/CGDecl.cpp | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp
index 8bdafa7c569b08..3f05ebb561da57 100644
--- a/clang/lib/CodeGen/CGDecl.cpp
+++ b/clang/lib/CodeGen/CGDecl.cpp
@@ -2216,8 +2216,11 @@ void CodeGenFunction::pushDestroyAndDeferDeactivation(
 void CodeGenFunction::pushDestroyAndDeferDeactivation(
     CleanupKind cleanupKind, Address addr, QualType type, Destroyer *destroyer,
     bool useEHCleanupForArray) {
-  pushCleanupAndDeferDeactivation<DestroyObject>(
-      cleanupKind, addr, type, destroyer, useEHCleanupForArray);
+  llvm::Instruction *DominatingIP =
+      Builder.CreateFlagLoad(llvm::Constant::getNullValue(Int8PtrTy));
+  pushDestroy(cleanupKind, addr, type, destroyer, useEHCleanupForArray);
+  DeferredDeactivationCleanupStack.push_back(
+      {EHStack.stable_begin(), DominatingIP});
 }
 
 void CodeGenFunction::pushStackRestore(CleanupKind Kind, Address SPMem) {

>From a27c77a1506d8044d55eb6961ba69229cb9c1fd7 Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena <usx at google.com>
Date: Mon, 15 Apr 2024 12:41:27 +0000
Subject: [PATCH 2/4] Add tests

---
 .../CodeGenCXX/destory-with-init-list.cpp     | 49 +++++++++++++++++++
 1 file changed, 49 insertions(+)
 create mode 100644 clang/test/CodeGenCXX/destory-with-init-list.cpp

diff --git a/clang/test/CodeGenCXX/destory-with-init-list.cpp b/clang/test/CodeGenCXX/destory-with-init-list.cpp
new file mode 100644
index 00000000000000..b9495db3a23d6f
--- /dev/null
+++ b/clang/test/CodeGenCXX/destory-with-init-list.cpp
@@ -0,0 +1,49 @@
+// RUN: %clang_cc1 -emit-llvm -fexceptions -o - %s -triple x86_64-linux-gnu | FileCheck -check-prefixes=EH,CHECK %s
+// RUN: %clang_cc1 -emit-llvm -o - %s -triple x86_64-linux-gnu | FileCheck -check-prefixes=NOEH,CHECK %s
+namespace std {
+  typedef decltype(sizeof(int)) size_t;
+
+  // libc++'s implementation
+  template <class _E>
+  class initializer_list
+  {
+    const _E* __begin_;
+    size_t    __size_;
+    initializer_list(const _E* __b, size_t __s);
+  };
+}
+
+class Object {
+public:
+  Object() = default;
+  struct KV;
+  explicit Object(std::initializer_list<KV> Properties);
+};
+
+class Value {
+public:
+  Value(std::initializer_list<Value> Elements);
+  Value(const char *V);
+  ~Value();
+};
+
+class ObjectKey {
+public:
+  ObjectKey(const char *S);
+  ~ObjectKey();
+};
+
+struct Object::KV {
+  ObjectKey K;
+  Value V;
+};
+
+bool foo();
+void bar() {
+  // Verify we use conditional cleanups.
+  foo() ? Object{{"key1", {"val1", "val2"}}} : Object{{"key2", "val2"}};
+  // CHECK:   cond.true:
+  // EH:        invoke void @_ZN9ObjectKeyC1EPKc
+  // NOEH:      call void @_ZN9ObjectKeyC1EPKc
+  // CHECK:     store ptr %K, ptr %cond-cleanup.save
+}

>From 33fda57e72f08d6f1d30667b10a5c05d2453b34a Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena <usx at google.com>
Date: Mon, 15 Apr 2024 18:49:59 +0000
Subject: [PATCH 3/4] Moved test to existing file

---
 .../CodeGenCXX/control-flow-in-stmt-expr.cpp  | 56 ++++++++++++++++++-
 .../CodeGenCXX/destory-with-init-list.cpp     | 49 ----------------
 2 files changed, 55 insertions(+), 50 deletions(-)
 delete mode 100644 clang/test/CodeGenCXX/destory-with-init-list.cpp

diff --git a/clang/test/CodeGenCXX/control-flow-in-stmt-expr.cpp b/clang/test/CodeGenCXX/control-flow-in-stmt-expr.cpp
index ffde1bd6a724d8..295a9b118ff63d 100644
--- a/clang/test/CodeGenCXX/control-flow-in-stmt-expr.cpp
+++ b/clang/test/CodeGenCXX/control-flow-in-stmt-expr.cpp
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 --std=c++20 -triple x86_64-linux-gnu -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 --std=c++20 -fexceptions -triple x86_64-linux-gnu -emit-llvm %s -o - | FileCheck -check-prefixes=EH %s
+// RUN: %clang_cc1 --std=c++20 -triple x86_64-linux-gnu -emit-llvm %s -o - | FileCheck -check-prefixes=NOEH,CHECK %s
 
 struct Printy {
   Printy(const char *name) : name(name) {}
@@ -349,6 +350,59 @@ void NewArrayInit() {
   // CHECK-NEXT:    br label %return
 }
 
+namespace std {
+  typedef decltype(sizeof(int)) size_t;
+
+  // libc++'s implementation
+  template <class _E>
+  class initializer_list
+  {
+    const _E* __begin_;
+    size_t    __size_;
+    initializer_list(const _E* __b, size_t __s);
+  };
+}
+
+class Object {
+public:
+  Object() = default;
+  struct KV;
+  Object(std::initializer_list<KV>);
+  Object(KV);
+};
+
+class Value {
+public:
+  Value(std::initializer_list<Value>);
+  Value(const char *V);
+  ~Value();
+};
+
+class ObjectKey {
+public:
+  ObjectKey(const char *S);
+  ~ObjectKey();
+};
+
+struct Object::KV {
+  ObjectKey K;
+  Value V;
+};
+
+void DestroyInConditionalCleanup() {
+  // EH-LABEL: DestroyInConditionalCleanupv()
+  // NOEH-LABEL: DestroyInConditionalCleanupv()
+  // Verify we use conditional cleanups.
+  foo() ? Object{{"key1", {"val1", "val2"}}} : Object{{"key2", "val2"}};
+  // NOEH:   cond.true:
+  // NOEH:      call void @_ZN9ObjectKeyC1EPKc
+  // NOEH:      store ptr %K, ptr %cond-cleanup.save
+
+  // EH:   cond.true:
+  // EH:        invoke void @_ZN9ObjectKeyC1EPKc
+  // EH:        store ptr %K, ptr %cond-cleanup.save
+}
+
 void ArrayInitWithContinue() {
   // CHECK-LABEL: @_Z21ArrayInitWithContinuev
   // Verify that we start to emit the array destructor.
diff --git a/clang/test/CodeGenCXX/destory-with-init-list.cpp b/clang/test/CodeGenCXX/destory-with-init-list.cpp
deleted file mode 100644
index b9495db3a23d6f..00000000000000
--- a/clang/test/CodeGenCXX/destory-with-init-list.cpp
+++ /dev/null
@@ -1,49 +0,0 @@
-// RUN: %clang_cc1 -emit-llvm -fexceptions -o - %s -triple x86_64-linux-gnu | FileCheck -check-prefixes=EH,CHECK %s
-// RUN: %clang_cc1 -emit-llvm -o - %s -triple x86_64-linux-gnu | FileCheck -check-prefixes=NOEH,CHECK %s
-namespace std {
-  typedef decltype(sizeof(int)) size_t;
-
-  // libc++'s implementation
-  template <class _E>
-  class initializer_list
-  {
-    const _E* __begin_;
-    size_t    __size_;
-    initializer_list(const _E* __b, size_t __s);
-  };
-}
-
-class Object {
-public:
-  Object() = default;
-  struct KV;
-  explicit Object(std::initializer_list<KV> Properties);
-};
-
-class Value {
-public:
-  Value(std::initializer_list<Value> Elements);
-  Value(const char *V);
-  ~Value();
-};
-
-class ObjectKey {
-public:
-  ObjectKey(const char *S);
-  ~ObjectKey();
-};
-
-struct Object::KV {
-  ObjectKey K;
-  Value V;
-};
-
-bool foo();
-void bar() {
-  // Verify we use conditional cleanups.
-  foo() ? Object{{"key1", {"val1", "val2"}}} : Object{{"key2", "val2"}};
-  // CHECK:   cond.true:
-  // EH:        invoke void @_ZN9ObjectKeyC1EPKc
-  // NOEH:      call void @_ZN9ObjectKeyC1EPKc
-  // CHECK:     store ptr %K, ptr %cond-cleanup.save
-}

>From cc9d35c6f1d614de1edee8d161cf7dbea080916d Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena <usx at google.com>
Date: Mon, 15 Apr 2024 19:27:23 +0000
Subject: [PATCH 4/4] Further reduce test

---
 .../CodeGenCXX/control-flow-in-stmt-expr.cpp  | 63 ++++++-------------
 1 file changed, 19 insertions(+), 44 deletions(-)

diff --git a/clang/test/CodeGenCXX/control-flow-in-stmt-expr.cpp b/clang/test/CodeGenCXX/control-flow-in-stmt-expr.cpp
index 295a9b118ff63d..95deee8bb1f1f2 100644
--- a/clang/test/CodeGenCXX/control-flow-in-stmt-expr.cpp
+++ b/clang/test/CodeGenCXX/control-flow-in-stmt-expr.cpp
@@ -350,57 +350,32 @@ void NewArrayInit() {
   // CHECK-NEXT:    br label %return
 }
 
-namespace std {
-  typedef decltype(sizeof(int)) size_t;
-
-  // libc++'s implementation
-  template <class _E>
-  class initializer_list
-  {
-    const _E* __begin_;
-    size_t    __size_;
-    initializer_list(const _E* __b, size_t __s);
-  };
-}
-
-class Object {
-public:
-  Object() = default;
-  struct KV;
-  Object(std::initializer_list<KV>);
-  Object(KV);
-};
-
-class Value {
-public:
-  Value(std::initializer_list<Value>);
-  Value(const char *V);
-  ~Value();
-};
-
-class ObjectKey {
-public:
-  ObjectKey(const char *S);
-  ~ObjectKey();
-};
-
-struct Object::KV {
-  ObjectKey K;
-  Value V;
-};
-
 void DestroyInConditionalCleanup() {
   // EH-LABEL: DestroyInConditionalCleanupv()
   // NOEH-LABEL: DestroyInConditionalCleanupv()
+  struct A {
+    A() {}
+    ~A() {}
+  };
+
+  struct Value {
+    Value(A) {}
+    ~Value() {}
+  };
+
+  struct V2 {
+    Value K;
+    Value V;
+  };
   // Verify we use conditional cleanups.
-  foo() ? Object{{"key1", {"val1", "val2"}}} : Object{{"key2", "val2"}};
+  (void)(foo() ? V2{A(), A()} : V2{A(), A()});
   // NOEH:   cond.true:
-  // NOEH:      call void @_ZN9ObjectKeyC1EPKc
-  // NOEH:      store ptr %K, ptr %cond-cleanup.save
+  // NOEH:      call void @_ZZ27DestroyInConditionalCleanupvEN1AC1Ev
+  // NOEH:      store ptr %{{.*}}, ptr %cond-cleanup.save
 
   // EH:   cond.true:
-  // EH:        invoke void @_ZN9ObjectKeyC1EPKc
-  // EH:        store ptr %K, ptr %cond-cleanup.save
+  // EH:        invoke void @_ZZ27DestroyInConditionalCleanupvEN1AC1Ev
+  // EH:        store ptr %{{.*}}, ptr %cond-cleanup.save
 }
 
 void ArrayInitWithContinue() {



More information about the cfe-commits mailing list