From: Abdul Basit Ijaz Date: Wed, 8 Apr 2026 08:03:57 +0000 (+0200) Subject: gdb/dwarf: Use the function scope for DW_TAG_imported_declaration X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=90fe72f797828eabae2a876f7b4356ca7845123c;p=thirdparty%2Fbinutils-gdb.git 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 --- diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c index a1081da2317..efe96f6510d 100644 --- a/gdb/dwarf2/read.c +++ b/gdb/dwarf2/read.c @@ -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); diff --git a/gdb/testsuite/gdb.fortran/module_declarations.exp b/gdb/testsuite/gdb.fortran/module_declarations.exp new file mode 100644 index 00000000000..8953841c599 --- /dev/null +++ b/gdb/testsuite/gdb.fortran/module_declarations.exp @@ -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 . + +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" +} diff --git a/gdb/testsuite/gdb.fortran/module_declarations.f90 b/gdb/testsuite/gdb.fortran/module_declarations.f90 new file mode 100644 index 00000000000..314e2405b34 --- /dev/null +++ b/gdb/testsuite/gdb.fortran/module_declarations.f90 @@ -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 . + +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