Bug 92326 - [10 Regression] wrong bound in zero-length array diagnostics
Summary: [10 Regression] wrong bound in zero-length array diagnostics
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c (show other bugs)
Version: 10.0
: P3 trivial
Target Milestone: 10.0
Assignee: Martin Sebor
URL:
Keywords: diagnostic, patch
Depends on:
Blocks:
 
Reported: 2019-11-01 23:16 UTC by Martin Sebor
Modified: 2020-04-17 15:02 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2019-11-01 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Martin Sebor 2019-11-01 23:16:39 UTC
r277728 changed the formatting of zero-length arrays in diagnostics to include their bound, but the change also inadvertently added the zero bound to flexible array members (because they are gratuitously represented differently between the front-ends).  The test case below shows the problem.  It only affects C code:

$ cat x.c && gcc -O2 -S -Wall x.c
struct S0 { int n, a[0]; } s0;
struct Sx { int n, a[]; } sx = { 0 };

void f (void)
{
  s0.a[0] = 0;
  sx.a[0] = 0;
}
x.c: In function ‘f’:
x.c:6:7: warning: array subscript 0 is above array bounds of ‘int[0]’ [-Warray-bounds]
    6 |   s0.a[0] = 0;
      |   ~~~~^~~
x.c:1:20: note: while referencing ‘a’
    1 | struct S0 { int n, a[0]; } s0;
      |                    ^
x.c:1:28: note: defined here ‘s0’
    1 | struct S0 { int n, a[0]; } s0;
      |                            ^~
x.c:7:7: warning: array subscript 0 is above array bounds of ‘int[0]’ [-Warray-bounds]
    7 |   sx.a[0] = 0;
      |   ~~~~^~~
x.c:2:20: note: while referencing ‘a’
    2 | struct Sx { int n, a[]; } sx = { 0 };
      |                    ^
x.c:2:27: note: defined here ‘sx’
    2 | struct Sx { int n, a[]; } sx = { 0 };
      |                           ^~


When compiled by the C++ front-end, the format of the arrays is as expected:

$ gcc -O2 -S -Wall -xc++ x.c
x.c: In function ‘void f()’:
x.c:6:9: warning: array subscript 0 is above array bounds of ‘int [0]’ [-Warray-bounds]
    6 |   s0.a[0] = 0;
      |   ~~~~~~^
x.c:1:20: note: while referencing ‘S0::a’
    1 | struct S0 { int n, a[0]; } s0;
      |                    ^
x.c:1:28: note: defined here ‘s0’
    1 | struct S0 { int n, a[0]; } s0;
      |                            ^~
x.c:7:9: warning: array subscript 0 is above array bounds of ‘int []’ [-Warray-bounds]
    7 |   sx.a[0] = 0;
      |   ~~~~~~^
x.c:2:20: note: while referencing ‘Sx::a’
    2 | struct Sx { int n, a[]; } sx = { 0 };
      |                    ^
x.c:2:27: note: defined here ‘sx’
    2 | struct Sx { int n, a[]; } sx = { 0 };
      |                           ^~
Comment 1 Martin Liška 2019-12-02 14:13:02 UTC
Just for the record, I see the failure in grub2 package.
Comment 2 Martin Liška 2020-01-28 09:55:54 UTC
Any update on this Martin?
Comment 3 Martin Liška 2020-01-28 09:57:50 UTC
And for the record, qemu package build is also affected with this:

/home/abuild/rpmbuild/BUILD/qemu-4.2.0/scsi/qemu-pr-helper.c: In function ‘multipath_pr_out’:
/home/abuild/rpmbuild/BUILD/qemu-4.2.0/scsi/qemu-pr-helper.c:523:32: error: array subscript 0 is above array bounds of ‘struct transportid *[0]’ [-Werror=array-bounds]
In file included from /home/abuild/rpmbuild/BUILD/qemu-4.2.0/scsi/qemu-pr-helper.c:36:
Comment 4 Martin Sebor 2020-01-28 17:01:54 UTC
No progress yet.

This bug is only cosmetic, in the format of the flexible array member in the warning, so it shouldn't cause any failures (as in false positives or negatives).  Can you clarify how the builds of grub2 and qemu are affected by it?
Comment 5 Martin Liška 2020-01-29 08:44:40 UTC
> negatives).  Can you clarify how the builds of grub2 and qemu are affected
> by it?

Despite our rules, these packages use -Werror ;) So it's not a critical issue this PR.
Comment 7 GCC Commits 2020-04-13 21:32:54 UTC
The master branch has been updated by Martin Sebor <msebor@gcc.gnu.org>:

https://gcc.gnu.org/g:09f041390245da60411a9f0e08c4bedf7430585a

commit r10-7706-g09f041390245da60411a9f0e08c4bedf7430585a
Author: Martin Sebor <msebor@redhat.com>
Date:   Mon Apr 13 15:31:44 2020 -0600

    PR c/92326 - wrong bound in zero-length array diagnostics
    
    gcc/c-family/ChangeLog:
    
            PR c/92326
            * c-pretty-print.c (c_pretty_printer::direct_abstract_declarator): Avoid
            printing array bound for flexible array members.
    
    gcc/testsuite/ChangeLog:
    
            PR c/92326
            * c-c++-common/Warray-bounds-8.c: New test.
            * gcc.dg/Warray-bounds-46.c: Adjust expected format of flexible array
            memebrs in diagnostics.
            * gcc.dg/Warray-bounds-49.c: Same.
Comment 8 Martin Sebor 2020-04-13 21:33:23 UTC
Fixed.
Comment 9 Martin Liška 2020-04-16 07:43:33 UTC
The qemu test-case is still reported as warning.
Reduced test-case:

$ cat qemu.i
struct A a;

int c, d;

struct A {
  int scalar;
  int flexible[];
};

void g() {
  a.flexible[c] = d;
}

$ gcc -O2 -c qemu.i -Werror=array-bounds
qemu.i: In function ‘g’:
qemu.i:11:13: error: array subscript <unknown> is outside array bounds of ‘int[]’ [-Werror=array-bounds]
   11 |   a.flexible[c] = d;
      |   ~~~~~~~~~~^~~
qemu.i:7:7: note: while referencing ‘flexible’
    7 |   int flexible[];
      |       ^~~~~~~~
qemu.i:1:10: note: defined here ‘a’
    1 | struct A a;
      |          ^
cc1: some warnings being treated as errors
Comment 10 Martin Sebor 2020-04-16 23:50:11 UTC
This bug isn't about whether or not a warning is issued but about the format of the flexible array member printed by it: it should be 'int[]' but was 'int[0]'.  (That's why Jeff and I have been wondering what you meant.)

The warning in the test case in comment #9 is justified: the flexible array has no elements because struct a is defined but doesn't initialize it with any (there would be no warning if the struct were only declared but not defined).

Hopefully this test case will explain it:

$ cat pr92326.c && gcc -O2 -S -Wall pr92326.c
struct A a;   // a.flexible has no elements

int c, d;

struct A {
  int scalar;
  int flexible[];
};

void g() {
  a.flexible[c] = d;   // out-of-bounds regardless of c
}

struct A a2 = { 1, { 0 } };   // b.flexible has 1 element

void g2 (void) {
  a2.flexible[c] = d;   // out-of-bounds only if c != 0 (probably should warn)
}

extern struct A a3;  // b.flexible might have one or more elements

void g3 (void) {
  a3.flexible[c] = d;   // unknown if it's in-bounds or out-of-bounds
}

pr92326.c: In function ‘g’:
pr92326.c:11:13: warning: array subscript <unknown> is outside array bounds of ‘int[]’ [-Warray-bounds]
   11 |   a.flexible[c] = d;   // out-of-bounds regardless of c
      |   ~~~~~~~~~~^~~
pr92326.c:7:7: note: while referencing ‘flexible’
    7 |   int flexible[];
      |       ^~~~~~~~
pr92326.c:1:10: note: defined here ‘a’
    1 | struct A a;   // a.flexible has no elements
      |          ^
Comment 11 Martin Liška 2020-04-17 07:35:06 UTC
All right, thanks for the clarification. Btw. qemu fixed the warning in the meantime:
https://github.com/patchew-project/qemu/commit/4ce1e15fbc7266a108a7c77a3962644b3935346e
Comment 12 Martin Sebor 2020-04-17 15:02:33 UTC
Thanks!  I'm glad to see the new warning has helpe identify (and fix) a real bug!