public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c/97261] New: gcc-10 produces invalid -Warray-bounds warning
@ 2020-10-01  3:32 gccbugs at dima dot secretsauce.net
  2020-10-01  3:32 ` [Bug c/97261] " gccbugs at dima dot secretsauce.net
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: gccbugs at dima dot secretsauce.net @ 2020-10-01  3:32 UTC (permalink / raw)
  To: gcc-bugs

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

            Bug ID: 97261
           Summary: gcc-10 produces invalid -Warray-bounds warning
           Product: gcc
           Version: 10.1.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
          Assignee: unassigned at gcc dot gnu.org
          Reporter: gccbugs at dima dot secretsauce.net
  Target Milestone: ---

Hi. I'm seeing gcc-10 flag a warning that I'm pretty sure is incorrect. gcc-9
and older did not warn about this (although that's probably because they
weren't looking for these kinds of problems).

Recipe:

1. save the attached as tst.c

2. gcc-10 -Wall -Wextra -Wno-unused-variable -fPIC -O3 -c -o tst.o tst.c

I see this:



tst.c: In function 'f':
tst.c:21:17: warning: array subscript -1 is outside array bounds of 'double[1]'
[-Warray-bounds]
   21 |     const ab_t* ab = (ab_t*)(pb - 1);
      |                 ^~
tst.c:16:13: note: while referencing 'b'
   16 |     double  b  = 4.;
      |             ^



I believe this is false. Inside g(), ab->a is indeed out-of-bounds, but ab->b
is not. And I only use ab->b. Taking away -fPIC or -O3 makes the warning go
away. Making g() static makes it go away also.

I'm using gcc-10 from Debian. Package version 10.1.0-5.

Thanks!

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

* [Bug c/97261] gcc-10 produces invalid -Warray-bounds warning
  2020-10-01  3:32 [Bug c/97261] New: gcc-10 produces invalid -Warray-bounds warning gccbugs at dima dot secretsauce.net
@ 2020-10-01  3:32 ` gccbugs at dima dot secretsauce.net
  2020-10-01  6:26 ` rguenth at gcc dot gnu.org
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: gccbugs at dima dot secretsauce.net @ 2020-10-01  3:32 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #1 from Dima Kogan <gccbugs at dima dot secretsauce.net> ---
Created attachment 49294
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=49294&action=edit
Code to demo the issue

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

* [Bug c/97261] gcc-10 produces invalid -Warray-bounds warning
  2020-10-01  3:32 [Bug c/97261] New: gcc-10 produces invalid -Warray-bounds warning gccbugs at dima dot secretsauce.net
  2020-10-01  3:32 ` [Bug c/97261] " gccbugs at dima dot secretsauce.net
@ 2020-10-01  6:26 ` rguenth at gcc dot gnu.org
  2020-10-01  7:06 ` gccbugs at dima dot secretsauce.net
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: rguenth at gcc dot gnu.org @ 2020-10-01  6:26 UTC (permalink / raw)
  To: gcc-bugs

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

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

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

--- Comment #2 from Richard Biener <rguenth at gcc dot gnu.org> ---

    const ab_t* ab = (ab_t*)(pb - 1);

note that this invokes undefined behavior as you are producing the address
of one-before the start of an object.  You are also violating strict aliasing
rules with the access in g() which accesses a ab_t object but there's only
a double where you point to (well, there's nothing actually).

While the particular warning isn't very useful:

tst.c:21:17: warning: array subscript -1 is outside array bounds of 'double[1]'
[-Warray-bounds]
   21 |     const ab_t* ab = (ab_t*)(pb - 1);
      |                 ^~

it does point to the offending statement.  It probably should read
'warning: computing the address one element before the object 'double' invokes
undefined behavior'
or so.  Mentioning double[1] when there's just a 'double' is likely also more
confusing than it helps.  Maybe spelling out 'non-array object X' would be
better here.

All in all the bug for the testcase is invalid but I'm leaving it open to
eventually improve the actual diagnostic message.

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

* [Bug c/97261] gcc-10 produces invalid -Warray-bounds warning
  2020-10-01  3:32 [Bug c/97261] New: gcc-10 produces invalid -Warray-bounds warning gccbugs at dima dot secretsauce.net
  2020-10-01  3:32 ` [Bug c/97261] " gccbugs at dima dot secretsauce.net
  2020-10-01  6:26 ` rguenth at gcc dot gnu.org
@ 2020-10-01  7:06 ` gccbugs at dima dot secretsauce.net
  2020-10-01  7:54 ` rguenth at gcc dot gnu.org
  2020-10-01 15:18 ` [Bug c/97261] distinguish invalid subscripts from invalid addresses in -Warray-bounds msebor at gcc dot gnu.org
  4 siblings, 0 replies; 6+ messages in thread
From: gccbugs at dima dot secretsauce.net @ 2020-10-01  7:06 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #3 from Dima Kogan <gccbugs at dima dot secretsauce.net> ---
Hi. Thanks for replying. I don't the warning that I'm claiming is bogus is
complaining about the points you raised. If it did, then making g() static or
building without -fPIC or -O3 wouldn't make the warning go away.

I have some questions about your analysis, if that's ok. g() doesn't know where
its ab argument came from, so how can the strict aliasing rules be violated?
The only reason the compiler knows anything at all here is that with -O3 it's
tracing the flow. With -O0, there's no warning. And g() may as well be in an
entirely different compilation unit, in which case it'd compile that unit with
no complaint at any optimization level.

Similarly, for the undefined behavior. If I have a function that takes some
double* x, then is it undefined behavior to refer to x[-1]? If not, then how is
this different?

Thanks.

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

* [Bug c/97261] gcc-10 produces invalid -Warray-bounds warning
  2020-10-01  3:32 [Bug c/97261] New: gcc-10 produces invalid -Warray-bounds warning gccbugs at dima dot secretsauce.net
                   ` (2 preceding siblings ...)
  2020-10-01  7:06 ` gccbugs at dima dot secretsauce.net
@ 2020-10-01  7:54 ` rguenth at gcc dot gnu.org
  2020-10-01 15:18 ` [Bug c/97261] distinguish invalid subscripts from invalid addresses in -Warray-bounds msebor at gcc dot gnu.org
  4 siblings, 0 replies; 6+ messages in thread
From: rguenth at gcc dot gnu.org @ 2020-10-01  7:54 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #4 from Richard Biener <rguenth at gcc dot gnu.org> ---
(In reply to Dima Kogan from comment #3)
> Hi. Thanks for replying. I don't the warning that I'm claiming is bogus is
> complaining about the points you raised. If it did, then making g() static
> or building without -fPIC or -O3 wouldn't make the warning go away.

It's likely optimized away before warning.

> I have some questions about your analysis, if that's ok. g() doesn't know
> where its ab argument came from, so how can the strict aliasing rules be
> violated?

strict aliasing rules are violated because of the actual accesses, not
because what a compiler or the function can or cannot see.

> The only reason the compiler knows anything at all here is that
> with -O3 it's tracing the flow. With -O0, there's no warning. And g() may as
> well be in an entirely different compilation unit, in which case it'd
> compile that unit with no complaint at any optimization level.

But it's still a strict aliasing violation.

> Similarly, for the undefined behavior. If I have a function that takes some
> double* x, then is it undefined behavior to refer to x[-1]? If not, then how
> is this different?

It is undefined to refer to x[-1] in case x points to the first element
of an array.  This is simply how the C abstract machine defines things.

"hiding" violations doesn't make them go away, you just might be more
lucky in the compiler not taking advantage of the undefinedness and
not "miscompiling" your code (or issueing "bogus" diagnostics).

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

* [Bug c/97261] distinguish invalid subscripts from invalid addresses in -Warray-bounds
  2020-10-01  3:32 [Bug c/97261] New: gcc-10 produces invalid -Warray-bounds warning gccbugs at dima dot secretsauce.net
                   ` (3 preceding siblings ...)
  2020-10-01  7:54 ` rguenth at gcc dot gnu.org
@ 2020-10-01 15:18 ` msebor at gcc dot gnu.org
  4 siblings, 0 replies; 6+ messages in thread
From: msebor at gcc dot gnu.org @ 2020-10-01 15:18 UTC (permalink / raw)
  To: gcc-bugs

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

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

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |NEW
     Ever confirmed|0                           |1
            Summary|gcc-10 produces invalid     |distinguish invalid
                   |-Warray-bounds warning      |subscripts from invalid
                   |                            |addresses in -Warray-bounds
   Last reconfirmed|                            |2020-10-01
           Severity|normal                      |enhancement

--- Comment #5 from Martin Sebor <msebor at gcc dot gnu.org> ---
Where pointers (as opposed to arrays) are involved, the IL doesn't
differentiate taking the address of a subscript expression like &pb[-1] from
pointer subtraction like (pb - 1).  So changing the text of the warning, while
possible,  will come with a trade-off: losing the part about the
invalid/negative subscript in the former cases.

That said, the current detection of out of bounds pointers is incomplete and
could stand to be enhanced to also detect the case below.  Let me look into
adjusting the wording when I work on that.

$ cat x.c && gcc -O2 -S -Wall x.c 
int a[2];

int* f (int i)
{
  i = 3;
  return a + i;   // warning
}

int* g (int i)
{
  if (i < 3)
    i = 3;
  return a + i;   // missing warning
}

x.c: In function ‘f’:
x.c:6:12: warning: array subscript 3 is outside array bounds of ‘int[2]’
[-Warray-bounds]
    6 |   return a + i;
      |          ~~^~~
x.c:1:5: note: while referencing ‘a’
    1 | int a[2];
      |     ^

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

end of thread, other threads:[~2020-10-01 15:18 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-10-01  3:32 [Bug c/97261] New: gcc-10 produces invalid -Warray-bounds warning gccbugs at dima dot secretsauce.net
2020-10-01  3:32 ` [Bug c/97261] " gccbugs at dima dot secretsauce.net
2020-10-01  6:26 ` rguenth at gcc dot gnu.org
2020-10-01  7:06 ` gccbugs at dima dot secretsauce.net
2020-10-01  7:54 ` rguenth at gcc dot gnu.org
2020-10-01 15:18 ` [Bug c/97261] distinguish invalid subscripts from invalid addresses in -Warray-bounds 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).