# This testcase is part of GDB, the GNU debugger. # Copyright 2018-2019 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # Some targets can't call functions, so don't even bother with this # test. if [target_info exists gdb,cannot_call_functions] { unsupported "this target can not call functions" continue } # Only test C++ if we are able. Always use C. if { [skip_cplus_tests] || [get_compiler_info "c++"] } { set lang {c} } else { set lang {c c++} } foreach l $lang { set dir "$l" remote_exec host "rm -rf [standard_output_file ${dir}]" remote_exec host "mkdir -p [standard_output_file ${dir}]" } set int_types { tc ts ti tl tll } set float_types { tf td tld } set complex_types { tfc tdc tldc } set compile_flags {debug} if [support_complex_tests] { lappend compile_flags "additional_flags=-DTEST_COMPLEX" lappend compile_flags "additional_flags=-Wno-psabi" } # Given N (0..25), return the corresponding alphabetic letter in upper # case. proc I2A { n } { return [string range "ABCDEFGHIJKLMNOPQRSTUVWXYZ" $n $n] } # Compile a variant of nested-structs.c using TYPES to specify the # types of the struct fields within the source. Run up to main. # Also updates the global "testfile" to reflect the most recent build. proc start_nested_structs_test { lang types } { global testfile global srcfile global binfile global subdir global srcdir global compile_flags standard_testfile .c set dir "$lang" # Create the additional flags set flags $compile_flags lappend flags $lang for {set n 0} {$n<[llength ${types}]} {incr n} { set m [I2A ${n}] set t [lindex ${types} $n] lappend flags "additional_flags=-Dt${m}=${t}" append testfile "-" "$t" } set binfile [standard_output_file ${dir}/${testfile}] if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable "${flags}"] != "" } { unresolved "failed to compile" return 0 } # Start with a fresh gdb. clean_restart ${binfile} # Make certain that the output is consistent gdb_test_no_output "set print sevenbit-strings" gdb_test_no_output "set print address off" gdb_test_no_output "set print pretty off" gdb_test_no_output "set width 0" gdb_test_no_output "set print elements 300" # Advance to main if { ![runto_main] } then { fail "can't run to main" return 0 } # Now continue forward to a suitable location to run the tests. # Some targets only enable the FPU on first use, so ensure that we # have used the FPU before we make calls from GDB to code that # could use the FPU. gdb_breakpoint [gdb_get_line_number "Break Here"] temporary gdb_continue_to_breakpoint "breakpt" ".* Break Here\\. .*" return 1 } # Assuming GDB is stopped at main within a test binary, run some tests # passing structures, and reading return value structures. proc run_tests { lang types } { global gdb_prompt foreach {name} {struct_01_01 struct_01_02 struct_01_03 struct_01_04 struct_02_01 struct_02_02 struct_02_03 struct_02_04 struct_04_01 struct_04_02 struct_04_03 struct_04_04 struct_05_01 struct_05_02 struct_05_03 struct_05_04 struct_static_02_01 struct_static_02_02 struct_static_02_03 struct_static_02_04 struct_static_04_01 struct_static_04_02 struct_static_04_03 struct_static_04_04 struct_static_06_01 struct_static_06_02 struct_static_06_03 struct_static_06_04} { # Only run static member tests on C++ if { $lang == "c" && [regexp "static" $name match] } { continue } if { $lang == "c++" && ( ( [regexp "struct_01_0(1|2|3)" $name match] && [regexp "^types-(td($|-)|tl(|l)(|-tf|-td|-tld)$)" $types match] ) || ( $name == "struct_01_02" && $types == "types-tfc" ) || ( $name == "struct_01_04" && [regexp "^types-(tf($|-)|ti(|-tf|-td|-tld)$)" $types match] ) || ( $name == "struct_02_01" && [regexp "^types-tf-t(c|s|i)" $types match] ) || ( $name == "struct_static_02_02" && [regexp "^types-(t(f|d|ld)-t(d|l|ll)$|t(d|l|ll)$|t(c|s|i|l|ll)-td)" $types match] ) || ( $name == "struct_static_02_03" && [regexp "^types-(ti-t(f|l|d|)|tf(-|$)|ti$)" $types match] ) || ( $name == "struct_static_04_02" && [regexp "^types-(t(c|s)-tf|tf-ts)" $types match] ) || ( $name == "struct_static_06_04" && ![regexp "^types-(t(c|dc|ldc|ld)$|t.-tld|tl(l|d)-tld|t(f|d|ld)-tc)" $types match] ) ) } { setup_xfail gdb/24104 "x86_64-*-linux*" } gdb_test "p/d check_arg_${name} (ref_val_${name})" "= 1" set refval [ get_valueof "" "ref_val_${name}" "" ] verbose -log "Refval: ${refval}" set test "check return value ${name}" if { ${refval} != "" } { set answer [ get_valueof "" "rtn_str_${name} ()" "XXXX"] verbose -log "Answer: ${answer}" if { ($lang == "c++" && $name == "struct_02_01" && [regexp "^types-(tf-t(c|s|i)|t(c|s|i)-tf)" $types match] ) } { setup_xfail gdb/24104 "x86_64-*-linux*" } gdb_assert [string eq ${answer} ${refval}] ${test} } else { unresolved $test } } } # Set up a test prefix, compile the test binary, run to main, and then # run some tests. proc start_gdb_and_run_tests { lang types } { set prefix "types" foreach t $types { append prefix "-" "${t}" } foreach_with_prefix l $lang { with_test_prefix $prefix { if { [start_nested_structs_test $l $types] } { run_tests $l $prefix } } } } foreach ta $int_types { start_gdb_and_run_tests $lang $ta } if [support_complex_tests] { foreach ta $complex_types { start_gdb_and_run_tests $lang $ta } } if ![gdb_skip_float_test] { foreach ta $float_types { start_gdb_and_run_tests $lang $ta } foreach ta $int_types { foreach tb $float_types { start_gdb_and_run_tests $lang [list $ta $tb] } } foreach ta $float_types { foreach tb $int_types { start_gdb_and_run_tests $lang [list $ta $tb] } foreach tb $float_types { start_gdb_and_run_tests $lang [list $ta $tb] } } }