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