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]

fix array_ref_element_size and friends


These functions use size_binop to compute their values.  Except that
the value here may not be sizetype, which leads to an abort.

It'll not be sizetype in the case that there is a value in a type the
same size and signedness as sizetype, but is not actually sizetype.
The cast to sizetype will be eliminated as useless.  Which, given that
the value involved is provably unchanged seems totally reasonable as
far as the optimizers are concerned.

Yet Another Reason why these routines should not be doing any computation
at all, but I didn't have the patience to change that just yet.

This triggered with a Fortran front-end change I have queued.
Tested on i686, alpha, and amd64 linux.


r~


        * expr.c (array_ref_element_size): Force aligned_size back to
        sizetype.
        (component_ref_field_offset): Similarly for aligned_offset.
        * tree.c (recompute_tree_invarant_for_addr_expr): Mark raw
        low-bound, element-size, field-offset fields rather than
        computed values.

Index: expr.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/expr.c,v
retrieving revision 1.712
diff -c -p -d -r1.712 expr.c
*** expr.c	30 Aug 2004 18:34:32 -0000	1.712
--- expr.c	30 Aug 2004 21:36:13 -0000
*************** array_ref_element_size (tree exp)
*** 5481,5488 ****
    /* If a size was specified in the ARRAY_REF, it's the size measured
       in alignment units of the element type.  So multiply by that value.  */
    if (aligned_size)
!     return size_binop (MULT_EXPR, aligned_size,
! 		       size_int (TYPE_ALIGN (elmt_type) / BITS_PER_UNIT));
  
    /* Otherwise, take the size from that of the element type.  Substitute
       any PLACEHOLDER_EXPR that we have.  */
--- 5481,5494 ----
    /* If a size was specified in the ARRAY_REF, it's the size measured
       in alignment units of the element type.  So multiply by that value.  */
    if (aligned_size)
!     {
!       /* ??? tree_ssa_useless_type_conversion will eliminate casts to
! 	 sizetype from another type of the same width and signedness.  */
!       if (TREE_TYPE (aligned_size) != sizetype)
! 	aligned_size = fold_convert (sizetype, aligned_size);
!       return size_binop (MULT_EXPR, aligned_size,
! 		         size_int (TYPE_ALIGN (elmt_type) / BITS_PER_UNIT));
!     }
  
    /* Otherwise, take the size from that of the element type.  Substitute
       any PLACEHOLDER_EXPR that we have.  */
*************** component_ref_field_offset (tree exp)
*** 5541,5548 ****
       in units of DECL_OFFSET_ALIGN / BITS_PER_UNIT.  So multiply by that
       value.  */
    if (aligned_offset)
!     return size_binop (MULT_EXPR, aligned_offset,
! 		       size_int (DECL_OFFSET_ALIGN (field) / BITS_PER_UNIT));
  
    /* Otherwise, take the offset from that of the field.  Substitute
       any PLACEHOLDER_EXPR that we have.  */
--- 5547,5560 ----
       in units of DECL_OFFSET_ALIGN / BITS_PER_UNIT.  So multiply by that
       value.  */
    if (aligned_offset)
!     {
!       /* ??? tree_ssa_useless_type_conversion will eliminate casts to
! 	 sizetype from another type of the same width and signedness.  */
!       if (TREE_TYPE (aligned_offset) != sizetype)
! 	aligned_offset = fold_convert (sizetype, aligned_offset);
!       return size_binop (MULT_EXPR, aligned_offset,
! 		         size_int (DECL_OFFSET_ALIGN (field) / BITS_PER_UNIT));
!     }
  
    /* Otherwise, take the offset from that of the field.  Substitute
       any PLACEHOLDER_EXPR that we have.  */
Index: tree.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree.c,v
retrieving revision 1.417
diff -c -p -d -r1.417 tree.c
*** tree.c	27 Aug 2004 00:55:38 -0000	1.417
--- tree.c	30 Aug 2004 21:36:14 -0000
*************** do { tree _node = (NODE); \
*** 2252,2266 ****
  	  && TREE_CODE (TREE_TYPE (TREE_OPERAND (node, 0))) == ARRAY_TYPE)
  	{
  	  UPDATE_TITCSE (TREE_OPERAND (node, 1));
! 	  UPDATE_TITCSE (array_ref_low_bound (node));
! 	  UPDATE_TITCSE (array_ref_element_size (node));
  	}
        /* Likewise, just because this is a COMPONENT_REF doesn't mean we have a
  	 FIELD_DECL, apparently.  The G++ front end can put something else
  	 there, at least temporarily.  */
        else if (TREE_CODE (node) == COMPONENT_REF
  	       && TREE_CODE (TREE_OPERAND (node, 1)) == FIELD_DECL)
! 	UPDATE_TITCSE (component_ref_field_offset (node));
        else if (TREE_CODE (node) == BIT_FIELD_REF)
  	UPDATE_TITCSE (TREE_OPERAND (node, 2));
      }
--- 2252,2271 ----
  	  && TREE_CODE (TREE_TYPE (TREE_OPERAND (node, 0))) == ARRAY_TYPE)
  	{
  	  UPDATE_TITCSE (TREE_OPERAND (node, 1));
! 	  if (TREE_OPERAND (node, 2))
! 	    UPDATE_TITCSE (TREE_OPERAND (node, 2));
! 	  if (TREE_OPERAND (node, 3))
! 	    UPDATE_TITCSE (TREE_OPERAND (node, 3));
  	}
        /* Likewise, just because this is a COMPONENT_REF doesn't mean we have a
  	 FIELD_DECL, apparently.  The G++ front end can put something else
  	 there, at least temporarily.  */
        else if (TREE_CODE (node) == COMPONENT_REF
  	       && TREE_CODE (TREE_OPERAND (node, 1)) == FIELD_DECL)
! 	{
! 	  if (TREE_OPERAND (node, 2))
! 	    UPDATE_TITCSE (TREE_OPERAND (node, 2));
! 	}
        else if (TREE_CODE (node) == BIT_FIELD_REF)
  	UPDATE_TITCSE (TREE_OPERAND (node, 2));
      }


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