forked from OSchip/llvm-project
Fix for PR3418: make sure to handle the RHS of expressions starting with
__extension__. This sort of construct shows up in the gcc source code. llvm-svn: 63100
This commit is contained in:
parent
f1ca7d3e02
commit
eb3a9b03ab
clang
|
@ -567,6 +567,8 @@ private:
|
|||
|
||||
OwningExprResult ParseExpressionWithLeadingAt(SourceLocation AtLoc);
|
||||
|
||||
OwningExprResult ParseExpressionWithLeadingExtension(SourceLocation ExtLoc);
|
||||
|
||||
OwningExprResult ParseRHSOfBinaryExpression(OwningExprResult LHS,
|
||||
unsigned MinPrec);
|
||||
OwningExprResult ParseCastExpression(bool isUnaryExpression);
|
||||
|
|
|
@ -192,6 +192,25 @@ Parser::ParseExpressionWithLeadingAt(SourceLocation AtLoc) {
|
|||
return ParseRHSOfBinaryExpression(move(LHS), prec::Comma);
|
||||
}
|
||||
|
||||
/// This routine is called when a leading '__extension__' is seen and
|
||||
/// consumed. This is necessary because the token gets consumed in the
|
||||
/// process of disambiguating between an expression and a declaration.
|
||||
Parser::OwningExprResult
|
||||
Parser::ParseExpressionWithLeadingExtension(SourceLocation ExtLoc) {
|
||||
// FIXME: The handling for throw is almost certainly wrong.
|
||||
if (Tok.is(tok::kw_throw))
|
||||
return ParseThrowExpression();
|
||||
|
||||
OwningExprResult LHS(ParseCastExpression(false));
|
||||
if (LHS.isInvalid()) return move(LHS);
|
||||
|
||||
LHS = Actions.ActOnUnaryOp(CurScope, ExtLoc, tok::kw___extension__,
|
||||
move_arg(LHS));
|
||||
if (LHS.isInvalid()) return move(LHS);
|
||||
|
||||
return ParseRHSOfBinaryExpression(move(LHS), prec::Comma);
|
||||
}
|
||||
|
||||
/// ParseAssignmentExpression - Parse an expr that doesn't include commas.
|
||||
///
|
||||
Parser::OwningExprResult Parser::ParseAssignmentExpression() {
|
||||
|
|
|
@ -366,6 +366,7 @@ Parser::OwningStmtResult Parser::ParseCompoundStatementBody(bool isStmtExpr) {
|
|||
// __extension__ can start declarations and it can also be a unary
|
||||
// operator for expressions. Consume multiple __extension__ markers here
|
||||
// until we can determine which is which.
|
||||
// FIXME: This loses extension expressions in the AST!
|
||||
SourceLocation ExtLoc = ConsumeToken();
|
||||
while (Tok.is(tok::kw___extension__))
|
||||
ConsumeToken();
|
||||
|
@ -381,21 +382,14 @@ Parser::OwningStmtResult Parser::ParseCompoundStatementBody(bool isStmtExpr) {
|
|||
// FIXME: Pass in the right location for the end of the declstmt.
|
||||
R = Actions.ActOnDeclStmt(Res, DeclStart, DeclStart);
|
||||
} else {
|
||||
// Otherwise this was a unary __extension__ marker. Parse the
|
||||
// subexpression and add the __extension__ unary op.
|
||||
OwningExprResult Res(ParseCastExpression(false));
|
||||
// Otherwise this was a unary __extension__ marker.
|
||||
OwningExprResult Res(ParseExpressionWithLeadingExtension(ExtLoc));
|
||||
|
||||
if (Res.isInvalid()) {
|
||||
SkipUntil(tok::semi);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Add the __extension__ node to the AST.
|
||||
Res = Actions.ActOnUnaryOp(CurScope, ExtLoc, tok::kw___extension__,
|
||||
move_arg(Res));
|
||||
if (Res.isInvalid())
|
||||
continue;
|
||||
|
||||
// Eat the semicolon at the end of stmt and convert the expr into a
|
||||
// statement.
|
||||
ExpectAndConsume(tok::semi, diag::err_expected_semi_after_expr);
|
||||
|
|
|
@ -36,4 +36,8 @@ void test_sizeof(){
|
|||
sizeof(arr)[0];
|
||||
}
|
||||
|
||||
// PR3418
|
||||
int test_leading_extension() {
|
||||
__extension__ (*(char*)0) = 1;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue