1 /* This testcase is part of GDB, the GNU debugger. 2 3 Copyright 2019-2020 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 class ByVal { 19 public: 20 ByVal (void); 21 22 int x; 23 }; 24 ByVal(void)25ByVal::ByVal (void) 26 { 27 x = 2; 28 } 29 30 class ByRef { 31 public: 32 ByRef (void); 33 34 ByRef (const ByRef &rhs); 35 36 int x; 37 }; 38 ByRef(void)39ByRef::ByRef (void) 40 { 41 x = 2; 42 } 43 ByRef(const ByRef & rhs)44ByRef::ByRef (const ByRef &rhs) 45 { 46 x = 3; /* ByRef-cctor */ 47 } 48 49 class ArrayContainerByVal { 50 public: 51 ByVal items[2]; 52 }; 53 54 int cbvArrayContainerByVal(ArrayContainerByVal arg)55cbvArrayContainerByVal (ArrayContainerByVal arg) 56 { 57 arg.items[0].x += 4; // intentionally modify 58 return arg.items[0].x; 59 } 60 61 class ArrayContainerByRef { 62 public: 63 ByRef items[2]; 64 }; 65 66 int cbvArrayContainerByRef(ArrayContainerByRef arg)67cbvArrayContainerByRef (ArrayContainerByRef arg) 68 { 69 arg.items[0].x += 4; // intentionally modify 70 return arg.items[0].x; 71 } 72 73 class DynamicBase { 74 public: 75 DynamicBase (void); 76 77 virtual int get (void); 78 79 int x; 80 }; 81 DynamicBase(void)82DynamicBase::DynamicBase (void) 83 { 84 x = 2; 85 } 86 87 int get(void)88DynamicBase::get (void) 89 { 90 return 42; 91 } 92 93 class Dynamic : public DynamicBase { 94 public: 95 virtual int get (void); 96 }; 97 98 int get(void)99Dynamic::get (void) 100 { 101 return 9999; 102 } 103 104 int cbvDynamic(DynamicBase arg)105cbvDynamic (DynamicBase arg) 106 { 107 arg.x += 4; // intentionally modify 108 return arg.x + arg.get (); 109 } 110 111 class Inlined { 112 public: 113 Inlined (void); 114 115 __attribute__((always_inline)) Inlined(const Inlined & rhs)116 Inlined (const Inlined &rhs) 117 { 118 x = 3; 119 } 120 121 int x; 122 }; 123 Inlined(void)124Inlined::Inlined (void) 125 { 126 x = 2; 127 } 128 129 int cbvInlined(Inlined arg)130cbvInlined (Inlined arg) 131 { 132 arg.x += 4; // intentionally modify 133 return arg.x; 134 } 135 136 class DtorDel { 137 public: 138 DtorDel (void); 139 140 ~DtorDel (void) = delete; 141 142 int x; 143 }; 144 DtorDel(void)145DtorDel::DtorDel (void) 146 { 147 x = 2; 148 } 149 150 int cbvDtorDel(DtorDel arg)151cbvDtorDel (DtorDel arg) 152 { 153 // Calling this method should be rejected 154 return arg.x; 155 } 156 157 class FourCCtor { 158 public: 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 FourCCtor(void)169FourCCtor::FourCCtor (void) 170 { 171 x = 2; 172 } 173 FourCCtor(FourCCtor & rhs)174FourCCtor::FourCCtor (FourCCtor &rhs) 175 { 176 x = 3; 177 } 178 FourCCtor(const FourCCtor & rhs)179FourCCtor::FourCCtor (const FourCCtor &rhs) 180 { 181 x = 4; 182 } 183 FourCCtor(volatile FourCCtor & rhs)184FourCCtor::FourCCtor (volatile FourCCtor &rhs) 185 { 186 x = 5; 187 } 188 FourCCtor(const volatile FourCCtor & rhs)189FourCCtor::FourCCtor (const volatile FourCCtor &rhs) 190 { 191 x = 6; 192 } 193 194 int cbvFourCCtor(FourCCtor arg)195cbvFourCCtor (FourCCtor arg) 196 { 197 arg.x += 10; // intentionally modify 198 return arg.x; 199 } 200 201 class TwoMCtor { 202 public: 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 TwoMCtor(void)213TwoMCtor::TwoMCtor (void) 214 { 215 x = 2; 216 } 217 TwoMCtor(const TwoMCtor && rhs)218TwoMCtor::TwoMCtor (const TwoMCtor &&rhs) 219 { 220 x = 3; 221 } 222 223 int cbvTwoMCtor(TwoMCtor arg)224cbvTwoMCtor (TwoMCtor arg) 225 { 226 arg.x += 10; // intentionally modify 227 return arg.x; 228 } 229 230 class TwoMCtorAndCCtor { 231 public: 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 TwoMCtorAndCCtor(void)244TwoMCtorAndCCtor::TwoMCtorAndCCtor (void) 245 { 246 x = 2; 247 } 248 TwoMCtorAndCCtor(const TwoMCtorAndCCtor && rhs)249TwoMCtorAndCCtor::TwoMCtorAndCCtor (const TwoMCtorAndCCtor &&rhs) 250 { 251 x = 4; 252 } 253 254 int cbvTwoMCtorAndCCtor(TwoMCtorAndCCtor arg)255cbvTwoMCtorAndCCtor (TwoMCtorAndCCtor arg) 256 { 257 arg.x += 10; // intentionally modify 258 return arg.x; 259 } 260 261 ArrayContainerByVal arrayContainerByVal; 262 ArrayContainerByRef arrayContainerByRef; 263 Dynamic dynamic; 264 Inlined inlined; 265 // Cannot stack-allocate DtorDel 266 DtorDel *dtorDel; 267 FourCCtor fourCctor_c0v0; 268 const FourCCtor fourCctor_c1v0; 269 volatile FourCCtor fourCctor_c0v1; 270 const volatile FourCCtor fourCctor_c1v1; 271 TwoMCtor twoMctor; 272 TwoMCtorAndCCtor twoMctorAndCctor; 273 274 int main(void)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