This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rG8fc3d719eee7: Stop wrapping GCCAsmStmts inside StmtExprs to 
destruct temporaries (authored by ahatanak).

Changed prior to commit:
  https://reviews.llvm.org/D125936?vs=437796&id=438076#toc

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D125936/new/

https://reviews.llvm.org/D125936

Files:
  clang/lib/CodeGen/CGStmt.cpp
  clang/lib/Parse/ParseStmt.cpp
  clang/lib/Sema/SemaStmtAsm.cpp
  clang/test/CodeGenCXX/asm.cpp
  clang/test/CodeGenObjC/asm.m
  clang/test/SemaTemplate/instantiate-expr-1.cpp

Index: clang/test/SemaTemplate/instantiate-expr-1.cpp
===================================================================
--- clang/test/SemaTemplate/instantiate-expr-1.cpp
+++ clang/test/SemaTemplate/instantiate-expr-1.cpp
@@ -190,3 +190,19 @@
     test_asm_tied(1.f); // expected-note {{instantiation of}}
   }
 }
+
+namespace TestAsmCleanup {
+struct S {
+  operator int() const { return 1; }
+  ~S();
+};
+
+template <class T>
+void foo() {
+  __asm__ __volatile__("%[i]"
+                       :
+                       : [i] "r"(-S()));
+}
+
+void test() { foo<void>(); }
+} // namespace TestAsmCleanup
Index: clang/test/CodeGenObjC/asm.m
===================================================================
--- /dev/null
+++ clang/test/CodeGenObjC/asm.m
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fblocks -fobjc-arc -emit-llvm -o - %s | FileCheck %s
+
+// CHECK: %[[STRUCT_A:.*]] = type { ptr }
+
+typedef struct {
+  id f;
+} A;
+
+id a;
+
+// Check that the compound literal is destructed at the end of the enclosing scope.
+
+// CHECK-LABEL: define void @foo0()
+// CHECK: %[[_COMPOUNDLITERAL:.*]] = alloca %[[STRUCT_A]], align 8
+// CHECK: getelementptr inbounds %[[STRUCT_A]], ptr %[[_COMPOUNDLITERAL]], i32 0, i32 0
+// CHECK: %[[F1:.*]] = getelementptr inbounds %[[STRUCT_A]], ptr %[[_COMPOUNDLITERAL]], i32 0, i32 0
+// CHECK: %[[V2:.*]] = load ptr, ptr %[[F1]], align 8
+// CHECK: call void asm sideeffect "", "r,~{dirflag},~{fpsr},~{flags}"(ptr %[[V2]])
+// CHECK: call void asm sideeffect "",
+// CHECK: call void @__destructor_8_s0(ptr %[[_COMPOUNDLITERAL]])
+
+void foo0() {
+  asm("" : : "r"(((A){a}).f) );
+  asm("");
+}
Index: clang/test/CodeGenCXX/asm.cpp
===================================================================
--- clang/test/CodeGenCXX/asm.cpp
+++ clang/test/CodeGenCXX/asm.cpp
@@ -1,4 +1,6 @@
-// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -triple i386-unknown-unknown -fblocks -emit-llvm %s -o - | FileCheck %s
+
+// CHECK: %[[STRUCT_A:.*]] = type { i8 }
 
 struct A
 {
@@ -12,3 +14,39 @@
     asm("" : : "r"(foo(a)) ); // rdar://8540491
     // CHECK: call void @_ZN1AD1Ev
 }
+
+namespace TestTemplate {
+// Check that the temporary is destructed after the first asm statement.
+
+// CHECK: define {{.*}}void @_ZN12TestTemplate4foo0IvEEvR1A(
+// CHECK: %[[AGG_TMP:.*]] = alloca %[[STRUCT_A]],
+// CHECK: %[[CALL:.*]] = call noundef i32 @_Z3foo1A({{.*}}%[[AGG_TMP]])
+// CHECK: call void asm sideeffect "", "r,~{dirflag},~{fpsr},~{flags}"(i32 %[[CALL]])
+// CHECK: call void @_ZN1AD1Ev({{.*}}%[[AGG_TMP]])
+// CHECK: call void asm sideeffect "",
+
+template <class T>
+void foo0(A &a) {
+  asm("" : : "r"(foo(a)) );
+  asm("");
+}
+
+void test0(A &a) { foo0<void>(a); }
+
+// Check that the block capture is destructed at the end of the enclosing scope.
+
+// CHECK: define {{.*}}void @_ZN12TestTemplate4foo1IvEEv1A(
+// CHECK: %[[BLOCK:.*]] = alloca <{ ptr, i32, i32, ptr, ptr, %[[STRUCT_A]] }>, align 4
+// CHECK: %[[BLOCK_CAPTURED:.*]] = getelementptr inbounds <{ ptr, i32, i32, ptr, ptr, %[[STRUCT_A]] }>, ptr %[[BLOCK]], i32 0, i32 5
+// CHECK: call void asm sideeffect "", "r,~{dirflag},~{fpsr},~{flags}"(i32 %{{.*}})
+// CHECK: call void asm sideeffect "", "~{dirflag},~{fpsr},~{flags}"()
+// CHECK: call void @_ZN1AD1Ev({{.*}} %[[BLOCK_CAPTURED]])
+
+template <class T>
+void foo1(A a) {
+  asm("" : : "r"(^{ (void)a; return 0; }()));
+  asm("");
+}
+
+void test1(A &a) { foo1<void>(a); }
+} // namespace TestTemplate
Index: clang/lib/Sema/SemaStmtAsm.cpp
===================================================================
--- clang/lib/Sema/SemaStmtAsm.cpp
+++ clang/lib/Sema/SemaStmtAsm.cpp
@@ -733,6 +733,9 @@
   }
   if (NS->isAsmGoto())
     setFunctionHasBranchIntoScope();
+
+  CleanupVarDeclMarking();
+  DiscardCleanupsInEvaluationContext();
   return NS;
 }
 
Index: clang/lib/Parse/ParseStmt.cpp
===================================================================
--- clang/lib/Parse/ParseStmt.cpp
+++ clang/lib/Parse/ParseStmt.cpp
@@ -325,7 +325,6 @@
     ProhibitAttributes(GNUAttrs);
     bool msAsm = false;
     Res = ParseAsmStatement(msAsm);
-    Res = Actions.ActOnFinishFullStmt(Res.get());
     if (msAsm) return Res;
     SemiError = "asm";
     break;
Index: clang/lib/CodeGen/CGStmt.cpp
===================================================================
--- clang/lib/CodeGen/CGStmt.cpp
+++ clang/lib/CodeGen/CGStmt.cpp
@@ -2289,6 +2289,9 @@
 }
 
 void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) {
+  // Pop all cleanup blocks at the end of the asm statement.
+  CodeGenFunction::RunCleanupsScope Cleanups(*this);
+
   // Assemble the final asm string.
   std::string AsmString = S.generateAsmString(getContext());
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to