forked from OSchip/llvm-project
Parse: Don't crash when namespace is in GNU statement expr
Parser::ParseNamespace can get a little confused when it found itself inside a compound statement inside of a non-static data member initializer. Try to determine that the statement expression's scope makes sense before trying to parse it's contents. llvm-svn: 225514
This commit is contained in:
parent
ed13fab4bc
commit
02e764487f
|
@ -131,6 +131,8 @@ def ext_gnu_indirect_goto : Extension<
|
|||
"use of GNU indirect-goto extension">, InGroup<GNULabelsAsValue>;
|
||||
def ext_gnu_address_of_label : Extension<
|
||||
"use of GNU address-of-label extension">, InGroup<GNULabelsAsValue>;
|
||||
def err_stmtexpr_file_scope : Error<
|
||||
"statement expression not allowed at file scope">;
|
||||
def ext_gnu_statement_expr : Extension<
|
||||
"use of GNU statement expression extension">, InGroup<GNUStatementExpression>;
|
||||
def ext_gnu_conditional_expr : Extension<
|
||||
|
|
|
@ -4984,8 +4984,6 @@ def err_typecheck_op_on_nonoverlapping_address_space_pointers : Error<
|
|||
"|arithmetic operation with operands of type %diff{ ($ and $)|}0,1}2"
|
||||
" which are pointers to non-overlapping address spaces">;
|
||||
def err_typecheck_assign_const : Error<"read-only variable is not assignable">;
|
||||
def err_stmtexpr_file_scope : Error<
|
||||
"statement expression not allowed at file scope">;
|
||||
def warn_mixed_sign_comparison : Warning<
|
||||
"comparison of integers of different signs: %0 and %1">,
|
||||
InGroup<SignCompare>, DefaultIgnore;
|
||||
|
|
|
@ -2084,16 +2084,21 @@ 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();
|
||||
|
||||
StmtResult Stmt(ParseCompoundStatement(true));
|
||||
ExprType = CompoundStmt;
|
||||
|
||||
// If the substmt parsed correctly, build the AST node.
|
||||
if (!Stmt.isInvalid()) {
|
||||
Result = Actions.ActOnStmtExpr(OpenLoc, Stmt.get(), Tok.getLocation());
|
||||
if (!getCurScope()->getFnParent() && !getCurScope()->getBlockParent()) {
|
||||
Result = ExprError(Diag(OpenLoc, diag::err_stmtexpr_file_scope));
|
||||
} else {
|
||||
Actions.ActOnStmtExprError();
|
||||
Actions.ActOnStartStmtExpr();
|
||||
|
||||
StmtResult Stmt(ParseCompoundStatement(true));
|
||||
ExprType = CompoundStmt;
|
||||
|
||||
// If the substmt parsed correctly, build the AST node.
|
||||
if (!Stmt.isInvalid()) {
|
||||
Result = Actions.ActOnStmtExpr(OpenLoc, Stmt.get(), Tok.getLocation());
|
||||
} else {
|
||||
Actions.ActOnStmtExprError();
|
||||
}
|
||||
}
|
||||
} else if (ExprType >= CompoundLiteral && BridgeCast) {
|
||||
tok::TokenKind tokenKind = Tok.getKind();
|
||||
|
|
|
@ -10275,11 +10275,6 @@ Sema::ActOnStmtExpr(SourceLocation LPLoc, Stmt *SubStmt,
|
|||
assert(!ExprNeedsCleanups && "cleanups within StmtExpr not correctly bound!");
|
||||
PopExpressionEvaluationContext();
|
||||
|
||||
bool isFileScope
|
||||
= (getCurFunctionOrMethodDecl() == nullptr) && (getCurBlock() == nullptr);
|
||||
if (isFileScope)
|
||||
return ExprError(Diag(LPLoc, diag::err_stmtexpr_file_scope));
|
||||
|
||||
// FIXME: there are a variety of strange constraints to enforce here, for
|
||||
// example, it is not possible to goto into a stmt expression apparently.
|
||||
// More semantic analysis is needed.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// RUN: %clang_cc1 -fsyntax-only -verify %s
|
||||
// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
|
||||
|
||||
// PR6596
|
||||
namespace g { enum { o = 0 }; }
|
||||
|
@ -10,3 +10,7 @@ void foo() {
|
|||
// PR14085
|
||||
namespace PR14085 {}
|
||||
namespace = PR14085; // expected-error {{expected identifier}}
|
||||
|
||||
struct namespace_nested_in_record {
|
||||
int k = ({namespace {}}); // expected-error {{statement expression not allowed at file scope}}
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue