[clang] [Clang] Update missing varargs arg extension warnings (PR #84520)

via cfe-commits cfe-commits at lists.llvm.org
Wed Mar 20 11:17:10 PDT 2024


https://github.com/Sirraide updated https://github.com/llvm/llvm-project/pull/84520

>From 502692869e3105bb2c55955bc4baff63b1475770 Mon Sep 17 00:00:00 2001
From: Sirraide <aeternalmail at gmail.com>
Date: Fri, 8 Mar 2024 18:15:07 +0100
Subject: [PATCH 1/3] [Clang] Update missing varargs arg extension warnings

---
 clang/docs/ReleaseNotes.rst                    |  3 +++
 .../include/clang/Basic/DiagnosticLexKinds.td  | 13 ++++++++++---
 clang/lib/Lex/PPMacroExpansion.cpp             | 13 ++++++++++---
 clang/test/C/C2x/n2975.c                       |  4 ++--
 clang/test/Lexer/gnu-flags.c                   |  2 --
 clang/test/Preprocessor/empty_va_arg.cpp       | 18 +++++++++++-------
 clang/test/Preprocessor/macro_fn.c             |  4 ++--
 7 files changed, 38 insertions(+), 19 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 0ff4a93b15ea8f..ffc88e79961ce6 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -212,6 +212,9 @@ Improvements to Clang's diagnostics
 - Clang now diagnoses lambda function expressions being implicitly cast to boolean values, under ``-Wpointer-bool-conversion``.
   Fixes #GH82512.
 
+- Clang now correctly diagnoses no arguments to a variadic macro parameter as a C23/C++20 extension.
+  Fixes #GH84495.
+
 Improvements to Clang's time-trace
 ----------------------------------
 
diff --git a/clang/include/clang/Basic/DiagnosticLexKinds.td b/clang/include/clang/Basic/DiagnosticLexKinds.td
index d7c172e6546351..ad6bacfb118d49 100644
--- a/clang/include/clang/Basic/DiagnosticLexKinds.td
+++ b/clang/include/clang/Basic/DiagnosticLexKinds.td
@@ -465,9 +465,16 @@ def err_embedded_directive : Error<
 def ext_embedded_directive : Extension<
   "embedding a directive within macro arguments has undefined behavior">,
   InGroup<DiagGroup<"embedded-directive">>;
-def ext_missing_varargs_arg : Extension<
-  "must specify at least one argument for '...' parameter of variadic macro">,
-  InGroup<GNUZeroVariadicMacroArguments>;
+def ext_c_missing_varargs_arg : Extension<
+  "passing no argument for the '...' parameter of a variadic macro is "
+  "a C23 extension">, InGroup<C23>;
+def ext_cxx_missing_varargs_arg : Extension<
+  "passing no argument for the '...' parameter of a variadic macro is "
+  "a C++20 extension">, InGroup<CXX20>;
+def warn_c17_compat_missing_varargs_arg : Warning<
+  "passing no argument for the '...' parameter of a variadic macro is "
+  "incompatible with C standards before C23">,
+  InGroup<CPre23Compat>, DefaultIgnore;
 def warn_cxx17_compat_missing_varargs_arg : Warning<
   "passing no argument for the '...' parameter of a variadic macro is "
   "incompatible with C++ standards before C++20">,
diff --git a/clang/lib/Lex/PPMacroExpansion.cpp b/clang/lib/Lex/PPMacroExpansion.cpp
index 3017461dc66e86..3cde001e84760e 100644
--- a/clang/lib/Lex/PPMacroExpansion.cpp
+++ b/clang/lib/Lex/PPMacroExpansion.cpp
@@ -995,9 +995,16 @@ MacroArgs *Preprocessor::ReadMacroCallArgumentList(Token &MacroName,
       if (!MI->hasCommaPasting()) {
         // C++20 allows this construct, but standards before C++20 and all C
         // standards do not allow the construct (we allow it as an extension).
-        Diag(Tok, getLangOpts().CPlusPlus20
-                      ? diag::warn_cxx17_compat_missing_varargs_arg
-                      : diag::ext_missing_varargs_arg);
+        unsigned ID;
+        if (getLangOpts().CPlusPlus20)
+          ID = diag::warn_cxx17_compat_missing_varargs_arg;
+        else if (getLangOpts().CPlusPlus)
+          ID = diag::ext_cxx_missing_varargs_arg;
+        else if (getLangOpts().C23)
+          ID = diag::warn_c17_compat_missing_varargs_arg;
+        else
+          ID = diag::ext_c_missing_varargs_arg;
+        Diag(Tok, ID);
         Diag(MI->getDefinitionLoc(), diag::note_macro_here)
           << MacroName.getIdentifierInfo();
       }
diff --git a/clang/test/C/C2x/n2975.c b/clang/test/C/C2x/n2975.c
index 5fc641dd66e781..2269400fe47c34 100644
--- a/clang/test/C/C2x/n2975.c
+++ b/clang/test/C/C2x/n2975.c
@@ -11,7 +11,7 @@
 void func(...) { // expected-warning {{'...' as the only parameter of a function is incompatible with C standards before C23}}
   // Show that va_start doesn't require the second argument in C23 mode.
   va_list list;
-  va_start(list); // FIXME: it would be nice to issue a portability warning to C17 and earlier here.
+  va_start(list); // expected-warning {{passing no argument for the '...' parameter of a variadic macro is incompatible with C standards before C23}} expected-note@* {{macro 'va_start' defined here}}
   va_end(list);
 
   // Show that va_start doesn't expand or evaluate the second argument.
@@ -26,7 +26,7 @@ void func(...) { // expected-warning {{'...' as the only parameter of a function
   __builtin_va_start(list); // expected-error {{too few arguments to function call, expected 2, have 1}}
 
   // Verify that the return type of a call to va_start is 'void'.
-  _Static_assert(__builtin_types_compatible_p(__typeof__(va_start(list)), void), "");
+  _Static_assert(__builtin_types_compatible_p(__typeof__(va_start(list)), void), ""); // expected-warning {{passing no argument for the '...' parameter of a variadic macro is incompatible with C standards before C23}} expected-note@* {{macro 'va_start' defined here}}
   _Static_assert(__builtin_types_compatible_p(__typeof__(__builtin_va_start(list, 0)), void), "");
 }
 
diff --git a/clang/test/Lexer/gnu-flags.c b/clang/test/Lexer/gnu-flags.c
index 384339fc859429..4d6d216b101f4a 100644
--- a/clang/test/Lexer/gnu-flags.c
+++ b/clang/test/Lexer/gnu-flags.c
@@ -17,8 +17,6 @@
 
 
 #if ALL || ZEROARGS
-// expected-warning at +9 {{must specify at least one argument for '...' parameter of variadic macro}}
-// expected-note at +4 {{macro 'efoo' defined here}}
 // expected-warning at +3 {{token pasting of ',' and __VA_ARGS__ is a GNU extension}}
 #endif
 
diff --git a/clang/test/Preprocessor/empty_va_arg.cpp b/clang/test/Preprocessor/empty_va_arg.cpp
index 2ee431f6bde838..7c7d49d8fb1632 100644
--- a/clang/test/Preprocessor/empty_va_arg.cpp
+++ b/clang/test/Preprocessor/empty_va_arg.cpp
@@ -1,12 +1,16 @@
-// RUN: %clang_cc1 -Eonly -std=c++17 -pedantic -verify %s
-// RUN: %clang_cc1 -Eonly -std=c17 -pedantic -verify -x c %s
-// RUN: %clang_cc1 -Eonly -std=c++20 -pedantic -Wpre-c++20-compat -verify=compat %s
+// RUN: %clang_cc1 -Eonly -std=c17 -pedantic -verify=c17,expected -x c %s
+// RUN: %clang_cc1 -Eonly -std=c23 -pedantic -Wpre-c23-compat -verify=c23,expected -x c %s
+// RUN: %clang_cc1 -Eonly -std=c++17 -pedantic -verify=cxx17,expected %s
+// RUN: %clang_cc1 -Eonly -std=c++20 -pedantic -Wpre-c++20-compat -verify=cxx20,expected %s
 
-#define FOO(x, ...) // expected-note {{macro 'FOO' defined here}} \
-                    // compat-note {{macro 'FOO' defined here}}
+// silent-no-diagnostics
+
+#define FOO(x, ...) // expected-note  {{macro 'FOO' defined here}}
 
 int main() {
-  FOO(42) // expected-warning {{must specify at least one argument for '...' parameter of variadic macro}} \
-          // compat-warning {{passing no argument for the '...' parameter of a variadic macro is incompatible with C++ standards before C++20}}
+  FOO(42) // c17-warning {{passing no argument for the '...' parameter of a variadic macro is a C23 extension}} \
+          // cxx17-warning {{passing no argument for the '...' parameter of a variadic macro is a C++20 extension}} \
+          // c23-warning {{passing no argument for the '...' parameter of a variadic macro is incompatible with C standards before C23}} \
+          // cxx20-warning {{passing no argument for the '...' parameter of a variadic macro is incompatible with C++ standards before C++20}}
 }
 
diff --git a/clang/test/Preprocessor/macro_fn.c b/clang/test/Preprocessor/macro_fn.c
index 5f4ea0e26d5d8b..81d83632140788 100644
--- a/clang/test/Preprocessor/macro_fn.c
+++ b/clang/test/Preprocessor/macro_fn.c
@@ -37,8 +37,8 @@ e(x)
 e()
 
 zero_dot()
-one_dot(x)  /* empty ... argument: expected-warning {{must specify at least one argument for '...' parameter of variadic macro}}  */
-one_dot()   /* empty first argument, elided ...: expected-warning {{must specify at least one argument for '...' parameter of variadic macro}} */
+one_dot(x)  /* empty ... argument: expected-warning {{passing no argument for the '...' parameter of a variadic macro is a C23 extension}}  */
+one_dot()   /* empty first argument, elided ...: expected-warning {{passing no argument for the '...' parameter of a variadic macro is a C23 extension}} */
 
 
 /* Crash with function-like macro test at end of directive. */

>From f5b663d6510be6eea1a534749b34c8f81c188d9d Mon Sep 17 00:00:00 2001
From: Sirraide <aeternalmail at gmail.com>
Date: Fri, 8 Mar 2024 18:24:43 +0100
Subject: [PATCH 2/3] [NFC] Update comment

---
 clang/lib/Lex/PPMacroExpansion.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/clang/lib/Lex/PPMacroExpansion.cpp b/clang/lib/Lex/PPMacroExpansion.cpp
index 3cde001e84760e..200d1d996f677b 100644
--- a/clang/lib/Lex/PPMacroExpansion.cpp
+++ b/clang/lib/Lex/PPMacroExpansion.cpp
@@ -993,8 +993,8 @@ MacroArgs *Preprocessor::ReadMacroCallArgumentList(Token &MacroName,
       // If the macro contains the comma pasting extension, the diagnostic
       // is suppressed; we know we'll get another diagnostic later.
       if (!MI->hasCommaPasting()) {
-        // C++20 allows this construct, but standards before C++20 and all C
-        // standards do not allow the construct (we allow it as an extension).
+        // C++20 and C23 allow this construct, but standards before that
+        // do not (we allow it as an extension).
         unsigned ID;
         if (getLangOpts().CPlusPlus20)
           ID = diag::warn_cxx17_compat_missing_varargs_arg;

>From 0af09b3930343b27d92fe8b4c9959cd802e9d3fe Mon Sep 17 00:00:00 2001
From: Sirraide <aeternalmail at gmail.com>
Date: Wed, 20 Mar 2024 19:16:57 +0100
Subject: [PATCH 3/3] [Clang] Add standards citation

---
 clang/lib/Lex/PPMacroExpansion.cpp | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/clang/lib/Lex/PPMacroExpansion.cpp b/clang/lib/Lex/PPMacroExpansion.cpp
index 200d1d996f677b..516269c0c6013e 100644
--- a/clang/lib/Lex/PPMacroExpansion.cpp
+++ b/clang/lib/Lex/PPMacroExpansion.cpp
@@ -993,6 +993,8 @@ MacroArgs *Preprocessor::ReadMacroCallArgumentList(Token &MacroName,
       // If the macro contains the comma pasting extension, the diagnostic
       // is suppressed; we know we'll get another diagnostic later.
       if (!MI->hasCommaPasting()) {
+        // C++20 [cpp.replace]p15, C23 6.10.5p12
+        //
         // C++20 and C23 allow this construct, but standards before that
         // do not (we allow it as an extension).
         unsigned ID;



More information about the cfe-commits mailing list