mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2026-08-27 00:26:02 -04:00
gdb/dwarf: Use the function scope for DW_TAG_imported_declaration
All Fortran imported variable aliases (`use module, alias => var`)
were being added to "global scope", regardless of whether they appeared
in:
- Program/module scope (should be global)
- Function scope (should be local)
This caused conflicts when different functions had the same alias name
pointing to different variables.
DW_TAG_imported_declaration and DW_TAG_namespace cases are now handled
separately. This patch modifies the case for DW_TAG_imported_
declaration in the function new_symbol () to use cu->list_in_scope
instead of global symbols for all languages. This ensures that
function-scoped aliases use the current scope rather than being forced
into the global scope.
Bug Scenario:
subroutine sub1
use mod1, var_i_alias=>var_i ! alias points to mod1::var_i
var_i_alias = 3
var_i = 4
end subroutine
subroutine sub2
use mod2, var_i_alias=>var_i ! alias points to mod2::var_i
var_i_alias = 23
var_i = 25
end subroutine
Before: var_i_alias in sub2 incorrectly resolved to mod1::var_i
(value 25)
After: Each function's alias correctly resolves to its own imported
variable (value 23)
New test files verify the fix and include regression tests for global
program-scope imports:
- gdb/testsuite/gdb.fortran/module_declarations.exp
- gdb/testsuite/gdb.fortran/module_declarations.f90
Before the change:
(gdb) print var_i_alias
$4 = 25
FAIL: gdb.fortran/module_declarations.exp: sub2_test: print var_i_alias
After the change:
(gdb) print var_i_alias
$4 = 23
PASS: gdb.fortran/module_declarations.exp: sub2_test: print var_i_alias
Approved-By: Tom Tromey <tom@tromey.com>
This commit is contained in:
parent
297fe552ed
commit
90fe72f797
3 changed files with 131 additions and 0 deletions
|
|
@ -15846,6 +15846,16 @@ new_symbol (struct die_info *die, struct dwarf2_cu *cu, struct symbol *sym,
|
|||
: cu->list_in_scope);
|
||||
break;
|
||||
case DW_TAG_imported_declaration:
|
||||
sym->set_domain (TYPE_DOMAIN);
|
||||
sym->set_loc_class_index (LOC_TYPEDEF);
|
||||
/* Use current scope context rather than forcing global scope. This
|
||||
ensures variable aliases are scoped correctly (function-level,
|
||||
module-level, or program-level). */
|
||||
list_to_add
|
||||
= ((cu->list_in_scope == &cu->get_builder ()->get_file_symbols ())
|
||||
? &cu->get_builder ()->get_global_symbols ()
|
||||
: cu->list_in_scope);
|
||||
break;
|
||||
case DW_TAG_namespace:
|
||||
sym->set_domain (TYPE_DOMAIN);
|
||||
sym->set_loc_class_index (LOC_TYPEDEF);
|
||||
|
|
|
|||
62
gdb/testsuite/gdb.fortran/module_declarations.exp
Normal file
62
gdb/testsuite/gdb.fortran/module_declarations.exp
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
# Copyright 2026 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
load_lib "fortran.exp"
|
||||
|
||||
require allow_fortran_tests
|
||||
|
||||
standard_testfile .f90
|
||||
|
||||
if { [prepare_for_testing "failed to prepare" $testfile $srcfile {debug f90}] } {
|
||||
return
|
||||
}
|
||||
|
||||
if {![fortran_runto_main]} {
|
||||
return
|
||||
}
|
||||
|
||||
# Test global alias at program scope
|
||||
gdb_breakpoint [gdb_get_line_number "bp-main"]
|
||||
gdb_continue_to_breakpoint "bp-main" ".*bp-main.*"
|
||||
|
||||
with_test_prefix "global_test" {
|
||||
gdb_test "print global_alias" " = 200"
|
||||
gdb_test "print global_var_i_from_mod1" " = 300"
|
||||
}
|
||||
|
||||
gdb_breakpoint [gdb_get_line_number "bp-sub1"]
|
||||
gdb_continue_to_breakpoint "bp-sub1" ".*bp-sub1.*"
|
||||
|
||||
with_test_prefix "sub1_test" {
|
||||
gdb_test "print var_i_alias" " = 3"
|
||||
gdb_test "print var_i" " = 4"
|
||||
}
|
||||
|
||||
gdb_breakpoint [gdb_get_line_number "bp-sub2"]
|
||||
gdb_continue_to_breakpoint "bp-sub2" ".*bp-sub2.*"
|
||||
|
||||
with_test_prefix "sub2_test" {
|
||||
gdb_test "print var_i_alias" " = 23"
|
||||
gdb_test "print var_i" " = 25"
|
||||
}
|
||||
|
||||
# Test same-name variables shadowed within same function
|
||||
gdb_breakpoint [gdb_get_line_number "bp-sub3"]
|
||||
gdb_continue_to_breakpoint "bp-sub3" ".*bp-sub3.*"
|
||||
|
||||
with_test_prefix "sub3_shadow_test" {
|
||||
gdb_test "print var_i_from_mod1" " = 31"
|
||||
gdb_test "print var_i_from_mod2" " = 32"
|
||||
}
|
||||
59
gdb/testsuite/gdb.fortran/module_declarations.f90
Normal file
59
gdb/testsuite/gdb.fortran/module_declarations.f90
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
! Copyright 2026 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
module mod1
|
||||
implicit none
|
||||
integer :: var_i = 1
|
||||
integer :: global_var = 100
|
||||
end module mod1
|
||||
|
||||
module mod2
|
||||
implicit none
|
||||
integer :: var_i = 2
|
||||
end module mod2
|
||||
|
||||
subroutine sub1
|
||||
use mod1, var_i_alias=>var_i
|
||||
use mod2
|
||||
implicit none
|
||||
var_i_alias = 3
|
||||
var_i = 4
|
||||
end subroutine ! bp-sub1
|
||||
|
||||
subroutine sub2
|
||||
use mod1
|
||||
use mod2, var_i_alias=>var_i
|
||||
implicit none
|
||||
var_i_alias = 23
|
||||
var_i = 25
|
||||
end subroutine ! bp-sub2
|
||||
|
||||
subroutine sub3
|
||||
use mod1, var_i_from_mod1=>var_i
|
||||
use mod2, var_i_from_mod2=>var_i
|
||||
implicit none
|
||||
var_i_from_mod1 = 31
|
||||
var_i_from_mod2 = 32
|
||||
end subroutine ! bp-sub3
|
||||
|
||||
program main
|
||||
use mod1, global_alias=>global_var, global_var_i_from_mod1=>var_i
|
||||
implicit none
|
||||
global_alias = 200
|
||||
global_var_i_from_mod1 = 300
|
||||
call sub1 ! bp-main
|
||||
call sub2
|
||||
call sub3
|
||||
end
|
||||
Loading…
Add table
Add a link
Reference in a new issue