]> granicus.if.org Git - clang/commitdiff
fix PR5740: a colon is sacred when parsing case statement expressions!
authorChris Lattner <sabre@nondot.org>
Thu, 10 Dec 2009 00:38:54 +0000 (00:38 +0000)
committerChris Lattner <sabre@nondot.org>
Thu, 10 Dec 2009 00:38:54 +0000 (00:38 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@91016 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Parse/ParseStmt.cpp
lib/Parse/RAIIObjectsForParser.h
test/Parser/cxx-stmt.cpp

index f0de3f534562824c7570003ecc454ca37d3f2efd..5267ef0ecccbda3bd026090b29b74c0366799e26 100644 (file)
@@ -279,6 +279,11 @@ Parser::OwningStmtResult Parser::ParseCaseStatement(AttributeList *Attr) {
       ConsumeToken();
     }
     
+    /// We don't want to treat 'case x : y' as a potential typo for 'case x::y'.
+    /// Disable this form of error recovery while we're parsing the case
+    /// expression.
+    ColonProtectionRAIIObject ColonProtection(*this);
+    
     OwningExprResult LHS(ParseConstantExpression());
     if (LHS.isInvalid()) {
       SkipUntil(tok::colon);
@@ -298,6 +303,8 @@ Parser::OwningStmtResult Parser::ParseCaseStatement(AttributeList *Attr) {
         return StmtError();
       }
     }
+    
+    ColonProtection.restore();
 
     if (Tok.isNot(tok::colon)) {
       Diag(Tok, diag::err_expected_colon_after) << "'case'";
index d18d2f802633aa967260cf9924e95a954ac564ed..bacdf29c8ae3940d549a5f35025fbe66b79c13e3 100644 (file)
@@ -50,9 +50,15 @@ namespace clang {
       P.ColonIsSacred = true;
     }
     
-    ~ColonProtectionRAIIObject() {
+    /// restore - This can be used to restore the state early, before the dtor
+    /// is run.
+    void restore() {
       P.ColonIsSacred = OldVal;
     }
+    
+    ~ColonProtectionRAIIObject() {
+      restore();
+    }
   };
   
 } // end namespace clang
index 535f40d7805720a3cf7cb2b9276e58398c7b20e8..cc35ba153f6b07e0517f700846f788b438ef07a2 100644 (file)
@@ -1,6 +1,6 @@
 // RUN: clang-cc -fsyntax-only -verify %s
 
-void f()
+void f1()
 {
   try {
     ;
@@ -10,7 +10,7 @@ void f()
   }
 }
 
-void g()
+void f2()
 {
   try; // expected-error {{expected '{'}}
 
@@ -24,7 +24,7 @@ void g()
   catch {} // expected-error {{expected '('}}
 }
 
-void h() try {
+void f3() try {
 } catch(...) {
 }
 
@@ -39,3 +39,16 @@ struct A {
 
 A::A(char) : i(0) try {} // expected-error {{expected '{' or ','}}
 A::A(int j) try : i(j) {} catch(...) {}
+
+
+
+// PR5740
+struct Type { };
+
+enum { Type } Kind;
+void f4() {
+  int i = 0;
+  switch (Kind) {
+    case Type: i = 7; break;  // no error.
+  }
+}
\ No newline at end of file