This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC 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]

[Ada PATCH] don't modify record fields in update_pointer_to


When an unconstrained array type is frozen, update_pointer_to updates
the fat pointer type for the old, dummy, type and makes it point to the
new type.  It does this by overwriting the old pointer type's fields (a
fat pointer is a record) with the fields from the new fat pointer.  This
leads to trouble, since the original fields may have been used already,
for example in a COMPONENT_REF or a CONSTRUCTOR: after the update, the
field argument of the component reference is no longer a field of the
type being referenced!  (The field argument is a field from the original
fat pointer type; that field has been overwritten in the type with a
field from the new fat pointer type).  There is a workaround for this
in trans.c (removed in this patch).  Similarly for a constructor: the
constructor elements are not fields of the type being constructed!  You
can get away with this in mainline gcc, because it simply doesn't notice,
however this instantly caused trouble in my port of the Ada f-e to LLVM.
This patch changes update_pointer_to so as to not replace fields: instead
it uses update_pointer_to (simple pointer case) to update the pointer types
used in the fields.  For this to work, the dummy fat pointer fields are
changed from being void pointers into pointers to dummy nodes.

This passes bootstrap and acats and gnat deja-gnu testing.

Please let me know what you think.

Best wishes,

Duncan.
Index: gcc.fsf.master/gcc/ada/decl.c
===================================================================
--- gcc.fsf.master.orig/gcc/ada/decl.c	2007-02-19 16:32:37.000000000 +0100
+++ gcc.fsf.master/gcc/ada/decl.c	2007-02-21 13:40:21.000000000 +0100
@@ -3050,6 +3050,21 @@
 	    gnu_type = TYPE_POINTER_TO (gnu_old);
 	    if (!gnu_type)
 	      {
+                tree gnu_template_type = make_node (ENUMERAL_TYPE);
+                tree gnu_ptr_template = build_pointer_type (gnu_template_type);
+                tree gnu_array_type = make_node (ENUMERAL_TYPE);
+                tree gnu_ptr_array = build_pointer_type (gnu_array_type);
+
+		TYPE_NAME (gnu_template_type)
+		  = concat_id_with_name (get_entity_name (gnat_desig_type),
+					 "XUB");
+		TYPE_DUMMY_P (gnu_template_type) = 1;
+
+		TYPE_NAME (gnu_array_type)
+		  = concat_id_with_name (get_entity_name (gnat_desig_type),
+					 "XUA");
+		TYPE_DUMMY_P (gnu_array_type) = 1;
+
 		gnu_type = make_node (RECORD_TYPE);
 		SET_TYPE_UNCONSTRAINED_ARRAY (gnu_type, gnu_old);
 		TYPE_POINTER_TO (gnu_old) = gnu_type;
@@ -3059,11 +3074,11 @@
 		  = chainon (chainon (NULL_TREE,
 				      create_field_decl
 				      (get_identifier ("P_ARRAY"),
-				       ptr_void_type_node, gnu_type,
-				       0, 0, 0, 0)),
+                                       gnu_ptr_array, gnu_type,
+                                       0, 0, 0, 0)),
 			     create_field_decl (get_identifier ("P_BOUNDS"),
-						ptr_void_type_node,
-						gnu_type, 0, 0, 0, 0));
+                                                gnu_ptr_template,
+                                                gnu_type, 0, 0, 0, 0));
 
 		/* Make sure we can place this into a register.  */
 		TYPE_ALIGN (gnu_type)
Index: gcc.fsf.master/gcc/ada/trans.c
===================================================================
--- gcc.fsf.master.orig/gcc/ada/trans.c	2007-02-19 16:32:37.000000000 +0100
+++ gcc.fsf.master/gcc/ada/trans.c	2007-02-21 13:40:21.000000000 +0100
@@ -4846,19 +4846,6 @@
 	  return GS_ALL_DONE;
 	}
 
-      return GS_UNHANDLED;
-
-    case COMPONENT_REF:
-      /* We have a kludge here.  If the FIELD_DECL is from a fat pointer and is
-	 from an early dummy type, replace it with the proper FIELD_DECL.  */
-      if (TYPE_FAT_POINTER_P (TREE_TYPE (TREE_OPERAND (*expr_p, 0)))
-	  && DECL_ORIGINAL_FIELD (TREE_OPERAND (*expr_p, 1)))
-	{
-	  TREE_OPERAND (*expr_p, 1)
-	    = DECL_ORIGINAL_FIELD (TREE_OPERAND (*expr_p, 1));
-	  return GS_OK;
-	}
-
       /* ... fall through ... */
 
     default:
Index: gcc.fsf.master/gcc/ada/utils.c
===================================================================
--- gcc.fsf.master.orig/gcc/ada/utils.c	2007-02-19 16:32:37.000000000 +0100
+++ gcc.fsf.master/gcc/ada/utils.c	2007-02-21 13:40:21.000000000 +0100
@@ -2935,19 +2935,15 @@
   else
     {
       tree new_obj_rec = TYPE_OBJECT_RECORD_TYPE (new_type);
-      tree ptr_temp_type;
+      tree array_field = TYPE_FIELDS (ptr);
+      tree bounds_field = TREE_CHAIN (TYPE_FIELDS (ptr));
+      tree new_ptr = TYPE_POINTER_TO (new_type);
       tree new_ref;
       tree var;
 
-      SET_DECL_ORIGINAL_FIELD (TYPE_FIELDS (ptr),
-			       TYPE_FIELDS (TYPE_POINTER_TO (new_type)));
-      SET_DECL_ORIGINAL_FIELD (TREE_CHAIN (TYPE_FIELDS (ptr)),
-			       TREE_CHAIN (TYPE_FIELDS
-					   (TYPE_POINTER_TO (new_type))));
-
-      TYPE_FIELDS (ptr) = TYPE_FIELDS (TYPE_POINTER_TO (new_type));
-      DECL_CONTEXT (TYPE_FIELDS (ptr)) = ptr;
-      DECL_CONTEXT (TREE_CHAIN (TYPE_FIELDS (ptr))) = ptr;
+      update_pointer_to
+        (TREE_TYPE (TREE_TYPE (bounds_field)),
+         TREE_TYPE (TREE_TYPE (TREE_CHAIN (TYPE_FIELDS (new_ptr)))));
 
       /* Rework the PLACEHOLDER_EXPR inside the reference to the
 	 template bounds.
@@ -2955,25 +2951,22 @@
 	 ??? This is now the only use of gnat_substitute_in_type, which
 	 is now a very "heavy" routine to do this, so it should be replaced
 	 at some point.  */
-      ptr_temp_type = TREE_TYPE (TREE_CHAIN (TYPE_FIELDS (ptr)));
-      new_ref = build3 (COMPONENT_REF, ptr_temp_type,
+      new_ref = build3 (COMPONENT_REF, TREE_TYPE (bounds_field),
 			build0 (PLACEHOLDER_EXPR, ptr),
-			TREE_CHAIN (TYPE_FIELDS (ptr)), NULL_TREE);
+			bounds_field, NULL_TREE);
+
+      update_pointer_to
+	(TREE_TYPE (TREE_TYPE (TYPE_FIELDS (new_ptr))),
+	 gnat_substitute_in_type (TREE_TYPE (TREE_TYPE (TYPE_FIELDS (new_ptr))),
+				  TREE_CHAIN (TYPE_FIELDS (new_ptr)), new_ref));
 
       update_pointer_to
-	(TREE_TYPE (TREE_TYPE (TYPE_FIELDS (ptr))),
-	 gnat_substitute_in_type (TREE_TYPE (TREE_TYPE (TYPE_FIELDS (ptr))),
-				  TREE_CHAIN (TYPE_FIELDS (ptr)), new_ref));
+        (TREE_TYPE (TREE_TYPE (array_field)),
+         TREE_TYPE (TREE_TYPE (TYPE_FIELDS (new_ptr))));
 
       for (var = TYPE_MAIN_VARIANT (ptr); var; var = TYPE_NEXT_VARIANT (var))
-	{
 	  SET_TYPE_UNCONSTRAINED_ARRAY (var, new_type);
 
-	  /* This may seem a bit gross, in particular wrt DECL_CONTEXT, but
-	     actually is in keeping with what build_qualified_type does.  */
-	  TYPE_FIELDS (var) = TYPE_FIELDS (ptr);
-	}
-
       TYPE_POINTER_TO (new_type) = TYPE_REFERENCE_TO (new_type)
 	= TREE_TYPE (new_type) = ptr;
 
@@ -2983,13 +2976,12 @@
 
       update_pointer_to (TYPE_OBJECT_RECORD_TYPE (old_type), new_obj_rec);
 
-      TREE_TYPE (TYPE_FIELDS (new_obj_rec)) = TREE_TYPE (ptr_temp_type);
       TREE_TYPE (TREE_CHAIN (TYPE_FIELDS (new_obj_rec)))
-	= TREE_TYPE (TREE_TYPE (TYPE_FIELDS (ptr)));
+	= TREE_TYPE (TREE_TYPE (array_field));
       DECL_SIZE (TREE_CHAIN (TYPE_FIELDS (new_obj_rec)))
-	= TYPE_SIZE (TREE_TYPE (TREE_TYPE (TYPE_FIELDS (ptr))));
+	= TYPE_SIZE (TREE_TYPE (TREE_TYPE (array_field)));
       DECL_SIZE_UNIT (TREE_CHAIN (TYPE_FIELDS (new_obj_rec)))
-	= TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (TYPE_FIELDS (ptr))));
+	= TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (array_field)));
 
       TYPE_SIZE (new_obj_rec)
 	= size_binop (PLUS_EXPR,

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