]> granicus.if.org Git - clang/commitdiff
Fix a parser crash when there are #pragmas in a context which requires a single
authorRichard Smith <richard-llvm@metafoo.co.uk>
Mon, 28 Oct 2013 22:04:30 +0000 (22:04 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Mon, 28 Oct 2013 22:04:30 +0000 (22:04 +0000)
statement (after a case label, if, etc). Patch by Olivier Goffart!

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

include/clang/Parse/Parser.h
lib/Parse/ParseStmt.cpp
test/CodeGen/pragma-weak.c
test/Parser/pragma-weak.c

index 1fd1d866b239b7ecf60f1c931be473aebb52b654..9ff5bdfb456cf7b061f0d53897fe22dc37659e59 100644 (file)
@@ -1470,10 +1470,7 @@ private:
   /// A SmallVector of types.
   typedef SmallVector<ParsedType, 12> TypeVector;
 
-  StmtResult ParseStatement(SourceLocation *TrailingElseLoc = 0) {
-    StmtVector Stmts;
-    return ParseStatementOrDeclaration(Stmts, true, TrailingElseLoc);
-  }
+  StmtResult ParseStatement(SourceLocation *TrailingElseLoc = 0);
   StmtResult ParseStatementOrDeclaration(StmtVector &Stmts,
                                          bool OnlyStatement,
                                          SourceLocation *TrailingElseLoc = 0);
index f57ff97ceb514664c49996b690bdd87b2086be2b..caf0011dba9cc6c1d30b3a77054121c53d37a227 100644 (file)
@@ -41,6 +41,21 @@ using namespace clang;
 // C99 6.8: Statements and Blocks.
 //===----------------------------------------------------------------------===//
 
+/// \brief Parse a standalone statement (for instance, as the body of an 'if',
+/// 'while', or 'for').
+StmtResult Parser::ParseStatement(SourceLocation *TrailingElseLoc) {
+  StmtResult Res;
+
+  // We may get back a null statement if we found a #pragma. Keep going until
+  // we get an actual statement.
+  do {
+    StmtVector Stmts;
+    Res = ParseStatementOrDeclaration(Stmts, true, TrailingElseLoc);
+  } while (!Res.isInvalid() && !Res.get());
+
+  return Res;
+}
+
 /// ParseStatementOrDeclaration - Read 'statement' or 'declaration'.
 ///       StatementOrDeclaration:
 ///         statement
index 559be831a55f5c3b98aaa4cb629b81faadc66f3c..b5d186324bf67d21f3f71bd43efbd5b6bbd64663 100644 (file)
@@ -149,6 +149,28 @@ void PR14046f() {
 }
 // CHECK: declare extern_weak i32 @PR14046e()
 
+// Parse #pragma weak after a label or case statement
+extern int PR16705a(void);
+extern int PR16705b(void);
+extern int PR16705c(void);
+void PR16705f(int a) {
+  switch(a) {
+  case 1:
+#pragma weak PR16705a
+    PR16705a();
+  default:
+#pragma weak PR16705b
+    PR16705b();
+  }
+label:
+  #pragma weak PR16705c
+  PR16705c();
+}
+
+// CHECK: declare extern_weak i32 @PR16705a()
+// CHECK: declare extern_weak i32 @PR16705b()
+// CHECK: declare extern_weak i32 @PR16705c()
+
 
 ///////////// TODO: stuff that still doesn't work
 
index 7e5740b483085db42cbbf94ada524a606675086a..fd47dd8696b86214912ace19a18e70987d2802eb 100644 (file)
@@ -15,3 +15,30 @@ extern int z;
 extern int a;
 /* expected-warning {{extra tokens at end of '#pragma weak'}}*/ #pragma weak a b
 /* expected-warning {{extra tokens at end of '#pragma weak'}}*/ #pragma weak a = x c
+
+
+void pragma_is_not_a_statement(int x)
+{
+  int t;
+
+  {
+    if (x)
+#pragma weak t
+    else // expected-error {{expected expression}}
+#pragma weak t
+  }
+
+  switch (x) {
+    case 1:
+#pragma weak t
+  } // expected-error {{expected statement}}
+  switch(x) {
+    default:
+#pragma weak t
+  } // expected-error {{expected statement}}
+
+label:
+#pragma weak t
+} // expected-error {{expected statement}}
+
+