public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c/101525] New: "out of the bounds" warning for an Innocuous memset call with LTO
@ 2021-07-20 12:14 Hi-Angel at yandex dot ru
  2021-07-21  6:33 ` [Bug tree-optimization/101525] " rguenth at gcc dot gnu.org
  2021-08-02 17:23 ` [Bug tree-optimization/101525] "out of the bounds" warning for an innocuous " msebor at gcc dot gnu.org
  0 siblings, 2 replies; 3+ messages in thread
From: Hi-Angel at yandex dot ru @ 2021-07-20 12:14 UTC (permalink / raw)
  To: gcc-bugs

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

            Bug ID: 101525
           Summary: "out of the bounds" warning for an Innocuous memset
                    call with LTO
           Product: gcc
           Version: 11.1.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
          Assignee: unassigned at gcc dot gnu.org
          Reporter: Hi-Angel at yandex dot ru
  Target Milestone: ---

Created attachment 51176
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=51176&action=edit
preprocessed file that triggers the warnings

Given this memset call

    static bool
    append_space_for_newline (struct it *it, bool default_face_p) {
    […]
          memset (&it->position, 0, sizeof it->position);

GCC complains:

    xdisp.c: In function ‘append_space_for_newline’:
    xdisp.c:21906:7: warning: ‘memset’ offset [2352, 2359] from the object at
‘it_122(D)’ is out of the bounds of referenced subobject ‘charpos’ with type
‘long int’ at offset 2344 [-Warray-bounds]
    21906 |       memset (&it->position, 0, sizeof it->position);
          |       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    In file included from composite.h:29,
                     from xdisp.c:441:
    dispextern.h:214:13: note: subobject ‘charpos’ declared here
      214 |   ptrdiff_t charpos;
          |             ^~~~~~~

I can't see any overflow on this line. Either way, further experiments show
that removing the function content below the offending line makes warnings
disappear. Since it's impossible to make overflow disappear by removing a code
below the overflow, the warning disappearance suggests the warning is a GCC bug
and should not be there.

----------------------------------------

I couldn't reduce it down to a minimal testcase because removing irrelevant
code makes warning go away, so instead in steps-to-reproduce I use a
preprocessed source. I had to compress it to be able to attach. The original is
a `src/xdisp.c` file in Emacs project at commit `6ebe8b03d80`.

# Steps to reproduce

1. Download `xdisp.preprocessed.c.zst`
2. Unpack with: zstd -d xdisp.preprocessed.c.zst
3. Compile with: gcc -c -Warray-bounds=2 -flto=2 -O3 -ffat-lto-objects 
xdisp.preprocessed.c

## Expected

No warnings for `append_space_for_newline` function

## Actual

There is a warning:

    xdisp.c: In function ‘append_space_for_newline’:
    xdisp.c:21906:7: warning: ‘memset’ offset [2352, 2359] from the object at
‘it_140(D)’ is out of the bounds of referenced subobject ‘charpos’ with type
‘long int’ at offset 2344 [-Warray-bounds]
    In file included from composite.h:29,
                     from xdisp.c:441:
    dispextern.h:214:13: note: subobject ‘charpos’ declared here

^ permalink raw reply	[flat|nested] 3+ messages in thread

* [Bug tree-optimization/101525] "out of the bounds" warning for an Innocuous memset call with LTO
  2021-07-20 12:14 [Bug c/101525] New: "out of the bounds" warning for an Innocuous memset call with LTO Hi-Angel at yandex dot ru
@ 2021-07-21  6:33 ` rguenth at gcc dot gnu.org
  2021-08-02 17:23 ` [Bug tree-optimization/101525] "out of the bounds" warning for an innocuous " msebor at gcc dot gnu.org
  1 sibling, 0 replies; 3+ messages in thread
From: rguenth at gcc dot gnu.org @ 2021-07-21  6:33 UTC (permalink / raw)
  To: gcc-bugs

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

Richard Biener <rguenth at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |msebor at gcc dot gnu.org

--- Comment #1 from Richard Biener <rguenth at gcc dot gnu.org> ---
The address is likely CSEd to &it->position.charpos (? just guessing) and then
the warning fires because it's misdesigned.

^ permalink raw reply	[flat|nested] 3+ messages in thread

* [Bug tree-optimization/101525] "out of the bounds" warning for an innocuous memset call with LTO
  2021-07-20 12:14 [Bug c/101525] New: "out of the bounds" warning for an Innocuous memset call with LTO Hi-Angel at yandex dot ru
  2021-07-21  6:33 ` [Bug tree-optimization/101525] " rguenth at gcc dot gnu.org
@ 2021-08-02 17:23 ` msebor at gcc dot gnu.org
  1 sibling, 0 replies; 3+ messages in thread
From: msebor at gcc dot gnu.org @ 2021-08-02 17:23 UTC (permalink / raw)
  To: gcc-bugs

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

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2021-08-02 17:23 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-07-20 12:14 [Bug c/101525] New: "out of the bounds" warning for an Innocuous memset call with LTO Hi-Angel at yandex dot ru
2021-07-21  6:33 ` [Bug tree-optimization/101525] " rguenth at gcc dot gnu.org
2021-08-02 17:23 ` [Bug tree-optimization/101525] "out of the bounds" warning for an innocuous " msebor at gcc dot gnu.org

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).