https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105149
--- Comment #6 from Richard Biener <rguenth at gcc dot gnu.org> --- (In reply to Richard Biener from comment #5) > The C++ frontend accepts this and diagnoses > > In file included from t.c:1: > t.c: In function 'void foo(int, ...)': > t.c:6:15: warning: 'D()' is promoted to 'D (*)()' when passed through '...' > 6 | va_arg (ap, D()) (); > > and produces the following GENERIC, decaying the "loaded function": include/stdarg.h:49:44: note: in definition of macro 'va_arg' 49 | #define va_arg(v,l) __builtin_va_arg(v,l) | ^ t.c:6:15: note: (so you should pass 'D (*)()' not 'D()' to 'va_arg') 6 | va_arg (ap, D()) (); include/stdarg.h:49:44: note: in definition of macro 'va_arg' 49 | #define va_arg(v,l) __builtin_va_arg(v,l) | ^ t.c:6:15: note: if this code is reached, the program will abort 6 | va_arg (ap, D()) (); include/stdarg.h:49:44: note: in definition of macro 'va_arg' 49 | #define va_arg(v,l) __builtin_va_arg(v,l) | ^ because the C++ implementation of lang_hooks.types.type_promotes_to says the function type doesn't promote to itself. The C frontend seems to lack that. > > > <call_expr 0x7ffff6692c00 > type <record_type 0x7ffff6681348 D cxx-odr-p type_5 QI > size <integer_cst 0x7ffff653a048 constant 8> > unit-size <integer_cst 0x7ffff653a060 constant 1> > align:8 warn_if_not_align:0 symtab:0 alias-set -1 canonical-type > 0x7ffff6681348 > fields <function_decl 0x7ffff6685600 __dt type <method_type > 0x7ffff6698000> > public abstract external autoinline decl_3 QI t.c:2:19 align:16 > warn_if_not_align:0 context <record_type 0x7ffff6681348 D> > full-name "D::~D() noexcept (<uninstantiated>)" > not-really-extern chain <function_decl 0x7ffff6685800 __dt_base > >> context <translation_unit_decl 0x7ffff6525168 t.c> > full-name "struct D" > X() X(constX&) this=(X&) n_parents=0 use_template=0 interface-unknown > pointer_to_this <pointer_type 0x7ffff66817e0> chain <type_decl > 0x7ffff6547980 ._anon_0>> > side-effects > fn <addr_expr 0x7ffff6678980 > type <pointer_type 0x7ffff6681690 type <function_type 0x7ffff66815e8> > unsigned DI > size <integer_cst 0x7ffff6517f48 constant 64> > unit-size <integer_cst 0x7ffff6517f60 constant 8> > align:64 warn_if_not_align:0 symtab:0 alias-set -1 > canonical-type 0x7ffff6681690> > side-effects > arg:0 <va_arg_expr 0x7ffff6678960 type <function_type 0x7ffff66815e8> > side-effects > arg:0 <addr_expr 0x7ffff6678a00 type <pointer_type > 0x7ffff6544dc8> > arg:0 <var_decl 0x7ffff6526c60 ap>> > t.c:6:3 start: t.c:6:3 finish: t.c:6:3> > t.c:6:3 start: t.c:6:3 finish: t.c:6:3> > t.c:6:3 start: t.c:6:3 finish: t.c:6:3> > > which we then gimplify to > > __builtin_trap (); > <<< Unknown tree: integer_cst >>> ();