diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2012-09-18 00:52:05 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2012-09-18 00:52:05 +0000 |
commit | 0875c53239dde03319099d8ae4ac12a4025709e8 (patch) | |
tree | 7649b32a1e208b22e0d951a72764cb8ba0697347 /clang/lib/Parse/ParseExpr.cpp | |
parent | 5657555357af46e44a1970f7a7aa8f5ced35aa79 (diff) | |
download | bcm5719-llvm-0875c53239dde03319099d8ae4ac12a4025709e8.tar.gz bcm5719-llvm-0875c53239dde03319099d8ae4ac12a4025709e8.zip |
If a comma operator is followed by a token which unambiguously indicates the
start of a statement or the end of a compound-statement, diagnose the comma as
a typo for a semicolon. Patch by Ahmed Bougacha! Additional test cases and
minor refactoring by me.
llvm-svn: 164085
Diffstat (limited to 'clang/lib/Parse/ParseExpr.cpp')
-rw-r--r-- | clang/lib/Parse/ParseExpr.cpp | 22 |
1 files changed, 22 insertions, 0 deletions
diff --git a/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp index af3389532e2..9b95641f46b 100644 --- a/clang/lib/Parse/ParseExpr.cpp +++ b/clang/lib/Parse/ParseExpr.cpp @@ -265,6 +265,17 @@ ExprResult Parser::ParseConstantExpression(TypeCastState isTypeCast) { return Actions.ActOnConstantExpression(Res); } +bool Parser::isNotExpressionStart() { + tok::TokenKind K = Tok.getKind(); + if (K == tok::l_brace || K == tok::r_brace || + K == tok::kw_for || K == tok::kw_while || + K == tok::kw_if || K == tok::kw_else || + K == tok::kw_goto || K == tok::kw_try) + return true; + // If this is a decl-specifier, we can't be at the start of an expression. + return isKnownToBeDeclarationSpecifier(); +} + /// \brief Parse a binary expression that starts with \p LHS and has a /// precedence of at least \p MinPrec. ExprResult @@ -285,6 +296,17 @@ Parser::ParseRHSOfBinaryExpression(ExprResult LHS, prec::Level MinPrec) { Token OpToken = Tok; ConsumeToken(); + // Bail out when encountering a comma followed by a token which can't + // possibly be the start of an expression. For instance: + // int f() { return 1, } + // We can't do this before consuming the comma, because + // isNotExpressionStart() looks at the token stream. + if (OpToken.is(tok::comma) && isNotExpressionStart()) { + PP.EnterToken(Tok); + Tok = OpToken; + return LHS; + } + // Special case handling for the ternary operator. ExprResult TernaryMiddle(true); if (NextTokPrec == prec::Conditional) { |