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

Martin Sebor <msebor at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Blocks|                            |56456
     Ever confirmed|0                           |1
             Status|UNCONFIRMED                 |NEW
   Last reconfirmed|                            |2021-08-02

--- Comment #2 from Martin Sebor <msebor at gcc dot gnu.org> ---
GCC 12 issues a bunch of warnings for this file (below) but the one mentioned
in comment #0 is the first one below.  It's issued for the following IL:

  vector(2) long int * vectp.5288;
  ...
  vectp.5288_337 = &it_140(D)->position.charpos;   <<< memset accesses
  vect_saved_pos_charpos_84.5289_336 = MEM <vector(2) long int> [(long int
*)vectp.5288_337];
  saved_pos$charpos_84 = it_140(D)->position.charpos;
  saved_pos$bytepos_83 = it_140(D)->position.bytepos;
  saved_object_148 = it_140(D)->object;
  it_140(D)->what = 0;
  memset (vectp.5288_337, 0, 16);                  <<< warning here
  it_140(D)->object = 0B;
  it_140(D)->len = 1;

So vectp.5288_337 points to it->position's charpos member but the memset clears
the whole struct.  To detect buffer overflow the access warnings assume that
the accesses in the IL they work with correspond to those in the original
source (in fact all warnings necessarily assume the IL corresponds to the
source code).  Optimizations that substitute one subobject for another (e.g.,
FRE which introduces this IL) reak this assumption and trigger false positives.
 There's nothing the warning can do in these cases except to give up on
detecting buffer overflow in member accesses.  That's obviously not desirable. 
But the problem can be solved by changing optimization to refer to subobjects
by their offsets from the beginning of the enclosing object instead of by their
name.  In other words, in the above, GCC should emit:

  vectp.5288_337 = &it_140(D)->position;

This has no adverse impact on optimization.  The last time we have discussed
this I said I'd look into it for GCC 12 and I still plan (hope) to.

$ gcc -O3 -S -Warray-bounds=2 -flto=2 -ffat-lto-objects -fdump-tree-vrp1
xdisp.preprocessed.c.c 
xdisp.preprocessed.c.c: In function ‘append_space_for_newline’:
xdisp.preprocessed.c.c:95847:7: warning: ‘memset’ offset [2352, 2359] from the
object at ‘it_138(D)’ is out of the bounds of referenced subobject ‘charpos’
with type ‘long int’ at offset 2344 [-Warray-bounds]
95847 |       memset (&it->position, 0, sizeof it->position);
      |       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
xdisp.preprocessed.c.c:16291:13: note: subobject ‘charpos’ declared here
16291 |   ptrdiff_t charpos;
      |             ^~~~~~~
xdisp.preprocessed.c.c: In function ‘extend_face_to_end_of_line’:
xdisp.preprocessed.c.c:96182:8: warning: ‘memset’ offset [2352, 2359] from the
object at ‘it_309(D)’ is out of the bounds of referenced subobject ‘charpos’
with type ‘long int’ at offset 2344 [-Warray-bounds]
96182 |        memset (&it->position, 0, sizeof it->position);
      |        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
xdisp.preprocessed.c.c:16291:13: note: subobject ‘charpos’ declared here
16291 |   ptrdiff_t charpos;
      |             ^~~~~~~
xdisp.preprocessed.c.c:96216:5: warning: ‘memset’ offset [2352, 2359] from the
object at ‘it_309(D)’ is out of the bounds of referenced subobject ‘charpos’
with type ‘long int’ at offset 2344 [-Warray-bounds]
96216 |     memset (&it->position, 0, sizeof it->position);
      |     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
xdisp.preprocessed.c.c:16291:13: note: subobject ‘charpos’ declared here
16291 |   ptrdiff_t charpos;
      |             ^~~~~~~
xdisp.preprocessed.c.c:96267:8: warning: ‘memset’ offset [2352, 2359] from the
object at ‘it_309(D)’ is out of the bounds of referenced subobject ‘charpos’
with type ‘long int’ at offset 2344 [-Warray-bounds]
96267 |        memset (&it->position, 0, sizeof it->position);
      |        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
xdisp.preprocessed.c.c:16291:13: note: subobject ‘charpos’ declared here
16291 |   ptrdiff_t charpos;
      |             ^~~~~~~
xdisp.preprocessed.c.c:96298:7: warning: ‘memset’ offset [2352, 2359] from the
object at ‘it_309(D)’ is out of the bounds of referenced subobject ‘charpos’
with type ‘long int’ at offset 2344 [-Warray-bounds]
96298 |       memset (&it->position, 0, sizeof it->position);
      |       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
xdisp.preprocessed.c.c:16291:13: note: subobject ‘charpos’ declared here
16291 |   ptrdiff_t charpos;
      |             ^~~~~~~
In function ‘SDATA’,
    inlined from ‘SSDATA’ at xdisp.preprocessed.c.c:5996:19,
    inlined from ‘tty_handle_tab_bar_click’ at xdisp.preprocessed.c.c:90014:19:
xdisp.preprocessed.c.c:5990:31: warning: array subscript 0 is outside array
bounds of ‘struct Lisp_X[9223372036854775807]’ [-Warray-bounds]
 5990 |   return XSTRING (string)->u.s.data;
      |          ~~~~~~~~~~~~~~~~~~~~~^~~~~
In function ‘AREF’,
    inlined from ‘tty_get_tab_bar_item’ at xdisp.preprocessed.c.c:89963:29,
    inlined from ‘tty_handle_tab_bar_click’ at xdisp.preprocessed.c.c:89991:25:
xdisp.preprocessed.c.c:6258:35: note: at offset -4 into object ‘MEM[(struct
Lisp_Vector *)_45 + -5B].contents[_30]’ of size [0, 9223372036854775807]
 6258 |   return XVECTOR (array)->contents[idx];
      |          ~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~
In function ‘SCHARS’,
    inlined from ‘tty_handle_tab_bar_click’ at xdisp.preprocessed.c.c:90014:36:
xdisp.preprocessed.c.c:6013:13: warning: array subscript 0 is outside array
bounds of ‘struct Lisp_X[9223372036854775807]’ [-Warray-bounds]
 6013 |   ptrdiff_t nchars = XSTRING (string)->u.s.size;
      |             ^~~~~~
In function ‘AREF’,
    inlined from ‘tty_get_tab_bar_item’ at xdisp.preprocessed.c.c:89963:29,
    inlined from ‘tty_handle_tab_bar_click’ at xdisp.preprocessed.c.c:89991:25:
xdisp.preprocessed.c.c:6258:35: note: at offset -4 into object ‘MEM[(struct
Lisp_Vector *)_45 + -5B].contents[_30]’ of size [0, 9223372036854775807]
 6258 |   return XVECTOR (array)->contents[idx];
      |          ~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~
In function ‘STRING_MULTIBYTE’,
    inlined from ‘display_mode_element’ at xdisp.preprocessed.c.c:99480:91:
xdisp.preprocessed.c.c:5984:33: warning: array subscript 0 is outside array
bounds of ‘struct Lisp_X[9223372036854775807]’ [-Warray-bounds]
 5984 |   return 0 <= XSTRING (str)->u.s.size_byte;
      |               ~~~~~~~~~~~~~~~~~~^~~~~~~~~~


Referenced Bugs:

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56456
[Bug 56456] [meta-bug] bogus/missing -Warray-bounds

Reply via email to