[binutils-gdb] gdb/dwarf: Use the function scope for DW_TAG_imported_declaration

Abdul Basit Ijaz via Gdb-cvs <[email protected]>
Newsgroups gmane.comp.gdb.cvs
Message-ID <[email protected]>
https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=90fe72f797828eabae2a876f7b4356ca7845123c

commit 90fe72f797828eabae2a876f7b4356ca7845123c
Author: Abdul Basit Ijaz <[email protected]>
Date:   Wed Apr 8 10:03:57 2026 +0200

    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 <[email protected]>

Diff:
---
 gdb/dwarf2/read.c                                 | 10 ++++
 gdb/testsuite/gdb.fortran/module_declarations.exp | 62 +++++++++++++++++++++++
 gdb/testsuite/gdb.fortran/module_declarations.f90 | 59 +++++++++++++++++++++
 3 files changed, 131 insertions(+)

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 <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"
+}
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 <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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.