Hi rsmith, hfinkel,

Currently, if the argument to _Pragma is not a parenthesised string literal, 
the bad token will be consumed, as well as the ')', if present. If additional 
bad tokens are passed to the _Pragma, this results in extra error messages 
which may distract from the true problem. For example:

```
temp.c:1:1: error: _Pragma takes a parenthesized string literal
_Pragma(unroll 1)
^
temp.c:1:16: error: expected identifier or '('
_Pragma(unroll 1)
               ^
2 errors generated.
}
```

The proposed patch causes all tokens to be consumed until the closing ')' or a 
new line, whichever is reached first.

http://reviews.llvm.org/D8308

Files:
  lib/Lex/Pragma.cpp
  test/Preprocessor/_Pragma.c

Index: lib/Lex/Pragma.cpp
===================================================================
--- lib/Lex/Pragma.cpp
+++ lib/Lex/Pragma.cpp
@@ -190,8 +190,10 @@
   Lex(Tok);
   if (!tok::isStringLiteral(Tok.getKind())) {
     Diag(PragmaLoc, diag::err__Pragma_malformed);
-    // Skip this token, and the ')', if present.
-    if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::eof))
+    // Skip bad tokens, and the ')', if present.
+    while (Tok.isNot(tok::r_paren) &&
+           !Tok.isAtStartOfLine() &&
+           Tok.isNot(tok::eof))
       Lex(Tok);
     if (Tok.is(tok::r_paren))
       Lex(Tok);
Index: test/Preprocessor/_Pragma.c
===================================================================
--- test/Preprocessor/_Pragma.c
+++ test/Preprocessor/_Pragma.c
@@ -12,4 +12,8 @@
 #error #define invalid
 #endif
 
+_Pragma(unroll 1 // expected-error{{_Pragma takes a parenthesized string 
literal}}
+
+_Pragma(clang diagnostic push) // expected-error{{_Pragma takes a 
parenthesized string literal}}
+
 _Pragma( // expected-error{{_Pragma takes a parenthesized string literal}}

EMAIL PREFERENCES
  http://reviews.llvm.org/settings/panel/emailpreferences/
Index: lib/Lex/Pragma.cpp
===================================================================
--- lib/Lex/Pragma.cpp
+++ lib/Lex/Pragma.cpp
@@ -190,8 +190,10 @@
   Lex(Tok);
   if (!tok::isStringLiteral(Tok.getKind())) {
     Diag(PragmaLoc, diag::err__Pragma_malformed);
-    // Skip this token, and the ')', if present.
-    if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::eof))
+    // Skip bad tokens, and the ')', if present.
+    while (Tok.isNot(tok::r_paren) &&
+           !Tok.isAtStartOfLine() &&
+           Tok.isNot(tok::eof))
       Lex(Tok);
     if (Tok.is(tok::r_paren))
       Lex(Tok);
Index: test/Preprocessor/_Pragma.c
===================================================================
--- test/Preprocessor/_Pragma.c
+++ test/Preprocessor/_Pragma.c
@@ -12,4 +12,8 @@
 #error #define invalid
 #endif
 
+_Pragma(unroll 1 // expected-error{{_Pragma takes a parenthesized string literal}}
+
+_Pragma(clang diagnostic push) // expected-error{{_Pragma takes a parenthesized string literal}}
+
 _Pragma( // expected-error{{_Pragma takes a parenthesized string literal}}
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to