aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2012-04-28 16:24:20 +0000
committerChris Lattner <sabre@nondot.org>2012-04-28 16:24:20 +0000
commitbddc7e5ed3982b5845e4fbb5d9bc7b7431c35a4f (patch)
treef07ae427142b22a727e2f37f5ecd9fc25d11b21e
parent8bb21d32e9ccc9d9c221506dff26acafa8724cca (diff)
improve error recovery for extra ')'s after a if/switch/while condition. Before:
t.c:3:9: error: expected expression if (x)) { ^ .. which isn't even true - a statement or expression is fine. After: t.c:3:9: error: extraneous ')' after condition, expected a statement if (x)) { ^ This is the second part of PR12595 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@155762 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/clang/Basic/DiagnosticParseKinds.td2
-rw-r--r--lib/Parse/ParseStmt.cpp10
-rw-r--r--test/Parser/recovery.c5
3 files changed, 15 insertions, 2 deletions
diff --git a/include/clang/Basic/DiagnosticParseKinds.td b/include/clang/Basic/DiagnosticParseKinds.td
index 15c93e3b2f..d28e1dcda0 100644
--- a/include/clang/Basic/DiagnosticParseKinds.td
+++ b/include/clang/Basic/DiagnosticParseKinds.td
@@ -396,6 +396,8 @@ def err_expected_init_in_condition : Error<
"variable declaration in condition must have an initializer">;
def err_expected_init_in_condition_lparen : Error<
"variable declaration in condition cannot have a parenthesized initializer">;
+def err_extraneous_rparen_in_condition : Error<
+ "extraneous ')' after condition, expected a statement">;
def warn_parens_disambiguated_as_function_decl : Warning<
"parentheses were disambiguated as a function declarator">,
InGroup<VexingParse>;
diff --git a/lib/Parse/ParseStmt.cpp b/lib/Parse/ParseStmt.cpp
index 8dd0a2a5dc..9796ea69ba 100644
--- a/lib/Parse/ParseStmt.cpp
+++ b/lib/Parse/ParseStmt.cpp
@@ -895,6 +895,16 @@ bool Parser::ParseParenExprOrCondition(ExprResult &ExprResult,
// Otherwise the condition is valid or the rparen is present.
T.consumeClose();
+
+ // Check for extraneous ')'s to catch things like "if (foo())) {". We know
+ // that all callers are looking for a statement after the condition, so ")"
+ // isn't valid.
+ while (Tok.is(tok::r_paren)) {
+ Diag(Tok, diag::err_extraneous_rparen_in_condition)
+ << FixItHint::CreateRemoval(Tok.getLocation());
+ ConsumeParen();
+ }
+
return false;
}
diff --git a/test/Parser/recovery.c b/test/Parser/recovery.c
index 3916acfda1..178427e4b3 100644
--- a/test/Parser/recovery.c
+++ b/test/Parser/recovery.c
@@ -37,8 +37,9 @@ void test(int a) {
test(0);
else
;
-
- if (x.i == 0)) // expected-error {{expected expression}}
+
+ // PR12595
+ if (x.i == 0)) // expected-error {{extraneous ')' after condition, expected a statement}}
test(0);
else
;