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]

Re: [PATCH][1/n] No longer sign-extend sizetype constants, remove TYPE_IS_SIZETYPE


> Well.  I suppose fixing that negative DECL_FIELD_OFFSET thing should
> be #1 priority.

Tentative patch attached (you need an up-to-date tree).  We cannot really get 
rid of the negative offsets for thin pointers, so the patch pulls them out of 
record types and uses pointer arithmetics instead.


        * gcc-interface/gigi.h (shift_unc_components_for_thin_pointers): Kill.
        * gcc-interface/decl.c (gnat_to_gnu_entity) <E_Array_Type>: Remove call
        to above function.
        * gcc-interface/trans.c (Attribute_to_gnu) <Attr_Pool_Address>: Adjust
        handling of thin pointers.
        <Attr_Descriptor_Size>: Likewise.
        (gnat_to_gnu) <N_Free_Statement>: Likewise.
        * gcc-interface/utils.c (shift_unc_components_for_thin_pointers): Kill.
        (convert_to_fat_pointer): Adjust handling of thin pointers.
        (convert) <POINTER_TYPE>: Likewise.
        * gcc-interface/utils2.c (build_unary_op) <INDIRECT_REF>: Likewise.


-- 
Eric Botcazou
Index: gcc-interface/utils.c
===================================================================
--- gcc-interface/utils.c	(revision 185132)
+++ gcc-interface/utils.c	(working copy)
@@ -3411,27 +3411,6 @@ build_unc_object_type_from_ptr (tree thi
   return
     build_unc_object_type (template_type, object_type, name, debug_info_p);
 }
-
-/* Shift the component offsets within an unconstrained object TYPE to make it
-   suitable for use as a designated type for thin pointers.  */
-
-void
-shift_unc_components_for_thin_pointers (tree type)
-{
-  /* Thin pointer values designate the ARRAY data of an unconstrained object,
-     allocated past the BOUNDS template.  The designated type is adjusted to
-     have ARRAY at position zero and the template at a negative offset, so
-     that COMPONENT_REFs on (*thin_ptr) designate the proper location.  */
-
-  tree bounds_field = TYPE_FIELDS (type);
-  tree array_field  = DECL_CHAIN (TYPE_FIELDS (type));
-
-  DECL_FIELD_OFFSET (bounds_field)
-    = size_binop (MINUS_EXPR, size_zero_node, byte_position (array_field));
-
-  DECL_FIELD_OFFSET (array_field) = size_zero_node;
-  DECL_FIELD_BIT_OFFSET (array_field) = bitsize_zero_node;
-}
 
 /* Update anything previously pointing to OLD_TYPE to point to NEW_TYPE.
    In the normal case this is just two adjustments, but we have more to
@@ -3616,7 +3595,18 @@ convert_to_fat_pointer (tree type, tree
       if (TREE_CODE (expr) == ADDR_EXPR)
 	expr = TREE_OPERAND (expr, 0);
       else
-	expr = build1 (INDIRECT_REF, TREE_TYPE (etype), expr);
+	{
+	  /* If we have a TYPE_UNCONSTRAINED_ARRAY attached to the RECORD_TYPE,
+	     the thin pointer value has been shifted so we first need to shift
+	     it back to get the template address.  */
+	  if (TYPE_UNCONSTRAINED_ARRAY (TREE_TYPE (etype)))
+	    expr
+	      = build_binary_op (POINTER_PLUS_EXPR, etype, expr,
+				 fold_build1 (NEGATE_EXPR, sizetype,
+					      byte_position
+					      (DECL_CHAIN (field))));
+	  expr = build1 (INDIRECT_REF, TREE_TYPE (etype), expr);
+	}
 
       template_tree = build_component_ref (expr, NULL_TREE, field, false);
       expr = build_unary_op (ADDR_EXPR, NULL_TREE,
@@ -4103,12 +4093,19 @@ convert (tree type, tree expr)
     case POINTER_TYPE:
     case REFERENCE_TYPE:
       /* If converting between two thin pointers, adjust if needed to account
-	 for any differing offsets, since one of them might be negative.  */
+	 for differing offsets from the base pointer, depending on whether
+	 there is a TYPE_UNCONSTRAINED_ARRAY attached to the record type.  */
       if (TYPE_IS_THIN_POINTER_P (etype) && TYPE_IS_THIN_POINTER_P (type))
 	{
-	  tree byte_diff
-	    = size_diffop (byte_position (TYPE_FIELDS (TREE_TYPE (etype))),
-			   byte_position (TYPE_FIELDS (TREE_TYPE (type))));
+	  tree etype_pos
+	    = TYPE_UNCONSTRAINED_ARRAY (TREE_TYPE (etype)) != NULL_TREE
+	      ? byte_position (DECL_CHAIN (TYPE_FIELDS (TREE_TYPE (etype))))
+	      : size_zero_node;
+	  tree type_pos
+	    = TYPE_UNCONSTRAINED_ARRAY (TREE_TYPE (type)) != NULL_TREE
+	      ? byte_position (DECL_CHAIN (TYPE_FIELDS (TREE_TYPE (type))))
+	      : size_zero_node;
+	  tree byte_diff = size_diffop (type_pos, etype_pos);
 
 	  expr = build1 (NOP_EXPR, type, expr);
 	  if (integer_zerop (byte_diff))
Index: gcc-interface/decl.c
===================================================================
--- gcc-interface/decl.c	(revision 185130)
+++ gcc-interface/decl.c	(working copy)
@@ -2280,13 +2280,14 @@ gnat_to_gnu_entity (Entity_Id gnat_entit
 			  gnu_fat_type, NULL, !Comes_From_Source (gnat_entity),
 			  debug_info_p, gnat_entity);
 
-	/* Create the type to be used as what a thin pointer designates:
-	   a record type for the object and its template with the fields
-	   shifted to have the template at a negative offset.  */
+	/* Create the type to be designated by thin pointers: a record type for
+	   the array and its template.  We used to shift the fields to have the
+	   template at a negative offset, but this was somewhat of a kludge; we
+	   now shift thin pointer values explicitly but only those which have a
+	   TYPE_UNCONSTRAINED_ARRAY attached to the designated RECORD_TYPE.  */
 	tem = build_unc_object_type (gnu_template_type, tem,
 				     create_concat_name (gnat_name, "XUT"),
 				     debug_info_p);
-	shift_unc_components_for_thin_pointers (tem);
 
 	SET_TYPE_UNCONSTRAINED_ARRAY (tem, gnu_type);
 	TYPE_OBJECT_RECORD_TYPE (gnu_type) = tem;
Index: gcc-interface/utils2.c
===================================================================
--- gcc-interface/utils2.c	(revision 185132)
+++ gcc-interface/utils2.c	(working copy)
@@ -1396,9 +1396,8 @@ build_unary_op (enum tree_code op_code,
 	    tree rec_type = TREE_TYPE (type);
 
 	    if (TREE_CODE (operand) == POINTER_PLUS_EXPR
-		&& integer_zerop
-		   (size_binop (PLUS_EXPR, TREE_OPERAND (operand, 1),
-				byte_position (TYPE_FIELDS (rec_type))))
+		&& TREE_OPERAND (operand, 1)
+		   == byte_position (DECL_CHAIN (TYPE_FIELDS (rec_type)))
 		&& TREE_CODE (TREE_OPERAND (operand, 0)) == NOP_EXPR)
 	      {
 		operand = TREE_OPERAND (TREE_OPERAND (operand, 0), 0);
Index: gcc-interface/gigi.h
===================================================================
--- gcc-interface/gigi.h	(revision 185130)
+++ gcc-interface/gigi.h	(working copy)
@@ -736,10 +736,6 @@ extern tree build_unc_object_type_from_p
 					    tree object_type, tree name,
 					    bool debug_info_p);
 
-/* Shift the component offsets within an unconstrained object TYPE to make it
-   suitable for use as a designated type for thin pointers.  */
-extern void shift_unc_components_for_thin_pointers (tree type);
-
 /* Update anything previously pointing to OLD_TYPE to point to NEW_TYPE.  In
    the normal case this is just two adjustments, but we have more to do
    if NEW is an UNCONSTRAINED_ARRAY_TYPE.  */
Index: gcc-interface/trans.c
===================================================================
--- gcc-interface/trans.c	(revision 185132)
+++ gcc-interface/trans.c	(working copy)
@@ -1439,7 +1439,10 @@ Attribute_to_gnu (Node_Id gnat_node, tre
 	  gnu_ptr
 	    = build_binary_op (POINTER_PLUS_EXPR, TREE_TYPE (gnu_ptr),
 			       gnu_ptr,
-			       byte_position (TYPE_FIELDS (gnu_obj_type)));
+			       fold_build1 (NEGATE_EXPR, sizetype,
+					    byte_position
+					    (DECL_CHAIN
+					     TYPE_FIELDS ((gnu_obj_type)))));
 
 	gnu_result = convert (gnu_result_type, gnu_ptr);
       }
@@ -1950,12 +1953,10 @@ Attribute_to_gnu (Node_Id gnat_node, tre
       gnu_type = TREE_TYPE (gnu_prefix);
       gcc_assert (TREE_CODE (gnu_type) == UNCONSTRAINED_ARRAY_TYPE);
 
-      /* What we want is the offset of the ARRAY field in the record that the
-        thin pointer designates, but the components have been shifted so this
-        is actually the opposite of the offset of the BOUNDS field.  */
+      /* What we want is the offset of the ARRAY field in the record
+	 that the thin pointer designates.  */
       gnu_type = TYPE_OBJECT_RECORD_TYPE (gnu_type);
-      gnu_result = size_binop (MINUS_EXPR, bitsize_zero_node,
-                               bit_position (TYPE_FIELDS (gnu_type)));
+      gnu_result = bit_position (DECL_CHAIN (TYPE_FIELDS (gnu_type)));
       gnu_result_type = get_unpadded_type (Etype (gnat_node));
       prefix_unused = true;
       break;
@@ -6622,7 +6623,10 @@ gnat_to_gnu (Node_Id gnat_node)
 	    gnu_ptr
 	      = build_binary_op (POINTER_PLUS_EXPR, TREE_TYPE (gnu_ptr),
 				 gnu_ptr,
-				 byte_position (TYPE_FIELDS (gnu_obj_type)));
+				 fold_build1 (NEGATE_EXPR, sizetype,
+					      byte_position
+					      (DECL_CHAIN
+					       TYPE_FIELDS ((gnu_obj_type)))));
 
 	  /* If we have a special dynamic constrained subtype on the node, use
 	     it to compute the size; otherwise, use the designated subtype.  */

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