]> granicus.if.org Git - clang/commitdiff
Emit a -Wmicrosoft warning when pasting /##/ into a comment token in MS mode.
authorNico Weber <nicolasweber@gmx.de>
Tue, 29 Dec 2015 23:06:17 +0000 (23:06 +0000)
committerNico Weber <nicolasweber@gmx.de>
Tue, 29 Dec 2015 23:06:17 +0000 (23:06 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@256595 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/DiagnosticGroups.td
include/clang/Basic/DiagnosticLexKinds.td
include/clang/Lex/TokenLexer.h
lib/Lex/PPLexerChange.cpp
lib/Lex/TokenLexer.cpp
test/Preprocessor/macro_paste_msextensions.c

index 44a6a114ed74c1fde992b3e0cb4b795fb715d24c..32353b51ee580834069bf49293d40269d874ea5a 100644 (file)
@@ -765,6 +765,7 @@ def MicrosoftCast : DiagGroup<"microsoft-cast">;
 def MicrosoftConstInit : DiagGroup<"microsoft-const-init">;
 def MicrosoftVoidPseudoDtor : DiagGroup<"microsoft-void-pseudo-dtor">;
 def MicrosoftAnonTag : DiagGroup<"microsoft-anon-tag">;
+def MicrosoftCommentPaste : DiagGroup<"microsoft-comment-paste">;
 // Aliases.
 def : DiagGroup<"msvc-include", [MicrosoftInclude]>;
                 // -Wmsvc-include = -Wmicrosoft-include
@@ -778,7 +779,8 @@ def Microsoft : DiagGroup<"microsoft",
      MicrosoftEnumValue, MicrosoftDefaultArgRedefinition, MicrosoftTemplate,
      MicrosoftRedeclareStatic, MicrosoftEnumForwardReference, MicrosoftGoto,
      MicrosoftFlexibleArray, MicrosoftExtraQualification, MicrosoftCast,
-     MicrosoftConstInit, MicrosoftVoidPseudoDtor, MicrosoftAnonTag]>;
+     MicrosoftConstInit, MicrosoftVoidPseudoDtor, MicrosoftAnonTag,
+     MicrosoftCommentPaste]>;
 
 def ObjCNonUnifiedException : DiagGroup<"objc-nonunified-exceptions">;
 
index 38599d6b1f50a526eea57b4af724eee4fd641bba..2ed40c0cdedd9280c5b6a008ed4abd3afe8f55a4 100644 (file)
@@ -59,6 +59,9 @@ def ext_dollar_in_identifier : Extension<"'$' in identifier">,
 def ext_charize_microsoft : Extension<
   "charizing operator #@ is a Microsoft extension">,
   InGroup<MicrosoftCharize>;
+def ext_comment_paste_microsoft : Extension<
+  "pasting two '/' tokens into a '//' comment token is a Microsoft extension">,
+  InGroup<MicrosoftCommentPaste>;
 
 def ext_token_used : Extension<"extension used">,
   InGroup<DiagGroup<"language-extension-token">>;
index 31197367c422db58bd2c53e5ef32c7509a150626..fdeed44d8f9b332dff7115fc2994cb806b30758f 100644 (file)
@@ -175,7 +175,7 @@ private:
   /// macro, other active macros, and anything left on the current physical
   /// source line of the expanded buffer.  Handle this by returning the
   /// first token on the next line.
-  void HandleMicrosoftCommentPaste(Token &Tok);
+  void HandleMicrosoftCommentPaste(Token &Tok, SourceLocation OpLoc);
 
   /// \brief If \p loc is a FileID and points inside the current macro
   /// definition, returns the appropriate source location pointing at the
index 7c0d55e1f036698917aed08bbdd3bb8d954f1322..2f09841c5b5d05a0b297077dc91f23cb3a2cfd2c 100644 (file)
@@ -561,7 +561,6 @@ void Preprocessor::RemoveTopOfLexerStack() {
 void Preprocessor::HandleMicrosoftCommentPaste(Token &Tok) {
   assert(CurTokenLexer && !CurPPLexer &&
          "Pasted comment can only be formed from macro");
-
   // We handle this by scanning for the closest real lexer, switching it to
   // raw mode and preprocessor mode.  This will cause it to return \n as an
   // explicit EOD token.
index e7512fa2831af5c02209f7a5898cc7158b466f88..c42966928e52ca377b2cbaf87419845637d42ba4 100644 (file)
@@ -624,21 +624,22 @@ bool TokenLexer::PasteTokens(Token &Tok) {
       // error.  This occurs with "x ## +"  and other stuff.  Return with Tok
       // unmodified and with RHS as the next token to lex.
       if (isInvalid) {
+        // Explicitly convert the token location to have proper expansion
+        // information so that the user knows where it came from.
+        SourceManager &SM = PP.getSourceManager();
+        SourceLocation Loc =
+          SM.createExpansionLoc(PasteOpLoc, ExpandLocStart, ExpandLocEnd, 2);
+
         // Test for the Microsoft extension of /##/ turning into // here on the
         // error path.
         if (PP.getLangOpts().MicrosoftExt && Tok.is(tok::slash) &&
             RHS.is(tok::slash)) {
-          HandleMicrosoftCommentPaste(Tok);
+          HandleMicrosoftCommentPaste(Tok, Loc);
           return true;
         }
 
         // Do not emit the error when preprocessing assembler code.
         if (!PP.getLangOpts().AsmPreprocessor) {
-          // Explicitly convert the token location to have proper expansion
-          // information so that the user knows where it came from.
-          SourceManager &SM = PP.getSourceManager();
-          SourceLocation Loc =
-            SM.createExpansionLoc(PasteOpLoc, ExpandLocStart, ExpandLocEnd, 2);
           // If we're in microsoft extensions mode, downgrade this from a hard
           // error to an extension that defaults to an error.  This allows
           // disabling it.
@@ -719,7 +720,9 @@ bool TokenLexer::isParsingPreprocessorDirective() const {
 /// macro, other active macros, and anything left on the current physical
 /// source line of the expanded buffer.  Handle this by returning the
 /// first token on the next line.
-void TokenLexer::HandleMicrosoftCommentPaste(Token &Tok) {
+void TokenLexer::HandleMicrosoftCommentPaste(Token &Tok, SourceLocation OpLoc) {
+  PP.Diag(OpLoc, diag::ext_comment_paste_microsoft);
+
   // We 'comment out' the rest of this macro by just ignoring the rest of the
   // tokens that have not been lexed yet, if any.
 
index aa5f41f9ee4fc5863876acf8984c09137a6e8fd6..dcc5336b91c1437b840bb31bc5367c5d775144d4 100644 (file)
@@ -1,3 +1,4 @@
+// RUN: %clang_cc1 -verify -fms-extensions -Wmicrosoft %s
 // RUN: not %clang_cc1 -P -E -fms-extensions %s | FileCheck -strict-whitespace %s
 
 // This horrible stuff should preprocess into (other than whitespace):
@@ -10,6 +11,7 @@ int foo;
 // CHECK: int foo;
 
 #define comment /##/  dead tokens live here
+// expected-warning@+1 {{pasting two '/' tokens}}
 comment This is stupidity
 
 int bar;
@@ -18,6 +20,7 @@ int bar;
 
 #define nested(x) int x comment cute little dead tokens...
 
+// expected-warning@+1 {{pasting two '/' tokens}}
 nested(baz)  rise of the dead tokens
 
 ;
@@ -29,13 +32,13 @@ nested(baz)  rise of the dead tokens
 // rdar://8197149 - VC++ allows invalid token pastes: (##baz
 #define foo(x) abc(x)
 #define bar(y) foo(##baz(y))
-bar(q)
+bar(q) // expected-warning {{type specifier missing}} expected-error {{invalid preprocessing token}} expected-error {{parameter list without types}}
 
 // CHECK: abc(baz(q))
 
 
 #define str(x) #x
 #define collapse_spaces(a, b, c, d) str(a ## - ## b ## - ## c ## d)
-collapse_spaces(1a, b2, 3c, d4)
+collapse_spaces(1a, b2, 3c, d4) // expected-error 4 {{invalid preprocessing token}} expected-error {{expected function body}}
 
 // CHECK: "1a-b2-3cd4"