Automatic Copyright Year update after running gdb/copyright.py
[deliverable/binutils-gdb.git] / gdb / testsuite / gdb.cp / pass-by-ref.exp
CommitLineData
88b9d363 1# Copyright 2007-2022 Free Software Foundation, Inc.
41f1b697
DJ
2
3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by
5# the Free Software Foundation; either version 3 of the License, or
6# (at your option) any later version.
7#
8# This program is distributed in the hope that it will be useful,
9# but WITHOUT ANY WARRANTY; without even the implied warranty of
10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11# GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License
14# along with this program. If not, see <http://www.gnu.org/licenses/>.
15
16# Check that GDB can call C++ functions whose parameters have
c855a912
TBA
17# object type, and are either passed by value or implicitly by reference.
18#
19# Suppose F is a function that has a call-by-value parameter whose
20# type is class C. When calling F with an argument A, a copy of A should
21# be created and passed to F. If C is a trivially-copyable type, A can
22# be copied by a straightforward memory copy. However, roughly speaking,
23# if C has a user-defined copy constructor and/or a user-defined
24# destructor, the copy ctor should be used to initialize the copy of A
25# before calling F, and a reference to that copy is passed to F. After
26# the function returns, the destructor should be called to destruct the
27# copy. In this case, C is said to be a 'pass-by-reference' type.
28# Determining whether C is pass-by-ref depends on
29# how the copy ctor, destructor, and the move ctor of C are defined.
30# First of all, C is not copy constructible if its copy constructor is
31# explicitly or implicitly deleted. In this case, it would be illegal
32# to pass values of type C to a function. C is pass-by-value, if all of
33# its copy ctor, dtor, and move ctor are trivially defined.
34# Otherwise, it is pass-by-ref.
35#
36# To cover the many possible combinations, this test generates classes
37# that contain three special functions:
38# (1) a copy constructor,
39# (2) a destructor, and
40# (3) a move constructor.
41# A special function is in one of the following states:
42# * explicit: The function is explicitly defined by the user.
43# * defaultedIn: The function is defaulted inside the class decl,
44# using the 'default' keyword.
45# * defaultedOut: The function is declared inside the class decl,
46# and defaulted outside using the 'default' keyword.
47# * deleted: The function is explicitly deleted by the user,
48# using the 'delete' keyword.
49# * absent: The function is not declared by the user (i.e. it does not
50# exist in the source. The compiler generates (or deletes) the
51# definition in this case.
52#
53# The C++ ABI decides if a class is pass-by-value or pass-by-ref
54# (i.e. trivially copyable or not) first at the language level, based
55# on the state of the special functions. Then, at the target level, a
56# class may be determined to be pass-by-ref because of its size
57# (e.g. if it is too large to fit on registers). For this reason, this
58# test generates both a small and a large version for the same
59# combination of special function states.
60#
61# A class is not trivially-copyable if a base class or a field is not
62# trivially-copyable, even though the class definition itself seems
63# trivial. To test these cases, we also generate derived classes and
64# container classes.
65#
66# The generated code is placed in the test output directory.
67#
68# The companion test file pass-by-ref-2.exp also contains
69# manually-written cases.
41f1b697 70
c855a912
TBA
71if {[skip_cplus_tests]} {
72 untested "c++ test skipped"
73 continue
74}
41f1b697 75
c855a912
TBA
76# The program source is generated in the output directory.
77# We use standard_testfile here to set convenience variables.
f5f3a911
TT
78standard_testfile .cc
79
c855a912
TBA
80# Some constant values used when generating the source
81
82set SMALL 2
83set LARGE 150
84set ORIGINAL 2
85set CUSTOM 3
86set ADDED 4
87set TRACE 5
88
89
90# Return 1 if the class whose special function states are STATES
91# is copyable. Otherwise return 0.
92
93proc is_copy_constructible { states } {
94 set cctor [lindex $states 0]
95 set dtor [lindex $states 1]
96 set mctor [lindex $states 2]
97
98 if {$cctor == "deleted" || ($cctor == "absent" && $mctor != "absent")} {
99 return 0
100 }
101 return 1
102}
103
104# Generate a declaration and an out-of-class definition for a function
105# with the provided signature. The STATE should be one of the following:
106# - explicit, defaultedIn, defaultedOut, deleted, absent
107
108proc generate_member_function { classname signature length state } {
109 set declaration ""
110 set definition ""
111
112 global CUSTOM
113 global TRACE
114
115 switch $state {
116 explicit {
117 set declaration "$signature;\n"
118 set definition "$classname\:\:$signature
119 {
120 data\[0\] = $CUSTOM;
121 data\[[expr $length - 1]\] = $CUSTOM;
122 tracer = $TRACE;
123 }\n"
124 }
125 defaultedIn {
126 set declaration "$signature = default;\n"
127 }
128 defaultedOut {
129 set declaration "$signature;\n"
130 set definition "$classname\:\:$signature = default;\n"
131 }
132 deleted {
133 set declaration "$signature = delete;\n"
134 }
135 default {
136 # function is not user-defined in this case
137 }
138 }
139
140 return [list $declaration $definition]
141}
142
143# Generate a C++ class with the given CLASSNAME and LENGTH-many
144# integer elements. The STATES is an array of 3 items
145# containing the desired state of the special functions
146# in this order:
147# copy constructor, destructor, move constructor
148
149proc generate_class { classname length states } {
150 set declarations ""
151 set definitions ""
152 set classname "${classname}_[join $states _]"
153
154 for {set i 0} {$i < [llength $states]} {incr i} {
155 set sig ""
156 switch $i {
157 0 {set sig "$classname (const $classname \&rhs)"}
158 1 {set sig "\~$classname (void)"}
159 2 {set sig "$classname ($classname \&\&rhs)"}
160 }
161
162 set state [lindex $states $i]
163 set code [generate_member_function $classname $sig $length $state]
164 append declarations [lindex $code 0]
165 append definitions [lindex $code 1]
166 }
167
168 global ORIGINAL
169
170 return "
171 /*** C++ class $classname ***/
172 class ${classname} {
173 public:
174 $classname (void);
175 $declarations
176
177 int data\[$length\];
178 };
179
180 $classname\:\:$classname (void)
181 {
182 data\[0\] = $ORIGINAL;
183 data\[[expr $length - 1]\] = $ORIGINAL;
184 }
185
186 $definitions
187
188 $classname ${classname}_var; /* global var */
189
190 template int cbv<$classname> ($classname arg);"
191}
192
193# Generate a small C++ class
194
195proc generate_small_class { states } {
196 global SMALL
197 return [generate_class Small $SMALL $states];
198}
199
200# Generate a large C++ class
201
202proc generate_large_class { states } {
203 global LARGE
204 return [generate_class Large $LARGE $states];
205}
206
207# Generate a class that derives from a small class
208
209proc generate_derived_class { states } {
210 set base "Small_[join $states _]"
211 set classname "Derived_[join $states _]"
212
213 return "
214 /*** Class derived from $base ***/
215 class $classname : public $base {
216 public:
217 };
218
219 $classname ${classname}_var; /* global var */
220
221 template int cbv<$classname> ($classname arg);"
222}
223
224# Generate a class that contains a small class item
225
226proc generate_container_class { states } {
227 set contained "Small_[join $states _]"
228 set classname "Container_[join $states _]"
229
230 return "
231 /*** Class that contains $contained ***/
232 class $classname {
233 public:
234 $contained item;
235 };
236
237 $classname ${classname}_var; /* global var */
238
239 template int cbv_container<$classname> ($classname arg);"
240}
241
242# Generate useful statements that use a class in the debugee program
243
244proc generate_stmts { classprefix states {cbvfun "cbv"}} {
245 set classname "${classprefix}_[join $states _]"
246
247 # Having an explicit call to the cbv function in the debugee program
248 # ensures that the compiler will emit necessary function in the binary.
249 if {[is_copy_constructible $states]} {
250 set cbvcall "$cbvfun<$classname> (${classname}_var);\n"
251 } else {
252 set cbvcall ""
253 }
254
255 return "$cbvcall"
256}
257
258# Generate the complete debugee program
259
260proc generate_program { classes stmts } {
261 global ADDED
262
263 return "
264 /*** THIS FILE IS GENERATED BY THE TEST. ***/
265
266 static int tracer = 0;
267
268 /* The call-by-value function. */
269 template <class T>
270 int
271 cbv (T arg)
272 {
273 arg.data\[0\] += $ADDED; // intentionally modify the arg
274 return arg.data\[0\];
275 }
276
277 template <class T>
278 int
279 cbv_container (T arg)
280 {
281 arg.item.data\[0\] += $ADDED; // intentionally modify
282 return arg.item.data\[0\];
283 }
284
285 $classes
286
287 int
288 main (void)
289 {
290 $stmts
291
292 /* stop here */
293
294 return 0;
295 }"
296}
297
298# Compute all the combinations of special function states.
299# We do not contain the 'deleted' state for the destructor,
300# because it is illegal to have stack-allocated objects
301# whose destructor have been deleted. This case is covered
302# in pass-by-ref-2 via heap-allocated objects.
303
304set options_nodelete [list absent explicit defaultedIn defaultedOut]
305set options [concat $options_nodelete {deleted}]
306set all_combinations {}
307
308foreach cctor $options {
309 foreach dtor $options_nodelete {
310 foreach mctor $options {
311 lappend all_combinations [list $cctor $dtor $mctor]
312 }
313 }
314}
315
316# Generate the classes.
317
318set classes ""
319set stmts ""
320
321foreach state $all_combinations {
322 append classes [generate_small_class $state]
323 append stmts [generate_stmts "Small" $state]
324
325 append classes [generate_large_class $state]
326 append stmts [generate_stmts "Large" $state]
327
328 append classes [generate_derived_class $state]
329 append stmts [generate_stmts "Derived" $state]
330
331 append classes [generate_container_class $state]
332 append stmts [generate_stmts "Container" $state "cbv_container"]
333}
334
335# Generate the program code and compile
336set program [generate_program $classes $stmts]
337set srcfile [standard_output_file ${srcfile}]
338gdb_produce_source $srcfile $program
339
340set options {debug c++ additional_flags=-std=c++11}
341if {[prepare_for_testing "failed to prepare" $testfile $srcfile $options]} {
41f1b697
DJ
342 return -1
343}
344
c855a912
TBA
345if {![runto_main]} {
346 untested "failed to run to main"
41f1b697
DJ
347 return -1
348}
349
c855a912
TBA
350set bp_location [gdb_get_line_number "stop here"]
351gdb_breakpoint $bp_location
352gdb_continue_to_breakpoint "end of main" ".*return .*;"
353
354# Do the checks for a given class whose name is prefixed with PREFIX,
355# and whose special functions have the states given in STATES.
356# The name of the call-by-value function and the expression to access
357# the data field can be specified explicitly if the default values
358# do not work.
359
360proc test_for_class { prefix states cbvfun data_field length} {
361 set name "${prefix}_[join $states _]"
362
363 set cctor [lindex $states 0]
364 set dtor [lindex $states 1]
365 set mctor [lindex $states 2]
366
367 global ORIGINAL
368 global CUSTOM
369 global ADDED
370 global TRACE
371
5f440116
TBA
372 # GCC version <= 6 and Clang do not emit DW_AT_defaulted and DW_AT_deleted.
373 set is_gcc_6_or_older [test_compiler_info {gcc-[0-6]-*}]
374 set is_clang [test_compiler_info {clang-*}]
375 # But Clang version >= 7 emits DW_AT_calling_convention for types.
376 set is_clang_6_or_older [test_compiler_info {clang-[0-6]-*}]
377
c855a912
TBA
378 with_test_prefix $name {
379 if {[is_copy_constructible $states]} {
380 set expected [expr {$ORIGINAL + $ADDED}]
381 if {$cctor == "explicit"} {
382 set expected [expr {$CUSTOM + $ADDED}]
383 }
384 if {$dtor == "explicit"} {
385 gdb_test "print tracer = 0" " = 0" "reset the tracer"
386 }
5f440116
TBA
387
388 if {$cctor == "defaultedIn" || $dtor == "defaultedIn"} {
389 if {$is_gcc_6_or_older || $is_clang_6_or_older} {
390 setup_xfail "*-*-*"
391 } elseif {$is_clang} {
392 # If this is a pass-by-value case, Clang >= 7's
393 # DW_AT_calling_convention leads to the right decision.
394 # Otherwise, it is expected to fail.
395 if {"defaultedOut" in $states || "explicit" in $states} {
396 setup_xfail "*-*-*"
397 }
398 }
399 }
c855a912
TBA
400 gdb_test "print ${cbvfun}<$name> (${name}_var)" " = $expected" \
401 "call '$cbvfun'"
402 gdb_test "print ${name}_var.${data_field}\[0\]" " = $ORIGINAL" \
403 "cbv argument should not change (item 0)"
404 if {$length > 1} {
405 set last_index [expr $length - 1]
406 gdb_test "print ${name}_var.${data_field}\[$last_index\]" \
407 " = $ORIGINAL" \
408 "cbv argument should not change (item $last_index)"
409 }
410 if {$dtor == "explicit"} {
5f440116
TBA
411 if {$cctor == "defaultedIn"
412 && ($is_gcc_6_or_older || $is_clang)} {
413 setup_xfail "*-*-*"
414 }
c855a912
TBA
415 gdb_test "print tracer" " = $TRACE" \
416 "destructor should be called"
417 }
418 } else {
5f440116
TBA
419 if {$cctor == "deleted" && ($is_gcc_6_or_older || $is_clang)} {
420 setup_xfail "*-*-*"
421 }
c855a912
TBA
422 gdb_test "print ${cbvfun}<$name> (${name}_var)" \
423 ".* cannot be evaluated .* '${name}' is not copy constructible" \
424 "calling '$cbvfun' should be refused"
425 }
426 }
427}
428
429foreach state $all_combinations {
430 test_for_class "Small" $state "cbv" "data" $SMALL
431 test_for_class "Large" $state "cbv" "data" $LARGE
432 test_for_class "Derived" $state "cbv" "data" 1
433 test_for_class "Container" $state "cbv_container" "item.data" 1
434}
This page took 1.739167 seconds and 4 git commands to generate.