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
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
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
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
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
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
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 }