forked from OSchip/llvm-project
Properly handle temporaries that are created in a AsmStmt.
Previously the temporaries would get destroyed before the asm call. llvm-svn: 118001
This commit is contained in:
parent
315d2cab27
commit
3050d9bdb8
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
|
@ -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
|
||||
}
|
Loading…
Reference in New Issue