forked from OSchip/llvm-project
Enter an expression evaluation context when parsing
statement-expressions. Prevents cleanups and such from being claimed by the first full-expression in the block. llvm-svn: 153989
This commit is contained in:
parent
34b4546c06
commit
3abee49d1c
|
@ -2802,8 +2802,10 @@ public:
|
|||
ExprResult ActOnAddrLabel(SourceLocation OpLoc, SourceLocation LabLoc,
|
||||
LabelDecl *TheDecl);
|
||||
|
||||
void ActOnStartStmtExpr();
|
||||
ExprResult ActOnStmtExpr(SourceLocation LPLoc, Stmt *SubStmt,
|
||||
SourceLocation RPLoc); // "({..})"
|
||||
void ActOnStmtExprError();
|
||||
|
||||
// __builtin_offsetof(type, identifier(.identifier|[expr])*)
|
||||
struct OffsetOfComponent {
|
||||
|
|
|
@ -1917,13 +1917,19 @@ Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr,
|
|||
// unless they've already reported an error.
|
||||
if (ExprType >= CompoundStmt && Tok.is(tok::l_brace)) {
|
||||
Diag(Tok, diag::ext_gnu_statement_expr);
|
||||
|
||||
Actions.ActOnStartStmtExpr();
|
||||
|
||||
ParsedAttributes attrs(AttrFactory);
|
||||
StmtResult Stmt(ParseCompoundStatement(attrs, true));
|
||||
ExprType = CompoundStmt;
|
||||
|
||||
// If the substmt parsed correctly, build the AST node.
|
||||
if (!Stmt.isInvalid())
|
||||
if (!Stmt.isInvalid()) {
|
||||
Result = Actions.ActOnStmtExpr(OpenLoc, Stmt.take(), Tok.getLocation());
|
||||
} else {
|
||||
Actions.ActOnStmtExprError();
|
||||
}
|
||||
} else if (ExprType >= CompoundLiteral && BridgeCast) {
|
||||
tok::TokenKind tokenKind = Tok.getKind();
|
||||
SourceLocation BridgeKeywordLoc = ConsumeToken();
|
||||
|
|
|
@ -8546,12 +8546,26 @@ static Expr *maybeRebuildARCConsumingStmt(Stmt *Statement) {
|
|||
return cleanups;
|
||||
}
|
||||
|
||||
void Sema::ActOnStartStmtExpr() {
|
||||
PushExpressionEvaluationContext(ExprEvalContexts.back().Context);
|
||||
}
|
||||
|
||||
void Sema::ActOnStmtExprError() {
|
||||
DiscardCleanupsInEvaluationContext();
|
||||
PopExpressionEvaluationContext();
|
||||
}
|
||||
|
||||
ExprResult
|
||||
Sema::ActOnStmtExpr(SourceLocation LPLoc, Stmt *SubStmt,
|
||||
SourceLocation RPLoc) { // "({..})"
|
||||
assert(SubStmt && isa<CompoundStmt>(SubStmt) && "Invalid action invocation!");
|
||||
CompoundStmt *Compound = cast<CompoundStmt>(SubStmt);
|
||||
|
||||
if (hasAnyUnrecoverableErrorsInThisFunction())
|
||||
DiscardCleanupsInEvaluationContext();
|
||||
assert(!ExprNeedsCleanups && "cleanups within StmtExpr not correctly bound!");
|
||||
PopExpressionEvaluationContext();
|
||||
|
||||
bool isFileScope
|
||||
= (getCurFunctionOrMethodDecl() == 0) && (getCurBlock() == 0);
|
||||
if (isFileScope)
|
||||
|
|
|
@ -514,3 +514,10 @@ void test13(id x) {
|
|||
void test14() {
|
||||
void (^const x[1])(void) = { ^{} };
|
||||
}
|
||||
|
||||
// rdar://11149025
|
||||
// Don't make invalid ASTs and crash.
|
||||
void test15_helper(void (^block)(void), int x);
|
||||
void test15(int a) {
|
||||
test15_helper(^{ (void) a; }, ({ a; }));
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue