Don't crash on missing '{' after __except or __finally, PR22687.
authorNico Weber <nicolasweber@gmx.de>
Wed, 25 Feb 2015 02:22:06 +0000 (02:22 +0000)
committerNico Weber <nicolasweber@gmx.de>
Wed, 25 Feb 2015 02:22:06 +0000 (02:22 +0000)
Also add some general test/Parser coverage for SEH blocks.

llvm-svn: 230449

clang/lib/Parse/ParseStmt.cpp
clang/test/Parser/ms-seh.c [new file with mode: 0644]

index 3b878e8..e77f07a 100644 (file)
@@ -421,7 +421,7 @@ StmtResult Parser::ParseSEHTryBlock() {
   assert(Tok.is(tok::kw___try) && "Expected '__try'");
   SourceLocation TryLoc = ConsumeToken();
 
-  if(Tok.isNot(tok::l_brace))
+  if (Tok.isNot(tok::l_brace))
     return StmtError(Diag(Tok, diag::err_expected) << tok::l_brace);
 
   StmtResult TryBlock(ParseCompoundStatement(/*isStmtExpr=*/false,
@@ -438,7 +438,7 @@ StmtResult Parser::ParseSEHTryBlock() {
     SourceLocation Loc = ConsumeToken();
     Handler = ParseSEHFinallyBlock(Loc);
   } else {
-    return StmtError(Diag(Tok,diag::err_seh_expected_handler));
+    return StmtError(Diag(Tok, diag::err_seh_expected_handler));
   }
 
   if(Handler.isInvalid())
@@ -491,6 +491,9 @@ StmtResult Parser::ParseSEHExceptBlock(SourceLocation ExceptLoc) {
   if (ExpectAndConsume(tok::r_paren))
     return StmtError();
 
+  if (Tok.isNot(tok::l_brace))
+    return StmtError(Diag(Tok, diag::err_expected) << tok::l_brace);
+
   StmtResult Block(ParseCompoundStatement());
 
   if(Block.isInvalid())
@@ -509,6 +512,9 @@ StmtResult Parser::ParseSEHFinallyBlock(SourceLocation FinallyBlock) {
     raii2(Ident___abnormal_termination, false),
     raii3(Ident_AbnormalTermination, false);
 
+  if (Tok.isNot(tok::l_brace))
+    return StmtError(Diag(Tok, diag::err_expected) << tok::l_brace);
+
   StmtResult Block(ParseCompoundStatement());
   if(Block.isInvalid())
     return Block;
diff --git a/clang/test/Parser/ms-seh.c b/clang/test/Parser/ms-seh.c
new file mode 100644 (file)
index 0000000..68c2e30
--- /dev/null
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 %s -fsyntax-only -Wmicrosoft -verify -fms-extensions
+
+void f() {
+  int a;
+
+  __try a; // expected-error {{expected '{'}} expected-warning {{expression result unused}}
+
+  __try {
+  }
+} // expected-error {{expected '__except' or '__finally' block}}
+
+void g() {
+  int a;
+
+  __try {
+  } __except(1) a; // expected-error {{expected '{'}} expected-warning {{expression result unused}}
+}
+
+void h() {
+  int a;
+
+  __try {
+  } __finally a; // expected-error {{expected '{'}} expected-warning {{expression result unused}}
+}