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