[PATCH] gdb: Preserve the operand type in DW_OP_plus_uconst

Jielun Wu <[email protected]>
Newsgroups gmane.comp.gdb.patches
Message-ID <[email protected]>
DWARF v5 requires DW_OP_plus_uconst to interpret its unsigned LEB128
constant as the type of the popped stack entry and push a result of that
same type.  GDB instead reconstructs the result using address_type,
discarding an explicit base type.

Construct the result using the popped value's type.

Add a DWARF assembler test that uses a typed value after
DW_OP_plus_uconst in another typed arithmetic operation.  Without the
fix, the expression fails with incompatible DWARF stack types.

Tested on x86_64-linux.

Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=34315
Signed-off-by: Jielun Wu <[email protected]>
---
 gdb/dwarf2/expr.c                             |  2 +-
 .../gdb.dwarf2/dw2-plus-uconst-type.exp       | 75 +++++++++++++++++++
 2 files changed, 76 insertions(+), 1 deletion(-)
 create mode 100644 gdb/testsuite/gdb.dwarf2/dw2-plus-uconst-type.exp

diff --git a/gdb/dwarf2/expr.c b/gdb/dwarf2/expr.c
index 3a6b8f58199..2d9408a3a27 100644
--- a/gdb/dwarf2/expr.c
+++ b/gdb/dwarf2/expr.c
@@ -2063,7 +2063,7 @@ dwarf_expr_context::execute_stack_op (gdb::array_view<const gdb_byte> expr)
 		result = value_as_long (result_val);
 		op_ptr = safe_read_uleb128 (op_ptr, op_end, &reg);
 		result += reg;
-		result_val = value_from_ulongest (address_type, result);
+		result_val = value_from_ulongest (result_val->type (), result);
 		break;
 	      }
 	  }
diff --git a/gdb/testsuite/gdb.dwarf2/dw2-plus-uconst-type.exp b/gdb/testsuite/gdb.dwarf2/dw2-plus-uconst-type.exp
new file mode 100644
index 00000000000..224324798c6
--- /dev/null
+++ b/gdb/testsuite/gdb.dwarf2/dw2-plus-uconst-type.exp
@@ -0,0 +1,75 @@
+# 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 that DW_OP_plus_uconst preserves the type of the popped stack value.
+# A following DW_OP_plus checks this: it reports an error if the intermediate
+# result and the second explicitly typed value have incompatible types.
+
+load_lib dwarf.exp
+
+require dwarf2_support
+
+standard_testfile main.c -dw.S
+
+set asm_file [standard_output_file $srcfile2]
+
+Dwarf::assemble $asm_file {
+    cu {version 5} {
+	compile_unit {} {
+	    declare_labels uint32_label
+
+	    uint32_label: base_type {
+		DW_AT_name "uint32_t"
+		DW_AT_encoding @DW_ATE_unsigned
+		DW_AT_byte_size 4 DW_FORM_sdata
+	    }
+
+	    DW_TAG_variable {
+		DW_AT_name "plus_uconst_preserves_type"
+		DW_AT_type :$uint32_label
+		DW_AT_external 1 DW_FORM_flag
+		DW_AT_location {
+		    variable _constants
+		    variable _cu_label
+
+		    _op .byte $_constants(DW_OP_const_type)
+		    _op .uleb128 "$uint32_label - $_cu_label" \
+			"base type DIE offset"
+		    _op .byte 4 "constant size"
+		    _op .4byte 40 "constant data"
+		    DW_OP_plus_uconst 1
+		    _op .byte $_constants(DW_OP_const_type)
+		    _op .uleb128 "$uint32_label - $_cu_label" \
+			"base type DIE offset"
+		    _op .byte 4 "constant size"
+		    _op .4byte 1 "constant data"
+		    DW_OP_plus
+		    DW_OP_stack_value
+		} SPECIAL_expr
+	    }
+	}
+    }
+}
+
+if {[prepare_for_testing "failed to prepare" ${testfile} \
+	 [list $srcfile $asm_file] nodebug]} {
+    return
+}
+
+if {![runto_main]} {
+    return
+}
+
+gdb_test "print plus_uconst_preserves_type" " = 42"
-- 
2.34.1
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.