https://github.com/serge-sans-paille created https://github.com/llvm/llvm-project/pull/188624
Also provide an appropriate fixit. >From 174b065d76f254b59ffc6ae5b0080592d42c457f Mon Sep 17 00:00:00 2001 From: serge-sans-paille <[email protected]> Date: Wed, 25 Mar 2026 22:52:31 +0100 Subject: [PATCH] [clang] Suggest using __VA_OPT__(,) instead of GNU zero variadic macro argument Also provide an appropriate fixit. --- clang/include/clang/Basic/DiagnosticLexKinds.td | 3 ++- clang/lib/Lex/TokenLexer.cpp | 11 ++++++++++- .../Lexer/gnu-zero-variadic-macro-argument-fixit.c | 9 +++++++++ 3 files changed, 21 insertions(+), 2 deletions(-) create mode 100644 clang/test/Lexer/gnu-zero-variadic-macro-argument-fixit.c diff --git a/clang/include/clang/Basic/DiagnosticLexKinds.td b/clang/include/clang/Basic/DiagnosticLexKinds.td index 5eceeced311f2..99a3109baa01c 100644 --- a/clang/include/clang/Basic/DiagnosticLexKinds.td +++ b/clang/include/clang/Basic/DiagnosticLexKinds.td @@ -769,7 +769,8 @@ def err_paste_at_start : Error< "'##' cannot appear at start of macro expansion">; def err_paste_at_end : Error<"'##' cannot appear at end of macro expansion">; def ext_paste_comma : Extension< - "token pasting of ',' and __VA_ARGS__ is a GNU extension">, InGroup<GNUZeroVariadicMacroArguments>; + "token pasting of ',' and __VA_ARGS__ is a GNU extension.%select{| Consider using __VA_OPT__(,) instead}0">, + InGroup<GNUZeroVariadicMacroArguments>; def err_unterm_macro_invoc : Error< "unterminated function-like macro invocation">; def err_too_many_args_in_macro_invoc : Error< diff --git a/clang/lib/Lex/TokenLexer.cpp b/clang/lib/Lex/TokenLexer.cpp index db4313f766812..699b3a6a6c7d8 100644 --- a/clang/lib/Lex/TokenLexer.cpp +++ b/clang/lib/Lex/TokenLexer.cpp @@ -523,7 +523,16 @@ void TokenLexer::ExpandFunctionArguments() { Macro->isVariadic()) { VaArgsPseudoPaste = true; // Remove the paste operator, report use of the extension. - PP.Diag(ResultToks.pop_back_val().getLocation(), diag::ext_paste_comma); + const bool hint = PP.getLangOpts().C23 || PP.getLangOpts().CPlusPlus20; + auto diag = PP.Diag(ResultToks.pop_back_val().getLocation(), + diag::ext_paste_comma) + << hint; + if (hint) { + diag << FixItHint::CreateReplacement( + SourceRange(ResultToks[ResultToks.size() - 1].getLocation(), + CurTok.getLocation()), + " __VA_OPT__(,) __VA_ARGS__"); + } } ResultToks.append(ArgToks, ArgToks+NumToks); diff --git a/clang/test/Lexer/gnu-zero-variadic-macro-argument-fixit.c b/clang/test/Lexer/gnu-zero-variadic-macro-argument-fixit.c new file mode 100644 index 0000000000000..e796ed001c0be --- /dev/null +++ b/clang/test/Lexer/gnu-zero-variadic-macro-argument-fixit.c @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -fdiagnostics-parseable-fixits %s -Wgnu-zero-variadic-macro-arguments -std=c23 + +void foo(const char* fmt, ...); +// expected-warning@+1 {{token pasting of ',' and __VA_ARGS__ is a GNU extension. Consider using __VA_OPT__(,) instead}} +#define FOO(format, ...) foo(format, ##__VA_ARGS__) + +void bar(void) { + FOO("", 0); +} _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
