[binutils-gdb] gdb: Handle TYPE_CODE_COMPLEX in valprint_check_validity.
Abdul Basit Ijaz via Gdb-cvs <[email protected]> Wed, 20 May 2026 15:59:17 +0000 (GMT)
| Newsgroups | gmane.comp.gdb.cvs |
|---|---|
| Message-ID | <[email protected]> |
https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=ba415df8ba3817ab6eb5c9ec441ed2d979abe3b1 commit ba415df8ba3817ab6eb5c9ec441ed2d979abe3b1 Author: Abdul Basit Ijaz <[email protected]> Date: Tue Apr 21 14:05:08 2026 +0200 gdb: Handle TYPE_CODE_COMPLEX in valprint_check_validity. When printing complex variables with partial optimization (e.g., real part available but imaginary part optimized out), GDB incorrectly reported the entire variable as <optimized out> instead of showing available components. The issue occurred because valprint_check_validity () only exempted TYPE_CODE_UNION, TYPE_CODE_STRUCT, and TYPE_CODE_ARRAY from the optimized-out check, but not TYPE_CODE_COMPLEX. Complex types, like structures, can have components with different availability. A new test gdb.dwarf2/complex-partial-optimized.exp is added to verify that available components are printed. (gdb) print z1 $1 = <optimized out> Now after this change: (gdb) print z1 $1 = 3 + <optimized out>i Approved-By: Tom Tromey <[email protected]> Diff: --- .../gdb.dwarf2/complex-partial-optimized.exp | 101 +++++++++++++++++++++ gdb/valprint.c | 3 +- gdb/valprint.h | 8 +- 3 files changed, 108 insertions(+), 4 deletions(-) diff --git a/gdb/testsuite/gdb.dwarf2/complex-partial-optimized.exp b/gdb/testsuite/gdb.dwarf2/complex-partial-optimized.exp new file mode 100644 index 00000000000..c22a729826b --- /dev/null +++ b/gdb/testsuite/gdb.dwarf2/complex-partial-optimized.exp @@ -0,0 +1,101 @@ +# 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 printing of partially optimized complex variables. + +load_lib dwarf.exp + +# This test can only be run on targets which support DWARF-2. +require dwarf2_support + +standard_testfile main.c -dw.S + +set asm_file [standard_output_file $srcfile2] + +Dwarf::assemble $asm_file { + cu {} { + compile_unit { + DW_AT_language @DW_LANG_C99 + DW_AT_name $::srcfile + DW_AT_comp_dir /tmp + } { + declare_labels float_label complex_label + + float_label: DW_TAG_base_type { + DW_AT_byte_size 4 DW_FORM_sdata + DW_AT_encoding @DW_ATE_float + DW_AT_name float + } + + complex_label: DW_TAG_base_type { + DW_AT_byte_size 8 DW_FORM_sdata + DW_AT_encoding @DW_ATE_complex_float + DW_AT_name "complex float" + } + + DW_TAG_subprogram { + MACRO_AT_func {main} + DW_AT_type :$float_label + DW_AT_external 1 DW_FORM_flag + } { + # Complex variable 'z1' with real part as constant value, imaginary + # optimized out + DW_TAG_variable { + DW_AT_name z1 + DW_AT_type :$complex_label + DW_AT_location { + DW_OP_implicit_value 0x00 0x00 0x40 0x40 + DW_OP_piece 4 + DW_OP_piece 4 + } SPECIAL_expr + } + # Complex variable 'z2' with real part optimized out, imaginary + # part as constant value + DW_TAG_variable { + DW_AT_name z2 + DW_AT_type :$complex_label + DW_AT_location { + DW_OP_piece 4 + DW_OP_implicit_value 0x00 0x00 0x40 0x40 + DW_OP_piece 4 + } SPECIAL_expr + } + } + } + } +} + +if {[prepare_for_testing "failed to prepare" ${testfile} \ + [list $srcfile $asm_file] {nodebug}]} { + return +} + +if {![runto_main]} { + return +} + +# Test that complex variable prints with real part shown and imaginary as +# <optimized out>. +# Expected output format: "$1 = <real_value> + <optimized out>i". +# The regex ensures there's a real value (not <optimized out>) before the +. +gdb_test "print z1" "= \[0-9\]+ \\+ <optimized out>i" \ + "complex with imaginary part optimized out shows real value" + +# Test that complex variable prints with real part optimized out and imaginary +# part shown. +# Expected output format: "$2 = <optimized out> + <imaginary_value>i". +# The regex ensures there's an imaginary value (not <optimized out>) after the +. +gdb_test "print z2" "= <optimized out> \\+ \[0-9\]+i" \ + "complex with real part optimized out shows imaginary value" diff --git a/gdb/valprint.c b/gdb/valprint.c index 482069fbbaa..b266db550d1 100644 --- a/gdb/valprint.c +++ b/gdb/valprint.c @@ -336,7 +336,8 @@ valprint_check_validity (struct ui_file *stream, if (type->code () != TYPE_CODE_UNION && type->code () != TYPE_CODE_STRUCT - && type->code () != TYPE_CODE_ARRAY) + && type->code () != TYPE_CODE_ARRAY + && type->code () != TYPE_CODE_COMPLEX) { if (val->bits_any_optimized_out (TARGET_CHAR_BIT * field_byte_offset, TARGET_CHAR_BIT * type->length ())) diff --git a/gdb/valprint.h b/gdb/valprint.h index 146a24d174f..8e88b964722 100644 --- a/gdb/valprint.h +++ b/gdb/valprint.h @@ -197,10 +197,12 @@ extern void print_function_pointer_address (const struct value_print_options *op /* Helper function to check the validity of some bits of a value. - If TYPE represents some aggregate type (e.g., a structure), return true. + If TYPE is a structure, union, array, or complex type, return 1. These + types can have components with different availability states, so callers + should check components individually. - For non-aggregate TYPEs, if any of the bytes starting at FIELD_BYTE_OFFSET - and extending for TYPE->length () bytes are invalid, print a message to + Otherwise, if any of the bytes starting at FIELD_BYTE_OFFSET and + extending for TYPE->length () bytes are invalid, print a message to STREAM and return false. Otherwise, return true. */ extern bool valprint_check_validity (struct ui_file *stream, struct type *type,