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)25 ByVal::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)39 ByRef::ByRef (void)
40 {
41   x = 2;
42 }
43 
ByRef(const ByRef & rhs)44 ByRef::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)55 cbvArrayContainerByVal (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)67 cbvArrayContainerByRef (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)82 DynamicBase::DynamicBase (void)
83 {
84   x = 2;
85 }
86 
87 int
get(void)88 DynamicBase::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)99 Dynamic::get (void)
100 {
101   return 9999;
102 }
103 
104 int
cbvDynamic(DynamicBase arg)105 cbvDynamic (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)124 Inlined::Inlined (void)
125 {
126   x = 2;
127 }
128 
129 int
cbvInlined(Inlined arg)130 cbvInlined (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)145 DtorDel::DtorDel (void)
146 {
147   x = 2;
148 }
149 
150 int
cbvDtorDel(DtorDel arg)151 cbvDtorDel (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)169 FourCCtor::FourCCtor (void)
170 {
171   x = 2;
172 }
173 
FourCCtor(FourCCtor & rhs)174 FourCCtor::FourCCtor (FourCCtor &rhs)
175 {
176   x = 3;
177 }
178 
FourCCtor(const FourCCtor & rhs)179 FourCCtor::FourCCtor (const FourCCtor &rhs)
180 {
181   x = 4;
182 }
183 
FourCCtor(volatile FourCCtor & rhs)184 FourCCtor::FourCCtor (volatile FourCCtor &rhs)
185 {
186   x = 5;
187 }
188 
FourCCtor(const volatile FourCCtor & rhs)189 FourCCtor::FourCCtor (const volatile FourCCtor &rhs)
190 {
191   x = 6;
192 }
193 
194 int
cbvFourCCtor(FourCCtor arg)195 cbvFourCCtor (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)213 TwoMCtor::TwoMCtor (void)
214 {
215   x = 2;
216 }
217 
TwoMCtor(const TwoMCtor && rhs)218 TwoMCtor::TwoMCtor (const TwoMCtor &&rhs)
219 {
220   x = 3;
221 }
222 
223 int
cbvTwoMCtor(TwoMCtor arg)224 cbvTwoMCtor (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)244 TwoMCtorAndCCtor::TwoMCtorAndCCtor (void)
245 {
246   x = 2;
247 }
248 
TwoMCtorAndCCtor(const TwoMCtorAndCCtor && rhs)249 TwoMCtorAndCCtor::TwoMCtorAndCCtor (const TwoMCtorAndCCtor &&rhs)
250 {
251   x = 4;
252 }
253 
254 int
cbvTwoMCtorAndCCtor(TwoMCtorAndCCtor arg)255 cbvTwoMCtorAndCCtor (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)275 main (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