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

--- Comment #11 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
It is still invalid even if you are lucky and it doesn't crash.
And it easily can crash at least with older gcc versions.
E.g. with
#include <stdarg.h>
int
foo (int a, ...)
{
  va_list ap;
  va_start (ap, a);
  if (a == 42)
    a = va_arg (ap, double);
  va_end (ap);
  return a;
}
until GCC 4.5 on x86_64 this emitted an indirect jump based on %rax value upon
entry, so if it is garbage from the caller, if you are lucky and it is 0-8, it
will seem to work, if it is above that, the code will just crash.
GCC 4.6 changed it so that the compiler at least when optimizing tracks if some
floating point (or some integer) va_arg is ever used and how many and only uses
if (rax) save_the_needed_xmm_regs; but it is still undefined behavior then.
In C you can't in another TU do
int foo ();
void bar (void) { foo (1, 2, 3); }
either, it is UB as well.

Reply via email to