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

--- Comment #9 from qinzhao at gcc dot gnu.org ---
(In reply to Kees Cook from comment #8)

> Normally -Warray-bounds doesn't warn when a value is totally unknown (i.e.
> "index" here can be [-INT_MAX,INT_MAX]). Why does the warning change when
> the MAX_ENTRIES test is moved inside assign()?

it's due to both inline transformation + thread jump optimization (and some
other compiler transformation inbetween). 

***After GCC inlines both calls to "assign" into the caller "sparx5_set" and
applies some other optimizations on the caller body before thread jump phase,
the body of the routine "sparx5_set" is (logically):

void sparx5_set (int * ptr, struct nums * sg, int index)
{
  if (index >= 4)
    warn ();
  *ptr = 0;

  *val = sg->vals[index];
  if (index >= 4)
    warn ();
  *ptr = *val;

  return;
}

***Thread jump optimization tried to reduce the # of branches inside the
routine "sparx5_set", in order to do this, sometime it needs to duplicate the
code. for the above routine, after thread jump optimization, the body of the
routine "sparx5_set" becomes (logically):

void sparx5_set (int * ptr, struct nums * sg, int index)
{
  if (index >= 4)
    { 
      warn ();
      *ptr = 0;               // code duplications since "warn" does return;
      *val = sg->vals[index]; // same this line. in this path, since it's under
                              // the condition "index >= 4", the compiler knows
                              // the value of "index" is larger then 4,
therefore
                              // the out-of-bound warning.
      warn ();
    }
  else
    { 
      *ptr = 0;
      *val = sg->vals[index];
    }
  *ptr = *val;
  return;

}

with the thread jump optimization, the # of branches inside the routine
"sparx5_set" is reduced from 2 to 1, however, due to the code duplication
(which is needed for the correctness of the code), we got a out-of-bound
warning. 

actually, I don't think that the compiler's behavior is wrong. and it's not
very reasonable for the users of -Warray-bounds to assume there is zero false
positive warnings. 
However, it might be reasonable to put such warnings to -Warray-bounds=2 but
not in -Warray-bounds=1?

Reply via email to