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.