1 /* PR tree-optimization/84047 - missing -Warray-bounds on an out-of-bounds
2    index into an array
3    { dg-do compile }
4    { dg-options "-O2 -Warray-bounds=2 -ftrack-macro-expansion=0" }
5    { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
6 
7 #include "range.h"
8 
9 #define MAX DIFF_MAX
10 #define MIN DIFF_MIN
11 
12 void sink (int, ...);
13 
14 #define T(...)   sink (0, __VA_ARGS__)
15 
test_global_char_array(void)16 void test_global_char_array (void)
17 {
18   extern char gcar1[1];
19   char *p = gcar1;
20 
21   T (p[MIN]);       /* { dg-warning "subscript -\[0-9\]+ is outside array bounds of .char\\\[1]." } */
22   T (p[-1]);        /* { dg-warning "subscript -1 is outside array bounds of .char\\\[1]." } */
23   T (p[0]);
24   T (p[1]);         /* { dg-warning "subscript 1 is outside array bounds of .char\\\[1]." } */
25   T (p[MAX]);       /* { dg-warning "subscript \[0-9\]+ is outside array bounds of .char\\\[1]." } */
26 
27   T (&p[MIN]);      /* { dg-warning "subscript -\[0-9\]+ is \(below|outside\) array bounds of .char\\\[1]." } */
28   T (&p[-1]);       /* { dg-warning "subscript -1 is \(below|outside\) array bounds of .char\\\[1]." } */
29   T (&p[0]);
30   T (&p[1]);
31   T (&p[2]);        /* { dg-warning "subscript 2 is \(above|outside\) array bounds of .char\\\[1]." } */
32   T (&p[MAX]);      /* { dg-warning "subscript \[0-9\]+ is \(above|outside\) array bounds of .char\\\[1]." } */
33 
34   extern char gcar3[3];
35   char *q = gcar3;
36 
37   T (q[MIN]);       /* { dg-warning "subscript -\[0-9\]+ is outside array bounds of .char\\\[3]." } */
38   T (q[-1]);        /* { dg-warning "subscript -1 is outside array bounds of .char\\\[3]." } */
39   T (q[0]);
40   T (q[1]);
41   T (q[2]);
42   T (q[3]);         /* { dg-warning "subscript 3 is outside array bounds of .char\\\[3]." } */
43   T (q[MAX]);       /* { dg-warning "subscript \[0-9\]+ is outside array bounds of .char\\\[3]." } */
44 
45   T (&q[MIN]);      /* { dg-warning "subscript -\[0-9\]+ is \(below|outside\) array bounds of .char\\\[3]." } */
46   T (&q[-1]);       /* { dg-warning "subscript -1 is \(below|outside\) array bounds of .char\\\[3]." } */
47   T (&q[0]);
48   T (&q[1]);
49   T (&q[2]);
50   T (&q[3]);
51   T (&q[4]);        /* { dg-warning "subscript 4 is \(above|outside\) array bounds of .char\\\[3]." } */
52   T (&q[MAX]);      /* { dg-warning "subscript \[0-9\]+ is \(above|outside\) array bounds of .char\\\[3]." } */
53 }
54 
55 
test_global_int_array(void)56 void test_global_int_array (void)
57 {
58   /* Use smaller values to prevent false negatives due to undetected
59      integer overflow/wrapping.  */
60   ptrdiff_t min = MIN / sizeof (int);
61   ptrdiff_t max = MAX / sizeof (int);
62 
63   extern int giar1[1];
64   extern int giar3[3];
65 
66   int *p = giar1;
67 
68   T (p[min]);       /* { dg-warning "subscript -\[0-9\]+ is outside array bounds of .int\\\[1]." } */
69   T (p[-1]);        /* { dg-warning "subscript -1 is outside array bounds of .int\\\[1]." } */
70   T (p[0]);
71   T (p[1]);         /* { dg-warning "subscript 1 is outside array bounds of .int\\\[1]." } */
72   T (p[max]);       /* { dg-warning "subscript \[0-9\]+ is outside array bounds of .int\\\[1]." } */
73 
74   T (&p[min]);      /* { dg-warning "subscript -\[0-9\]+ is \(below|outside\) array bounds of .int\\\[1]." } */
75   T (&p[-1]);       /* { dg-warning "subscript -1 is \(below|outside\) array bounds of .int\\\[1]." } */
76   T (&p[0]);
77   T (&p[1]);
78   T (&p[2]);        /* { dg-warning "subscript 2 is \(above|outside\) array bounds of .int\\\[1]." } */
79   T (&p[max]);      /* { dg-warning "subscript \[0-9\]+ is \(above|outside\) array bounds of .int\\\[1]." } */
80 
81   int *q = giar3;
82 
83   T (q[min]);       /* { dg-warning "subscript -\[0-9\]+ is outside array bounds of .int\\\[3]." } */
84   T (q[-1]);        /* { dg-warning "subscript -1 is outside array bounds of .int\\\[3]." } */
85   T (q[0]);
86   T (q[1]);
87   T (q[2]);
88   T (q[3]);         /* { dg-warning "subscript 3 is outside array bounds of .int\\\[3]." } */
89   T (q[max]);       /* { dg-warning "subscript \[0-9\]+ is outside array bounds of .int\\\[3]." } */
90 
91   T (&q[min]);      /* { dg-warning "subscript -\[0-9\]+ is \(below|outside\) array bounds of .int\\\[3]." } */
92   T (&q[-1]);       /* { dg-warning "subscript -1 is \(below|outside\) array bounds of .int\\\[3]." } */
93   T (&q[0]);
94   T (&q[1]);
95   T (&q[2]);
96   T (&q[3]);
97   T (&q[4]);        /* { dg-warning "subscript 4 is \(above|outside\) array bounds of .int\\\[3]." } */
98   T (&q[max]);      /* { dg-warning "subscript \[0-9\]+ is \(above|outside\) array bounds of .int\\\[3]." } */
99 }
100 
101 
test_global_short_2dim_array(void)102 void test_global_short_2dim_array (void)
103 {
104   extern short giar3_5[3][5];
105 
106   short *p = giar3_5[0];
107 
108   /* The access below isn't diagnosed because the reference is transformed
109      into MEM_REF (short*, &giar3_5, 0), i.e., *giar3_5[0][0].  */
110   T (p[MIN]);       /* { dg-warning "subscript -\[0-9\]+ is outside array bounds of .short int\\\[3]" "bug" { xfail *-*-*} } */
111   T (p[-1]);        /* { dg-warning "subscript -1 is outside array bounds of .short int\\\[3]" } */
112   T (p[0]);
113   T (p[1]);
114   T (p[2]);
115   T (p[15]);        /* { dg-warning "subscript 15 is outside array bounds of .short int\\\[3]" } */
116   T (p[MAX]);       /* { dg-warning "subscript -?\[0-9\]+ is outside array bounds of .short int\\\[3]" } */
117 
118   T (&p[MIN]);      /* { dg-warning "subscript -\[0-9\]+ is \(below|outside\) array bounds of .short int\\\[3]" "bug" { xfail *-*-* } } */
119   T (&p[-1]);       /* { dg-warning "subscript -1 is \(below|outside\) array bounds of .short int\\\[3]" } */
120   T (&p[0]);
121   T (&p[1]);
122   T (&p[2]);
123   T (&p[3]);
124   T (&p[16]);       /* { dg-warning "subscript 16 is \(above|outside\) array bounds of .short int\\\[3]" } */
125   T (&p[MAX]);      /* { dg-warning "subscript -?\[0-9\]+ is \(above|outside\) array bounds of .short int\\\[3]" } */
126 }
127 
128 
test_local_char_array(void)129 void test_local_char_array (void)
130 {
131   char ar1[1] = { 1 };
132   char *p = ar1;
133 
134   T (p[MIN]);      /* { dg-warning "subscript -\[0-9\]+ is outside array bounds of .char\\\[1]." } */
135   T (p[-1]);       /* { dg-warning "subscript -1 is outside array bounds of .char\\\[1]." } */
136   T (p[0]);
137   T (p[1]);         /* { dg-warning "subscript 1 is outside array bounds of .char\\\[1]." } */
138   T (p[MAX]);       /* { dg-warning "subscript \[0-9\]+ is outside array bounds of .char\\\[1]." } */
139 
140   T (&p[MIN]);     /* { dg-warning "subscript -\[0-9\]+ is \(below|outside\) array bounds of .char\\\[1]." } */
141   T (&p[-1]);      /* { dg-warning "subscript -1 is \(below|outside\) array bounds of .char\\\[1]." } */
142   T (&p[0]);
143   T (&p[1]);
144   T (&p[2]);        /* { dg-warning "subscript 2 is \(above|outside\) array bounds of .char\\\[1]." } */
145   T (&p[MAX]);      /* { dg-warning "subscript \[0-9\]+ is \(above|outside\) array bounds of .char\\\[1]." } */
146 
147   char ar3[3] = { 1, 2, 3 };
148   p = ar3;
149 
150   T (p[MIN]);       /* { dg-warning "subscript -\[0-9\]+ is outside array bounds of .char\\\[3]." } */
151   T (p[-1]);        /* { dg-warning "subscript -1 is outside array bounds of .char\\\[3]." } */
152   T (p[0]);
153   T (p[1]);
154   T (p[2]);
155   T (p[3]);         /* { dg-warning "subscript 3 is outside array bounds of .char\\\[3]." } */
156   T (p[MAX]);       /* { dg-warning "subscript \[0-9\]+ is outside array bounds of .char\\\[3]." } */
157 
158   T (&p[MIN]);      /* { dg-warning "subscript -\[0-9\]+ is \(below|outside\) array bounds of .char\\\[3]." } */
159   T (&p[-1]);       /* { dg-warning "subscript -1 is \(below|outside\) array bounds of .char\\\[3]." } */
160   T (&p[0]);
161   T (&p[1]);
162   T (&p[2]);
163   T (&p[3]);
164   T (&p[4]);        /* { dg-warning "subscript 4 is \(above|outside\) array bounds of .char\\\[3]." } */
165   T (&p[MAX]);      /* { dg-warning "subscript \[0-9\]+ is \(above|outside\) array bounds of .char\\\[3]." } */
166 }
167 
168 struct S
169 {
170   int a[2], b[3];
171 } s [4];
172 
test_struct_array_cst(void)173 void test_struct_array_cst (void)
174 {
175   T (s[0].a[0] + s[0].a[1] + s[0].b[0] + s[0].b[1] + s[0].b[2] + s[0].b[2]
176      + s[1].a[0] + s[1].a[1] + s[1].b[0] + s[1].b[1] + s[1].b[2] + s[1].b[2]
177      + s[2].a[0] + s[2].a[1] + s[2].b[0] + s[2].b[1] + s[2].b[2] + s[2].b[2]
178      + s[3].a[0] + s[3].a[1] + s[3].b[0] + s[3].b[1] + s[3].b[2] + s[3].b[2]);
179 
180   T (&s[0].a[2],
181      &s[0].b[3],
182      &s[1].a[2],
183      &s[1].b[3],
184      &s[2].a[2],
185      &s[2].b[3],
186      &s[3].a[2],
187      &s[3].b[3]);
188 
189   T (s[0].a[2]);    /* { dg-warning "subscript 2 is above array bounds of .int\\\[2\\\]." } */
190   T (s[0].b[3]);    /* { dg-warning "subscript 3 is above array bounds of .int\\\[3\\\]." } */
191   T (s[1].a[2]);    /* { dg-warning "subscript 2 is above array bounds of .int\\\[2\\\]." } */
192   T (s[1].b[3]);    /* { dg-warning "subscript 3 is above array bounds of .int\\\[3\\\]." } */
193   T (s[2].a[2]);    /* { dg-warning "subscript 2 is above array bounds of .int\\\[2\\\]." } */
194   T (s[2].b[3]);    /* { dg-warning "subscript 3 is above array bounds of .int\\\[3\\\]." } */
195   T (s[3].a[2]);    /* { dg-warning "subscript 2 is above array bounds of .int\\\[2\\\]." } */
196   T (s[3].b[3]);    /* { dg-warning "subscript 3 is above array bounds of .int\\\[3\\\]." } */
197 
198   T (s[4].a[0]);    /* { dg-warning "subscript 4 is above array bounds of .struct S\\\[4\\\]." } */
199   T (s[4].a[2]);    /* { dg-warning "subscript 4 is above array bounds of .struct S\\\[4\\\]." } */
200                     /* { dg-warning "subscript 2 is above array bounds of .int\\\[2\\\]." "" { target *-*-* } .-1 } */
201 }
202