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 18class ByVal { 19public: 20 ByVal (void); 21 22 int x; 23}; 24 25ByVal::ByVal (void) 26{ 27 x = 2; 28} 29 30class ByRef { 31public: 32 ByRef (void); 33 34 ByRef (const ByRef &rhs); 35 36 int x; 37}; 38 39ByRef::ByRef (void) 40{ 41 x = 2; 42} 43 44ByRef::ByRef (const ByRef &rhs) 45{ 46 x = 3; /* ByRef-cctor */ 47} 48 49class ArrayContainerByVal { 50public: 51 ByVal items[2]; 52}; 53 54int 55cbvArrayContainerByVal (ArrayContainerByVal arg) 56{ 57 arg.items[0].x += 4; // intentionally modify 58 return arg.items[0].x; 59} 60 61class ArrayContainerByRef { 62public: 63 ByRef items[2]; 64}; 65 66int 67cbvArrayContainerByRef (ArrayContainerByRef arg) 68{ 69 arg.items[0].x += 4; // intentionally modify 70 return arg.items[0].x; 71} 72 73class DynamicBase { 74public: 75 DynamicBase (void); 76 77 virtual int get (void); 78 79 int x; 80}; 81 82DynamicBase::DynamicBase (void) 83{ 84 x = 2; 85} 86 87int 88DynamicBase::get (void) 89{ 90 return 42; 91} 92 93class Dynamic : public DynamicBase { 94public: 95 virtual int get (void); 96}; 97 98int 99Dynamic::get (void) 100{ 101 return 9999; 102} 103 104int 105cbvDynamic (DynamicBase arg) 106{ 107 arg.x += 4; // intentionally modify 108 return arg.x + arg.get (); 109} 110 111class Inlined { 112public: 113 Inlined (void); 114 115 __attribute__((always_inline)) 116 Inlined (const Inlined &rhs) 117 { 118 x = 3; 119 } 120 121 int x; 122}; 123 124Inlined::Inlined (void) 125{ 126 x = 2; 127} 128 129int 130cbvInlined (Inlined arg) 131{ 132 arg.x += 4; // intentionally modify 133 return arg.x; 134} 135 136class DtorDel { 137public: 138 DtorDel (void); 139 140 ~DtorDel (void) = delete; 141 142 int x; 143}; 144 145DtorDel::DtorDel (void) 146{ 147 x = 2; 148} 149 150int 151cbvDtorDel (DtorDel arg) 152{ 153 // Calling this method should be rejected 154 return arg.x; 155} 156 157class FourCCtor { 158public: 159 FourCCtor (void); 160 161 FourCCtor (FourCCtor &rhs); 162 FourCCtor (const FourCCtor &rhs); 163 FourCCtor (volatile FourCCtor &rhs); 164 FourCCtor (const volatile FourCCtor &rhs); 165 166 int x; 167}; 168 169FourCCtor::FourCCtor (void) 170{ 171 x = 2; 172} 173 174FourCCtor::FourCCtor (FourCCtor &rhs) 175{ 176 x = 3; 177} 178 179FourCCtor::FourCCtor (const FourCCtor &rhs) 180{ 181 x = 4; 182} 183 184FourCCtor::FourCCtor (volatile FourCCtor &rhs) 185{ 186 x = 5; 187} 188 189FourCCtor::FourCCtor (const volatile FourCCtor &rhs) 190{ 191 x = 6; 192} 193 194int 195cbvFourCCtor (FourCCtor arg) 196{ 197 arg.x += 10; // intentionally modify 198 return arg.x; 199} 200 201class TwoMCtor { 202public: 203 TwoMCtor (void); 204 205 /* Even though one move ctor is defaulted, the other 206 is explicit. */ 207 TwoMCtor (const TwoMCtor &&rhs); 208 TwoMCtor (TwoMCtor &&rhs) = default; 209 210 int x; 211}; 212 213TwoMCtor::TwoMCtor (void) 214{ 215 x = 2; 216} 217 218TwoMCtor::TwoMCtor (const TwoMCtor &&rhs) 219{ 220 x = 3; 221} 222 223int 224cbvTwoMCtor (TwoMCtor arg) 225{ 226 arg.x += 10; // intentionally modify 227 return arg.x; 228} 229 230class TwoMCtorAndCCtor { 231public: 232 TwoMCtorAndCCtor (void); 233 234 TwoMCtorAndCCtor (const TwoMCtorAndCCtor &rhs) = default; 235 236 /* Even though one move ctor is defaulted, the other 237 is explicit. This makes the type pass-by-ref. */ 238 TwoMCtorAndCCtor (const TwoMCtorAndCCtor &&rhs); 239 TwoMCtorAndCCtor (TwoMCtorAndCCtor &&rhs) = default; 240 241 int x; 242}; 243 244TwoMCtorAndCCtor::TwoMCtorAndCCtor (void) 245{ 246 x = 2; 247} 248 249TwoMCtorAndCCtor::TwoMCtorAndCCtor (const TwoMCtorAndCCtor &&rhs) 250{ 251 x = 4; 252} 253 254int 255cbvTwoMCtorAndCCtor (TwoMCtorAndCCtor arg) 256{ 257 arg.x += 10; // intentionally modify 258 return arg.x; 259} 260 261ArrayContainerByVal arrayContainerByVal; 262ArrayContainerByRef arrayContainerByRef; 263Dynamic dynamic; 264Inlined inlined; 265// Cannot stack-allocate DtorDel 266DtorDel *dtorDel; 267FourCCtor fourCctor_c0v0; 268const FourCCtor fourCctor_c1v0; 269volatile FourCCtor fourCctor_c0v1; 270const volatile FourCCtor fourCctor_c1v1; 271TwoMCtor twoMctor; 272TwoMCtorAndCCtor twoMctorAndCctor; 273 274int 275main (void) 276{ 277 int v; 278 dtorDel = new DtorDel; 279 /* Explicitly call the cbv function to make sure the compiler 280 will not omit any code in the binary. */ 281 v = cbvArrayContainerByVal (arrayContainerByVal); 282 v = cbvArrayContainerByRef (arrayContainerByRef); 283 v = cbvDynamic (dynamic); 284 v = cbvInlined (inlined); 285 v = cbvFourCCtor (fourCctor_c0v0); 286 v = cbvFourCCtor (fourCctor_c1v0); 287 v = cbvFourCCtor (fourCctor_c0v1); 288 v = cbvFourCCtor (fourCctor_c1v1); 289 /* v = cbvTwoMCtor (twoMctor); */ // This is illegal, cctor is deleted 290 v = cbvTwoMCtorAndCCtor (twoMctorAndCctor); 291 292 /* stop here */ 293 294 return 0; 295} 296