r193545 - Fix a parser crash when there are #pragmas in a context which requires a single

Richard Smith richard-llvm at metafoo.co.uk
Mon Oct 28 15:04:30 PDT 2013


Author: rsmith
Date: Mon Oct 28 17:04:30 2013
New Revision: 193545

URL: http://llvm.org/viewvc/llvm-project?rev=193545&view=rev
Log:
Fix a parser crash when there are #pragmas in a context which requires a single
statement (after a case label, if, etc). Patch by Olivier Goffart!

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

Modified: cfe/trunk/include/clang/Parse/Parser.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=193545&r1=193544&r2=193545&view=diff
==============================================================================
--- cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/trunk/include/clang/Parse/Parser.h Mon Oct 28 17:04:30 2013
@@ -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);

Modified: cfe/trunk/lib/Parse/ParseStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseStmt.cpp?rev=193545&r1=193544&r2=193545&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseStmt.cpp (original)
+++ cfe/trunk/lib/Parse/ParseStmt.cpp Mon Oct 28 17:04:30 2013
@@ -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

Modified: cfe/trunk/test/CodeGen/pragma-weak.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/pragma-weak.c?rev=193545&r1=193544&r2=193545&view=diff
==============================================================================
--- cfe/trunk/test/CodeGen/pragma-weak.c (original)
+++ cfe/trunk/test/CodeGen/pragma-weak.c Mon Oct 28 17:04:30 2013
@@ -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
 

Modified: cfe/trunk/test/Parser/pragma-weak.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/pragma-weak.c?rev=193545&r1=193544&r2=193545&view=diff
==============================================================================
--- cfe/trunk/test/Parser/pragma-weak.c (original)
+++ cfe/trunk/test/Parser/pragma-weak.c Mon Oct 28 17:04:30 2013
@@ -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}}
+
+





More information about the cfe-commits mailing list