]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
Fix bug in gdb.lookup_type
authorTom Tromey <tom@tromey.com>
Fri, 4 Apr 2025 04:13:00 +0000 (22:13 -0600)
committerTom Tromey <tom@tromey.com>
Tue, 30 Sep 2025 14:08:30 +0000 (08:08 -0600)
gdb.lookup_type accepts a 'block' argument, but in some cases does not
use it.  This can cause the wrong type to be returned.

This patch fixes the problem by simply passing the block through.  I
have no idea why it worked the way it did, and there weren't any tests
for the 'block' parameter.  (I didn't look at git blame out of fear
that it was my patch back in the day.)

Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=16942

gdb/python/py-type.c
gdb/testsuite/gdb.python/lookup-type-block.exp [new file with mode: 0644]
gdb/testsuite/gdb.python/lookup1.c [new file with mode: 0644]
gdb/testsuite/gdb.python/lookup2.c [new file with mode: 0644]

index a2c5939cf5ca5c2a90502473187458a1e38fbad9..65753fd5fcd4047881803ca1dbdf9eb9a7385cc8 100644 (file)
@@ -842,11 +842,11 @@ typy_lookup_typename (const char *type_name, const struct block *block)
   try
     {
       if (startswith (type_name, "struct "))
-       type = lookup_struct (type_name + 7, NULL);
+       type = lookup_struct (type_name + 7, block);
       else if (startswith (type_name, "union "))
-       type = lookup_union (type_name + 6, NULL);
+       type = lookup_union (type_name + 6, block);
       else if (startswith (type_name, "enum "))
-       type = lookup_enum (type_name + 5, NULL);
+       type = lookup_enum (type_name + 5, block);
       else
        type = lookup_typename (current_language,
                                type_name, block, 0);
diff --git a/gdb/testsuite/gdb.python/lookup-type-block.exp b/gdb/testsuite/gdb.python/lookup-type-block.exp
new file mode 100644 (file)
index 0000000..7d04eb6
--- /dev/null
@@ -0,0 +1,68 @@
+# Copyright (C) 2025 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 the 'block' argument to gdb.lookup_type.
+
+load_lib gdb-python.exp
+
+require allow_python_tests
+
+standard_testfile lookup1.c lookup2.c
+
+if {[prepare_for_testing "failed to prepare" ${testfile} \
+        [list $srcfile $srcfile2]]} {
+    return
+}
+
+proc check_type {which type_name} {
+    if {$which == "one"} {
+       set fn_name function
+    } else {
+       set fn_name main
+    }
+
+    gdb_test_no_output \
+       "python block = gdb.decode_line(\"$fn_name\")\[1\]\[0\].symtab.static_block()" \
+       "compute block"
+    gdb_test_no_output \
+       "python ty = gdb.lookup_type(\"$type_name\", block).strip_typedefs()" \
+       "find the type"
+    gdb_test "python print(ty.fields()\[0\].name)" \
+       "$which" \
+       "examine first field"
+}
+
+proc check_all_types {} {
+    foreach_with_prefix which {one two} {
+       foreach_with_prefix type_name {
+           "struct the_struct"
+           "enum the_enum"
+           "union the_union"
+           "the_typedef"
+       } {
+           check_type $which $type_name
+       }
+    }
+}
+
+check_all_types
+
+if {![runto_main]} {
+    return
+}
+
+with_test_prefix "while running" {
+    check_all_types
+}
diff --git a/gdb/testsuite/gdb.python/lookup1.c b/gdb/testsuite/gdb.python/lookup1.c
new file mode 100644 (file)
index 0000000..488ffcb
--- /dev/null
@@ -0,0 +1,44 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2025 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/>.  */
+
+struct the_struct {
+  int one;
+};
+
+struct the_struct struct1;
+
+enum the_enum {
+  one
+};
+
+enum the_enum enum1;
+
+union the_union {
+  int one;
+  void *ptr;
+};
+
+union the_union union1;
+
+typedef struct the_struct the_typedef;
+
+the_typedef typedef1;
+
+int function (void)
+{
+  return 0;
+}
diff --git a/gdb/testsuite/gdb.python/lookup2.c b/gdb/testsuite/gdb.python/lookup2.c
new file mode 100644 (file)
index 0000000..63d1030
--- /dev/null
@@ -0,0 +1,46 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2025 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/>.  */
+
+struct the_struct {
+  int two;
+};
+
+struct the_struct struct2;
+
+enum the_enum {
+  two
+};
+
+enum the_enum enum2;
+
+union the_union {
+  int two;
+  void *ptr;
+};
+
+union the_union union2;
+
+typedef struct the_struct the_typedef;
+
+the_typedef typedef2;
+
+extern int function (void);
+
+int main (void)
+{
+  return function ();
+}