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]

[patch] Fix maybe_fold_offset_to_component_ref


Hello,

maybe_fold_offset_to_component_ref sometimes forgets to remove offset of
the field (FIELD_OFFSET) from the OFFSET parameter before recursing; concretely in
these cases:

1) FIELD_OFFSET == OFFSET, but field still has aggregate type
   incompatible with the result, so we must recurse.
2) Field is the tail array.

This causes misscompilations together with one of my experimental
patches.

Bootstrapped & regtested on i686.

Zdenek

	* tree-ssa-ccp.c (maybe_fold_offset_to_component_ref): Always subtract
	the offset of the selected field.

Index: tree-ssa-ccp.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-ssa-ccp.c,v
retrieving revision 2.53
diff -c -3 -p -r2.53 tree-ssa-ccp.c
*** tree-ssa-ccp.c	29 Nov 2004 01:15:39 -0000	2.53
--- tree-ssa-ccp.c	19 Jan 2005 09:53:23 -0000
*************** maybe_fold_offset_to_component_ref (tree
*** 1449,1493 ****
  	continue;
  
        field_type = TREE_TYPE (f);
-       if (cmp < 0)
- 	{
- 	  /* Don't care about offsets into the middle of scalars.  */
- 	  if (!AGGREGATE_TYPE_P (field_type))
- 	    continue;
- 
- 	  /* Check for array at the end of the struct.  This is often
- 	     used as for flexible array members.  We should be able to
- 	     turn this into an array access anyway.  */
- 	  if (TREE_CODE (field_type) == ARRAY_TYPE)
- 	    tail_array_field = f;
- 
- 	  /* Check the end of the field against the offset.  */
- 	  if (!DECL_SIZE_UNIT (f)
- 	      || TREE_CODE (DECL_SIZE_UNIT (f)) != INTEGER_CST)
- 	    continue;
- 	  t = int_const_binop (MINUS_EXPR, offset, DECL_FIELD_OFFSET (f), 1);
- 	  if (!tree_int_cst_lt (t, DECL_SIZE_UNIT (f)))
- 	    continue;
- 
- 	  /* If we matched, then set offset to the displacement into
- 	     this field.  */
- 	  offset = t;
- 	}
  
        /* Here we exactly match the offset being checked.  If the types match,
  	 then we can return that field.  */
!       else if (lang_hooks.types_compatible_p (orig_type, field_type))
  	{
  	  if (base_is_ptr)
  	    base = build1 (INDIRECT_REF, record_type, base);
  	  t = build (COMPONENT_REF, field_type, base, f, NULL_TREE);
  	  return t;
  	}
! 
!       /* Don't care about type-punning of scalars.  */
!       else if (!AGGREGATE_TYPE_P (field_type))
! 	return NULL_TREE;
! 
        goto found;
      }
  
--- 1449,1487 ----
  	continue;
  
        field_type = TREE_TYPE (f);
  
        /* Here we exactly match the offset being checked.  If the types match,
  	 then we can return that field.  */
!       if (cmp == 0
! 	  && lang_hooks.types_compatible_p (orig_type, field_type))
  	{
  	  if (base_is_ptr)
  	    base = build1 (INDIRECT_REF, record_type, base);
  	  t = build (COMPONENT_REF, field_type, base, f, NULL_TREE);
  	  return t;
  	}
!       
!       /* Don't care about offsets into the middle of scalars.  */
!       if (!AGGREGATE_TYPE_P (field_type))
! 	continue;
! 
!       /* Check for array at the end of the struct.  This is often
! 	 used as for flexible array members.  We should be able to
! 	 turn this into an array access anyway.  */
!       if (TREE_CODE (field_type) == ARRAY_TYPE)
! 	tail_array_field = f;
! 
!       /* Check the end of the field against the offset.  */
!       if (!DECL_SIZE_UNIT (f)
! 	  || TREE_CODE (DECL_SIZE_UNIT (f)) != INTEGER_CST)
! 	continue;
!       t = int_const_binop (MINUS_EXPR, offset, field_offset, 1);
!       if (!tree_int_cst_lt (t, DECL_SIZE_UNIT (f)))
! 	continue;
! 
!       /* If we matched, then set offset to the displacement into
! 	 this field.  */
!       offset = t;
        goto found;
      }
  
*************** maybe_fold_offset_to_component_ref (tree
*** 1496,1501 ****
--- 1490,1496 ----
  
    f = tail_array_field;
    field_type = TREE_TYPE (f);
+   offset = int_const_binop (MINUS_EXPR, offset, byte_position (f), 1);
  
   found:
    /* If we get here, we've got an aggregate field, and a possibly 


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