/* This testcase is part of GDB, the GNU debugger.
- Copyright 1993-2022 Free Software Foundation, Inc.
+ Copyright 2022 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
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
-#if defined __x86_64__
-# define ASM_REG "rax"
-#elif defined __i386__
-# define ASM_REG "eax"
-#elif defined __powerpc64__
-# define ASM_REG "r9"
-#else
-# error "port me"
-#endif
-
-/* A class small enough that it fits in a register. */
-struct small
-{
- int x;
- int method ();
-};
-
-int
-small::method ()
-{
- return x + 5;
-}
-
-int
-register_class ()
-{
- /* Given the use of the GNU register-asm local variables extension,
- the compiler puts this variable in a register. This means that
- GDB can't call any methods for this variable, which is what we
- want to test. */
- register small v asm (ASM_REG);
-
- int i;
-
- /* Perform a computation sufficiently complicated that optimizing
- compilers won't optimize out the variable. If some compiler
- constant-folds this whole loop, maybe using a parameter to this
- function here would help. */
- v.x = 0;
- for (i = 0; i < 13; ++i)
- v.x += i;
- --v.x; /* v.x is now 77 */
- return v.x + 5; /* set breakpoint here */
-}
-
int
main ()
{
- register_class ();
+ asm ("main_label: .globl main_label");
return 0;
}
if { [skip_cplus_tests] } { continue }
load_lib "cp-support.exp"
+load_lib dwarf.exp
-standard_testfile .cc
+standard_testfile .cc -dw.S
-if {[prepare_for_testing "failed to prepare" $testfile $srcfile {debug c++}]} {
+if {[prepare_for_testing "failed to prepare" $testfile $srcfile \
+ {debug c++}]} {
return -1
}
-if {![test_compiler_info gcc-*-* c++]} {
- untested "test relies on a gcc extension"
- return
-}
+set asm_file [standard_output_file $srcfile2]
+Dwarf::assemble $asm_file {
+
+ set main_result \
+ [function_range main ${::srcdir}/${::subdir}/${::srcfile}]
+ set main_start [lindex $main_result 0]
+ set main_length [lindex $main_result 1]
+
+ cu {} {
+ compile_unit {
+ {DW_AT_language @DW_LANG_C_plus_plus}
+ {DW_AT_name $::srcfile}
+ {DW_AT_comp_dir /tmp}
+ } {
+ declare_labels int_type_label struct_type_label \
+ struct_ptr_type_label
+ set ptr_size [get_sizeof "void *" 96]
+
+ DW_TAG_subprogram {
+ {name main}
+ {low_pc $main_start addr}
+ {high_pc $main_length data8}
+ {DW_AT_type :$int_type_label}
+ }
+
+ int_type_label: DW_TAG_base_type {
+ {DW_AT_byte_size 4 DW_FORM_sdata}
+ {DW_AT_encoding @DW_ATE_signed}
+ {DW_AT_name int}
+ }
+
+ struct_type_label: DW_TAG_structure_type {
+ {DW_AT_byte_size 4 DW_FORM_sdata}
+ {DW_AT_name small}
+ } {
+ member {
+ {name xxx}
+ {type :$int_type_label}
+ {data_member_location 0 data1}
+ }
+ subprogram {
+ {name yyy}
+ {type :$int_type_label}
+ } {
+ formal_parameter {
+ {type :$struct_ptr_type_label}
+ {artificial 1 flag_present}
+ }
+ }
+ }
-proc test_call_register_class {} {
- global gdb_prompt
+ struct_ptr_type_label: DW_TAG_pointer_type {
+ {DW_AT_byte_size $ptr_size DW_FORM_data1}
+ {type :$struct_type_label}
+ }
- if ![runto_main] {
- return
+ DW_TAG_variable {
+ {DW_AT_name global_var}
+ {DW_AT_type :$struct_type_label}
+ {DW_AT_location {
+ DW_OP_reg0
+ } SPECIAL_expr}
+ {external 1 flag}
+ }
+ }
}
+}
- set bp_location [gdb_get_line_number "set breakpoint here"]
- gdb_breakpoint $bp_location
- gdb_continue_to_breakpoint "break here"
-
- # This class is so small that an instance of it can fit in a register.
- # When gdb tries to call a method, it gets embarrassed about taking
- # the address of a register.
- #
- # That message is a PASS, not an XFAIL, because gdb prints an
- # informative message and declines to do something impossible.
- #
- # The method call actually succeeds if the compiler allocates very
- # small classes in memory instead of registers. If that happens,
- # it's a FAIL, because the testcase is written in a form such that
- # it should not happen.
- gdb_test "print v.method ()" \
- "Address requested for identifier \"v\" which is in register .*" \
- "call method on register local"
+if { [prepare_for_testing "failed to prepare" ${testfile} \
+ [list $srcfile $asm_file] {nodebug}] } {
+ return -1
+}
+
+if ![runto_main] {
+ return -1
}
-test_call_register_class
+gdb_test "print global_var.yyy ()" \
+ "Address requested for identifier \"global_var\" which is in register .*" \
+ "call method on register local"