public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug other/103542] New: bogus -Warray-bounds while index is limited by switch/case
@ 2021-12-03 15:33 patrickdepinguin at gmail dot com
  2021-12-03 20:04 ` [Bug tree-optimization/103542] [10/11/12 Regregression] " pinskia at gcc dot gnu.org
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: patrickdepinguin at gmail dot com @ 2021-12-03 15:33 UTC (permalink / raw)
  To: gcc-bugs

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

            Bug ID: 103542
           Summary: bogus -Warray-bounds while index is limited by
                    switch/case
           Product: gcc
           Version: 11.2.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: other
          Assignee: unassigned at gcc dot gnu.org
          Reporter: patrickdepinguin at gmail dot com
  Target Milestone: ---

gcc 11.2.0 reports the following on a reduced test case:

$ powerpc-linux-gcc -c array-bounds-fruit.c -O2 -Wall -Werror

array-bounds-fruit.c: In function 'get_default_config.part.0':
array-bounds-fruit.c:69:37: error: array subscript 4 is above array bounds of
'struct fruit_config[4]' [-Werror=array-bounds]
   69 |             do_something(id, &config[id].num_lemons);
      |                               ~~~~~~^~~~
array-bounds-fruit.c:19:28: note: while referencing 'config'
   19 | static struct fruit_config config[4];
      |                            ^~~~~~
cc1: all warnings being treated as errors


Above is for powerpc, but I have the same problem with ARM.

The offending line is inside a switch/case, within the block where 'id' is
tested to be 0, 1, 2, or 3.
gcc/g++ is considering a case where 'id' becomes 4, which is not possible in
this code.

If I make any more changes (even seemingly unrelated changes) to the test case,
the error disappears.

Test code:

#include <stddef.h>
#include <stdbool.h>
#include <stdint.h>

enum {
    ID_0 = 0,
    ID_1 = 1,
    ID_2 = 2,
    ID_3 = 3,
    MAX_IDS,
};
#define MAX_ENTRIES 256

struct fruit_config {
    uint32_t num_apples;
    uint32_t num_lemons;
    uint32_t * lemons;
};
static struct fruit_config config[4];

static uint32_t unrelated_table[MAX_IDS][MAX_ENTRIES];

uint32_t do_something(const uint32_t id, uint32_t * number_of_entries)
{
    uint32_t error = 0;

    switch (id) {
        /* merging these case statements with identical body removes the issue
*/
        case ID_0: {
            *number_of_entries = 0;
            break;
        }
        case ID_1: {
            *number_of_entries = 0;
            break;
        }
        case ID_2: {
            *number_of_entries = 0;
            break;
        }
        case ID_3: {
            *number_of_entries = 0;
            break;
        }
        default: {
            error = 0xff;
            *number_of_entries = 0;
            break;
        }
    }
    return error;
}

struct fruit_config * get_default_config(const uint32_t id)
{
    switch (id) {
        case ID_0:
        case ID_1:
        case ID_2:
        case ID_3:
        {
            uint32_t entry = 0;
            for (entry = 0; entry <config[id].num_apples ; entry++) {
                   unrelated_table[0][0] = 0;
            }

            config[id].num_apples = 0;

            do_something(id, &config[id].num_lemons);

            /* removing following two lines removes the issue, even though
             * the error already occurs above */
            config[id].num_lemons = 0;
            config[id].lemons = NULL;

            /* removing use of error removes the issue */
            extern void foo(uint32_t arg);
            uint32_t error = 0;
            foo(error);

            break;
        }
        default: {
            break;
        }
    }

    return NULL;
}

void func_start(void)
{
    uint32_t i = 0;
    for (i = 0; i < MAX_IDS; i++) {
        get_default_config(i);
    }
}

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

* [Bug tree-optimization/103542] [10/11/12 Regregression] bogus -Warray-bounds while index is limited by switch/case
  2021-12-03 15:33 [Bug other/103542] New: bogus -Warray-bounds while index is limited by switch/case patrickdepinguin at gmail dot com
@ 2021-12-03 20:04 ` pinskia at gcc dot gnu.org
  2021-12-04 22:41 ` msebor at gcc dot gnu.org
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: pinskia at gcc dot gnu.org @ 2021-12-03 20:04 UTC (permalink / raw)
  To: gcc-bugs

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

Andrew Pinski <pinskia at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
      Known to fail|                            |10.3.0
           Keywords|                            |diagnostic
   Target Milestone|---                         |10.4
          Component|other                       |tree-optimization
            Summary|bogus -Warray-bounds while  |[10/11/12 Regregression]
                   |index is limited by         |bogus -Warray-bounds while
                   |switch/case                 |index is limited by
                   |                            |switch/case
     Ever confirmed|0                           |1
             Status|UNCONFIRMED                 |NEW
      Known to work|                            |9.4.0
   Last reconfirmed|                            |2021-12-03

--- Comment #1 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
Confirmed. Part of the problem is we split the get_default_config function
early on losing that id<=3

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

* [Bug tree-optimization/103542] [10/11/12 Regregression] bogus -Warray-bounds while index is limited by switch/case
  2021-12-03 15:33 [Bug other/103542] New: bogus -Warray-bounds while index is limited by switch/case patrickdepinguin at gmail dot com
  2021-12-03 20:04 ` [Bug tree-optimization/103542] [10/11/12 Regregression] " pinskia at gcc dot gnu.org
@ 2021-12-04 22:41 ` msebor at gcc dot gnu.org
  2022-06-28 10:47 ` jakub at gcc dot gnu.org
  2022-11-30 13:42 ` rguenth at gcc dot gnu.org
  3 siblings, 0 replies; 5+ messages in thread
From: msebor at gcc dot gnu.org @ 2021-12-04 22:41 UTC (permalink / raw)
  To: gcc-bugs

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

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

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |missed-optimization
             Blocks|                            |56456
                 CC|                            |msebor at gcc dot gnu.org

--- Comment #2 from Martin Sebor <msebor at gcc dot gnu.org> ---
The IL for the function is below.  It seems quite inefficient compared to GCC
9.

void get_default_config.part.0 (const uint32_t id)
{
  uint32_t error;
  uint32_t entry;
  unsigned int _4;
  uint32_t * _5;

  <bb 2> [local count: 118111600]:
  goto <bb 4>; [100.00%]

  <bb 3> [local count: 955630225]:
  entry_2 = entry_1 + 1;

  <bb 4> [local count: 1073741824]:
  # entry_1 = PHI <entry_2(3), 0(2)>
  _4 = config[id_3(D)].num_apples;
  if (entry_1 < _4)
    goto <bb 3>; [89.00%]
  else
    goto <bb 5>; [11.00%]

  <bb 5> [local count: 118111600]:
  config[id_3(D)].num_apples = 0;
  _5 = &config[id_3(D)].num_lemons;
  switch (id_3(D)) <default: <L4> [20.00%], case 0: <L0> [20.00%], case 1: <L1>
[20.00%], case 2: <L2> [20.00%], case 3: <L3> [20.00%]>

  <bb 6> [local count: 23622320]:
<L0>:
  MEM <struct fruit_config[4]> [(uint32_t *)&config][0].num_lemons = 0;
  goto <bb 11>; [100.00%]

  <bb 7> [local count: 23622320]:
<L1>:
  MEM <struct fruit_config[4]> [(uint32_t *)&config][1].num_lemons = 0;
  goto <bb 11>; [100.00%]

  <bb 8> [local count: 23622320]:
<L2>:
  MEM <struct fruit_config[4]> [(uint32_t *)&config][2].num_lemons = 0;
  goto <bb 11>; [100.00%]

  <bb 9> [local count: 23622320]:
<L3>:
  MEM <struct fruit_config[4]> [(uint32_t *)&config][3].num_lemons = 0;
  goto <bb 11>; [100.00%]

  <bb 10> [local count: 23622320]:
<L4>:
  MEM <struct fruit_config[4]> [(uint32_t *)&config][id_3(D)].num_lemons = 0;  
<<< -Warray-bounds

  <bb 11> [local count: 118111602]:
  # error_14 = PHI <0(7), 255(10), 0(6), 0(9), 0(8)>
  config[id_3(D)].num_lemons = 0;
  config[id_3(D)].lemons = 0B;
  foo (0);
  return;

}

In GCC 9 both the function and the final assembly are much more compact:

et_default_config.part.0 (const uint32_t id)
{
  struct fruit_config[4] * _2;
  sizetype _13;
  sizetype _14;

  <bb 2> [local count: 118111601]:
  _13 = (sizetype) id_3(D);
  _14 = _13 * 16;
  _2 = &config + _14;
  MEM[(unsigned int *)_2] = 0;
  config[id_3(D)].lemons = 0B;
  foo (0); [tail call]
  return;

}


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] 5+ messages in thread

* [Bug tree-optimization/103542] [10/11/12 Regregression] bogus -Warray-bounds while index is limited by switch/case
  2021-12-03 15:33 [Bug other/103542] New: bogus -Warray-bounds while index is limited by switch/case patrickdepinguin at gmail dot com
  2021-12-03 20:04 ` [Bug tree-optimization/103542] [10/11/12 Regregression] " pinskia at gcc dot gnu.org
  2021-12-04 22:41 ` msebor at gcc dot gnu.org
@ 2022-06-28 10:47 ` jakub at gcc dot gnu.org
  2022-11-30 13:42 ` rguenth at gcc dot gnu.org
  3 siblings, 0 replies; 5+ messages in thread
From: jakub at gcc dot gnu.org @ 2022-06-28 10:47 UTC (permalink / raw)
  To: gcc-bugs

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

Jakub Jelinek <jakub at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
   Target Milestone|10.4                        |10.5

--- Comment #3 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
GCC 10.4 is being released, retargeting bugs to GCC 10.5.

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

* [Bug tree-optimization/103542] [10/11/12 Regregression] bogus -Warray-bounds while index is limited by switch/case
  2021-12-03 15:33 [Bug other/103542] New: bogus -Warray-bounds while index is limited by switch/case patrickdepinguin at gmail dot com
                   ` (2 preceding siblings ...)
  2022-06-28 10:47 ` jakub at gcc dot gnu.org
@ 2022-11-30 13:42 ` rguenth at gcc dot gnu.org
  3 siblings, 0 replies; 5+ messages in thread
From: rguenth at gcc dot gnu.org @ 2022-11-30 13:42 UTC (permalink / raw)
  To: gcc-bugs

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

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

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |aldyh at gcc dot gnu.org,
                   |                            |hubicka at gcc dot gnu.org

--- Comment #4 from Richard Biener <rguenth at gcc dot gnu.org> ---
(In reply to Andrew Pinski from comment #1)
> Confirmed. Part of the problem is we split the get_default_config function
> early on losing that id<=3

That seems to be the problem, but I think we could get at the range
from a path ranger which we'd query for the function arguments we pass
on and where we could attach the ranges to the parameters default def.

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

end of thread, other threads:[~2022-11-30 13:42 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-12-03 15:33 [Bug other/103542] New: bogus -Warray-bounds while index is limited by switch/case patrickdepinguin at gmail dot com
2021-12-03 20:04 ` [Bug tree-optimization/103542] [10/11/12 Regregression] " pinskia at gcc dot gnu.org
2021-12-04 22:41 ` msebor at gcc dot gnu.org
2022-06-28 10:47 ` jakub at gcc dot gnu.org
2022-11-30 13:42 ` rguenth 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).