Skip to content

Commit 5231005

Browse files
authored
[Clang] Update missing varargs arg extension warnings (#84520)
This updates a few warnings that were diagnosing no arguments for a `...` variadic macro parameter as a GNU extension when it actually is a C++20/C23 extension now. This fixes #84495.
1 parent 62ed009 commit 5231005

File tree

7 files changed

+42
-21
lines changed

7 files changed

+42
-21
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,9 @@ Improvements to Clang's diagnostics
263263
operands, distinguishing it from potential typographical errors or unintended
264264
bitwise operations. Fixes #GH77601.
265265

266+
- Clang now correctly diagnoses no arguments to a variadic macro parameter as a C23/C++20 extension.
267+
Fixes #GH84495.
268+
266269
Improvements to Clang's time-trace
267270
----------------------------------
268271

clang/include/clang/Basic/DiagnosticLexKinds.td

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -465,9 +465,16 @@ def err_embedded_directive : Error<
465465
def ext_embedded_directive : Extension<
466466
"embedding a directive within macro arguments has undefined behavior">,
467467
InGroup<DiagGroup<"embedded-directive">>;
468-
def ext_missing_varargs_arg : Extension<
469-
"must specify at least one argument for '...' parameter of variadic macro">,
470-
InGroup<GNUZeroVariadicMacroArguments>;
468+
def ext_c_missing_varargs_arg : Extension<
469+
"passing no argument for the '...' parameter of a variadic macro is "
470+
"a C23 extension">, InGroup<C23>;
471+
def ext_cxx_missing_varargs_arg : Extension<
472+
"passing no argument for the '...' parameter of a variadic macro is "
473+
"a C++20 extension">, InGroup<CXX20>;
474+
def warn_c17_compat_missing_varargs_arg : Warning<
475+
"passing no argument for the '...' parameter of a variadic macro is "
476+
"incompatible with C standards before C23">,
477+
InGroup<CPre23Compat>, DefaultIgnore;
471478
def warn_cxx17_compat_missing_varargs_arg : Warning<
472479
"passing no argument for the '...' parameter of a variadic macro is "
473480
"incompatible with C++ standards before C++20">,

clang/lib/Lex/PPMacroExpansion.cpp

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -993,11 +993,20 @@ MacroArgs *Preprocessor::ReadMacroCallArgumentList(Token &MacroName,
993993
// If the macro contains the comma pasting extension, the diagnostic
994994
// is suppressed; we know we'll get another diagnostic later.
995995
if (!MI->hasCommaPasting()) {
996-
// C++20 allows this construct, but standards before C++20 and all C
997-
// standards do not allow the construct (we allow it as an extension).
998-
Diag(Tok, getLangOpts().CPlusPlus20
999-
? diag::warn_cxx17_compat_missing_varargs_arg
1000-
: diag::ext_missing_varargs_arg);
996+
// C++20 [cpp.replace]p15, C23 6.10.5p12
997+
//
998+
// C++20 and C23 allow this construct, but standards before that
999+
// do not (we allow it as an extension).
1000+
unsigned ID;
1001+
if (getLangOpts().CPlusPlus20)
1002+
ID = diag::warn_cxx17_compat_missing_varargs_arg;
1003+
else if (getLangOpts().CPlusPlus)
1004+
ID = diag::ext_cxx_missing_varargs_arg;
1005+
else if (getLangOpts().C23)
1006+
ID = diag::warn_c17_compat_missing_varargs_arg;
1007+
else
1008+
ID = diag::ext_c_missing_varargs_arg;
1009+
Diag(Tok, ID);
10011010
Diag(MI->getDefinitionLoc(), diag::note_macro_here)
10021011
<< MacroName.getIdentifierInfo();
10031012
}

clang/test/C/C2x/n2975.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
void func(...) { // expected-warning {{'...' as the only parameter of a function is incompatible with C standards before C23}}
1212
// Show that va_start doesn't require the second argument in C23 mode.
1313
va_list list;
14-
va_start(list); // FIXME: it would be nice to issue a portability warning to C17 and earlier here.
14+
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}}
1515
va_end(list);
1616

1717
// 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
2626
__builtin_va_start(list); // expected-error {{too few arguments to function call, expected 2, have 1}}
2727

2828
// Verify that the return type of a call to va_start is 'void'.
29-
_Static_assert(__builtin_types_compatible_p(__typeof__(va_start(list)), void), "");
29+
_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}}
3030
_Static_assert(__builtin_types_compatible_p(__typeof__(__builtin_va_start(list, 0)), void), "");
3131
}
3232

clang/test/Lexer/gnu-flags.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,6 @@
1717

1818

1919
#if ALL || ZEROARGS
20-
// expected-warning@+9 {{must specify at least one argument for '...' parameter of variadic macro}}
21-
// expected-note@+4 {{macro 'efoo' defined here}}
2220
// expected-warning@+3 {{token pasting of ',' and __VA_ARGS__ is a GNU extension}}
2321
#endif
2422

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
1-
// RUN: %clang_cc1 -Eonly -std=c++17 -pedantic -verify %s
2-
// RUN: %clang_cc1 -Eonly -std=c17 -pedantic -verify -x c %s
3-
// RUN: %clang_cc1 -Eonly -std=c++20 -pedantic -Wpre-c++20-compat -verify=compat %s
1+
// RUN: %clang_cc1 -Eonly -std=c17 -pedantic -verify=c17,expected -x c %s
2+
// RUN: %clang_cc1 -Eonly -std=c23 -pedantic -Wpre-c23-compat -verify=c23,expected -x c %s
3+
// RUN: %clang_cc1 -Eonly -std=c++17 -pedantic -verify=cxx17,expected %s
4+
// RUN: %clang_cc1 -Eonly -std=c++20 -pedantic -Wpre-c++20-compat -verify=cxx20,expected %s
45

5-
#define FOO(x, ...) // expected-note {{macro 'FOO' defined here}} \
6-
// compat-note {{macro 'FOO' defined here}}
6+
// silent-no-diagnostics
7+
8+
#define FOO(x, ...) // expected-note {{macro 'FOO' defined here}}
79

810
int main() {
9-
FOO(42) // expected-warning {{must specify at least one argument for '...' parameter of variadic macro}} \
10-
// compat-warning {{passing no argument for the '...' parameter of a variadic macro is incompatible with C++ standards before C++20}}
11+
FOO(42) // c17-warning {{passing no argument for the '...' parameter of a variadic macro is a C23 extension}} \
12+
// cxx17-warning {{passing no argument for the '...' parameter of a variadic macro is a C++20 extension}} \
13+
// c23-warning {{passing no argument for the '...' parameter of a variadic macro is incompatible with C standards before C23}} \
14+
// cxx20-warning {{passing no argument for the '...' parameter of a variadic macro is incompatible with C++ standards before C++20}}
1115
}
1216

clang/test/Preprocessor/macro_fn.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@ e(x)
3737
e()
3838

3939
zero_dot()
40-
one_dot(x) /* empty ... argument: expected-warning {{must specify at least one argument for '...' parameter of variadic macro}} */
41-
one_dot() /* empty first argument, elided ...: expected-warning {{must specify at least one argument for '...' parameter of variadic macro}} */
40+
one_dot(x) /* empty ... argument: expected-warning {{passing no argument for the '...' parameter of a variadic macro is a C23 extension}} */
41+
one_dot() /* empty first argument, elided ...: expected-warning {{passing no argument for the '...' parameter of a variadic macro is a C23 extension}} */
4242

4343

4444
/* Crash with function-like macro test at end of directive. */

0 commit comments

Comments
 (0)