https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93200
Bug ID: 93200
Summary: [10 Regression] spurious -Wstringop-overflow due to
assignment vectorization to multiple members
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: ---
This bug tracks the language-independent part of the Fortran-specific bug 92956
based on the test case in bug 92956 comment #10. The transformation of
assignments to multiple consecutive members into a single "vectorized" MEM_REF
assignment starting at the address of the first member can cause spurious
-Wstringop-overflow warnings, depending on the object layout. This has been
reported to cause false positives in builds of cjdns-v20.4.
The small test case below reproduces the problem:
$ cat t.c && gcc -O3 -S -Wall -fdump-tree-strlen=/dev/stdout t.c
struct A { char b, c; };
struct B { char i; struct A a; };
void f (struct B *p)
{
p->a.b = 1; // no warning here
p->a.c = 2;
}
struct C { int i; struct A a; };
void g (struct C *p)
{
p->a.b = 1; // spurious -Wstringop-overflow
p->a.c = 2;
}
;; Function f (f, funcdef_no=0, decl_uid=1936, 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 }
f (struct B * p)
{
<bb 2> [local count: 1073741824]:
p_2(D)->a.b = 1;
p_2(D)->a.c = 2;
return;
}
;; Function g (g, funcdef_no=1, decl_uid=1942, 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 }
t.c: In function ‘g’:
t.c:14:10: warning: writing 2 bytes into a region of size 1
[-Wstringop-overflow=]
14 | p->a.b = 1; // spurious -Wstringop-overflow
| ~~~~~~~^~~
t.c:1:17: note: at offset 0 to object ‘b’ with size 1 declared here
1 | struct A { char b, c; };
| ^
g (struct C * p)
{
vector(2) char * vectp.8;
vector(2) char * vectp_p.7;
<bb 2> [local count: 1073741824]:
vectp.8_6 = &p_2(D)->a.b;
MEM <vector(2) char> [(char *)vectp.8_6] = { 1, 2 };
return;
}