diff options
author | Jakub Jelinek <jakub@redhat.com> | 2024-12-05 12:57:44 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2024-12-05 12:57:44 +0100 |
commit | fca04028d7075a6eaae350774a3916f14d4004ae (patch) | |
tree | 50c81443cb758c5be1ca659359b03b15d2af6143 /gcc/c-family | |
parent | bf6f77edd625cfe2f2f164e90437df318b96527f (diff) | |
download | gcc-fca04028d7075a6eaae350774a3916f14d4004ae.zip gcc-fca04028d7075a6eaae350774a3916f14d4004ae.tar.gz gcc-fca04028d7075a6eaae350774a3916f14d4004ae.tar.bz2 |
c: Diagnose unexpected va_start arguments in C23 [PR107980]
va_start macro was changed in C23 from the C17 va_start (va_list ap, parmN)
where parmN is the identifier of the last parameter into
va_start (va_list ap, ...) where arguments after ap aren't evaluated.
Late in the C23 development
"If any additional arguments expand to include unbalanced parentheses, or
a preprocessing token that does not convert to a token, the behavior is
undefined."
has been added, plus there is
"NOTE The macro allows additional arguments to be passed for va_start for
compatibility with older versions of the library only."
and
"Additional arguments beyond the first given to the va_start macro may be
expanded and used in unspecified contexts where they are unevaluated. For
example, an implementation diagnoses potentially erroneous input for an
invocation of va_start such as:"
...
va_start(vl, 1, 3.0, "12", xd); // diagnostic encouraged
...
"Simultaneously, va_start usage consistent with older revisions of this
document should not produce a diagnostic:"
...
void neigh (int last_arg, ...) {
va_list vl;
va_start(vl, last_arg); // no diagnostic
The following patch implements the recommended diagnostics.
Until now in C23 mode va_start(v, ...) was defined to
__builtin_va_start(v, 0)
and the extra arguments were silently ignored.
The following patch adds a new builtin in a form of a keyword which
parses the first argument, is silent about the __builtin_c23_va_start (ap)
form, for __builtin_c23_va_start (ap, identifier) looks the identifier up
and is silent if it is the last named parameter (except that it diagnoses
if it has register keyword), otherwise diagnoses it isn't the last one
but something else, and if there is just __builtin_c23_va_start (ap, )
or if __builtin_c23_va_start (ap, is followed by tokens other than
identifier followed by ), it skips over the tokens (with handling of
balanced ()s) until ) and diagnoses the extra tokens.
In all cases in a form of warnings.
2024-12-05 Jakub Jelinek <jakub@redhat.com>
PR c/107980
gcc/
* ginclude/stdarg.h (va_start): For C23+ change parameters from
v, ... to just ... and define to __builtin_c23_va_start(__VA_ARGS__)
rather than __builtin_va_start(v, 0).
gcc/c-family/
* c-common.h (enum rid): Add RID_C23_VA_START.
* c-common.cc (c_common_reswords): Add __builtin_c23_va_start.
gcc/c/
* c-parser.cc (c_parser_postfix_expression): Handle RID_C23_VA_START.
gcc/testsuite/
* gcc.dg/c23-stdarg-4.c: Expect extra warning.
* gcc.dg/c23-stdarg-6.c: Likewise.
* gcc.dg/c23-stdarg-7.c: Likewise.
* gcc.dg/c23-stdarg-8.c: Likewise.
* gcc.dg/c23-stdarg-10.c: New test.
* gcc.dg/c23-stdarg-11.c: New test.
* gcc.dg/torture/c23-stdarg-split-1a.c: Expect extra warning.
* gcc.dg/torture/c23-stdarg-split-1b.c: Likewise.
Diffstat (limited to 'gcc/c-family')
-rw-r--r-- | gcc/c-family/c-common.cc | 1 | ||||
-rw-r--r-- | gcc/c-family/c-common.h | 2 |
2 files changed, 2 insertions, 1 deletions
diff --git a/gcc/c-family/c-common.cc b/gcc/c-family/c-common.cc index d21f2f9..0489523 100644 --- a/gcc/c-family/c-common.cc +++ b/gcc/c-family/c-common.cc @@ -459,6 +459,7 @@ const struct c_common_resword c_common_reswords[] = { "__builtin_tgmath", RID_BUILTIN_TGMATH, D_CONLY }, { "__builtin_offsetof", RID_OFFSETOF, 0 }, { "__builtin_types_compatible_p", RID_TYPES_COMPATIBLE_P, D_CONLY }, + { "__builtin_c23_va_start", RID_C23_VA_START, D_C23 }, { "__builtin_va_arg", RID_VA_ARG, 0 }, { "__complex", RID_COMPLEX, 0 }, { "__complex__", RID_COMPLEX, 0 }, diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h index 7834e0d..e2195aa 100644 --- a/gcc/c-family/c-common.h +++ b/gcc/c-family/c-common.h @@ -105,7 +105,7 @@ enum rid /* C extensions */ RID_ASM, RID_TYPEOF, RID_TYPEOF_UNQUAL, RID_ALIGNOF, RID_ATTRIBUTE, - RID_VA_ARG, + RID_C23_VA_START, RID_VA_ARG, RID_EXTENSION, RID_IMAGPART, RID_REALPART, RID_LABEL, RID_CHOOSE_EXPR, RID_TYPES_COMPATIBLE_P, RID_BUILTIN_COMPLEX, RID_BUILTIN_SHUFFLE, RID_BUILTIN_SHUFFLEVECTOR, RID_BUILTIN_CONVERTVECTOR, RID_BUILTIN_TGMATH, |