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][mem-ref2] Recover array-refs during inlining


This fixes the last warning regression.  I'm not 100% sure we want
to do this (we don't do it during forwprop either).

Bootstrapped and tested on x86_64-unknown-linux-gnu, applied.

Richard.

2010-06-22  Richard Guenther  <rguenther@suse.de>

	* gimple.h (maybe_fold_offset_to_reference): Re-export.
	* gimple-fold.c (maybe_fold_offset_to_reference): Re-export.
	Use types_compatible_p for type comparison.
	* tree-inline.c (remap_gimple_op_r): Try to recover array-refs.

	testsuite/
	* gcc.dg/pr36902.c: Adjust.

Index: gcc/gimple.h
===================================================================
*** gcc/gimple.h	(revision 161081)
--- gcc/gimple.h	(working copy)
*************** tree gimple_fold_builtin (gimple);
*** 4806,4811 ****
--- 4806,4813 ----
  bool fold_stmt (gimple_stmt_iterator *);
  bool fold_stmt_inplace (gimple);
  tree maybe_fold_offset_to_address (location_t, tree, tree, tree);
+ tree maybe_fold_offset_to_reference (location_t, tree, tree, tree);
+ 
  tree maybe_fold_stmt_addition (location_t, tree, tree, tree);
  tree get_symbol_constant_value (tree);
  bool may_propagate_address_into_dereference (tree, tree);
Index: gcc/gimple-fold.c
===================================================================
*** gcc/gimple-fold.c	(revision 161081)
--- gcc/gimple-fold.c	(working copy)
*************** maybe_fold_offset_to_array_ref (location
*** 244,250 ****
  
     Before attempting the conversion strip off existing ADDR_EXPRs.  */
  
! static tree
  maybe_fold_offset_to_reference (location_t loc, tree base, tree offset,
  				tree orig_type)
  {
--- 244,250 ----
  
     Before attempting the conversion strip off existing ADDR_EXPRs.  */
  
! tree
  maybe_fold_offset_to_reference (location_t loc, tree base, tree offset,
  				tree orig_type)
  {
*************** maybe_fold_offset_to_reference (location
*** 255,266 ****
      return NULL_TREE;
  
    base = TREE_OPERAND (base, 0);
!   if (useless_type_conversion_p (orig_type, TREE_TYPE (base))
        && integer_zerop (offset))
      return base;
  
    ret = maybe_fold_offset_to_array_ref (loc, base, offset);
!   if (ret && useless_type_conversion_p (orig_type, TREE_TYPE (ret)))
      return ret;
    return NULL_TREE;
  }
--- 255,266 ----
      return NULL_TREE;
  
    base = TREE_OPERAND (base, 0);
!   if (types_compatible_p (orig_type, TREE_TYPE (base))
        && integer_zerop (offset))
      return base;
  
    ret = maybe_fold_offset_to_array_ref (loc, base, offset);
!   if (ret && types_compatible_p (orig_type, TREE_TYPE (ret)))
      return ret;
    return NULL_TREE;
  }
Index: gcc/tree-inline.c
===================================================================
*** gcc/tree-inline.c	(revision 161081)
--- gcc/tree-inline.c	(working copy)
*************** remap_gimple_op_r (tree *tp, int *walk_s
*** 821,829 ****
  	  if (n)
  	    {
  	      tree old = *tp;
! 	      *tp = fold_build2 (MEM_REF, TREE_TYPE (*tp),
! 				 unshare_expr (*n), TREE_OPERAND (*tp, 1));
! 	      TREE_THIS_VOLATILE (*tp) = TREE_THIS_VOLATILE (old);
  	      TREE_NO_WARNING (*tp) = TREE_NO_WARNING (old);
  	      *walk_subtrees = 0;
  	      return NULL;
--- 821,857 ----
  	  if (n)
  	    {
  	      tree old = *tp;
! 	      tree ptr = unshare_expr (*n);
! 	      tree tem;
! 	      if ((tem = maybe_fold_offset_to_reference (EXPR_LOCATION (*tp),
! 							 ptr,
! 							 TREE_OPERAND (*tp, 1),
! 							 TREE_TYPE (*tp)))
! 		  && TREE_THIS_VOLATILE (tem) == TREE_THIS_VOLATILE (old))
! 		{
! 		  tree *tem_basep = &tem;
! 		  while (handled_component_p (*tem_basep))
! 		    tem_basep = &TREE_OPERAND (*tem_basep, 0);
! 		  if (TREE_CODE (*tem_basep) == MEM_REF)
! 		    *tem_basep
! 		      = build2 (MEM_REF, TREE_TYPE (*tem_basep),
! 				TREE_OPERAND (*tem_basep, 0),
! 				fold_convert (TREE_TYPE (TREE_OPERAND (*tp, 1)),
! 					      TREE_OPERAND (*tem_basep, 1)));
! 		  else
! 		    *tem_basep
! 		      = build2 (MEM_REF, TREE_TYPE (*tem_basep),
! 				build_fold_addr_expr (*tem_basep),
! 				build_int_cst
! 				  (TREE_TYPE (TREE_OPERAND (*tp, 1)), 0));
! 		  *tp = tem;
! 		}
! 	      else
! 		{
! 		  *tp = fold_build2 (MEM_REF, TREE_TYPE (*tp),
! 				     ptr, TREE_OPERAND (*tp, 1));
! 		  TREE_THIS_VOLATILE (*tp) = TREE_THIS_VOLATILE (old);
! 		}
  	      TREE_NO_WARNING (*tp) = TREE_NO_WARNING (old);
  	      *walk_subtrees = 0;
  	      return NULL;
Index: gcc/testsuite/gcc.dg/pr36902.c
===================================================================
*** gcc/testsuite/gcc.dg/pr36902.c	(revision 161081)
--- gcc/testsuite/gcc.dg/pr36902.c	(working copy)
*************** foo2(unsigned char * to, const unsigned
*** 44,50 ****
        *to = *from;
        break;
      case 5:
!       to[4] = from [4]; /* { dg-warning "20:array subscript is above array bounds" } */
        break;
      }
    return to;
--- 44,50 ----
        *to = *from;
        break;
      case 5:
!       to[4] = from [4]; /* { dg-warning "array subscript is above array bounds" } */
        break;
      }
    return to;


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