[PATCH 1/3] [gdb/exp] Fix target type of complex long double on arm

Tom de Vries tdevries@suse.de
Mon May 27 03:29:42 GMT 2024


When running test-case gdb.base/complex-parts.exp on arm-linux, I get:
...
(gdb) p $_cimag (z3)^M
$6 = 6.5^M
(gdb) PASS: gdb.base/complex-parts.exp: long double imaginary: p $_cimag (z3)
ptype $^M
type = double^M
(gdb) FAIL: gdb.base/complex-parts.exp: long double imaginary: ptype $
...

Given that z3 is a complex long double, the test-case expects the type of the
imaginary part of z3 to be long double, but it's double instead.

This is due to the fact that the dwarf info doesn't specify an explicit target
type:
...
    <5b>   DW_AT_name        : z3
    <60>   DW_AT_type        : <0xa4>
  ...
 <1><a4>: Abbrev Number: 2 (DW_TAG_base_type)
    <a5>   DW_AT_byte_size   : 16
    <a6>   DW_AT_encoding    : 3        (complex float)
    <a7>   DW_AT_name        : complex long double
...
and consequently we're guessing in dwarf2_init_complex_target_type based on
the size:
...
	case 64:
	  tt = builtin_type (gdbarch)->builtin_double;
	  break;
	case 96: /* The x86-32 ABI specifies 96-bit long double.  */
	case 128:
	  tt = builtin_type (gdbarch)->builtin_long_double;
	  break;
...

For arm-linux, complex long double is 16 bytes, so the target type is assumed
to be 8 bytes, which is handled by the "case 64", which gets us double
instead of long double.

Fix this by searching for "long" in the name_hint parameter, and using long
double instead.

Tested on arm-linux.
---
 gdb/dwarf2/read.c | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 4818da58acb..498c0464f97 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -15116,7 +15116,15 @@ dwarf2_init_complex_target_type (struct dwarf2_cu *cu,
 	  tt = builtin_type (gdbarch)->builtin_float;
 	  break;
 	case 64:
-	  tt = builtin_type (gdbarch)->builtin_double;
+	  /* If both "double" and "long double" are 8 bytes, choose "double"
+	     for "complex double" and "long double" for "complex long
+	     double".  */
+	  if (builtin_type (gdbarch)->builtin_long_double->length () == 8
+	      && name_hint != nullptr && *name_hint != '\0'
+	      && strstr (name_hint, "long") != nullptr)
+	    tt = builtin_type (gdbarch)->builtin_long_double;
+	  else
+	    tt = builtin_type (gdbarch)->builtin_double;
 	  break;
 	case 96:	/* The x86-32 ABI specifies 96-bit long double.  */
 	case 128:

base-commit: bdc10cded85aa8995e80394099c9e542b6172979
-- 
2.35.3



More information about the Gdb-patches mailing list