1 /* PR middle-end/96963 - -Wstringop-overflow false positive with
2    -ftree-vectorize when assigning consecutive char struct members
3    { dg-do compile }
4    { dg-options "-O2 -Wall -ftree-vectorize" } */
5 
6 void sink (void*);
7 
8 struct Char
9 {
10   int i;
11   char c, d, e, f;
12   char a[2], b[2];
13 };
14 
nowarn_char_assign(struct Char * p)15 void nowarn_char_assign (struct Char *p)
16 {
17   sink (&p->c);
18 
19   /* Verify the bogus warning triggered by the tree-ssa-strlen.c pass
20      is not issued.  */
21   p->c = 1;         // { dg-bogus "\\\[-Wstringop-overflow" }
22   p->d = 2;
23   p->e = 3;
24   p->f = 4;
25 }
26 
nowarn_char_array_assign(struct Char * p)27 void nowarn_char_array_assign (struct Char *p)
28 {
29   sink (p->a);
30 
31   p->a[0] = 1;      // { dg-bogus "\\\[-Wstringop-overflow" }
32   p->a[1] = 2;
33   p->b[0] = 3;
34   p->b[1] = 4;
35 }
36 
warn_char_array_assign_interior(struct Char * p)37 void warn_char_array_assign_interior (struct Char *p)
38 {
39   sink (p->a);
40 
41   p->a[0] = 1;
42   p->a[1] = 2;
43 #pragma GCC diagnostic push
44 #pragma GCC diagnostic ignored "-Warray-bounds"
45   /* Warnings are only suppressed for trailing arrays.  Verify
46      one is issued for an interior array.  */
47   p->a[2] = 5;      // { dg-warning "\\\[-Wstringop-overflow" }
48 #pragma GCC diagnostic pop
49 }
50 
warn_char_array_assign_trailing(struct Char * p)51 void warn_char_array_assign_trailing (struct Char *p)
52 {
53   /* This is separated from warn_char_array_assign_interior because
54      otherwise GCC removes the store to p->a[2] as dead since it's
55      overwritten by p->b[0].  */
56   sink (p->b);
57 
58   p->b[0] = 3;
59   p->b[1] = 4;
60 #pragma GCC diagnostic push
61 #pragma GCC diagnostic ignored "-Warray-bounds"
62   /* Warnings are only suppressed for trailing arrays with at most
63      one element.  Verify one is issued for a two-element array.  */
64   p->b[2] = 5;      // { dg-warning "\\\[-Wstringop-overflow" }
65 #pragma GCC diagnostic pop
66 }
67 
68 
69 /* Also verify there's no warning for other types than char (even though
70    the problem was limited to chars and -Wstringop-overflow should only
71    trigger for character accesses).  */
72 
73 struct Short
74 {
75   int i;
76   short c, d, e, f;
77   short a[2], b[2];
78 };
79 
nowarn_short_assign(struct Short * p)80 void nowarn_short_assign (struct Short *p)
81 {
82   sink (&p->c);
83 
84   p->c = 1;
85   p->d = 2;
86   p->e = 3;
87   p->f = 4;
88 }
89 
nowarn_short_array_assign(struct Short * p)90 void nowarn_short_array_assign (struct Short *p)
91 {
92   sink (p->a);
93 
94   p->a[0] = 1;
95   p->a[1] = 2;
96   p->b[0] = 3;
97   p->b[1] = 4;
98 }
99