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:
Eli Friedman 2009-01-27 08:43:38 +00:00
parent f1ca7d3e02
commit eb3a9b03ab
4 changed files with 28 additions and 9 deletions
clang
include/clang/Parse
lib/Parse
test/Parser

View File

@ -567,6 +567,8 @@ private:
OwningExprResult ParseExpressionWithLeadingAt(SourceLocation AtLoc);
OwningExprResult ParseExpressionWithLeadingExtension(SourceLocation ExtLoc);
OwningExprResult ParseRHSOfBinaryExpression(OwningExprResult LHS,
unsigned MinPrec);
OwningExprResult ParseCastExpression(bool isUnaryExpression);

View File

@ -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() {

View File

@ -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);

View File

@ -36,4 +36,8 @@ void test_sizeof(){
sizeof(arr)[0];
}
// PR3418
int test_leading_extension() {
__extension__ (*(char*)0) = 1;
}