[v2,2/2,gdb/exp] Fix ptype $_creal/$_cimag

Message ID 20240716152614.14512-2-tdevries@suse.de
State Committed
Headers
Series [v2,1/2,gdb/exp] Allow internal function to indicate return type |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_gdb_build--master-aarch64 success Build passed
linaro-tcwg-bot/tcwg_gdb_build--master-arm success Build passed
linaro-tcwg-bot/tcwg_gdb_check--master-arm success Test passed
linaro-tcwg-bot/tcwg_gdb_check--master-aarch64 success Test passed

Commit Message

Tom de Vries July 16, 2024, 3:26 p.m. UTC
  Consider test.c, compiled with -g:
...
__complex__ float cf = 1 + 2i;
int main (void) { return 0; }
...

The values of cf and its components are:
...
$ gdb -q a.out
Reading symbols from a.out...
(gdb) p cf
$1 = 1 + 2i
(gdb) p $_creal(cf)
$2 = 1
(gdb) p $_cimag(cf)
$3 = 2
...
and their respective types are:
...
(gdb) ptype $1
type = complex float
(gdb) ptype $2
type = float
(gdb) ptype $3
type = float
...

Now let's try that again, using ptype directly:
...
(gdb) ptype cf
type = complex float
(gdb) ptype $_creal(cf)
type = int
(gdb) ptype $_cimag(cf)
type = int
...

The last two types should have been float, not int.

Fix this by extending the internal function handlers creal_internal_fn and
cimag_internal_fn with the noside parameter, such that we get instead:
...
(gdb) ptype $_creal(cf)
type = float
(gdb) ptype $_cimag(cf)
type = float
...

Tested on x86_64-linux.

Reviewed-By: Keith Seitz <keiths@redhat.com>

PR exp/31816
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31816
---
 gdb/testsuite/gdb.base/complex-parts.exp | 24 ++++++++++++++++++------
 gdb/value.c                              |  9 +++++++--
 2 files changed, 25 insertions(+), 8 deletions(-)
  

Patch

diff --git a/gdb/testsuite/gdb.base/complex-parts.exp b/gdb/testsuite/gdb.base/complex-parts.exp
index a0ead3eecf6..40f14f42307 100644
--- a/gdb/testsuite/gdb.base/complex-parts.exp
+++ b/gdb/testsuite/gdb.base/complex-parts.exp
@@ -41,33 +41,45 @@  if {[test_compiler_info clang-*-*]} { setup_xfail *-*-* }
 gdb_test "ptype z3" " = complex long double"
 
 with_test_prefix "double imaginary" {
-    gdb_test {p $_cimag (z1)} " = 4.5"
+    set expr {$_cimag (z1)}
+    gdb_test "p $expr" " = 4.5"
     gdb_test {ptype $} " = double"
+    gdb_test "ptype $expr" " = double"
 }
 
 with_test_prefix "float imaginary" {
-    gdb_test {p $_cimag (z2)} " = -5.5"
+    set expr {$_cimag (z2)}
+    gdb_test "p $expr" " = -5.5"
     gdb_test {ptype $} " = float"
+    gdb_test "ptype $expr" " = float"
 }
 
 with_test_prefix "long double imaginary" {
-    gdb_test {p $_cimag (z3)} " = 6.5"
+    set expr {$_cimag (z3)}
+    gdb_test "p $expr" " = 6.5"
     gdb_test {ptype $} " = long double"
+    gdb_test "ptype $expr" " = long double"
 }
 
 with_test_prefix "double real" {
-    gdb_test {p $_creal (z1)} " = 1.5"
+    set expr {$_creal (z1)}
+    gdb_test "p $expr" " = 1.5"
     gdb_test {ptype $} " = double"
+    gdb_test "ptype $expr" " = double"
 }
 
 with_test_prefix "float real" {
-    gdb_test {p $_creal (z2)} " = 2.5"
+    set expr {$_creal (z2)}
+    gdb_test "p $expr" " = 2.5"
     gdb_test {ptype $} " = float"
+    gdb_test "ptype $expr" " = float"
 }
 
 with_test_prefix "long double real" {
-    gdb_test {p $_creal (z3)} " = 3.5"
+    set expr {$_creal (z3)}
+    gdb_test "p $expr" " = 3.5"
     gdb_test {ptype $} " = long double"
+    gdb_test "ptype $expr" " = long double"
 }
 
 gdb_test {p $_cimag (d1)} "expected a complex number"
diff --git a/gdb/value.c b/gdb/value.c
index 9435900ba94..09fb19b9bf8 100644
--- a/gdb/value.c
+++ b/gdb/value.c
@@ -4295,7 +4295,8 @@  isvoid_internal_fn (struct gdbarch *gdbarch,
 static struct value *
 creal_internal_fn (struct gdbarch *gdbarch,
 		   const struct language_defn *language,
-		   void *cookie, int argc, struct value **argv)
+		   void *cookie, int argc, struct value **argv,
+		   enum noside noside)
 {
   if (argc != 1)
     error (_("You must provide one argument for $_creal."));
@@ -4304,6 +4305,8 @@  creal_internal_fn (struct gdbarch *gdbarch,
   type *ctype = check_typedef (cval->type ());
   if (ctype->code () != TYPE_CODE_COMPLEX)
     error (_("expected a complex number"));
+  if (noside == EVAL_AVOID_SIDE_EFFECTS)
+    return value::zero (ctype->target_type (), not_lval);
   return value_real_part (cval);
 }
 
@@ -4314,7 +4317,7 @@  static struct value *
 cimag_internal_fn (struct gdbarch *gdbarch,
 		   const struct language_defn *language,
 		   void *cookie, int argc,
-		   struct value **argv)
+		   struct value **argv, enum noside noside)
 {
   if (argc != 1)
     error (_("You must provide one argument for $_cimag."));
@@ -4323,6 +4326,8 @@  cimag_internal_fn (struct gdbarch *gdbarch,
   type *ctype = check_typedef (cval->type ());
   if (ctype->code () != TYPE_CODE_COMPLEX)
     error (_("expected a complex number"));
+  if (noside == EVAL_AVOID_SIDE_EFFECTS)
+    return value::zero (ctype->target_type (), not_lval);
   return value_imaginary_part (cval);
 }