[binutils-gdb] gdb, fortran: Fix local variable lookup in Fortran parser

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=8c0ac471835ec86a67c5b42713d9f138f31e4014

commit 8c0ac471835ec86a67c5b42713d9f138f31e4014
Author: Abdul Basit Ijaz <[email protected]>
Date:   Tue Apr 14 23:23:51 2026 +0200

    gdb, fortran: Fix local variable lookup in Fortran parser
    
    This change fixes https://sourceware.org/bugzilla/show_bug.cgi?id=34059.
    
    The Fortran expression parser in GDB ("gdb/f-exp.y") previously performed
    symbol lookup in this order when parsing identifiers:
    
    - SEARCH_STRUCT_DOMAIN (types/structs)
    - SEARCH_VFT ("C-like" name lookups for variables/types/functions)
    - SEARCH_MODULE_DOMAIN (modules)
    
    It searched for "types before variables", causing type names from shared
    libraries to shadow local variable names.
    
    For a reproducer like the one given below, the Fortran parser fails to
    look up local variable name "array" and treats it as a type value instead
    of a variable, because there's a conflicting "array" type from system
    libraries.
    
    1 program test
    2
    3  ! Declare variables used in this test.
    4  integer, dimension (-2:2) :: array
    5
    6  array = 1
    7
    8  print *, ""           ! Break here
    9  print *, array
    10
    11 end program test
    
    Before the change, GDB shows:
    
    '''
    ./gdb --data-directory=./data-directory --args /tmp/a.out
    GNU gdb (GDB) 18.0.50.20260408-git
    Copyright (C) 2026 Free Software Foundation, Inc.
    ...
    Reading symbols from /tmp/a.out...
    (gdb) break 8
    Breakpoint 1 at 0x11b3: file test.f90, line 8.
    (gdb) run
    Starting program: /tmp/a.out
    [Thread debugging using libthread_db enabled]
    Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
    
    Breakpoint 1, test () at test.f90:8
    8         print *, ""           ! Break here
    (gdb) info locals
    array = (1, 1, 1, 1, 1)
    (gdb) print array
    Attempt to use a type name as an expression
    (gdb) ptype array
    type = Type array
        Type, C_Union :: :: u
        PTR TO -> ( char :: scratch(0:15 ))
    End Type array
    '''
    
    This issue is fixed in the Fortran expression parser in GDB ("gdb/f-exp.y")
    by prioritizing SEARCH_VFT over other search domains during symbol lookup.
    After the change, the 'array' variable is resolved to the correct value.
    
    '''
    (gdb) print array
    $1 = (1, 1, 1, 1, 1)
    (gdb) ptype array
    type = integer(kind=4) (-2:2)
    '''
    
    Approved-by: Kevin Buettner <[email protected]>

Diff:
---
 gdb/f-exp.y                                        |  2 +-
 .../gdb.fortran/var-type-precedence-lib.c          | 30 +++++++++++
 gdb/testsuite/gdb.fortran/var-type-precedence.exp  | 60 ++++++++++++++++++++++
 gdb/testsuite/gdb.fortran/var-type-precedence.f90  | 40 +++++++++++++++
 4 files changed, 131 insertions(+), 1 deletion(-)

diff --git a/gdb/f-exp.y b/gdb/f-exp.y
index 278e2091403..4216112c10b 100644
--- a/gdb/f-exp.y
+++ b/gdb/f-exp.y
@@ -1651,8 +1651,8 @@ yylex (void)
     struct block_symbol result;
     const domain_search_flags lookup_domains[] =
     {
-      SEARCH_STRUCT_DOMAIN,
       SEARCH_VFT,
+      SEARCH_STRUCT_DOMAIN,
       SEARCH_MODULE_DOMAIN
     };
     int hextype;
diff --git a/gdb/testsuite/gdb.fortran/var-type-precedence-lib.c b/gdb/testsuite/gdb.fortran/var-type-precedence-lib.c
new file mode 100644
index 00000000000..87bd19fad84
--- /dev/null
+++ b/gdb/testsuite/gdb.fortran/var-type-precedence-lib.c
@@ -0,0 +1,30 @@
+/* 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/>.  */
+
+/* Define a struct type that will conflict with Fortran variable name.  */
+struct type_shadowing_var
+{
+  int value;
+};
+
+/* Global variables to ensure types are in debug info.  */
+static struct type_shadowing_var global_conflicting_var = {42};
+
+/* Function to ensure library is linked and types are used.  */
+void
+fortran_var_type_order_test (void)
+{
+  global_conflicting_var.value = 42;
+}
diff --git a/gdb/testsuite/gdb.fortran/var-type-precedence.exp b/gdb/testsuite/gdb.fortran/var-type-precedence.exp
new file mode 100644
index 00000000000..8c9f80d43d9
--- /dev/null
+++ b/gdb/testsuite/gdb.fortran/var-type-precedence.exp
@@ -0,0 +1,60 @@
+# 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/>.
+
+# Test variable lookup when local Fortran variable names conflict with
+# type names from a C shared library.
+
+require allow_fortran_tests
+
+standard_testfile var-type-precedence.f90 var-type-precedence-lib.c
+load_lib fortran.exp
+
+set libname "${testfile}-lib"
+set srcfile_lib ${srcdir}/${subdir}/${srcfile2}
+set binfile_lib [standard_output_file ${libname}.so]
+
+# Compile the C shared library.
+if {[gdb_compile_shlib ${srcfile_lib} ${binfile_lib} \
+	{debug}] != ""} {
+  untested "failed to compile C shared library"
+  return
+}
+
+# Compile the Fortran main program with the C shared library.
+if {[prepare_for_testing "failed to prepare" $testfile \
+	${srcfile} [list debug f90 shlib=${binfile_lib}]]} {
+  return
+}
+
+if {![fortran_runto_main]} {
+  return
+}
+
+set bp_loc [gdb_get_line_number "break-here"]
+gdb_breakpoint "$srcfile:$bp_loc"
+gdb_continue_to_breakpoint "stop-at-bp" ".*$srcfile:$bp_loc.*"
+
+set integer4 [fortran_int4]
+
+# Test that local variable 'type_shadowing_var' is resolved correctly.
+gdb_test "print type_shadowing_var" "= \\(1, 1, 1, 1, 1\\)" \
+    "print local type_shadowing_var variable"
+gdb_test "ptype type_shadowing_var" "type = $integer4 \\(-2:2\\)" \
+    "ptype local type_shadowing_var"
+
+# Verify the C types exist in debug info by checking info types.
+gdb_test "info types type_shadowing_var" \
+    ".*File.*var-type-precedence-lib\\.c:.*struct type_shadowing_var.*" \
+    "C type type_shadowing_var exists in debug info"
diff --git a/gdb/testsuite/gdb.fortran/var-type-precedence.f90 b/gdb/testsuite/gdb.fortran/var-type-precedence.f90
new file mode 100644
index 00000000000..c0707cacda6
--- /dev/null
+++ b/gdb/testsuite/gdb.fortran/var-type-precedence.f90
@@ -0,0 +1,40 @@
+! 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/>.
+
+! Source code for var-type-precedence test to verify that local Fortran
+! variables take precedence over conflicting C type names from shared
+! libraries.
+
+program test
+  use iso_c_binding
+  implicit none
+
+  interface
+    subroutine fortran_var_type_order_test () bind (C)
+    end subroutine fortran_var_type_order_test
+  end interface
+
+  ! Declare variables with names that conflict with types in C library.
+  integer, dimension (-2:2) :: type_shadowing_var
+
+  ! Call C library function to ensure it's linked.
+  call fortran_var_type_order_test ()
+
+  type_shadowing_var = 1
+
+  print *, "" ! break-here
+  print *, type_shadowing_var
+
+end program test
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.