aboutsummaryrefslogtreecommitdiff
path: root/gcc/c-family
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2024-12-05 12:57:44 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2024-12-05 12:57:44 +0100
commitfca04028d7075a6eaae350774a3916f14d4004ae (patch)
tree50c81443cb758c5be1ca659359b03b15d2af6143 /gcc/c-family
parentbf6f77edd625cfe2f2f164e90437df318b96527f (diff)
downloadgcc-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.cc1
-rw-r--r--gcc/c-family/c-common.h2
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,