1 /* PR tree-optimization/86622 - incorrect strlen of array of array plus
2    variable offset
3    Exercise strlen() with a multi-dimensional array of strings with
4    offsets.  */
5 
6 extern int printf (const char*, ...);
7 extern __SIZE_TYPE__ strlen (const char*);
8 
9 typedef char A28[28];
10 typedef A28 A3_28[3];
11 typedef A3_28 A2_3_28[2];
12 
13 static const A2_3_28 a = {
14   /* [0][0]    [0][1]         [0][2] */
15   { "1\00012", "123\0001234", "12345\000123456" },
16   /* [1][0]    [1][1]         [1][2] */
17   { "1234567\00012345678", "123456789\0001234567890", "12345678901\000123456789012" }
18 };
19 
20 volatile int v0 = 0;
21 volatile int v1 = 1;
22 volatile int v2 = 2;
23 volatile int v3 = 3;
24 volatile int v4 = 4;
25 volatile int v5 = 5;
26 volatile int v6 = 6;
27 volatile int v7 = 7;
28 
29 #define A(expr, N)							\
30   ((strlen (expr) == N)							\
31    ? (void)0 : (printf ("line %i: strlen (%s = \"%s\") != %i\n",	\
32 			__LINE__, #expr, expr, N),			\
33 		__builtin_abort ()))
34 
35 /* Verify that strlen() involving pointer to array arguments computes
36    the correct result.  */
37 
test_array_ptr(void)38 void test_array_ptr (void)
39 {
40   /* Compute the length of the string at the refeenced array.  */
41   A (*(&a[0][0] + 0), 1);
42   A (*(&a[0][0] + 1), 3);
43   A (*(&a[0][0] + 2), 5);
44 
45   A (*(&a[0][1] - 1), 1);
46   A (*(&a[0][1] + 0), 3);
47   A (*(&a[0][1] + 1), 5);
48 
49   A (*(&a[0][2] - 2), 1);
50   A (*(&a[0][2] - 1), 3);
51   A (*(&a[0][2] + 0), 5);
52 
53   A (*(&a[1][0] + 0), 7);
54   A (*(&a[1][0] + 1), 9);
55   A (*(&a[1][0] + 2), 11);
56 
57   A (*(&a[1][1] - 1), 7);
58   A (*(&a[1][1] + 0), 9);
59   A (*(&a[1][1] + 1), 11);
60 
61   A (*(&a[1][2] - 2), 7);
62   A (*(&a[1][2] - 1), 9);
63   A (*(&a[1][2] - 0), 11);
64 
65   /* Compute the length of the string past the first nul.  */
66   A (*(&a[0][0] + 0) + 2, 2);
67   A (*(&a[0][0] + 1) + 4, 4);
68   A (*(&a[0][0] + 2) + 6, 6);
69 
70   /* Compute the length of the string past the second nul.  */
71   A (*(&a[0][0] + 0) + 5, 0);
72   A (*(&a[0][0] + 1) + 10, 0);
73   A (*(&a[0][0] + 2) + 14, 0);
74 
75   int i0 = 0;
76   int i1 = i0 + 1;
77   int i2 = i1 + 1;
78   int i3 = i2 + 1;
79   int i4 = i3 + 1;
80   int i5 = i4 + 1;
81 
82   A (*(&a[0][0] + i0), 1);
83   A (*(&a[0][0] + i1), 3);
84   A (*(&a[0][0] + i2), 5);
85 
86   A (*(&a[0][1] - i1), 1);
87   A (*(&a[0][1] + i0), 3);
88   A (*(&a[0][1] + i1), 5);
89 
90   A (*(&a[0][2] - i2), 1);
91   A (*(&a[0][2] - i1), 3);
92   A (*(&a[0][2] + i0), 5);
93 
94   A (*(&a[1][0] + i0), 7);
95   A (*(&a[1][0] + i1), 9);
96   A (*(&a[1][0] + i2), 11);
97 
98   A (*(&a[1][1] - i1), 7);
99   A (*(&a[1][1] + i0), 9);
100   A (*(&a[1][1] + i1), 11);
101 
102   A (*(&a[1][2] - i2), 7);
103   A (*(&a[1][2] - i1), 9);
104   A (*(&a[1][2] - i0), 11);
105 
106 
107   A (*(&a[i0][i0] + i0), 1);
108   A (*(&a[i0][i0] + i1), 3);
109   A (*(&a[i0][i0] + i2), 5);
110 
111   A (*(&a[i0][i1] - i1), 1);
112   A (*(&a[i0][i1] + i0), 3);
113   A (*(&a[i0][i1] + i1), 5);
114 
115   A (*(&a[i0][i2] - i2), 1);
116   A (*(&a[i0][i2] - i1), 3);
117   A (*(&a[i0][i2] + i0), 5);
118 
119   A (*(&a[i1][i0] + i0), 7);
120   A (*(&a[i1][i0] + i1), 9);
121   A (*(&a[i1][i0] + i2), 11);
122 
123   A (*(&a[i1][i1] - i1), 7);
124   A (*(&a[i1][i1] + i0), 9);
125   A (*(&a[i1][i1] + i1), 11);
126 
127   A (*(&a[i1][i2] - i2), 7);
128   A (*(&a[i1][i2] - i1), 9);
129   A (*(&a[i1][i2] - i0), 11);
130 
131 
132   A (*(&a[i0][i0] + v0), 1);
133   A (*(&a[i0][i0] + v1), 3);
134   A (*(&a[i0][i0] + v2), 5);
135 
136   A (*(&a[i0][i1] - v1), 1);
137   A (*(&a[i0][i1] + v0), 3);
138   A (*(&a[i0][i1] + v1), 5);
139 
140   A (*(&a[i0][i2] - v2), 1);
141   A (*(&a[i0][i2] - v1), 3);
142   A (*(&a[i0][i2] + v0), 5);
143 
144   A (*(&a[i1][i0] + v0), 7);
145   A (*(&a[i1][i0] + v1), 9);
146   A (*(&a[i1][i0] + v2), 11);
147 
148   A (*(&a[i1][i1] - v1), 7);
149   A (*(&a[i1][i1] + v0), 9);
150   A (*(&a[i1][i1] + v1), 11);
151 
152   A (*(&a[i1][i2] - v2), 7);
153   A (*(&a[i1][i2] - v1), 9);
154   A (*(&a[i1][i2] - v0), 11);
155 
156 
157   A (*(&a[i0][i0] + v0) + i1, 0);
158   A (*(&a[i0][i0] + v1) + i2, 1);
159   A (*(&a[i0][i0] + v2) + i3, 2);
160 
161   A (*(&a[i0][i1] - v1) + v1, 0);
162   A (*(&a[i0][i1] + v0) + v3, 0);
163   A (*(&a[i0][i1] + v1) + v5, 0);
164 
165   A (*(&a[i0][v1] - i1) + i1, 0);
166   A (*(&a[i0][v1] + i0) + i3, 0);
167   A (*(&a[i0][v1] + i1) + i5, 0);
168 }
169 
170 static const A3_28* const pa0 = &a[0];
171 static const A3_28* const pa1 = &a[1];
172 
173 static const A3_28* const paa[] = { &a[0], &a[1] };
174 
175 /* Verify that strlen() involving pointers and arrays of pointers
176    to array arguments computes the correct result.  */
177 
test_ptr_array(void)178 void test_ptr_array (void)
179 {
180   int i0 = 0;
181   int i1 = i0 + 1;
182   int i2 = i1 + 1;
183   int i3 = i2 + 1;
184 
185   A (*((*pa0) + i0), 1);
186   A (*((*pa0) + i1), 3);
187   A (*((*pa0) + i2), 5);
188 
189   A (*(pa0[0] + i0), 1);
190   A (*(pa0[0] + i1), 3);
191   A (*(pa0[0] + i2), 5);
192 
193   A ((*pa0)[i0] + i1, 0);
194   A ((*pa0)[i1] + i2, 1);
195   A ((*pa0)[i2] + i3, 2);
196 
197 
198   A (*((*pa1) + i0), 7);
199   A (*((*pa1) + i1), 9);
200   A (*((*pa1) + i2), 11);
201 
202   A (*(pa1[0] + i0), 7);
203   A (*(pa1[0] + i1), 9);
204   A (*(pa1[0] + i2), 11);
205 
206   A ((*pa1)[i0] + i1, 6);
207   A ((*pa1)[i1] + i2, 7);
208   A ((*pa1)[i2] + i3, 8);
209 
210   A (*(*(paa[0]) + i0), 1);
211   A (*(*(paa[0]) + i1), 3);
212   A (*(*(paa[0]) + i2), 5);
213 
214   A (*(*(paa[1]) + i0), 7);
215   A (*(*(paa[1]) + i1), 9);
216   A (*(*(paa[1]) + i2), 11);
217 
218   A (*(*(paa[1]) - i1), 5);
219   A (*(*(paa[1]) - i2), 3);
220   A (*(*(paa[1]) - i3), 1);
221 
222   A (*(*(paa[0]) + i0) + i1, 0);
223   A (*(*(paa[0]) + i1) + i2, 1);
224   A (*(*(paa[0]) + i2) + i3, 2);
225 }
226 
main(void)227 int main (void)
228 {
229   test_array_ptr ();
230 
231   test_ptr_array ();
232 }
233