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

Richard Biener <rguenth at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
          Component|tree-optimization           |c
                 CC|                            |jsm28 at gcc dot gnu.org
           Keywords|                            |accepts-invalid,
                   |                            |ice-on-invalid-code
           Assignee|rguenth at gcc dot gnu.org         |unassigned at gcc dot 
gnu.org
             Status|ASSIGNED                    |NEW

--- Comment #3 from Richard Biener <rguenth at gcc dot gnu.org> ---
The odd thing is that we parse

  d = va_arg (ap, typeof(d)()) ();

as function call, gimplifying it as

      _1 = .VA_ARG (&ap(address-taken), 0B, 0B);
      D.1987(address-taken) = _1;
      D.1987(address-taken) ();

 <modify_expr 0x7ffff6650d70
    type <record_type 0x7ffff66793f0 type_0 BLK
        size <integer_cst 0x7ffff6517dc8 constant 0>
        unit-size <integer_cst 0x7ffff6517d80 constant 0>
        align:8 warn_if_not_align:0 symtab:0 alias-set -1 canonical-type
0x7ffff66793f0 context <function_decl 0x7ffff6656200 foo>
        chain <type_decl 0x7ffff65415f0 D.1983>>
    side-effects
    arg:0 <var_decl 0x7ffff6526bd0 d type <record_type 0x7ffff66793f0>
        used read BLK t.c:4:13 size <integer_cst 0x7ffff6517dc8 0> unit-size
<integer_cst 0x7ffff6517d80 0>
        align:8 warn_if_not_align:0 context <function_decl 0x7ffff6656200 foo>
        chain <var_decl 0x7ffff6526c60 ap type <array_type 0x7ffff66792a0
va_list>
            addressable used read BLK t.c:5:11
            size <integer_cst 0x7ffff6537210 constant 192>
            unit-size <integer_cst 0x7ffff65371e0 constant 24>
            align:64 warn_if_not_align:0 context <function_decl 0x7ffff6656200
foo>>>
    arg:1 <call_expr 0x7ffff66786c0 type <record_type 0x7ffff66793f0>
        side-effects
        fn <addr_expr 0x7ffff66652a0 type <pointer_type 0x7ffff6679540>
            side-effects
            arg:0 <va_arg_expr 0x7ffff6665280 type <function_type
0x7ffff6679498>
                side-effects
                arg:0 <addr_expr 0x7ffff6665260 type <pointer_type
0x7ffff6542b28>
                    arg:0 <var_decl 0x7ffff6526c60 ap>>
                t.c:6:7 start: t.c:6:7 finish: t.c:6:7>
            t.c:6:7 start: t.c:6:7 finish: t.c:6:7>
        t.c:6:7 start: t.c:6:7 finish: t.c:6:33>
    t.c:6:5 start: t.c:6:3 finish: t.c:6:33>

I _think_ we fail to decay the function type in va_arg to a pointer type
or we fail to reject this testcase.

Somewhat reduced testcase:

#include <stdarg.h>
typedef struct {} D;
void foo (int size, ...)
{
  va_list ap;
  va_arg (ap, D()) ();
}

C17/7.16.1.1 isn't sufficiently clear as to whether this is valid, but
at least "The parameter type shall be a type name specified such that
the type of a pointer to an object that has the specified type can be
obtained simply by postfixing a * to type" isn't fulfilled here since
the corresponding pointer type would be D(*)(), not D()*.

clang rejects this with

t.c:6:15: error: second argument to 'va_arg' is of non-POD type 'D ()'
[-Wnon-pod-varargs]
  va_arg (ap, D()) ();
              ^~~

but not sure if "POD" is a thing to use in C language diagnostics.

Anyway, defering to C frontend maintainers.

Reply via email to