This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[commit/Ada] array pointers encoded as typedef to fat pointer


A recent change in check_typedef caused the following regression,
considering:

        type String_Access is access String;
        S1 : String_Access := null;

Trying to print S1, we get:

        (gdb) print s1
        $1 = (string) (null)

The type name is wrong.  We were expecting:

        (gdb) print s1
        $1 = (string_bug.string_access) (null)

The extensive comment in this patch explains how pointers to arrays
are encoded when the array is a "fat pointer".  What happened is
that the change in check_typedef broke a type-equality test that
we were performing.   The test really was on the fringe, but it
turns out that, for what we're doing, we're really only interested
in the main-type portion of the type.

The patch adjust the check accordingly.

gdb/ChangeLog:

        * ada-lang.c (ada_to_fixed_type): Expand function documentation.
        Return the original type if the main type portions match rather
         than when the type themselves match.

Tested on x86_64-linux.  Checked in.

---
 gdb/ChangeLog  |    6 ++++++
 gdb/ada-lang.c |   38 ++++++++++++++++++++++++++++++++++++--
 2 files changed, 42 insertions(+), 2 deletions(-)

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 8872ab4..dd91159 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,11 @@
 2010-11-22  Joel Brobecker  <brobecker@adacore.com>
 
+	* ada-lang.c (ada_to_fixed_type): Expand function documentation.
+	Return the original type if the main type portions match rather
+	than when the type themselves match.
+
+2010-11-22  Joel Brobecker  <brobecker@adacore.com>
+
 	* ada-lang.c (ada_template_to_fixed_record_type_1):
 	For dynamic fields, check the field size against the maximum
 	object size.
diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c
index 341db4a..4471481 100644
--- a/gdb/ada-lang.c
+++ b/gdb/ada-lang.c
@@ -7659,7 +7659,23 @@ ada_to_fixed_type_1 (struct type *type, const gdb_byte *valaddr,
 
 /* The same as ada_to_fixed_type_1, except that it preserves the type
    if it is a TYPE_CODE_TYPEDEF of a type that is already fixed.
-   ada_to_fixed_type_1 would return the type referenced by TYPE.  */
+
+   The typedef layer needs be preserved in order to differentiate between
+   arrays and array pointers when both types are implemented using the same
+   fat pointer.  In the array pointer case, the pointer is encoded as
+   a typedef of the pointer type.  For instance, considering:
+
+	  type String_Access is access String;
+	  S1 : String_Access := null;
+
+   To the debugger, S1 is defined as a typedef of type String.  But
+   to the user, it is a pointer.  So if the user tries to print S1,
+   we should not dereference the array, but print the array address
+   instead.
+
+   If we didn't preserve the typedef layer, we would lose the fact that
+   the type is to be presented as a pointer (needs de-reference before
+   being printed).  And we would also use the source-level type name.  */
 
 struct type *
 ada_to_fixed_type (struct type *type, const gdb_byte *valaddr,
@@ -7669,8 +7685,26 @@ ada_to_fixed_type (struct type *type, const gdb_byte *valaddr,
   struct type *fixed_type =
     ada_to_fixed_type_1 (type, valaddr, address, dval, check_tag);
 
+  /*  If TYPE is a typedef and its target type is the same as the FIXED_TYPE,
+      then preserve the typedef layer.
+
+      Implementation note: We can only check the main-type portion of
+      the TYPE and FIXED_TYPE, because eliminating the typedef layer
+      from TYPE now returns a type that has the same instance flags
+      as TYPE.  For instance, if TYPE is a "typedef const", and its
+      target type is a "struct", then the typedef elimination will return
+      a "const" version of the target type.  See check_typedef for more
+      details about how the typedef layer elimination is done.
+
+      brobecker/2010-11-19: It seems to me that the only case where it is
+      useful to preserve the typedef layer is when dealing with fat pointers.
+      Perhaps, we could add a check for that and preserve the typedef layer
+      only in that situation.  But this seems unecessary so far, probably
+      because we call check_typedef/ada_check_typedef pretty much everywhere.
+      */
   if (TYPE_CODE (type) == TYPE_CODE_TYPEDEF
-      && TYPE_TARGET_TYPE (type) == fixed_type)
+      && (TYPE_MAIN_TYPE (TYPE_TARGET_TYPE (type))
+	  == TYPE_MAIN_TYPE (fixed_type)))
     return type;
 
   return fixed_type;
-- 
1.7.1


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]