diff options
author | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2010-11-02 02:33:08 +0000 |
---|---|---|
committer | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2010-11-02 02:33:08 +0000 |
commit | bf8cafadb9d4e0d7a90fe78fc175efb80ae34d42 (patch) | |
tree | 1fb3ca0c96b6879a3baefc740d19d5d0af2bab19 | |
parent | 3698748400478880d2a146ef9eaa111cd0e60522 (diff) |
Properly handle temporaries that are created in a AsmStmt.
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
-rw-r--r-- | include/clang/Sema/Sema.h | 2 | ||||
-rw-r--r-- | lib/Parse/ParseStmt.cpp | 2 | ||||
-rw-r--r-- | lib/Sema/SemaExprCXX.cpp | 26 | ||||
-rw-r--r-- | test/CodeGenCXX/asm.cpp | 14 | ||||
-rw-r--r-- | test/SemaCXX/asm.cpp | 13 |
5 files changed, 43 insertions, 14 deletions
diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index 88a168927c..6f52bbbb76 100644 --- a/include/clang/Sema/Sema.h +++ b/include/clang/Sema/Sema.h @@ -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); diff --git a/lib/Parse/ParseStmt.cpp b/lib/Parse/ParseStmt.cpp index 76956732d4..78d0d2f2d5 100644 --- a/lib/Parse/ParseStmt.cpp +++ b/lib/Parse/ParseStmt.cpp @@ -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; diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp index 63e1a24cfa..e58c38cd58 100644 --- a/lib/Sema/SemaExprCXX.cpp +++ b/lib/Sema/SemaExprCXX.cpp @@ -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 index 0000000000..3b745a7336 --- /dev/null +++ b/test/CodeGenCXX/asm.cpp @@ -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 index cc2e6e75ca..0000000000 --- a/test/SemaCXX/asm.cpp +++ /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 -} |