1 /* Test to verify that -Wzero-length-bounds and not -Warray-bounds is
2 issued for accesses to interior zero-length array members that are
3 within the bounds of the enclosing struct.
4 { dg-do compile }
5 { dg-options "-O2 -Wall" } */
6
7 /* pr102706: disabled warnings because the now-disabled conditions for the
8 bogus warnings to come up do not take cost analysis into account, and often
9 come up wrong. */
10 /* { dg-additional-options "-Wno-stringop-overflow" } */
11
12 void sink (void*);
13
14 struct A { int i; };
15 struct B { int j; struct A a[0]; };
16
17 struct C
18 {
19 struct B b1;
20 struct B b2;
21 };
22
23
24 void test_B_ref (struct B *p)
25 {
26 // References with negative indices are always diagnosed by -Warray-bounds
27 // even though they could be considered the same as past the end accesses
28 // to trailing zero-length arrays.
29 p->a[-1].i = 0; // { dg-warning "\\\[-Warray-bounds" }
30 p->a[ 0].i = 0;
31 p->a[ 1].i = 0;
32 sink (p);
33
34 p[1].a[-1].i = 0; // { dg-warning "\\\[-Warray-bounds" }
35 p[1].a[ 0].i = 0;
36 p[1].a[ 1].i = 0;
37 }
38
39
40 void test_C_ref (struct C *p)
41 {
42 p->b1.a[-1].i = 0; // { dg-warning "\\\[-Warray-bounds" }
43 p->b1.a[ 0].i = 0; // { dg-warning "\\\[-Wzero-length-bounds" }
44 p->b1.a[ 1].i = 0; // { dg-warning "\\\[-Wzero-length-bounds" }
45
46 // Accesses to trailing zero-length arrays are not diagnosed (should
47 // they be?)
48 p->b2.a[ 0].i = 0;
49 p->b2.a[ 9].i = 0;
50 }
51
52
53 void test_C_decl (void)
54 {
55 struct C c, *p = &c;
56
57 p->b1.a[-1].i = 0; // { dg-warning "\\\[-Warray-bounds" }
58
59 // c.b1.a[0].i overlaps c.b2.j.
60 p->b1.a[ 0].i = 0; // { dg-warning "\\\[-Wzero-length-bounds" }
61
62 // c.b1.a[1].i is past the end of c...
63 p->b1.a[ 1].i = 0; // { dg-warning "\\\[-Warray-bounds" }
64 sink (p);
65
66 // ...and so are references to all elements of c.b2.a
67 p->b2.a[ 0].i = 0; // { dg-warning "\\\[-Warray-bounds" }
68 p->b2.a[ 1].i = 0; // { dg-warning "\\\[-Warray-bounds" }
69 sink (p);
70 }
71
72
73 char cbuf1[1 * sizeof (struct C)];
74 char cbuf2[2 * sizeof (struct C)] = { };
75
76 void test_C_global_buf (void)
77 {
78 struct C *p = (struct C*)&cbuf1;
79
80 p->b1.a[-1].i = 0; // { dg-warning "\\\[-Warray-bounds" }
81 p->b1.a[ 0].i = 0; // { dg-warning "\\\[-Wzero-length-bounds" }
82 p->b1.a[ 1].i = 0; // { dg-warning "\\\[-Warray-bounds" }
83 sink (p);
84
85 p->b2.a[ 0].i = 0; // { dg-warning "\\\[-Warray-bounds" }
86 p->b2.a[ 1].i = 0; // { dg-warning "\\\[-Warray-bounds" }
87 sink (p);
88
89 p = (struct C*)&cbuf2;
90 p->b1.a[-1].i = 0; // { dg-warning "\\\[-Warray-bounds" }
91 p->b1.a[ 0].i = 0; // { dg-warning "\\\[-Wzero-length-bounds" }
92 p->b1.a[ 1].i = 0; // { dg-warning "\\\[-Wzero-length-bounds" }
93 sink (p);
94
95 p->b2.a[ 0].i = 0; // { dg-bogus "\\\[-Wstringop-overflow" "pr102706" }
96 // { xfail { vect_slp_v2si_store_align && { ! vect_slp_v4si_store_unalign } } }
97 p->b2.a[ 1].i = 0;
98 p->b2.a[ 2].i = 0; // { dg-warning "\\\[-Warray-bounds" }
99 p->b2.a[ 3].i = 0; // { dg-warning "\\\[-Warray-bounds" }
100 sink (p);
101 }
102
103
104 void test_C_local_buf (void)
105 {
106 char cbuf1[1 * sizeof (struct C)] = "";
107 char cbuf2[2 * sizeof (struct C)] = { };
108
109 struct C *p = (struct C*)&cbuf1;
110
111 p->b1.a[-1].i = 1; // { dg-warning "\\\[-Warray-bounds" }
112 p->b1.a[ 0].i = 2; // { dg-warning "\\\[-Wzero-length-bounds" }
113 p->b1.a[ 1].i = 3; // { dg-warning "\\\[-Warray-bounds" }
114 sink (p);
115
116 p->b2.a[ 0].i = 4; // { dg-warning "\\\[-Warray-bounds" }
117 p->b2.a[ 1].i = 5; // { dg-warning "\\\[-Warray-bounds" }
118 sink (p);
119
120 p = (struct C*)&cbuf2;
121 p->b1.a[-1].i = 6; // { dg-warning "\\\[-Warray-bounds" }
122 p->b1.a[ 0].i = 7; // { dg-warning "\\\[-Wzero-length-bounds" }
123 p->b1.a[ 1].i = 8; // { dg-warning "\\\[-Wzero-length-bounds" }
124 sink (p);
125
126 p->b2.a[ 0].i = 9; // { dg-bogus "\\\[-Wstringop-overflow" "pr102706" }
127 // { xfail { vect_slp_v2si_store_align && { ! vect_slp_v4si_store_unalign } } }
128 p->b2.a[ 1].i = 10;
129 p->b2.a[ 2].i = 11; // { dg-warning "\\\[-Warray-bounds" }
130 p->b2.a[ 3].i = 12; // { dg-warning "\\\[-Warray-bounds" }
131 sink (p);
132 }