diff --git a/gdb/dwarf2/expr.c b/gdb/dwarf2/expr.c index ccdd87f3a55..7e1666165d7 100644 --- a/gdb/dwarf2/expr.c +++ b/gdb/dwarf2/expr.c @@ -2200,9 +2200,11 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr, goto no_push; case DW_OP_GNU_uninit: - if (op_ptr != op_end) + if (op_ptr != op_end && *op_ptr != DW_OP_piece + && *op_ptr != DW_OP_bit_piece) error (_("DWARF-2 expression error: DW_OP_GNU_uninit must always " - "be the very last op.")); + "be the very last op in a DWARF expression or " + "DW_OP_piece/DW_OP_bit_piece piece.")); this->m_initialized = false; goto no_push; diff --git a/gdb/testsuite/gdb.dwarf2/DW_OP_piece_with_DW_OP_GNU_uninit.exp b/gdb/testsuite/gdb.dwarf2/DW_OP_piece_with_DW_OP_GNU_uninit.exp new file mode 100644 index 00000000000..1d146c5b3f3 --- /dev/null +++ b/gdb/testsuite/gdb.dwarf2/DW_OP_piece_with_DW_OP_GNU_uninit.exp @@ -0,0 +1,94 @@ +# Copyright 2023 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 . + +# Test use of DW_OP_GNU_uninit with DW_OP_piece. For this case, GDB +# should not print: +# +# DWARF-2 expression error: DW_OP_GNU_uninit must always be the very last op. + +load_lib dwarf.exp + +require dwarf2_support + +standard_testfile main.c -dw.S + +set asm_file [standard_output_file $srcfile2] + +set c64 6639779683436459270 +set c32 1779823878 + +Dwarf::assemble $asm_file { + cu {} { + compile_unit {} { + declare_labels i64_type i32_type + + i64_type: base_type { + {name "int64_t"} + {encoding @DW_ATE_signed} + {byte_size 8 DW_FORM_sdata} + } + + i32_type: base_type { + {name "int32_t"} + {encoding @DW_ATE_signed} + {byte_size 4 DW_FORM_sdata} + } + + DW_TAG_variable { + {name i64_var} + {type :$i64_type} + {location { + DW_OP_constu $::c64 + DW_OP_stack_value + DW_OP_GNU_uninit + DW_OP_piece 8 + } SPECIAL_expr} + } + + DW_TAG_variable { + {name i32_var} + {type :$i32_type} + {location { + DW_OP_constu $::c32 + DW_OP_stack_value + DW_OP_GNU_uninit + DW_OP_piece 4 + } SPECIAL_expr} + } + } + } +} + +if {[build_executable ${testfile}.exp ${testfile} \ + [list $srcfile $asm_file] {nodebug}]} { + return -1 +} + +clean_restart ${testfile} + +if {![runto_main]} { + return -1 +} + +set cmd "print i64_var" +if { [is_64_target] } { + gdb_test $cmd \ + " = +\\\[uninitialized\\\] $c64" +} else { + unsupported $cmd +} + +gdb_test "print i32_var" \ + " = +\\\[uninitialized\\\] $c32"