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;

}

Reply via email to