]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/testsuite/gcc.dg/Wstringop-overflow-34.c
Correct handling of variable offset minus constant in -Warray-bounds [PR100137]
[thirdparty/gcc.git] / gcc / testsuite / gcc.dg / Wstringop-overflow-34.c
CommitLineData
a2c2cee9
MS
1/* PR middle-end/95353 - spurious -Wstringop-overflow writing to a trailing
2 array plus offset
3 { dg-do compile }
4 { dg-options "-O2 -Wall" } */
5
6typedef __SIZE_TYPE__ size_t;
7
8struct S0 { char n, a[0]; };
9
10
11void s0_nowarn_cstidx (struct S0 *p)
12{
13 char *q = p->a;
14 q[1] = __LINE__;
15 q[9] = __LINE__;
16}
17
18void s0_nowarn_cstoff_cstidx (struct S0 *p)
19{
20 char *q = p->a + 1;
21 q[1] = __LINE__;
22 q[9] = __LINE__;
23}
24
25void s0_nowarn_varoff_cstdix (struct S0 *p, int i)
26{
27 char *q = p->a + i;
28 q[1] = __LINE__; // { dg-bogus "\\\[-Wstringop-overflow" }
29 q[9] = __LINE__; // { dg-bogus "\\\[-Wstringop-overflow" }
30}
31
32void s0_nowarn_cstoff_varidx (struct S0 *p, int i)
33{
34 char *q = p->a + 1;
35 q[i] = __LINE__;
36}
37
38void s0_nowarn_varoff_varidx (struct S0 *p, int i, int j)
39{
40 char *q = p->a + i;
41 q[j] = __LINE__; // { dg-bogus "\\\[-Wstringop-overflow" }
42}
43
44
45/* Accesses past the end of a trailing array with one element is
46 discouraged but still reluctantly not diagnosed. This should
47 change. */
48
49struct S1 { char n, a[1]; };
50
51
52void s1_nowarn_cstidx (struct S1 *p)
53{
54 char *q = p->a;
55 q[1] = __LINE__;
56 q[9] = __LINE__;
57}
58
59void s1_nowarn_cstoff_cstidx (struct S1 *p)
60{
61 char *q = p->a + 1;
62 q[1] = __LINE__;
63 q[9] = __LINE__;
64}
65
66void s1_nowarn_varoff_cstdix (struct S1 *p, int i)
67{
68 char *q = p->a + i;
69 q[1] = __LINE__; // { dg-bogus "\\\[-Wstringop-overflow" }
70 q[9] = __LINE__; // { dg-bogus "\\\[-Wstringop-overflow" }
71}
72
73void s1_nowarn_cstoff_varidx (struct S1 *p, int i)
74{
75 char *q = p->a + 1;
76 q[i] = __LINE__;
77}
78
79void s1_nowarn_varoff_varidx (struct S1 *p, int i, int j)
80{
81 char *q = p->a + i;
82 q[j] = __LINE__;
83}
84
85
86/* Accesses past the end of a trailing array with more than one
87 element should be diagnosed but aren't yet because the MEM_REF
88 makes the out-of-bounds accesses indistinguishable from valid
89 ones to subsequent elements of the array pointed by P. */
90
91struct S2 { char n, a[2]; };
92
93
94void s2_warn_cstidx (struct S2 *p)
95{
96 char *q = p->a;
97
98 /* The following invalid store is represented as
99 MEM[(char *)p_1(D) + 3B] = __LINE__;
100 which is indistinguishable from the valid
101 q = &p[1].n; q[0] = __LINE__;
102 */
103 q[2] = __LINE__; // { dg-warning "\\\[-Wstringop-overflow" "pr?????" { xfail *-*-* } }
104}
105
106void s2_warn_cstoff_cstidx (struct S2 *p)
107{
108 char *q = p->a + 1;
109 q[1] = __LINE__; // { dg-warning "\\\[-Wstringop-overflow" "pr?????" { xfail *-*-* } }
110}
111
112void s2_warn_varoff_cstdix (struct S2 *p, int i)
113{
114 char *q = p->a + i;
a1108556 115 q[2] = __LINE__; // { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" }
a2c2cee9
MS
116}
117
118void s2_warn_cstoff_varidx (struct S2 *p, int i)
119{
120 char *q = p->a + 1;
121 q[i] = __LINE__; // { dg-warning "\\\[-Wstringop-overflow" "pr?????" { xfail *-*-* } }
122}
123
124void s2_warn_varoff_varidx (struct S2 *p, int i, int j)
125{
126 char *q = p->a + i;
127 q[j] = __LINE__; // { dg-warning "\\\[-Wstringop-overflow" "pr?????" { xfail *-*-* } }
128}
129
130
131/* Verify that none of these triggers a bogus warning (not tested
132 elsewhere but triggered during bootstrap). */
133
134void s2_nowarn_varidx_int (struct S2 *p, int i)
135{
136 extern struct S2 s2;
137 extern struct S2 s2a[];
138
139 s2.a[i - 1] = __LINE__;
140 s2.a[i] = __LINE__;
141 s2.a[i + 1] = __LINE__;
142
143 s2a[i].a[i - 1] = __LINE__;
144 s2a[i].a[i] = __LINE__;
145 s2a[i].a[i + 1] = __LINE__;
146
147 p[i].a[i - 1] = __LINE__;
148 p[i].a[i] = __LINE__;
149 p[i].a[i + 1] = __LINE__;
150
151 char *q = p->a;
152 q[i - 1] = __LINE__;
153 q[i] = __LINE__;
154 q[i + 1] = __LINE__;
155}
156
157/* Same as above but with a size_t index in range [1, SIZE_MAX]. */
158
159void* s2_nowarn_varidx_size (struct S2 *p, size_t i, size_t j)
160{
161 extern struct S2 s2;
162 extern struct S2 s2a[];
163 struct S2 *ps2 = __builtin_malloc (3 * sizeof *ps2);
164
165 s2.a[i - 1] = __LINE__;
166 s2.a[i] = __LINE__;
167 s2.a[i + 1] = __LINE__;
168
169 s2a[i].a[i - 1] = __LINE__;
170 s2a[i].a[i] = __LINE__;
171 s2a[i].a[i + 1] = __LINE__;
172
173 p[i].a[i - 1] = __LINE__;
174 p[i].a[i] = __LINE__;
175 p[i].a[i + 1] = __LINE__;
176
177 ps2->a[i - 1] = __LINE__;
178 ps2->a[i] = __LINE__;
179 ps2->a[i + 1] = __LINE__;
180
181 char *q = p->a;
182 q[i - 1] = __LINE__;
183 q[i] = __LINE__;
184 q[i + 1] = __LINE__;
185
186 if (j == 0)
187 return ps2;
188
189 s2.a[j - 1] = __LINE__;
190 s2.a[j] = __LINE__;
191 s2.a[j + 1] = __LINE__;
192
193 s2a[j].a[j - 1] = __LINE__;
194 s2a[j].a[j] = __LINE__;
195 s2a[j].a[j + 1] = __LINE__;
196
197 p[j].a[j - 1] = __LINE__;
198 p[j].a[j] = __LINE__;
199 p[j].a[j + 1] = __LINE__;
200
201 ps2->a[j - 1] = __LINE__;
202 ps2->a[j] = __LINE__;
203 ps2->a[j + 1] = __LINE__;
204
205 q = p->a;
206 q[j - 1] = __LINE__;
207 q[j] = __LINE__;
208 q[j + 1] = __LINE__;
209
210 return ps2;
211}
212
213/* Verify that accesses to an interior zero-length array are diagnosed. */
214
215struct Si0 { char c, a[0], d; };
216
217void si0_warn_cstidx (struct Si0 *p)
218{
219 // These are indistinguishable from valid accesses to p->d:
220 // MEM[(char *)p_1(D) + 1B] = 0;
221 char *q = p->a;
222 q[1] = __LINE__; // { dg-warning "writing 1 byte into a region of size 0" "pr?????" { xfail *-*-* } }
223 q[9] = __LINE__; // { dg-warning "\\\[-Wstringop-overflow" "pr?????" { xfail *-*-* } }
224}
225
226void si0_warn_cstoff_cstidx (struct Si0 *p)
227{
228 // Like those above, these too are indistinguishable from valid accesses
229 // to p->d.
230 char *q = p->a + 1;
231 q[1] = __LINE__; // { dg-warning "\\\[-Wstringop-overflow" "pr?????" { xfail *-*-* } }
232 q[9] = __LINE__; // { dg-warning "\\\[-Wstringop-overflow" "pr?????" { xfail *-*-* } }
233}
234
235void si0_warn_varoff_cstdix (struct Si0 *p, int i)
236{
237 char *q = p->a + i;
a1108556
MS
238 q[1] = __LINE__; // { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" }
239 q[9] = __LINE__; // { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" }
a2c2cee9
MS
240}
241
242void si0_warn_cstoff_varidx (struct Si0 *p, int i)
243{
244 char *q = p->a + 1;
245 q[i] = __LINE__; // { dg-warning "\\\[-Wstringop-overflow" "pr?????" { xfail *-*-* } }
246}
247
248void si0_warn_varoff_varidx (struct Si0 *p, int i, int j)
249{
250 char *q = p->a + i;
a1108556 251 q[j] = __LINE__; // { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" }
a2c2cee9 252}