[commit/Ada] fix handling of references to packed array types

Joel Brobecker brobecker@adacore.com
Fri Jan 4 20:52:00 GMT 2008


We have noticed that the handling of expressions that contain a
reference to a packed array causes a lot of trouble:

    (gdb) ptype &piti
    [1]    31696 segmentation fault  ../obj/gdb/gdb.ref foo

And also:

    (gdb) p &piti
    $1 = (array (...) of 
    ../../src-public/gdb/gdbtypes.c:1376: internal-error: check_typedef: Assertion `type' failed.

The attached patch fixes the problem.

2008-01-04  Jerome Guitton  <guitton@adacore.com>

        * ada-lang.c (decode_packed_array_type): Avoid a seg fault
        when the type is an anonymous pointer type.
        (ada_check_typedef): Avoid a seg fault when the type is null.
        * ada-typeprint.c (print_array_type): Add support for pointer
        to packed arrays.

Credits to Paul Hilfinger for reviewing the patch.

I manged to reproduce the problem inside one of the testcase that
we have already contributed.

2008-01-04  Joel Brobecker  <brobecker@adacore.com>

        * gdb.ada/packed_array.exp: Add testing of references to
        a packed array.

Tested on x86-linux, no regression. Checked in.

-- 
Joel
-------------- next part --------------
Index: ada-lang.c
===================================================================
--- ada-lang.c	(revision 77)
+++ ada-lang.c	(revision 78)
@@ -1911,13 +1911,21 @@ decode_packed_array_type (struct type *t
 {
   struct symbol *sym;
   struct block **blocks;
-  const char *raw_name = ada_type_name (ada_check_typedef (type));
-  char *name = (char *) alloca (strlen (raw_name) + 1);
-  char *tail = strstr (raw_name, "___XP");
+  char *raw_name = ada_type_name (ada_check_typedef (type));
+  char *name;
+  char *tail;
   struct type *shadow_type;
   long bits;
   int i, n;
 
+  if (!raw_name)
+    raw_name = ada_type_name (desc_base_type (type));
+
+  if (!raw_name)
+    return NULL;
+
+  name = (char *) alloca (strlen (raw_name) + 1);
+  tail = strstr (raw_name, "___XP");
   type = desc_base_type (type);
 
   memcpy (name, raw_name, tail - raw_name);
@@ -8450,6 +8458,9 @@ static_unwrap_type (struct type *type)
 struct type *
 ada_check_typedef (struct type *type)
 {
+  if (type == NULL)
+    return NULL;
+
   CHECK_TYPEDEF (type);
   if (type == NULL || TYPE_CODE (type) != TYPE_CODE_ENUM
       || !TYPE_STUB (type)
Index: ada-typeprint.c
===================================================================
--- ada-typeprint.c	(revision 77)
+++ ada-typeprint.c	(revision 78)
@@ -366,6 +366,9 @@ print_array_type (struct type *type, str
   int bitsize;
   int n_indices;
 
+  if (ada_is_packed_array_type (type))
+    type = ada_coerce_to_simple_array_type (type);
+
   bitsize = 0;
   fprintf_filtered (stream, "array (");
 
@@ -374,8 +377,6 @@ print_array_type (struct type *type, str
     fprintf_filtered (stream, "...");
   else
     {
-      if (ada_is_packed_array_type (type))
-	type = ada_coerce_to_simple_array_type (type);
       if (type == NULL)
         {
           fprintf_filtered (stream, _("<undecipherable array type>"));
@@ -782,7 +783,17 @@ ada_print_type (struct type *type0, char
   if (ada_is_aligner_type (type))
     ada_print_type (ada_aligned_type (type), "", stream, show, level);
   else if (ada_is_packed_array_type (type))
-    print_array_type (type, stream, show, level);
+    {
+      if (TYPE_CODE (type) == TYPE_CODE_PTR)
+        {
+          fprintf_filtered (stream, "access ");
+          print_array_type (TYPE_TARGET_TYPE (type), stream, show, level);
+        }
+      else
+        {
+          print_array_type (type, stream, show, level);
+        }
+    }
   else
     switch (TYPE_CODE (type))
       {
-------------- next part --------------
Index: gdb.ada/packed_array.exp
===================================================================
--- gdb.ada/packed_array.exp	(revision 78)
+++ gdb.ada/packed_array.exp	(revision 79)
@@ -41,3 +41,13 @@ gdb_test "print var" \
          ".* = \\(4 => true, false, true, false, true\\)" \
          "print var"
 
+# Try printing the value and the type definition of a reference
+# to variable "Var".
+
+gdb_test "ptype &var" \
+         "type = access array \\(4 \\.\\. 8\\) of boolean <packed: 1-bit elements>" \
+         "ptype &var"
+
+gdb_test "print &var" \
+         "\\(access array \\(\\.\\.\\.\\) of boolean\\) \\(4 => true, false, true, false, true\\)" \
+         "print &var"


More information about the Gdb-patches mailing list