[Parser] Fix TryParseLambdaIntroducer() error handling
authorJan Korous <jkorous@apple.com>
Mon, 6 Nov 2017 17:42:17 +0000 (17:42 +0000)
committerJan Korous <jkorous@apple.com>
Mon, 6 Nov 2017 17:42:17 +0000 (17:42 +0000)
rdar://35066196

Differential Revision: https://reviews.llvm.org/D39419

llvm-svn: 317493

clang/lib/Parse/ParseExprCXX.cpp
clang/test/Parser/objcxx11-invalid-lambda.cpp [new file with mode: 0644]

index ce6aa64..ad48019 100644 (file)
@@ -991,27 +991,34 @@ Optional<unsigned> Parser::ParseLambdaIntroducer(LambdaIntroducer &Intro,
 ///
 /// Returns true if it hit something unexpected.
 bool Parser::TryParseLambdaIntroducer(LambdaIntroducer &Intro) {
-  TentativeParsingAction PA(*this);
+  {
+    bool SkippedInits = false;
+    TentativeParsingAction PA1(*this);
 
-  bool SkippedInits = false;
-  Optional<unsigned> DiagID(ParseLambdaIntroducer(Intro, &SkippedInits));
+    if (ParseLambdaIntroducer(Intro, &SkippedInits)) {
+      PA1.Revert();
+      return true;
+    }
 
-  if (DiagID) {
-    PA.Revert();
-    return true;
+    if (!SkippedInits) {
+      PA1.Commit();
+      return false;
+    }
+
+    PA1.Revert();
   }
 
-  if (SkippedInits) {
-    // Parse it again, but this time parse the init-captures too.
-    PA.Revert();
-    Intro = LambdaIntroducer();
-    DiagID = ParseLambdaIntroducer(Intro);
-    assert(!DiagID && "parsing lambda-introducer failed on reparse");
+  // Try to parse it again, but this time parse the init-captures too.
+  Intro = LambdaIntroducer();
+  TentativeParsingAction PA2(*this);
+
+  if (!ParseLambdaIntroducer(Intro)) {
+    PA2.Commit();
     return false;
   }
 
-  PA.Commit();
-  return false;
+  PA2.Revert();
+  return true;
 }
 
 static void
diff --git a/clang/test/Parser/objcxx11-invalid-lambda.cpp b/clang/test/Parser/objcxx11-invalid-lambda.cpp
new file mode 100644 (file)
index 0000000..74c5636
--- /dev/null
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -x objective-c++ -std=c++11 %s
+
+void foo() {  // expected-note {{to match this '{'}}
+  int bar;
+  auto baz = [
+      bar(  // expected-note {{to match this '('}} expected-note {{to match this '('}}
+        foo_undeclared() // expected-error{{use of undeclared identifier 'foo_undeclared'}} expected-error{{use of undeclared identifier 'foo_undeclared'}}
+      /* ) */
+    ] () { };   // expected-error{{expected ')'}}
+}               // expected-error{{expected ')'}} expected-error{{expected ';' at end of declaration}} expected-error{{expected '}'}}