This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug middle-end/81908] [8 Regression] FAIL: gfortran.dg/alloc_comp_auto_array_2.f90 -O3 -g -m32


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

--- Comment #3 from Martin Sebor <msebor at gcc dot gnu.org> ---
(In reply to Richard Biener from comment #1)

The code was originally designed for -Walloc-size-larger-than and does the
right thing for that warning.  The range I see is

  _248: ~[1, 2147483647]
  __builtin_memcpy (_251, _259, _248);

leaving 0 as the only valid value less than SIZE_MAX / 2 in ILP32.  Zero is not
really a valid allocation size so the code excludes it.

But the code is also used for -Wstringop-overflow and the same logic doesn't
apply equally well there.  The warning does suggest that the memcpy could be
eliminated, so as in most instances of it, the true root cause is really a
missed optimization opportunity.   In fact, this whole block must be
unreachable because if it were executed it would either attempt to allocate
more than SIZE_MAX / 2 bytes (which would fail) or allocate and write past the
end of the 1-byte block:

  <bb 46> [0.43%] [count: INV]:
  vect_cst__246 = { -1, 265, 1, 1 };
  _247 = ubound.2_35 * 4;
  _248 = (character(kind=4)) _247;                                     // _248
is ~[1, 2147483647]
  _249 = MAX_EXPR <_248, 1>;                                           // _249
must be 1
  _251 = __builtin_malloc (_249);                                      // _251
= malloc(1)
  __builtin_memcpy (_251, _259, _248);                                 // no-op
  MEM[(struct grid_index_region *)&D.3501] = _251;
  MEM[(struct grid_index_region *)&D.3501 + 4B] = { -1, 265, 1, 1 };   //
invalid/write-past-end
  MEM[(struct grid_index_region *)&D.3501 + 20B] = ubound.2_35;        //
invalid/write-past-end


(In reply to Richard Biener from comment #1)

get_size_range() sets the RANGE[] array to the unsigned bounds of the range of
sizes.  It can't set RANGE[0] > RANGE[1].  For example, the following must not
be diagnosed but is with the suggested cleanup in comment #2.  There may be a
way to clean up the code but the suggested patch is not sufficient (it causes
test suite regressions).

void __attribute__ ((alloc_size (1))) f (unsigned long);

void g (int n)
{
  if (n < -9 || 9 < n)
    n = -9;

  f (n);
}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]