[Bug debug/37022] [4.4 regression] internal compiler error: in compute_barrier_args_size

hjl dot tools at gmail dot com gcc-bugzilla@gcc.gnu.org
Wed Aug 6 13:52:00 GMT 2008



------- Comment #6 from hjl dot tools at gmail dot com  2008-08-06 13:51 -------
>From Xuepeng:

__attribute__((noinline, used))
void
foo (int a, ...)
{
  va_list arg;
  char *p;
  int size;

  va_start (arg, a);
  size = va_arg (arg, int);

  if (size != 2)
/*A*/ abort ();        

  p = (char *) __builtin_alloca (size + 1);

  va_end (arg);

  if (v < 0)
/*B*/   abort ();      
}

This bug is caused by label optimization. Function compute_barrier_args_size
intends to walk the whole function rtl and compute args_size on BARRIERS. When
it reached the first if statement (size != 2), it will compute the destination
of this if statement, the destination was supposed to be at /*A*/ and then set
barrier_args_size[/*A*/]=cur_args_size. Unfortunately the destination /*A*/ was
optimized to /*B*/, so the actual result is barrier_args_size[/*B*/] was set to
cur_args_size. And at this point the cur_args_size was still zero, so the
barrier_args_size[/*B*/]=0. 

The __builtin_alloca will adjust stack pointer and make cur_args_size=32. 

The function compute_barrier_args_size continued and reached label /*B*/.
According to the author's comment that barrier_args_size[/*B*/] != -1 means
that the insns starting with this label have been already scanned or are in the
worklist, so the author thought barrier_args_size[/*B*/] should be
cur_args_size which is 32 now. But in fact the insns starting with this label
havn't been scanned, the barrier_args_size[/*B*/] was set to 0 just because of
label optimization. So the assert (barrier_args_size[/*B*/]== cur_args_size)
was generated.

If change label /*A*/ to something like v=0 rather than abort (), there will be
no compiler errors.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=37022



More information about the Gcc-bugs mailing list