From eec8101b9bf6b1a1b28e09dfd475f1e8aa3d852f Mon Sep 17 00:00:00 2001 From: Alp Toker Date: Sun, 5 Jan 2014 03:27:57 +0000 Subject: [PATCH] Fix bungled parse recovery in K&R function declarations void knrNoSemi(i) int i { } Adherents of The C Programming Language unfortunate enough to miss a semicolon as above would be met with a cascade of errors spanning the remainder of the TU. This patch introduces a beautiful parse error recovery, complete with helpful FixIt to restore sanity. Before (output redacted for brevity): error: 'error' diagnostics seen but not expected: File declarators.c Line 119: declaration does not declare a parameter File declarators.c Line 123: declaration does not declare a parameter File declarators.c Line 127: parameter named 'func_E12' is missing File declarators.c Line 127: expected ';' at end of declaration File declarators.c Line 133: parameter named 'func_E13' is missing File declarators.c Line 133: expected ';' at end of declaration File declarators.c Line 139: parameter named 'func_E14' is missing File declarators.c Line 139: expected ';' at end of declaration File declarators.c Line 145: parameter named 'func_E15' is missing File declarators.c Line 145: expected ';' at end of declaration File declarators.c Line 150: expected function body after function declarator File declarators.c Line 119: declaration of 'enum E11' will not be visible outside of this function File declarators.c Line 123: declaration of 'enum E12' will not be visible outside of this function File declarators.c Line 133: ISO C forbids forward references to 'enum' types File declarators.c Line 133: declaration of 'enum E13' will not be visible outside of this function File declarators.c Line 139: ISO C forbids forward references to 'enum' types File declarators.c Line 139: declaration of 'enum E14' will not be visible outside of this function File declarators.c Line 145: ISO C forbids forward references to 'enum' types File declarators.c Line 145: declaration of 'enum E15' will not be visible outside of this function ... After: declarators.c:103:24: error: expected ';' at end of declaration void knrNoSemi(i) int i { } ^ ; Patch found in a sealed envelope dated 1978 with the message "Do not open until January 2014" llvm-svn: 198540 --- clang/lib/Parse/Parser.cpp | 9 +++------ clang/test/Parser/declarators.c | 1 + 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp index 1c20a47f17c4..f668c5a8bdc6 100644 --- a/clang/lib/Parse/Parser.cpp +++ b/clang/lib/Parse/Parser.cpp @@ -1285,12 +1285,9 @@ void Parser::ParseKNRParamDeclarations(Declarator &D) { ParseDeclarator(ParmDeclarator); } - if (ExpectAndConsumeSemi(diag::err_expected_semi_declaration)) { - // Skip to end of block or statement - SkipUntil(tok::semi); - if (Tok.is(tok::semi)) - ConsumeToken(); - } + // Consume ';' or recover by skipping to the mandatory function body. + if (ExpectAndConsumeSemi(diag::err_expected_semi_declaration)) + SkipUntil(tok::l_brace, StopBeforeMatch); } // The actions module must verify that all arguments were declared. diff --git a/clang/test/Parser/declarators.c b/clang/test/Parser/declarators.c index f77c2d2192fb..39d9dc94490d 100644 --- a/clang/test/Parser/declarators.c +++ b/clang/test/Parser/declarators.c @@ -100,6 +100,7 @@ long struct X { int x; } test15(); // expected-error {{'long struct' is invalid} void test16(i) int i j; { } // expected-error {{expected ';' at end of declaration}} void test17(i, j) int i, j k; { } // expected-error {{expected ';' at end of declaration}} +void knrNoSemi(i) int i { } // expected-error {{expected ';' at end of declaration}} // PR12595