1# Copyright 2007-2021 Free Software Foundation, Inc. 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 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. 70 71if {[skip_cplus_tests]} { 72 untested "c++ test skipped" 73 continue 74} 75 76# The program source is generated in the output directory. 77# We use standard_testfile here to set convenience variables. 78standard_testfile .cc 79 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]} { 342 return -1 343} 344 345if {![runto_main]} { 346 untested "failed to run to main" 347 return -1 348} 349 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 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 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 } 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 } 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"} { 411 if {$cctor == "defaultedIn" 412 && ($is_gcc_6_or_older || $is_clang)} { 413 setup_xfail "*-*-*" 414 } 415 gdb_test "print tracer" " = $TRACE" \ 416 "destructor should be called" 417 } 418 } else { 419 if {$cctor == "deleted" && ($is_gcc_6_or_older || $is_clang)} { 420 setup_xfail "*-*-*" 421 } 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} 435