[clang] 8fc3d71 - Stop wrapping GCCAsmStmts inside StmtExprs to destruct temporaries
Akira Hatanaka via cfe-commits
cfe-commits at lists.llvm.org
Fri Jun 17 17:29:10 PDT 2022
Author: Akira Hatanaka
Date: 2022-06-17T17:28:00-07:00
New Revision: 8fc3d719eee7ab41641506cbdc59f3ade0eb36e4
URL: https://github.com/llvm/llvm-project/commit/8fc3d719eee7ab41641506cbdc59f3ade0eb36e4
DIFF: https://github.com/llvm/llvm-project/commit/8fc3d719eee7ab41641506cbdc59f3ade0eb36e4.diff
LOG: Stop wrapping GCCAsmStmts inside StmtExprs to destruct temporaries
Instead, just pop the cleanups at the end of the asm statement.
This fixes an assertion failure in BuildStmtExpr. It also fixes a bug
where blocks and C compound literals were destructed at the end of the
asm statement instead of at the end of the enclosing scope.
Differential Revision: https://reviews.llvm.org/D125936
Added:
clang/test/CodeGenObjC/asm.m
Modified:
clang/lib/CodeGen/CGStmt.cpp
clang/lib/Parse/ParseStmt.cpp
clang/lib/Sema/SemaStmtAsm.cpp
clang/test/CodeGenCXX/asm.cpp
clang/test/SemaTemplate/instantiate-expr-1.cpp
Removed:
################################################################################
diff --git a/clang/lib/CodeGen/CGStmt.cpp b/clang/lib/CodeGen/CGStmt.cpp
index 2412c91d16fb..f3564eb78707 100644
--- a/clang/lib/CodeGen/CGStmt.cpp
+++ b/clang/lib/CodeGen/CGStmt.cpp
@@ -2289,6 +2289,9 @@ static void UpdateAsmCallInst(llvm::CallBase &Result, bool HasSideEffect,
}
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());
diff --git a/clang/lib/Parse/ParseStmt.cpp b/clang/lib/Parse/ParseStmt.cpp
index f43e5b4c8922..1f6c74aeae7e 100644
--- a/clang/lib/Parse/ParseStmt.cpp
+++ b/clang/lib/Parse/ParseStmt.cpp
@@ -325,7 +325,6 @@ StmtResult Parser::ParseStatementOrDeclarationAfterAttributes(
ProhibitAttributes(GNUAttrs);
bool msAsm = false;
Res = ParseAsmStatement(msAsm);
- Res = Actions.ActOnFinishFullStmt(Res.get());
if (msAsm) return Res;
SemiError = "asm";
break;
diff --git a/clang/lib/Sema/SemaStmtAsm.cpp b/clang/lib/Sema/SemaStmtAsm.cpp
index c147d26b2dff..1aa71fa75946 100644
--- a/clang/lib/Sema/SemaStmtAsm.cpp
+++ b/clang/lib/Sema/SemaStmtAsm.cpp
@@ -733,6 +733,9 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple,
}
if (NS->isAsmGoto())
setFunctionHasBranchIntoScope();
+
+ CleanupVarDeclMarking();
+ DiscardCleanupsInEvaluationContext();
return NS;
}
diff --git a/clang/test/CodeGenCXX/asm.cpp b/clang/test/CodeGenCXX/asm.cpp
index 3b745a7336f2..bc639a2be587 100644
--- a/clang/test/CodeGenCXX/asm.cpp
+++ b/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 @@ void bar(A &a)
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
diff --git a/clang/test/CodeGenObjC/asm.m b/clang/test/CodeGenObjC/asm.m
new file mode 100644
index 000000000000..6901416f028b
--- /dev/null
+++ b/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("");
+}
diff --git a/clang/test/SemaTemplate/instantiate-expr-1.cpp b/clang/test/SemaTemplate/instantiate-expr-1.cpp
index 820ee38e3eab..20d3edd86f39 100644
--- a/clang/test/SemaTemplate/instantiate-expr-1.cpp
+++ b/clang/test/SemaTemplate/instantiate-expr-1.cpp
@@ -190,3 +190,19 @@ namespace PR10864 {
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
More information about the cfe-commits
mailing list