795ab4a3f916cd9e4166d1e78b7ce746eda044fc
[deliverable/binutils-gdb.git] / gdb / testsuite / gdb.base / infcall-nested-structs.c
1 /* This testcase is part of GDB, the GNU debugger.
2
3 Copyright 2018-2019 Free Software Foundation, Inc.
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 3 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>. */
17
18 /* This file is used for testing GDBs ability to pass structures to, and
19 return structures from, functions. All of the structures in this test
20 are special in that they are small structures containing from 1 up to 5
21 scalar fields, the fields can be inside nested structures, and there can
22 be empty structures around too.
23
24 When compiled for C++ this file also tests structures containing static
25 members (which live in global memory). In addition, empty structures in C++
26 have a size of 1 (compared to 0 in GNU C), which can effect structure
27 padding.
28
29 This test is specifically written for RiscV and Aarch64, which both have
30 special ABI rules for structures like these, however, there should be no harm
31 in running these tests on other targets, though in many cases the
32 structures will treated no differently to the structures already covered
33 in the structs.exp test script. */
34
35 #include <string.h>
36
37 /* Useful abreviations. */
38 typedef char tc;
39 typedef short ts;
40 typedef int ti;
41 typedef long tl;
42 typedef long long tll;
43 typedef float tf;
44 typedef double td;
45 typedef long double tld;
46
47 #ifdef TEST_COMPLEX
48 typedef float _Complex tfc;
49 typedef double _Complex tdc;
50 typedef long double _Complex tldc;
51 #endif /* TEST_COMPLEX */
52
53 #define MAKE_CHECK_FUNCS(TYPE) \
54 int \
55 check_arg_ ## TYPE (struct TYPE arg) \
56 { \
57 return cmp_ ## TYPE (arg, ref_val_ ## TYPE); \
58 } \
59 \
60 struct TYPE \
61 rtn_str_ ## TYPE (void) \
62 { \
63 return (ref_val_ ## TYPE); \
64 }
65
66 #define REF_VAL(NAME) struct NAME ref_val_ ## NAME
67 #define ES(NAME) struct { } NAME
68
69 /* Test is either for a single type or two differing types. */
70 #if defined tA && ! defined tB
71 #define tB tA
72 #endif
73 #if ! defined tB
74 #error "Incorrect configuration of tA and tB defines"
75 #endif
76
77 /* Structures with a single field nested to various depths, along with
78 some empty structures. */
79 struct struct_01_01 { ES(es1); struct { struct { tA a; } s1; } s2; };
80 struct struct_01_02 { tA a; struct { struct { ES(es1); } s1; } s2; };
81 struct struct_01_03 { struct { struct { ES(es1); } s1; } s2; ES(es1); struct { struct { tA a; } s3; } s4;};
82 struct struct_01_04 { ES(es1); ES(es2); tA a; ES(es3); };
83
84 /* Structures with two fields nested to various depths, along with
85 some empty structures. */
86 struct struct_02_01 { ES(es1); struct { struct { tA a; tB b; } s1; } s2; };
87 struct struct_02_02 { tA a; struct { struct { ES(es1); } s1; } s2; tB b; };
88 struct struct_02_03 { struct { struct { ES(es1); } s1; } s2; ES(es1); struct { struct { tA a; } s3; } s4; struct { struct { tB b; } s5; } s6;};
89 struct struct_02_04 { ES(es1); ES(es2); tA a; ES(es3); tB b; };
90
91 /* Structures with four fields nested to various depths, along with
92 some empty structures. */
93 struct struct_04_01 { ES(es1); struct { struct { tA a; tB b; tA c; tB d; } s1; } s2; };
94 struct struct_04_02 { tA a; struct { struct { ES(es1); } s1; } s2; tB b; struct { struct { ES(es1); } s2; } s3; tA c; struct { struct { ES(es2); } s4; } s5; tB d;};
95 struct struct_04_03 { struct { struct { ES(es1); } s1; } s2; ES(es1); struct { struct { tA a; } s3; } s4; struct { struct { tB b; } s5; } s6; struct { struct { tA c; } s7; } s8; struct { struct { tB d; } s9; } s10;};
96 struct struct_04_04 { ES(es1); ES(es2); tA a; ES(es3); tB b; ES(es4); tA c; ES(es5); tB d; };
97
98 /* Structures with five fields nested to various depths, along with
99 some empty structures. */
100 struct struct_05_01 { ES(es1); struct { struct { tA a; tB b; tA c; tB d; tA e; } s1; } s2; };
101 struct struct_05_02 { tA a; struct { struct { ES(es1); } s1; } s2; tB b; struct { struct { ES(es1); } s2; } s3; tA c; struct { struct { ES(es2); } s4; } s5; tB d; struct { struct { ES(es2); } s6; } s7; tB e;};
102 struct struct_05_03 { struct { struct { ES(es1); } s1; } s2; ES(es1); struct { struct { tA a; } s3; } s4; struct { struct { tB b; } s5; } s6; struct { struct { tA c; } s7; } s8; struct { struct { tB d; } s9; } s10; struct { struct { tA e; } s11; } s12;};
103 struct struct_05_04 { ES(es1); ES(es2); tA a; ES(es3); tB b; ES(es4); tA c; ES(es5); tB d; ES(es6); tA e; };
104
105 /* Only C++ allows structures to have static members. */
106 #ifdef __cplusplus
107
108 /* Structures with two fields nested to various depths, one of which is static.
109 Some include empty structures. */
110 struct struct_static_02_01 { struct sa { struct sb { tA a; static tB b; } s1; } s2; };
111 struct struct_static_02_02 { static tA a; struct { struct { ES(es1); } s1; } s2; tB b; };
112 struct struct_static_02_03 { struct { struct { ES(es1); } s1; } s2; ES(es1); struct { struct { tA a; } s3; } s4; struct sa { struct sb { static tB b; } s5; } s6;};
113 struct struct_static_02_04 { static tA a; tB b; };
114
115 /* Structures with four fields nested to various depths, some of which are
116 static. Some include empty structures. */
117 struct struct_static_04_01 { struct sa { struct sb { static tA a; tB b; tA c; tB d; } s1; } s2; };
118 struct struct_static_04_02 { tA a; struct { struct { ES(es1); } s1; } s2; tB b; struct { struct { ES(es1); } s2; } s3; static tA c; struct { struct { ES(es2); } s4; } s5; static tB d;};
119 struct struct_static_04_03 { struct sa { struct sb { static tA a; } s3; } s4; struct sc { struct sd { static tB b; } s5; } s6; struct se { struct sf { static tA c; } s7; } s8; struct sg { struct sh { static tB d; } s9; } s10;};
120 struct struct_static_04_04 { ES(es1); ES(es2); tA a; ES(es3); tB b; ES(es4); tA c; ES(es5); static tB d; };
121
122 /* Structures with six fields nested to various depths, some of which are
123 static. Some include empty structures. */
124 struct struct_static_06_01 { struct sa { struct sb { tA a; static tB b; tA c; tB d; tA e; } s1; } s2; tB f; };
125 struct struct_static_06_02 { tA a; static tB b; static tA c; tB d; tB e; tA f;};
126 struct struct_static_06_03 { struct { struct { ES(es1); } s1; } s2; ES(es1); struct sa { struct sb { static tA a; } s3; } s4; struct sc { struct sd { tB b; } s5; } s6; struct se { struct sf { static tA c; } s7; } s8; struct sg { struct sh { static tB d; } s9; } s10; struct { struct { tA e; tB f; } s11; } s12;};
127 struct struct_static_06_04 { ES(es1); ES(es2); static tA a; ES(es3); static tB b; ES(es4); static tA c; ES(es5); static tB d; ES(es6); static tA e; ES(es7); tB f; };
128
129 #endif
130
131 int cmp_struct_01_01 (struct struct_01_01 a, struct struct_01_01 b)
132 { return a.s2.s1.a == b.s2.s1.a; }
133
134 int cmp_struct_01_02 (struct struct_01_02 a, struct struct_01_02 b)
135 { return a.a == b.a; }
136
137 int cmp_struct_01_03 (struct struct_01_03 a, struct struct_01_03 b)
138 { return a.s4.s3.a == b.s4.s3.a; }
139
140 int cmp_struct_01_04 (struct struct_01_04 a, struct struct_01_04 b)
141 { return a.a == b.a; }
142
143 int cmp_struct_02_01 (struct struct_02_01 a, struct struct_02_01 b)
144 { return a.s2.s1.a == b.s2.s1.a && a.s2.s1.b == b.s2.s1.b; }
145
146 int cmp_struct_02_02 (struct struct_02_02 a, struct struct_02_02 b)
147 { return a.a == b.a && a.b == b.b; }
148
149 int cmp_struct_02_03 (struct struct_02_03 a, struct struct_02_03 b)
150 { return a.s4.s3.a == b.s4.s3.a && a.s6.s5.b == b.s6.s5.b; }
151
152 int cmp_struct_02_04 (struct struct_02_04 a, struct struct_02_04 b)
153 { return a.a == b.a && a.b == b.b; }
154
155 int cmp_struct_04_01 (struct struct_04_01 a, struct struct_04_01 b)
156 { return a.s2.s1.a == b.s2.s1.a && a.s2.s1.b == b.s2.s1.b
157 && a.s2.s1.c == b.s2.s1.c && a.s2.s1.d == b.s2.s1.d; }
158
159 int cmp_struct_04_02 (struct struct_04_02 a, struct struct_04_02 b)
160 { return a.a == b.a && a.b == b.b && a.c == b.c && a.d == b.d; }
161
162 int cmp_struct_04_03 (struct struct_04_03 a, struct struct_04_03 b)
163 { return a.s4.s3.a == b.s4.s3.a && a.s6.s5.b == b.s6.s5.b
164 && a.s8.s7.c == b.s8.s7.c && a.s10.s9.d == b.s10.s9.d; }
165
166 int cmp_struct_04_04 (struct struct_04_04 a, struct struct_04_04 b)
167 { return a.a == b.a && a.b == b.b && a.c == b.c && a.d == b.d; }
168
169 int cmp_struct_05_01 (struct struct_05_01 a, struct struct_05_01 b)
170 { return a.s2.s1.a == b.s2.s1.a && a.s2.s1.b == b.s2.s1.b
171 && a.s2.s1.c == b.s2.s1.c && a.s2.s1.d == b.s2.s1.d
172 && a.s2.s1.e == b.s2.s1.e; }
173
174 int cmp_struct_05_02 (struct struct_05_02 a, struct struct_05_02 b)
175 { return a.a == b.a && a.b == b.b && a.c == b.c && a.d == b.d && a.e == b.e; }
176
177 int cmp_struct_05_03 (struct struct_05_03 a, struct struct_05_03 b)
178 { return a.s4.s3.a == b.s4.s3.a && a.s6.s5.b == b.s6.s5.b
179 && a.s8.s7.c == b.s8.s7.c && a.s10.s9.d == b.s10.s9.d
180 && a.s12.s11.e == b.s12.s11.e; }
181
182 int cmp_struct_05_04 (struct struct_05_04 a, struct struct_05_04 b)
183 { return a.a == b.a && a.b == b.b && a.c == b.c && a.d == b.d && a.e == b.e; }
184
185 #ifdef __cplusplus
186
187 int
188 cmp_struct_static_02_01 (struct struct_static_02_01 a,
189 struct struct_static_02_01 b)
190 { return a.s2.s1.a == b.s2.s1.a && a.s2.s1.b == b.s2.s1.b; }
191
192 int
193 cmp_struct_static_02_02 (struct struct_static_02_02 a,
194 struct struct_static_02_02 b)
195 { return a.a == b.a && a.b == b.b; }
196
197 int
198 cmp_struct_static_02_03 (struct struct_static_02_03 a,
199 struct struct_static_02_03 b)
200 { return a.s4.s3.a == b.s4.s3.a && a.s6.s5.b == b.s6.s5.b; }
201
202 int
203 cmp_struct_static_02_04 (struct struct_static_02_04 a,
204 struct struct_static_02_04 b)
205 { return a.a == b.a && a.b == b.b; }
206
207 int
208 cmp_struct_static_04_01 (struct struct_static_04_01 a,
209 struct struct_static_04_01 b)
210 { return a.s2.s1.a == b.s2.s1.a && a.s2.s1.b == b.s2.s1.b
211 && a.s2.s1.c == b.s2.s1.c && a.s2.s1.d == b.s2.s1.d; }
212
213 int
214 cmp_struct_static_04_02 (struct struct_static_04_02 a,
215 struct struct_static_04_02 b)
216 { return a.a == b.a && a.b == b.b && a.c == b.c && a.d == b.d; }
217
218 int
219 cmp_struct_static_04_03 (struct struct_static_04_03 a,
220 struct struct_static_04_03 b)
221 { return a.s4.s3.a == b.s4.s3.a && a.s6.s5.b == b.s6.s5.b
222 && a.s8.s7.c == b.s8.s7.c && a.s10.s9.d == b.s10.s9.d; }
223
224 int
225 cmp_struct_static_04_04 (struct struct_static_04_04 a,
226 struct struct_static_04_04 b)
227 { return a.a == b.a && a.b == b.b && a.c == b.c && a.d == b.d; }
228
229 int
230 cmp_struct_static_06_01 (struct struct_static_06_01 a,
231 struct struct_static_06_01 b)
232 { return a.s2.s1.a == b.s2.s1.a && a.s2.s1.b == b.s2.s1.b
233 && a.s2.s1.c == b.s2.s1.c && a.s2.s1.d == b.s2.s1.d
234 && a.s2.s1.e == b.s2.s1.e && a.f == b.f; }
235
236 int
237 cmp_struct_static_06_02 (struct struct_static_06_02 a,
238 struct struct_static_06_02 b)
239 { return a.a == b.a && a.b == b.b && a.c == b.c && a.d == b.d && a.e == b.e
240 && a.f == b.f; }
241
242 int
243 cmp_struct_static_06_03 (struct struct_static_06_03 a,
244 struct struct_static_06_03 b)
245 { return a.s4.s3.a == b.s4.s3.a && a.s6.s5.b == b.s6.s5.b
246 && a.s8.s7.c == b.s8.s7.c && a.s10.s9.d == b.s10.s9.d
247 && a.s12.s11.e == b.s12.s11.e && a.s12.s11.f == b.s12.s11.f; }
248
249 int
250 cmp_struct_static_06_04 (struct struct_static_06_04 a,
251 struct struct_static_06_04 b)
252 { return a.a == b.a && a.b == b.b && a.c == b.c && a.d == b.d && a.e == b.e
253 && a.f == b.f; }
254
255 #endif
256
257 REF_VAL(struct_01_01) = { {}, { { 'a' } } };
258 REF_VAL(struct_01_02) = { 'a', { { {} } } };
259 REF_VAL(struct_01_03) = { { { {} } }, {}, { { 'a' } } };
260 REF_VAL(struct_01_04) = { {}, {}, 'a', {} };
261
262 REF_VAL(struct_02_01) = { {}, { { 'a', 'b' } } };
263 REF_VAL(struct_02_02) = { 'a', { { {} } }, 'b' };
264 REF_VAL(struct_02_03) = { { { {} } }, {}, { { 'a' } }, { { 'b' } } };
265 REF_VAL(struct_02_04) = { {}, {}, 'a', {}, 'b' };
266
267 REF_VAL(struct_04_01) = { {}, { { 'a', 'b', 'c', 'd' } } };
268 REF_VAL(struct_04_02) = { 'a', { { {} } }, 'b', { { {} } }, 'c', { { {} } }, 'd' };
269 REF_VAL(struct_04_03) = { { { {} } }, {}, { { 'a' } }, { { 'b' } }, { { 'c' } }, { { 'd' } } };
270 REF_VAL(struct_04_04) = { {}, {}, 'a', {}, 'b', {}, 'c', {}, 'd' };
271
272 REF_VAL(struct_05_01) = { {}, { { 'a', 'b', 'c', 'd', 'e' } } };
273 REF_VAL(struct_05_02) = { 'a', { { {} } }, 'b', { { {} } }, 'c', { { {} } }, 'd', { { {} } }, 'e' };
274 REF_VAL(struct_05_03) = { { { {} } }, {}, { { 'a' } }, { { 'b' } }, { { 'c' } }, { { 'd' } }, { { 'e' } } };
275 REF_VAL(struct_05_04) = { {}, {}, 'a', {}, 'b', {}, 'c', {}, 'd', {}, 'e' };
276
277 #ifdef __cplusplus
278
279 /* Initialise static members. */
280 tB struct_static_02_01::sa::sb::b = '1';
281 tA struct_static_02_02::a = '2';
282 tB struct_static_02_03::sa::sb::b = '3';
283 tA struct_static_02_04::a = '4';
284 tA struct_static_04_01::sa::sb::a = '5';
285 tA struct_static_04_02::c = '6';
286 tB struct_static_04_02::d = '7';
287 tA struct_static_04_03::sa::sb::a = '8';
288 tB struct_static_04_03::sc::sd::b = '9';
289 tA struct_static_04_03::se::sf::c = '0';
290 tB struct_static_04_03::sg::sh::d = 'A';
291 tB struct_static_04_04::d = 'B';
292 tB struct_static_06_01::sa::sb::b = 'C';
293 tB struct_static_06_02::b = 'D';
294 tA struct_static_06_02::c = 'E';
295 tA struct_static_06_03::sa::sb::a = 'F';
296 tA struct_static_06_03::se::sf::c = 'G';
297 tB struct_static_06_03::sg::sh::d = 'H';
298 tA struct_static_06_04::a = 'I';
299 tB struct_static_06_04::b = 'J';
300 tA struct_static_06_04::c = 'K';
301 tB struct_static_06_04::d = 'L';
302 tA struct_static_06_04::e = 'M';
303
304 REF_VAL(struct_static_02_01) = { { { 'a' } } };
305 REF_VAL(struct_static_02_02) = { { { {} } }, 'b' };
306 REF_VAL(struct_static_02_03) = { { { {} } }, {}, { { 'a' } }, { { } } };
307 REF_VAL(struct_static_02_04) = { 'b' };
308 REF_VAL(struct_static_04_01) = { { { 'b', 'c', 'd' } } };
309 REF_VAL(struct_static_04_02) = { 'a', { { {} } }, 'b', { { {} } }, { { {} } } };
310 REF_VAL(struct_static_04_03) = {};
311 REF_VAL(struct_static_04_04) = { {}, {}, 'a', {}, 'b', {}, 'c', {} };
312 REF_VAL(struct_static_06_01) = { { { 'a', 'c', 'd', 'e' } }, 'f' };
313 REF_VAL(struct_static_06_02) = { 'a', 'd', 'e', 'f' };
314 REF_VAL(struct_static_06_03) = { { { {} } }, {}, {}, { { 'b' } }, {}, /*{ { 'e', 'f' } }*/ };
315 REF_VAL(struct_static_06_04) = { {}, {}, {}, {}, {}, {}, {}, 'f' };
316
317 #endif
318
319 /* Create all of the functions GDB will call to check functionality. */
320 MAKE_CHECK_FUNCS(struct_01_01)
321 MAKE_CHECK_FUNCS(struct_01_02)
322 MAKE_CHECK_FUNCS(struct_01_03)
323 MAKE_CHECK_FUNCS(struct_01_04)
324 MAKE_CHECK_FUNCS(struct_02_01)
325 MAKE_CHECK_FUNCS(struct_02_02)
326 MAKE_CHECK_FUNCS(struct_02_03)
327 MAKE_CHECK_FUNCS(struct_02_04)
328 MAKE_CHECK_FUNCS(struct_04_01)
329 MAKE_CHECK_FUNCS(struct_04_02)
330 MAKE_CHECK_FUNCS(struct_04_03)
331 MAKE_CHECK_FUNCS(struct_04_04)
332 MAKE_CHECK_FUNCS(struct_05_01)
333 MAKE_CHECK_FUNCS(struct_05_02)
334 MAKE_CHECK_FUNCS(struct_05_03)
335 MAKE_CHECK_FUNCS(struct_05_04)
336 #ifdef __cplusplus
337 MAKE_CHECK_FUNCS(struct_static_02_01)
338 MAKE_CHECK_FUNCS(struct_static_02_02)
339 MAKE_CHECK_FUNCS(struct_static_02_03)
340 MAKE_CHECK_FUNCS(struct_static_02_04)
341 MAKE_CHECK_FUNCS(struct_static_04_01)
342 MAKE_CHECK_FUNCS(struct_static_04_02)
343 MAKE_CHECK_FUNCS(struct_static_04_03)
344 MAKE_CHECK_FUNCS(struct_static_04_04)
345 MAKE_CHECK_FUNCS(struct_static_06_01)
346 MAKE_CHECK_FUNCS(struct_static_06_02)
347 MAKE_CHECK_FUNCS(struct_static_06_03)
348 MAKE_CHECK_FUNCS(struct_static_06_04)
349 #endif
350
351 #define CALL_LINE(NAME) val += check_arg_ ## NAME (rtn_str_ ## NAME ())
352
353 int
354 call_all ()
355 {
356 int val;
357
358 CALL_LINE(struct_01_01);
359 CALL_LINE(struct_01_02);
360 CALL_LINE(struct_01_03);
361 CALL_LINE(struct_01_04);
362 CALL_LINE(struct_02_01);
363 CALL_LINE(struct_02_02);
364 CALL_LINE(struct_02_03);
365 CALL_LINE(struct_02_04);
366 CALL_LINE(struct_04_01);
367 CALL_LINE(struct_04_02);
368 CALL_LINE(struct_04_03);
369 CALL_LINE(struct_04_04);
370 CALL_LINE(struct_05_01);
371 CALL_LINE(struct_05_02);
372 CALL_LINE(struct_05_03);
373 CALL_LINE(struct_05_04);
374 #ifdef __cplusplus
375 CALL_LINE(struct_static_02_01);
376 CALL_LINE(struct_static_02_02);
377 CALL_LINE(struct_static_02_03);
378 CALL_LINE(struct_static_02_04);
379 CALL_LINE(struct_static_04_01);
380 CALL_LINE(struct_static_04_02);
381 CALL_LINE(struct_static_04_03);
382 CALL_LINE(struct_static_04_04);
383 CALL_LINE(struct_static_06_01);
384 CALL_LINE(struct_static_06_02);
385 CALL_LINE(struct_static_06_03);
386 CALL_LINE(struct_static_06_04);
387 #endif
388
389 return (val != 4);
390 }
391
392 void
393 breakpt (void)
394 {
395 /* Nothing. */
396 }
397
398 int
399 main ()
400 {
401 int res;
402
403 res = call_all ();
404 breakpt (); /* Break Here. */
405 return res;
406 }
This page took 0.129508 seconds and 3 git commands to generate.