xref: /netbsd-src/external/gpl3/gdb.old/dist/gdb/testsuite/gdb.base/infcall-nested-structs.c (revision 82d56013d7b633d116a93943de88e08335357a7c)
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 == a.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 == a.s2.s1.b
157 	 && a.s2.s1.c == b.s2.s1.c && a.s2.s1.d == a.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 == a.s2.s1.b
171 	 && a.s2.s1.c == b.s2.s1.c && a.s2.s1.d == a.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 == a.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 == a.s2.s1.b
211 	 && a.s2.s1.c == b.s2.s1.c && a.s2.s1.d == a.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 == a.s2.s1.b
233 	 && a.s2.s1.c == b.s2.s1.c && a.s2.s1.d == a.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 }
407