If we don't find a matching ) for a ( in an exception specification, keep the tokens...
authorRichard Smith <richard-llvm@metafoo.co.uk>
Tue, 13 Jan 2015 02:24:58 +0000 (02:24 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Tue, 13 Jan 2015 02:24:58 +0000 (02:24 +0000)
llvm-svn: 225755

clang/lib/Parse/ParseDeclCXX.cpp
clang/test/Parser/cxx-class.cpp

index 09239f4..062b63e 100644 (file)
@@ -3149,15 +3149,10 @@ Parser::tryParseExceptionSpecification(bool Delayed,
     ExceptionSpecTokens->push_back(StartTok); // 'throw' or 'noexcept'
     ExceptionSpecTokens->push_back(Tok); // '('
     SpecificationRange.setEnd(ConsumeParen()); // '('
-    
-    if (!ConsumeAndStoreUntil(tok::r_paren, *ExceptionSpecTokens,
-                              /*StopAtSemi=*/true,
-                              /*ConsumeFinalToken=*/true)) {
-      NoexceptExpr = 0;
-      delete ExceptionSpecTokens;
-      ExceptionSpecTokens = 0;
-      return IsNoexcept? EST_BasicNoexcept : EST_DynamicNone;
-    }
+
+    ConsumeAndStoreUntil(tok::r_paren, *ExceptionSpecTokens,
+                         /*StopAtSemi=*/true,
+                         /*ConsumeFinalToken=*/true);
     SpecificationRange.setEnd(Tok.getLocation());
     
     // Add the 'stop' token.
index b6eb1b4..0e9a3b9 100644 (file)
@@ -179,6 +179,14 @@ class X1 { a::operator=; }; // expected-error {{undeclared identifier 'a'}}
 class X2 { a::a; }; // expected-error {{undeclared identifier 'a'}}
 }
 
+class BadExceptionSpec {
+  void f() throw(int; // expected-error {{expected ')'}} expected-note {{to match}}
+  void g() throw( // expected-note {{to match}}
+      int( // expected-note {{to match}}
+          ; // expected-error 2{{expected ')'}} expected-error {{unexpected end of exception specification}}
+          ));
+};
+
 // PR11109 must appear at the end of the source file
 class pr11109r3 { // expected-note{{to match this '{'}}
   public // expected-error{{expected ':'}} expected-error{{expected '}'}} expected-error{{expected ';' after class}}