aboutsummaryrefslogtreecommitdiff
path: root/gdb
diff options
context:
space:
mode:
authorTom de Vries <tdevries@suse.de>2024-10-19 07:57:21 +0200
committerTom de Vries <tdevries@suse.de>2024-10-19 07:57:21 +0200
commitcd05f8d44dd3a11b753a11ef5f8e36dcf4a379f5 (patch)
tree8c0d4e9f9d2b65279e8b1b5ab86432446abce52a /gdb
parentf4b00218b542099c69b89bb8b77101607fd64ba0 (diff)
downloadbinutils-cd05f8d44dd3a11b753a11ef5f8e36dcf4a379f5.zip
binutils-cd05f8d44dd3a11b753a11ef5f8e36dcf4a379f5.tar.gz
binutils-cd05f8d44dd3a11b753a11ef5f8e36dcf4a379f5.tar.bz2
[gdb/symtab] Skip local variables in cooked index
Consider test-case gdb.dwarf2/local-var.exp. The corresponding source contains a function with a local variable: ... program test logical :: local_var local_var = .TRUE. end ... Currently, the local variable shows up in the cooked index: ... [2] ((cooked_index_entry *) 0xfffec40063b0) name: local_var canonical: local_var qualified: local_var DWARF tag: DW_TAG_variable flags: 0x2 [IS_STATIC] DIE offset: 0xa3 parent: ((cooked_index_entry *) 0xfffec4006380) [test] ... making the cooked index larger than necessary. Fix this by skipping it in cooked_indexer::index_dies. Tested on aarch64-linux. PR symtab/32276 Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32276
Diffstat (limited to 'gdb')
-rw-r--r--gdb/dwarf2/read.c24
-rw-r--r--gdb/testsuite/gdb.dwarf2/local-var.exp30
-rw-r--r--gdb/testsuite/gdb.dwarf2/local-var.f9019
3 files changed, 66 insertions, 7 deletions
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index ea31d8d..95498bf 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -16524,7 +16524,23 @@ cooked_indexer::index_dies (cutu_reader *reader,
continue;
}
- if (!abbrev->interesting)
+ parent_map::addr_type defer {};
+ if (std::holds_alternative<parent_map::addr_type> (parent))
+ defer = std::get<parent_map::addr_type> (parent);
+ const cooked_index_entry *parent_entry = nullptr;
+ if (std::holds_alternative<const cooked_index_entry *> (parent))
+ parent_entry = std::get<const cooked_index_entry *> (parent);
+
+ /* If a DIE parent is a DW_TAG_subprogram, then the DIE is only
+ interesting if it's a DW_TAG_subprogram or a DW_TAG_entry_point. */
+ bool die_interesting
+ = (abbrev->interesting
+ && (parent_entry == nullptr
+ || parent_entry->tag != DW_TAG_subprogram
+ || abbrev->tag == DW_TAG_subprogram
+ || abbrev->tag == DW_TAG_entry_point));
+
+ if (!die_interesting)
{
info_ptr = skip_one_die (reader, info_ptr, abbrev, !fully);
if (fully && abbrev->has_children)
@@ -16534,14 +16550,8 @@ cooked_indexer::index_dies (cutu_reader *reader,
const char *name = nullptr;
const char *linkage_name = nullptr;
- parent_map::addr_type defer {};
- if (std::holds_alternative<parent_map::addr_type> (parent))
- defer = std::get<parent_map::addr_type> (parent);
cooked_index_flag flags = IS_STATIC;
sect_offset sibling {};
- const cooked_index_entry *parent_entry = nullptr;
- if (std::holds_alternative<const cooked_index_entry *> (parent))
- parent_entry = std::get<const cooked_index_entry *> (parent);
const cooked_index_entry *this_parent_entry = parent_entry;
bool is_enum_class = false;
diff --git a/gdb/testsuite/gdb.dwarf2/local-var.exp b/gdb/testsuite/gdb.dwarf2/local-var.exp
new file mode 100644
index 0000000..6c53305
--- /dev/null
+++ b/gdb/testsuite/gdb.dwarf2/local-var.exp
@@ -0,0 +1,30 @@
+# Copyright 2024 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/>.
+
+# Check that local variables do not occur in the cooked index.
+
+standard_testfile .f90
+
+if { [prepare_for_testing "failed to prepare" ${testfile} $srcfile {debug f90}] } {
+ return -1
+}
+
+# Regression test for PR32276.
+gdb_test_lines "maint print objfiles" "local var not in index" "" -re-not "local_var"
+
+# Check that we still can find the type of the local variable, even when not
+# in the function.
+set hs \[^\r\n\]+
+gdb_test "ptype test::local_var" " = $hs"
diff --git a/gdb/testsuite/gdb.dwarf2/local-var.f90 b/gdb/testsuite/gdb.dwarf2/local-var.f90
new file mode 100644
index 0000000..eea0b13
--- /dev/null
+++ b/gdb/testsuite/gdb.dwarf2/local-var.f90
@@ -0,0 +1,19 @@
+! Copyright 2024 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/>.
+
+program test
+ logical :: local_var
+ local_var = .TRUE.
+end