https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118435
Bug ID: 118435 Summary: __builtin_va_arg does not check for POD type argument when it is passed by value Product: gcc Version: 15.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: wangbopku15 at gmail dot com Target Milestone: --- Consider the following code: $g++ -Wall -Wextra ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #include <stdarg.h> struct S { private: virtual void foo(); }; struct S arg; void foo (int z, ...) { va_list ap; va_start (ap, z); arg = va_arg (ap, struct S); va_end (ap); } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Clang rejects it and the diagnostic reveals that the argument of 'va_arg' must be a POD type when it is passed by value: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <source>:14:21: error: second argument to 'va_arg' is of non-POD type 'struct S' [-Wnon-pod-varargs] 14 | arg = va_arg (ap, struct S); | ^~~~~~~~ /opt/compiler-explorer/clang-trunk-20250112/lib/clang/20/include/__stdarg_va_arg.h:20:47: note: expanded from macro 'va_arg' 20 | #define va_arg(ap, type) __builtin_va_arg(ap, type) | ^~~~ 1 error generated. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ It seems that GCC does not have the corresponding restriction as the compiler always accepts the code despite under options like '-Wall -Wextra': https://godbolt.org/z/nKhMK54rW