1 /* PR middle-end/84051 - missing -Warray-bounds on an out-of-bounds access
2    via an array pointer
3    { dg-do compile }
4    { dg-options "-O2 -Wall -ftrack-macro-expansion=0" } */
5 
6 void sink (void*, ...);
7 #define T(x) sink (0, x)
8 
9 void
test_note(int (* pia3)[3])10 test_note (int (*pia3)[3])    // { dg-message "while referencing 'pia3'" }
11 {
12   int i = 0;
13   T ((*pia3)[i++]);
14   T ((*pia3)[i++]);
15   T ((*pia3)[i++]);
16   T ((*pia3)[i++]);           // { dg-warning "array subscript 3 is (above|outside) array bounds of 'int\\\[3]'" }
17   T ((*pia3)[i++]);           // { dg-warning "array subscript 4 is (above|outside) array bounds of 'int\\\[3]'" }
18 
19   {
20     /* Regrettably, the following isn't diagnosed because it's represented
21        the same as the possibly valid access below:
22          MEM[(int *)a_1(D) + 36B] = 0;  */
23     int *p0 = pia3[0];
24     T (p0[3]);                // { dg-warning "array subscript 3 is (above|outside) array bounds of 'int\\\[3]'" "pr?????" { xfail *-*-* } }
25 
26     int *p1 = pia3[3];
27     T (p1[0]);                // okay
28   }
29 }
30 
test_a1_cst(_Bool (* pba0)[0],char (* pca1)[1],short (* psa2)[2],int (* pia3)[3])31 void test_a1_cst (_Bool (*pba0)[0], char (*pca1)[1],
32 		  short (*psa2)[2], int (*pia3)[3])
33 {
34   T ((*pba0)[-1]);            // { dg-warning "array subscript -1 is (above|outside) array bounds of '_Bool\\\[0]'" }
35   T ((*pba0)[0]);             // { dg-warning "array subscript 0 is (above|outside) array bounds of '_Bool\\\[0]'" }
36   T ((*pba0)[1]);             // { dg-warning "array subscript 1 is (above|outside) array bounds of '_Bool\\\[0]'" }
37   T ((*pba0)[2]);             // { dg-warning "array subscript 2 is (above|outside) array bounds of '_Bool\\\[0]'" }
38   T ((*pba0)[12]);            // { dg-warning "array subscript 12 is (above|outside) array bounds of '_Bool\\\[0]'" }
39 
40   T ((*pca1)[-1]);            // { dg-warning "array subscript -1 is (below|outside) array bounds of 'char\\\[1]'" }
41   T ((*pca1)[0]);
42   T ((*pca1)[1]);             // { dg-warning "array subscript 1 is (above|outside) array bounds of 'char\\\[1]'" }
43   T ((*pca1)[2]);             // { dg-warning "array subscript 2 is (above|outside) array bounds of 'char\\\[1]'" }
44   T ((*pca1)[123]);           // { dg-warning "array subscript 123 is (above|outside) array bounds of 'char\\\[1]'" }
45 
46   T ((*psa2)[-1]);            // { dg-warning "array subscript -1 is (below|outside) array bounds of 'short int\\\[2]'" }
47   T ((*psa2)[0]);
48   T ((*psa2)[1]);
49   T ((*psa2)[2]);             // { dg-warning "array subscript 2 is (above|outside) array bounds of 'short int\\\[2]'" }
50   T ((*psa2)[1234]);          // { dg-warning "array subscript 1234 is (above|outside) array bounds of 'short int\\\[2]'" }
51 
52   T ((*pia3)[-1]);            // { dg-warning "array subscript -1 is (below|outside) array bounds of 'int\\\[3]'" }
53   T ((*pia3)[0]);
54   T ((*pia3)[1]);
55   T ((*pia3)[2]);
56   T ((*pia3)[3]);             // { dg-warning "array subscript 3 is (above|outside) array bounds of 'int\\\[3]'" }
57   T ((*pia3)[12345]);         // { dg-warning "array subscript 12345 is (above|outside) array bounds of 'int\\\[3]'" }
58 }
59 
60 
test_a2_cst(_Bool (* pba0_1)[0][1],char (* pca1_2)[1][2],short (* psa2_3)[2][3],int (* pia3_4)[3][4])61 void test_a2_cst (_Bool (*pba0_1)[0][1], char (*pca1_2)[1][2],
62 		  short (*psa2_3)[2][3], int (*pia3_4)[3][4])
63 {
64   T ((*pba0_1)[-1][-1]);        // { dg-warning "array subscript -1 is (below|outside) array bounds of '_Bool\\\[1]'" }
65   T ((*pba0_1)[-1][0]);         // { dg-warning "array subscript -1 is (above|outside) array bounds of '_Bool\\\[0]\\\[1]'" }
66 
67   T ((*pba0_1)[0][-1]);         // { dg-warning "array subscript -1 is (below|outside) array bounds of '_Bool\\\[1]'" }
68   T ((*pba0_1)[0][0]);          // { dg-warning "array subscript 0 is (above|outside) array bounds of '_Bool\\\[0]\\\[1]'" }
69   T ((*pba0_1)[0][1]);          // { dg-warning "array subscript 1 is (above|outside) array bounds of '_Bool\\\[1]'" }
70   T ((*pba0_1)[0][2]);          // { dg-warning "array subscript 2 is (above|outside) array bounds of '_Bool\\\[1]'" }
71   T ((*pba0_1)[0][12]);         // { dg-warning "array subscript 12 is (above|outside) array bounds of '_Bool\\\[1]'" }
72 
73   T ((*pba0_1)[1][-1]);         // { dg-warning "array subscript -1 is (below|outside) array bounds of '_Bool\\\[1]'" }
74   T ((*pba0_1)[1][0]);          // { dg-warning "array subscript 1 is (above|outside) array bounds of '_Bool\\\[0]\\\[1]'" }
75   T ((*pba0_1)[1][1]);          // { dg-warning "array subscript 1 is (above|outside) array bounds of '_Bool\\\[1]'" }
76   T ((*pba0_1)[1][2]);          // { dg-warning "array subscript 2 is (above|outside) array bounds of '_Bool\\\[1]'" }
77   T ((*pba0_1)[1][12]);         // { dg-warning "array subscript 12 is (above|outside) array bounds of '_Bool\\\[1]'" }
78 
79 
80   T ((*pca1_2)[0][0]);
81   T ((*pca1_2)[0][1]);
82   T ((*pca1_2)[0][2]);          // { dg-warning "array subscript 2 is (above|outside) array bounds of 'char\\\[2]'" }
83 
84   T ((*pca1_2)[1][0]);          // { dg-warning "array subscript 1 is (above|outside) array bounds of 'char\\\[1]\\\[2]'" }
85   T ((*pca1_2)[1][1]);          // { dg-warning "array subscript 1 is (above|outside) array bounds of 'char\\\[1]\\\[2]'" }
86   T ((*pca1_2)[1][2]);          // { dg-warning "array subscript 2 is (above|outside) array bounds of 'char\\\[2]'" }
87 
88 
89   T ((*psa2_3)[0][0]);
90   T ((*psa2_3)[0][1]);
91   T ((*psa2_3)[0][2]);
92   T ((*psa2_3)[0][3]);          // { dg-warning "array subscript 3 is (above|outside) array bounds of 'short int\\\[3]'" }
93 
94   T ((*psa2_3)[1][0]);
95   T ((*psa2_3)[1][1]);
96   T ((*psa2_3)[1][2]);
97   T ((*psa2_3)[1][3]);          // { dg-warning "array subscript 3 is (above|outside) array bounds of 'short int\\\[3]'" }
98 
99   T ((*psa2_3)[2][0]);          // { dg-warning "array subscript 2 is (above|outside) array bounds of 'short int\\\[2]\\\[3]'" }
100   T ((*psa2_3)[2][1]);          // { dg-warning "array subscript 2 is (above|outside) array bounds of 'short int\\\[2]\\\[3]'" }
101   T ((*psa2_3)[2][2]);          // { dg-warning "array subscript 2 is (above|outside) array bounds of 'short int\\\[2]\\\[3]'" }
102   T ((*psa2_3)[2][3]);          // { dg-warning "array subscript 3 is (above|outside) array bounds of 'short int\\\[3]'" }
103 
104 
105   T ((*pia3_4)[0][0]);
106   T ((*pia3_4)[0][1]);
107   T ((*pia3_4)[0][2]);
108   T ((*pia3_4)[0][3]);
109   T ((*pia3_4)[0][4]);          // { dg-warning "array subscript 4 is (above|outside) array bounds of 'int\\\[4]'" }
110 
111   T ((*pia3_4)[1][0]);
112   T ((*pia3_4)[1][1]);
113   T ((*pia3_4)[1][2]);
114   T ((*pia3_4)[1][3]);
115   T ((*pia3_4)[1][4]);          // { dg-warning "array subscript 4 is (above|outside) array bounds of 'int\\\[4]'" }
116 
117   T ((*pia3_4)[2][0]);
118   T ((*pia3_4)[2][1]);
119   T ((*pia3_4)[2][2]);
120   T ((*pia3_4)[2][3]);
121   T ((*pia3_4)[2][4]);          // { dg-warning "array subscript 4 is (above|outside) array bounds of 'int\\\[4]'" }
122 
123   T ((*pia3_4)[3][0]);          // { dg-warning "array subscript 3 is (above|outside) array bounds of 'int\\\[3]\\\[4]'" }
124   T ((*pia3_4)[3][1]);          // { dg-warning "array subscript 3 is (above|outside) array bounds of 'int\\\[3]\\\[4]'" }
125   T ((*pia3_4)[3][2]);          // { dg-warning "array subscript 3 is (above|outside) array bounds of 'int\\\[3]\\\[4]'" }
126   T ((*pia3_4)[3][3]);          // { dg-warning "array subscript 3 is (above|outside) array bounds of 'int\\\[3]\\\[4]'" }
127   T ((*pia3_4)[3][4]);          // { dg-warning "array subscript 4 is (above|outside) array bounds of 'int\\\[4]'" }
128 }
129 
130 
131 typedef int IA4[4];
132 typedef IA4 IA3_4[3];
133 
test_a2_var(IA3_4 * pia3_4)134 void test_a2_var (IA3_4 *pia3_4)
135 {
136   {
137     IA4 *pia4 = &(*pia3_4)[0];
138 
139     T ((*pia4)[-1]);            // { dg-warning "array subscript -1 is (below|outside) array bounds of 'IA4'" }
140     T ((*pia4)[0]);
141     T ((*pia4)[1]);
142     T ((*pia4)[2]);
143     T ((*pia4)[3]);
144     T ((*pia4)[4]);             // { dg-warning "array subscript 4 is (above|outside) array bounds of 'IA4'" }
145   }
146 
147   {
148     IA4 *pia4 = &(*pia3_4)[1];
149 
150     T ((*pia4)[-1]);            // { dg-warning "array subscript -1 is (below|outside) array bounds of 'IA4'" }
151     T ((*pia4)[0]);
152     T ((*pia4)[1]);
153     T ((*pia4)[2]);
154     T ((*pia4)[3]);
155     T ((*pia4)[4]);             // { dg-warning "array subscript 4 is (above|outside) array bounds of 'IA4'" }
156   }
157 
158   {
159     IA4 *pia4 = &(*pia3_4)[2];
160 
161     T ((*pia4)[-1]);            // { dg-warning "array subscript -1 is (below|outside) array bounds of 'IA4'" }
162     T ((*pia4)[0]);
163     T ((*pia4)[1]);
164     T ((*pia4)[2]);
165     T ((*pia4)[3]);
166     T ((*pia4)[4]);             // { dg-warning "array subscript 4 is (above|outside) array bounds of 'IA4'" }
167   }
168 
169   {
170     IA4 *pia4 = &(*pia3_4)[3];
171 
172     T ((*pia4)[-1]);            // { dg-warning "\\\[-Warray-bounds" }
173     /* The following aren't diagnosed unless N itself is out of bounds
174        because thanks to the MEM_REF they're indistinguishable from
175        possibly valid accesses:
176          MEM[(int[4] *)pia3_4_2(D) + 48B][N];  */
177     T ((*pia4)[0]);             // { dg-warning "\\\[-Warray-bounds" "pr?????" { xfail *-*-* } }
178     T ((*pia4)[1]);             // { dg-warning "\\\[-Warray-bounds" "pr?????" { xfail *-*-* } }
179     T ((*pia4)[2]);             // { dg-warning "\\\[-Warray-bounds" "pr?????" { xfail *-*-* } }
180     T ((*pia4)[3]);             // { dg-warning "\\\[-Warray-bounds" "pr?????" { xfail *-*-* } }
181     T ((*pia4)[4]);             // { dg-warning "\\\[-Warray-bounds" }
182   }
183 }
184 
185 
186 struct S { IA3_4 *pia3_4; };
187 typedef struct S S5[5];
188 typedef S5 S5_7[7];
189 
test_s5_7(S5_7 * ps5_7)190 void test_s5_7 (S5_7 *ps5_7)
191 {
192   {
193     S5 *ps5 = &(*ps5_7)[0];
194     T ((*ps5)[0]);
195     T ((*(*ps5)[0].pia3_4)[0][0]);
196     T ((*(*ps5)[0].pia3_4)[2][3]);
197     T ((*(*ps5)[0].pia3_4)[2][4]);    // { dg-warning "array subscript 4 is above array bounds of 'IA4'" }
198 
199     T ((*(*ps5)[1].pia3_4)[2][3]);
200     T ((*(*ps5)[5].pia3_4)[2][3]);    // { dg-warning "array subscript 5 is above array bounds of 'S5'" }
201   }
202 }
203