[Bug middle-end/92312] New: bogus -Wstringop-overflow storing into a trailing array backed by larger buffer
msebor at gcc dot gnu.org
gcc-bugzilla@gcc.gnu.org
Thu Oct 31 20:08:00 GMT 2019
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92312
Bug ID: 92312
Summary: bogus -Wstringop-overflow storing into a trailing
array backed by larger buffer
Product: gcc
Version: 10.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: middle-end
Assignee: unassigned at gcc dot gnu.org
Reporter: msebor at gcc dot gnu.org
Target Milestone: ---
GCC 10.0 issues a -Wstringop-overflow warning for stores into trailing arrays
that are backed by a large enough buffer to act as larger "flexible array
members." This is a safe idiom that should probably be allowed without a
warning. It's used for example in the Linux kernel where it triggers the
following warning (and a few others):
drivers/input/mouse/cyapa_gen5.c:1559:34: warning: writing 1 byte into a region
of size 0 [-Wstringop-overflow=]
1559 | app_cmd_head->parameter_data[0] = GEN5_PARAMETER_DISABLE_PIP_REPORT;
| ^
drivers/input/mouse/cyapa_gen5.c: In function ‘cyapa_gen5_set_power_mode’:
drivers/input/mouse/cyapa_gen5.c:317:5: note: at offset 0 to object
‘parameter_data’ with size 0 declared here
317 | u8 parameter_data[0]; /* Parameter data variable based on cmd_code */
| ^~~~~~~~~~~~~~
A small test case is below.
$ cat z.c && gcc -O2 -S -Wall -fdump-tree-strlen=/dev/stdout z.c
struct S0 { char a, b[0]; };
void f0 (void*);
void f1 (void)
{
char a[3];
struct S0 *p = (struct S0*)a;
p->a = 0;
__builtin_memset (p->b, 0, 2); // ok
f0 (p);
}
void f2 (void)
{
char a[3];
struct S0 *p = (struct S0*)a;
p->a = 0;
p->b[0] = 0;
p->b[1] = 1; // warning
f0 (p);
}
struct Sx { char a, b[]; };
void f3 (void)
{
char a[3];
struct Sx *p = (struct Sx*)a;
p->a = 0;
p->b[0] = 0;
p->b[1] = 1; // warning
f0 (p);
}
;; Function f1 (f1, funcdef_no=0, decl_uid=1935, cgraph_uid=1, symbol_order=0)
;; 1 loops found
;;
;; Loop 0
;; header 0, latch 1
;; depth 0, outer -1
;; nodes: 0 1 2
;; 2 succs { 1 }
f1 ()
{
char a[3];
<bb 2> [local count: 1073741824]:
MEM[(struct S0 *)&a].a = 0;
__builtin_memset (&MEM <char[0:]> [(void *)&a + 1B], 0, 2);
f0 (&a);
a ={v} {CLOBBER};
return;
}
;; Function f2 (f2, funcdef_no=1, decl_uid=1940, cgraph_uid=2, symbol_order=1)
;; 1 loops found
;;
;; Loop 0
;; header 0, latch 1
;; depth 0, outer -1
;; nodes: 0 1 2
;; 2 succs { 1 }
z.c: In function ‘f2’:
z.c:19:11: warning: writing 1 byte into a region of size 0
[-Wstringop-overflow=]
19 | p->b[0] = 0;
| ~~~~~~~~^~~
z.c:1:21: note: destination object declared here
1 | struct S0 { char a, b[0]; };
| ^
z.c:20:11: warning: writing 1 byte into a region of size 0
[-Wstringop-overflow=]
20 | p->b[1] = 1; // warning
| ~~~~~~~~^~~
z.c:1:21: note: destination object declared here
1 | struct S0 { char a, b[0]; };
| ^
f2 ()
{
char a[3];
<bb 2> [local count: 1073741824]:
MEM[(struct S0 *)&a].a = 0;
MEM[(struct S0 *)&a].b[0] = 0;
MEM[(struct S0 *)&a].b[1] = 1;
f0 (&a);
a ={v} {CLOBBER};
return;
}
;; Function f3 (f3, funcdef_no=2, decl_uid=1948, cgraph_uid=3, symbol_order=2)
;; 1 loops found
;;
;; Loop 0
;; header 0, latch 1
;; depth 0, outer -1
;; nodes: 0 1 2
;; 2 succs { 1 }
z.c: In function ‘f3’:
z.c:31:11: warning: writing 1 byte into a region of size 0
[-Wstringop-overflow=]
31 | p->b[0] = 0;
| ~~~~~~~~^~~
z.c:24:21: note: destination object declared here
24 | struct Sx { char a, b[]; };
| ^
z.c:32:11: warning: writing 1 byte into a region of size 0
[-Wstringop-overflow=]
32 | p->b[1] = 1; // warning
| ~~~~~~~~^~~
z.c:24:21: note: destination object declared here
24 | struct Sx { char a, b[]; };
| ^
f3 ()
{
char a[3];
<bb 2> [local count: 1073741824]:
MEM[(struct Sx *)&a].a = 0;
MEM[(struct Sx *)&a].b[0] = 0;
MEM[(struct Sx *)&a].b[1] = 1;
f0 (&a);
a ={v} {CLOBBER};
return;
}
More information about the Gcc-bugs
mailing list