]> granicus.if.org Git - clang/commitdiff
Properly handle temporaries that are created in a AsmStmt.
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>
Tue, 2 Nov 2010 02:33:08 +0000 (02:33 +0000)
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>
Tue, 2 Nov 2010 02:33:08 +0000 (02:33 +0000)
Previously the temporaries would get destroyed before the asm call.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@118001 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Sema/Sema.h
lib/Parse/ParseStmt.cpp
lib/Sema/SemaExprCXX.cpp
test/CodeGenCXX/asm.cpp [new file with mode: 0644]
test/SemaCXX/asm.cpp [deleted file]

index 88a168927c220f37bd28edf648f77643bab27e44..6f52bbbb7603ea7ce01dc89a485f785d485e2578 100644 (file)
@@ -2342,10 +2342,12 @@ public:
   /// non-empty, will create a new CXXExprWithTemporaries expression.
   /// Otherwise, just returs the passed in expression.
   Expr *MaybeCreateCXXExprWithTemporaries(Expr *SubExpr);
+  Stmt *MaybeCreateCXXStmtWithTemporaries(Stmt *SubStmt);
   ExprResult MaybeCreateCXXExprWithTemporaries(ExprResult SubExpr);
   FullExpr CreateFullExpr(Expr *SubExpr);
 
   ExprResult ActOnFinishFullExpr(Expr *Expr);
+  StmtResult ActOnFinishFullStmt(Stmt *Stmt);
 
   // Marks SS invalid if it represents an incomplete type.
   bool RequireCompleteDeclContext(CXXScopeSpec &SS, DeclContext *DC);
index 76956732d49b3d5b306439f9ffb5c4cdb357bd33..78d0d2f2d5512e940002ffb0260a45752a114e64 100644 (file)
@@ -188,6 +188,7 @@ Parser::ParseStatementOrDeclaration(StmtVector &Stmts, bool OnlyStatement) {
         << Attr.Range;
     bool msAsm = false;
     Res = ParseAsmStatement(msAsm);
+    Res = Actions.ActOnFinishFullStmt(Res.get());
     if (msAsm) return move(Res);
     SemiError = "asm";
     break;
@@ -1458,7 +1459,6 @@ bool Parser::ParseAsmOperandsOpt(llvm::SmallVectorImpl<IdentifierInfo *> &Names,
       SkipUntil(tok::r_paren);
       return true;
     }
-    Res = Actions.MakeFullExpr(Res.get()).release();
     Exprs.push_back(Res.release());
     // Eat the comma and continue parsing if it exists.
     if (Tok.isNot(tok::comma)) return false;
index 63e1a24cfadeafe0236957f29847279592a8b38e..e58c38cd5884cc7da36f930ae283d894459d871e 100644 (file)
@@ -3016,6 +3016,26 @@ FullExpr Sema::CreateFullExpr(Expr *SubExpr) {
   return E;
 }
 
+Stmt *Sema::MaybeCreateCXXStmtWithTemporaries(Stmt *SubStmt) {
+  assert(SubStmt && "sub statement can't be null!");
+
+  unsigned FirstTemporary = ExprEvalContexts.back().NumTemporaries;
+  assert(ExprTemporaries.size() >= FirstTemporary);
+  if (ExprTemporaries.size() == FirstTemporary)
+    return SubStmt;
+
+  // FIXME: In order to attach the temporaries, wrap the statement into
+  // a StmtExpr; currently this is only used for asm statements.
+  // This is hacky, either create a new CXXStmtWithTemporaries statement or
+  // a new AsmStmtWithTemporaries.
+  CompoundStmt *CompStmt = new (Context) CompoundStmt(Context, &SubStmt, 1,
+                                                      SourceLocation(),
+                                                      SourceLocation());
+  Expr *E = new (Context) StmtExpr(CompStmt, Context.VoidTy, SourceLocation(),
+                                   SourceLocation());
+  return MaybeCreateCXXExprWithTemporaries(E);
+}
+
 ExprResult
 Sema::ActOnStartCXXMemberReference(Scope *S, Expr *Base, SourceLocation OpLoc,
                                    tok::TokenKind OpKind, ParsedType &ObjectType,
@@ -3398,3 +3418,9 @@ ExprResult Sema::ActOnFinishFullExpr(Expr *FullExpr) {
   CheckImplicitConversions(FullExpr);
   return MaybeCreateCXXExprWithTemporaries(FullExpr);
 }
+
+StmtResult Sema::ActOnFinishFullStmt(Stmt *FullStmt) {
+  if (!FullStmt) return StmtError();
+
+  return MaybeCreateCXXStmtWithTemporaries(FullStmt);
+}
diff --git a/test/CodeGenCXX/asm.cpp b/test/CodeGenCXX/asm.cpp
new file mode 100644 (file)
index 0000000..3b745a7
--- /dev/null
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s
+
+struct A
+{
+    ~A();
+};
+int foo(A);
+
+void bar(A &a)
+{
+    // CHECK: call void asm
+    asm("" : : "r"(foo(a)) ); // rdar://8540491
+    // CHECK: call void @_ZN1AD1Ev
+}
diff --git a/test/SemaCXX/asm.cpp b/test/SemaCXX/asm.cpp
deleted file mode 100644 (file)
index cc2e6e7..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
-
-struct A
-{
-    ~A();
-};
-int foo(A);
-
-void bar()
-{
-    A a;
-    asm("" : : "r"(foo(a)) ); // rdar://8540491
-}