]> granicus.if.org Git - clang/commitdiff
Fix crash when both ExpectAndConsume and ConsumeAnyToken emit diagnostics
authorAlp Toker <alp@nuanti.com>
Sun, 23 Feb 2014 03:45:03 +0000 (03:45 +0000)
committerAlp Toker <alp@nuanti.com>
Sun, 23 Feb 2014 03:45:03 +0000 (03:45 +0000)
The DiagnosticBuilder's lifetime in parser typo recovery was overlapping with
the subsequent consume which can itself emit PP diagnostics.

Patch by Olivier Goffart!

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

lib/Parse/Parser.cpp
test/Parser/diag-crash.c [new file with mode: 0644]

index 71f5b845ddd3bc29b0e05100f584f325dfa09352..b76d430f17645fecdd9a1170386c4d905fe22f30 100644 (file)
@@ -118,18 +118,20 @@ bool Parser::ExpectAndConsume(tok::TokenKind ExpectedTok, unsigned DiagID,
   // Detect common single-character typos and resume.
   if (IsCommonTypo(ExpectedTok, Tok)) {
     SourceLocation Loc = Tok.getLocation();
-    DiagnosticBuilder DB = Diag(Loc, DiagID);
-    DB << FixItHint::CreateReplacement(SourceRange(Loc),
-                                       getPunctuatorSpelling(ExpectedTok));
-    if (DiagID == diag::err_expected)
-      DB << ExpectedTok;
-    else if (DiagID == diag::err_expected_after)
-      DB << Msg << ExpectedTok;
-    else
-      DB << Msg;
-    ConsumeAnyToken();
+    {
+      DiagnosticBuilder DB = Diag(Loc, DiagID);
+      DB << FixItHint::CreateReplacement(
+                SourceRange(Loc), tok::getPunctuatorSpelling(ExpectedTok));
+      if (DiagID == diag::err_expected)
+        DB << ExpectedTok;
+      else if (DiagID == diag::err_expected_after)
+        DB << Msg << ExpectedTok;
+      else
+        DB << Msg;
+    }
 
     // Pretend there wasn't a problem.
+    ConsumeAnyToken();
     return false;
   }
 
diff --git a/test/Parser/diag-crash.c b/test/Parser/diag-crash.c
new file mode 100644 (file)
index 0000000..4f1265f
--- /dev/null
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// Avoid preprocessor diag crash caused by a parser diag left in flight.
+
+int foo: // expected-error {{expected ';' after top level declarator}}
+#endif   // expected-error {{#endif without #if}}