]> granicus.if.org Git - clang/commitdiff
move token paste poisoning diagnostics to after the instantiation loc
authorChris Lattner <sabre@nondot.org>
Sun, 19 Apr 2009 20:29:42 +0000 (20:29 +0000)
committerChris Lattner <sabre@nondot.org>
Sun, 19 Apr 2009 20:29:42 +0000 (20:29 +0000)
for a token is set, this makes the diagnostic "expanded from stack" work
for this diagnostic.  Add a testcase for PR3918.

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

lib/Lex/TokenLexer.cpp
test/Preprocessor/macro_paste_bad.c

index 8cec43322179daefb4e7d2c5b88b6e2d92d15b41..7ff473f090b403904a977f0faa2cfe8df2e6aa83 100644 (file)
@@ -308,13 +308,18 @@ void TokenLexer::Lex(Token &Tok) {
   // Get the next token to return.
   Tok = Tokens[CurToken++];
   
+  bool TokenIsFromPaste = false;
+  
   // If this token is followed by a token paste (##) operator, paste the tokens!
   if (!isAtEnd() && Tokens[CurToken].is(tok::hashhash))
     if (PasteTokens(Tok)) {
       // When handling the microsoft /##/ extension, the final token is
       // returned by PasteTokens, not the pasted token.
       return;
+    } else {
+      TokenIsFromPaste = true;
     }
+      
 
   // The token's current location indicate where the token was lexed from.  We
   // need this information to compute the spelling of the token, but any
@@ -342,6 +347,17 @@ void TokenLexer::Lex(Token &Tok) {
     // turning "for" into a keyword.
     Tok.setKind(II->getTokenID());
     
+    // If this identifier was poisoned and from a paste, emit an error.  This
+    // won't be handled by Preprocessor::HandleIdentifier because this is coming
+    // from a macro expansion.
+    if (II->isPoisoned() && TokenIsFromPaste) {
+      // We warn about __VA_ARGS__ with poisoning.
+      if (II->isStr("__VA_ARGS__"))
+        PP.Diag(Tok, diag::ext_pp_bad_vaargs_use);
+      else
+        PP.Diag(Tok, diag::err_pp_used_poisoned_id);
+    }
+    
     if (!DisableMacroExpansion && II->isHandleIdentifierCase())
       PP.HandleIdentifier(Tok);
   }
@@ -476,17 +492,6 @@ bool TokenLexer::PasteTokens(Token &Tok) {
     // by saying we're skipping contents, so we need to do this manually.
     IdentifierInfo *II = PP.LookUpIdentifierInfo(Tok, ResultTokStrPtr);
     Tok.setIdentifierInfo(II);
-    
-    // If this identifier was poisoned, emit an error.  This won't be handled by
-    // Preprocessor::HandleIdentifier because this is coming from a macro
-    // expansion.
-    if (II->isPoisoned()) {
-      // We warn about __VA_ARGS__ with poisoning.
-      if (II->isStr("__VA_ARGS__"))
-        PP.Diag(Tok, diag::ext_pp_bad_vaargs_use);
-      else
-        PP.Diag(Tok, diag::err_pp_used_poisoned_id);
-    }
   }
   return false;
 }
index f70c3b3ba2e6cef7a7dbb49d0e0edba7a587820d..b43d70b0c4e47d6425bfd6558c723425349330c3 100644 (file)
@@ -18,3 +18,16 @@ XYZ
 #define i   ##      // expected-error {{'##' cannot appear at start of macro expansion}}
 #define j() ##      // expected-error {{'##' cannot appear at start of macro expansion}}
 
+// Invalid token pasting.
+// PR3918
+
+// When pasting creates poisoned identifiers, we error.
+#pragma GCC poison BLARG
+BLARG  // expected-error {{attempt to use a poisoned identifier}}
+#define XX BL ## ARG
+XX     // expected-error {{attempt to use a poisoned identifier}}
+
+#define VA __VA_ ## ARGS__
+int VA;   // expected-warning {{__VA_ARGS__ can only appear in the expansion of a C99 variadic macro}}
+
+