1 /* This testcase is part of GDB, the GNU debugger. 2 3 Copyright 2019-2023 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 #include <cstdint> 19 #include <cstdio> 20 #include <cstdlib> 21 #include <cassert> 22 23 /* A simple structure with a single integer field. Should be returned in 24 a register. */ 25 struct SimpleBase 26 { 27 SimpleBase (int32_t x) : x (x) {} 28 29 int32_t x; 30 }; 31 32 /* A simple structure derived from the simple base. Should be returned in 33 a register. */ 34 struct SimpleDerived : public SimpleBase 35 { 36 SimpleDerived (int32_t x) : SimpleBase (x) {} 37 }; 38 39 /* A structure derived from the simple base with a non-trivial destructor. 40 Should be returned on the stack. */ 41 struct NonTrivialDestructorDerived : public SimpleBase 42 { 43 NonTrivialDestructorDerived (int32_t x) : SimpleBase (x) {} 44 ~NonTrivialDestructorDerived() { x = 1; } 45 }; 46 47 /* A structure with unaligned fields. Should be returned on the stack. */ 48 struct UnalignedFields 49 { 50 UnalignedFields (int32_t x, double y) : x (x), y (y) {} 51 52 int32_t x; 53 double y; 54 } __attribute__((packed)); 55 56 /* A structure with unaligned fields in its base class. Should be 57 returned on the stack. */ 58 struct UnalignedFieldsInBase : public UnalignedFields 59 { 60 UnalignedFieldsInBase (int32_t x, double y, int32_t x2) 61 : UnalignedFields (x, y), x2 (x2) {} 62 63 int32_t x2; 64 }; 65 66 struct Bitfields 67 { 68 Bitfields(unsigned int x, unsigned int y) 69 : fld(x), fld2(y) 70 {} 71 72 unsigned fld : 7; 73 unsigned fld2 : 7; 74 }; 75 76 class Foo 77 { 78 public: 79 SimpleBase 80 return_simple_base (int32_t x) 81 { 82 assert (this->tag == EXPECTED_TAG); 83 return SimpleBase (x); 84 } 85 86 SimpleDerived 87 return_simple_derived (int32_t x) 88 { 89 assert (this->tag == EXPECTED_TAG); 90 return SimpleDerived (x); 91 } 92 93 NonTrivialDestructorDerived 94 return_non_trivial_destructor (int32_t x) 95 { 96 assert (this->tag == EXPECTED_TAG); 97 return NonTrivialDestructorDerived (x); 98 } 99 100 UnalignedFields 101 return_unaligned (int32_t x, double y) 102 { 103 assert (this->tag == EXPECTED_TAG); 104 return UnalignedFields (x, y); 105 } 106 107 UnalignedFieldsInBase 108 return_unaligned_in_base (int32_t x, double y, int32_t x2) 109 { 110 assert (this->tag == EXPECTED_TAG); 111 return UnalignedFieldsInBase (x, y, x2); 112 } 113 114 Bitfields 115 return_bitfields (unsigned int x, unsigned int y) 116 { 117 assert (this->tag == EXPECTED_TAG); 118 return Bitfields(x, y); 119 } 120 121 private: 122 /* Use a tag to detect if the "this" value is correct. */ 123 static const int EXPECTED_TAG = 0xF00F00F0; 124 int tag = EXPECTED_TAG; 125 }; 126 127 int 128 main (int argc, char *argv[]) 129 { 130 Foo foo; 131 foo.return_simple_base(1); 132 foo.return_simple_derived(2); 133 foo.return_non_trivial_destructor(3); 134 foo.return_unaligned(4, 5); 135 foo.return_unaligned_in_base(6, 7, 8); 136 foo.return_bitfields(23, 74); 137 return 0; // break-here 138 } 139