]> granicus.if.org Git - clang/commitdiff
Fix bungled parse recovery in K&R function declarations
authorAlp Toker <alp@nuanti.com>
Sun, 5 Jan 2014 03:27:57 +0000 (03:27 +0000)
committerAlp Toker <alp@nuanti.com>
Sun, 5 Jan 2014 03:27:57 +0000 (03:27 +0000)
  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"

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@198540 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Parse/Parser.cpp
test/Parser/declarators.c

index 1c20a47f17c47d591a05106a0736363a8619fc5e..f668c5a8bdc69029192bcae2f99027c2565408fd 100644 (file)
@@ -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.
index f77c2d2192fb8fdf3c2c639ca4e51e86271e7cb4..39d9dc94490dfe2c5253b0adc832dc3c115a8d2f 100644 (file)
@@ -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