Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
* [PATCH] Fix Ada 'ptype' of access to array
@ 2024-03-06 16:03 Tom Tromey
  2024-03-18 14:22 ` Tom Tromey
  0 siblings, 1 reply; 2+ messages in thread
From: Tom Tromey @ 2024-03-06 16:03 UTC (permalink / raw)
  To: gdb-patches; +Cc: Tom Tromey

ptype is a bit funny, in that it accepts both expressions and type
names.  It also evaluates the resulting expression using
EVAL_AVOID_SIDE_EFFECTS -- which both seems sensible (as a user would
you expect ptype to possibly cause inferior execution?), but is also a
historical artifact of how expressions are implemented (there's no
EVAL_FOR_TYPE).

In Ada, calling a function with an array will sometimes result in a
"thick pointer" array descriptor being made.  This is essentially a
structure holding a pointer and bounds information.

Currently, in such a callee, printing the type of the array will yield
funny results:

    (gdb) print str.all
    $1 = "Hello World"
    (gdb) ptype str
    type = array (<>) of character
    (gdb) ptype str.all
    type = array (1 .. 0) of character

That "1 .. 0" is the result of an EVAL_AVOID_SIDE_EFFECTS branch
trying to do "something" with an array descriptor, without doing too
much.

I tried briefly to make this code really dereference the array
descriptor and get the correct runtime type.  However, that proved to
be tricky; it certainly can't be done for all access types, because
that will cause dynamic type resolution and end up printing just the
runtime type -- which with variants may be pretty far from what the
user may expect.

Instead, this patch arranges to just leave such types alone in this
situation.  I don't think this should have an extra effects, because
things like array subscripting still work on thick pointers.

This patch also touches arrayptr.exp, because in that case the access
type is a "thin pointer", and this ensures that the output does not
change in that scenario.
---
 gdb/ada-lang.c                       |  8 +++++++-
 gdb/testsuite/gdb.ada/arrayparam.exp | 10 ++++++++++
 gdb/testsuite/gdb.ada/arrayptr.exp   |  5 +++++
 3 files changed, 22 insertions(+), 1 deletion(-)

diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c
index 1c26ebf7b30..62fc6680ed9 100644
--- a/gdb/ada-lang.c
+++ b/gdb/ada-lang.c
@@ -10930,12 +10930,18 @@ ada_unop_ind_operation::evaluate (struct type *expect_type,
   if (noside == EVAL_AVOID_SIDE_EFFECTS)
     {
       if (ada_is_array_descriptor_type (type))
-	/* GDB allows dereferencing GNAT array descriptors.  */
 	{
+	  /* GDB allows dereferencing GNAT array descriptors.
+	     However, for 'ptype' we don't want to try to
+	     "dereference" a thick pointer here -- that will end up
+	     giving us an array with (1 .. 0) for bounds, which is
+	     less clear than (<>).  */
 	  struct type *arrType = ada_type_of_array (arg1, 0);
 
 	  if (arrType == NULL)
 	    error (_("Attempt to dereference null array pointer."));
+	  if (is_thick_pntr (type))
+	    return arg1;
 	  return value_at_lazy (arrType, 0);
 	}
       else if (type->code () == TYPE_CODE_PTR
diff --git a/gdb/testsuite/gdb.ada/arrayparam.exp b/gdb/testsuite/gdb.ada/arrayparam.exp
index b6695254655..2921d64bef1 100644
--- a/gdb/testsuite/gdb.ada/arrayparam.exp
+++ b/gdb/testsuite/gdb.ada/arrayparam.exp
@@ -55,4 +55,14 @@ foreach_with_prefix scenario {all minimal} {
     gdb_test "print pck.length" \
 	"= 7" \
 	"print length after function call"
+
+    gdb_breakpoint "pck.call_me"
+    gdb_continue_to_breakpoint call_me
+
+    gdb_test "print str" " = \"Hello World\""
+    gdb_test "ptype str" "type = array \\(<>\\) of character"
+    gdb_test "ptype str.all" "type = array \\(<>\\) of character"
+    # This surrounds the type in <> -- I don't know why but it's not
+    # really relevant to the test.
+    gdb_test "ptype str.all(0)" "type = <character>"
 }
diff --git a/gdb/testsuite/gdb.ada/arrayptr.exp b/gdb/testsuite/gdb.ada/arrayptr.exp
index c941835f845..ca48993439b 100644
--- a/gdb/testsuite/gdb.ada/arrayptr.exp
+++ b/gdb/testsuite/gdb.ada/arrayptr.exp
@@ -46,6 +46,11 @@ foreach_with_prefix scenario {all minimal} {
 
     gdb_test "print arr_ptr(3..4)" "= \\(3 => 23, 24\\)"
 
+    gdb_test "ptype arr_ptr" \
+	[string_to_regexp "type = access array (1 .. 10) of integer"]
+    gdb_test "ptype arr_ptr.all" \
+	[string_to_regexp "type = array (1 .. 10) of integer"]
+
     gdb_test "ptype string_access" "= access array \\(<>\\) of character"
 
     # GNAT >= 12.0 has the needed fix here.
-- 
2.43.0


^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [PATCH] Fix Ada 'ptype' of access to array
  2024-03-06 16:03 [PATCH] Fix Ada 'ptype' of access to array Tom Tromey
@ 2024-03-18 14:22 ` Tom Tromey
  0 siblings, 0 replies; 2+ messages in thread
From: Tom Tromey @ 2024-03-18 14:22 UTC (permalink / raw)
  To: Tom Tromey; +Cc: gdb-patches

>>>>> "Tom" == Tom Tromey <tromey@adacore.com> writes:

...
Tom> Instead, this patch arranges to just leave such types alone in this
Tom> situation.  I don't think this should have an extra effects, because
Tom> things like array subscripting still work on thick pointers.

I'm checking this in.

Tom

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2024-03-18 14:22 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-03-06 16:03 [PATCH] Fix Ada 'ptype' of access to array Tom Tromey
2024-03-18 14:22 ` Tom Tromey

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox