diff --git a/clang/include/clang/Basic/DiagnosticLexKinds.td b/clang/include/clang/Basic/DiagnosticLexKinds.td index cd37bceedd98..9df0967b4485 100644 --- a/clang/include/clang/Basic/DiagnosticLexKinds.td +++ b/clang/include/clang/Basic/DiagnosticLexKinds.td @@ -387,7 +387,7 @@ def err_pp_expected_comma_in_arg_list : Error< def err_pp_duplicate_name_in_arg_list : Error< "duplicate macro parameter name %0">; def err_pp_stringize_not_parameter : Error< - "'#' is not followed by a macro parameter">; + "'%select{#|#@}0' is not followed by a macro parameter">; def err_pp_malformed_ident : Error<"invalid #ident directive">; def err_pp_unterminated_conditional : Error< "unterminated conditional directive">; diff --git a/clang/lib/Lex/PPDirectives.cpp b/clang/lib/Lex/PPDirectives.cpp index c36670ca6358..dc1f32fb5697 100644 --- a/clang/lib/Lex/PPDirectives.cpp +++ b/clang/lib/Lex/PPDirectives.cpp @@ -2151,7 +2151,7 @@ void Preprocessor::HandleDefineDirective(Token &DefineTok, while (Tok.isNot(tok::eod)) { LastTok = Tok; - if (Tok.isNot(tok::hash) && Tok.isNot(tok::hashhash)) { + if (!Tok.isOneOf(tok::hash, tok::hashat, tok::hashhash)) { MI->AddTokenToBody(Tok); // Get the next token of the macro. @@ -2210,7 +2210,8 @@ void Preprocessor::HandleDefineDirective(Token &DefineTok, MI->AddTokenToBody(LastTok); continue; } else { - Diag(Tok, diag::err_pp_stringize_not_parameter); + Diag(Tok, diag::err_pp_stringize_not_parameter) + << LastTok.is(tok::hashat); // Disable __VA_ARGS__ again. Ident__VA_ARGS__->setIsPoisoned(true); diff --git a/clang/test/Parser/MicrosoftExtensions.c b/clang/test/Parser/MicrosoftExtensions.c index e58a7455c083..39ab51f31fa6 100644 --- a/clang/test/Parser/MicrosoftExtensions.c +++ b/clang/test/Parser/MicrosoftExtensions.c @@ -35,6 +35,9 @@ void test_ms_alignof_alias(void) { /* Charify extension. */ #define FOO(x) #@x char x = FOO(a); +#define HASHAT #@ +#define MISSING_ARG(x) #@ +/* expected-error@-1 {{'#@' is not followed by a macro parameter}} */ typedef enum E { e1 }; diff --git a/clang/test/Preprocessor/stringize_misc.c b/clang/test/Preprocessor/stringize_misc.c index 6c2c78d17ac3..fc7253e50499 100644 --- a/clang/test/Preprocessor/stringize_misc.c +++ b/clang/test/Preprocessor/stringize_misc.c @@ -1,4 +1,5 @@ -// RUN: %clang_cc1 -E %s | FileCheck -strict-whitespace %s +#ifdef TEST1 +// RUN: %clang_cc1 -E %s -DTEST1 | FileCheck -strict-whitespace %s #define M(x, y) #x #y @@ -28,3 +29,13 @@ START_END( {a=1 , b=2;} ) /* braces are not parentheses */ M(a COMMA b, (a, b)) // CHECK: "a COMMA b" "(a, b)" +#endif + +#ifdef TEST2 +// RUN: %clang_cc1 -fsyntax-only -verify %s -DTEST2 + +#define HASH # +#define INVALID() # +// expected-error@-1{{'#' is not followed by a macro parameter}} + +#endif