]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
gdb: Handle TYPE_CODE_COMPLEX in valprint_check_validity.
authorAbdul Basit Ijaz <abdul.b.ijaz@intel.com>
Tue, 21 Apr 2026 12:05:08 +0000 (14:05 +0200)
committerAbdul Basit Ijaz <abdul.b.ijaz@intel.com>
Wed, 20 May 2026 15:56:37 +0000 (17:56 +0200)
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 <tom@tromey.com>
gdb/testsuite/gdb.dwarf2/complex-partial-optimized.exp [new file with mode: 0644]
gdb/valprint.c
gdb/valprint.h

diff --git a/gdb/testsuite/gdb.dwarf2/complex-partial-optimized.exp b/gdb/testsuite/gdb.dwarf2/complex-partial-optimized.exp
new file mode 100644 (file)
index 0000000..c22a729
--- /dev/null
@@ -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"
index 482069fbbaa402f199e5d66382566f006dce3e04..b266db550d18ff06ebb29cdb23f08b380a45e4ea 100644 (file)
@@ -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 ()))
index 146a24d174f674c52a160aa616ea16c113e0ab45..8e88b964722968edb0e3be34574add8d9922d429 100644 (file)
@@ -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,