https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107980

--- Comment #21 from GCC Commits <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Jakub Jelinek <ja...@gcc.gnu.org>:

https://gcc.gnu.org/g:fca04028d7075a6eaae350774a3916f14d4004ae

commit r15-5939-gfca04028d7075a6eaae350774a3916f14d4004ae
Author: Jakub Jelinek <ja...@redhat.com>
Date:   Thu Dec 5 12:57:44 2024 +0100

    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  <ja...@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.

Reply via email to