As reported in the PR, va_arg (ap, void) probably doesn't make any sense and should be rejected thus. cc1plus and clang reject va_arg with an incomplete type. This patch makes cc1 reject it as well.
Bootstrapped/regtested on x86_64-linux, ok for trunk? 2015-04-27 Marek Polacek <pola...@redhat.com> PR c/65901 * c-typeck.c (c_build_va_arg): Require TYPE be a complete type. * gcc.c-torture/compile/pr48767.c (foo): Add dg-error. * gcc.dg/pr65901.c: New test. diff --git gcc/c/c-typeck.c gcc/c/c-typeck.c index 91735b5..c58e918 100644 --- gcc/c/c-typeck.c +++ gcc/c/c-typeck.c @@ -12648,6 +12648,11 @@ c_build_va_arg (location_t loc, tree expr, tree type) if (warn_cxx_compat && TREE_CODE (type) == ENUMERAL_TYPE) warning_at (loc, OPT_Wc___compat, "C++ requires promoted type, not enum type, in %<va_arg%>"); + if (type == error_mark_node || !COMPLETE_TYPE_P (type)) + { + c_incomplete_type_error (NULL_TREE, type); + return error_mark_node; + } return build_va_arg (loc, expr, type); } diff --git gcc/testsuite/gcc.c-torture/compile/pr48767.c gcc/testsuite/gcc.c-torture/compile/pr48767.c index 66cb348..c8fef35 100644 --- gcc/testsuite/gcc.c-torture/compile/pr48767.c +++ gcc/testsuite/gcc.c-torture/compile/pr48767.c @@ -3,5 +3,5 @@ void foo (__builtin_va_list ap) { - __builtin_va_arg (ap, void); + __builtin_va_arg (ap, void); /* { dg-error "invalid use of void expression" } */ } diff --git gcc/testsuite/gcc.dg/pr65901.c gcc/testsuite/gcc.dg/pr65901.c index e69de29..8708a1e 100644 --- gcc/testsuite/gcc.dg/pr65901.c +++ gcc/testsuite/gcc.dg/pr65901.c @@ -0,0 +1,16 @@ +/* PR c/65901 */ +/* { dg-do compile } */ +/* { dg-options "" } */ + +struct S; +enum E; +union U; + +void +foo (__builtin_va_list ap) +{ + __builtin_va_arg (ap, void); /* { dg-error "invalid use of void expression" } */ + __builtin_va_arg (ap, struct S); /* { dg-error "invalid use of undefined type" } */ + __builtin_va_arg (ap, enum E); /* { dg-error "invalid use of undefined type" } */ + __builtin_va_arg (ap, union U); /* { dg-error "invalid use of undefined type" } */ +} Marek