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 type correctness of fold_indirect_ref


This patch fixes type correctness issues in fold_indirect_ref as
suggested by Roger.

Bootstrapped and tested on x86_64-unknown-linux-gnu for C and C++
with no regressions apart from

FAIL: g++.dg/opt/temp1.C execution test

which is an optimization test supposed to be performed by
gimplify_modify_expr_rhs:

      case INDIRECT_REF:
        {
          /* If we have code like

                *(const A*)(A*)&x

             where the type of "x" is a (possibly cv-qualified variant
             of "A"), treat the entire expression as identical to "x".
             This kind of code arises in C++ when an object is bound
             to a const reference, and if "x" is a TARGET_EXPR we want
             to take advantage of the optimization below.  */
          tree t = fold_indirect_ref (*from_p);
          if (t != *from_p)
            {
              *from_p = t;
              ret = GS_OK;
            }
          else
            ret = GS_UNHANDLED;
          break;
        }

but the changed fold_indirect_ref is not able to perform the required
transformation.  I agree with Roger that this may be a candidate for
a routine with less strict type requirements.


Ok for mainline?

Thanks,
Richard.
2005-05-15  Richard Guenther  <rguenth@gcc.gnu.org>

	* fold-const.c (fold_indirect_ref_1): Add type argument;
	make sure the resulting expression is of this type.
	(build_fold_indirect_ref, fold_indirect_ref): Adjust callers.


Index: fold-const.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/fold-const.c,v
retrieving revision 1.580
diff -c -3 -p -r1.580 fold-const.c
*** fold-const.c	14 May 2005 15:42:01 -0000	1.580
--- fold-const.c	15 May 2005 17:29:30 -0000
*************** build_fold_addr_expr (tree t)
*** 11396,11409 ****
    return build_fold_addr_expr_with_type (t, build_pointer_type (TREE_TYPE (t)));
  }
  
! /* Given a pointer value T, return a simplified version of an indirection
!    through T, or NULL_TREE if no simplification is possible.  */
  
  static tree
! fold_indirect_ref_1 (tree t)
  {
!   tree type = TREE_TYPE (TREE_TYPE (t));
!   tree sub = t;
    tree subtype;
  
    STRIP_NOPS (sub);
--- 11396,11409 ----
    return build_fold_addr_expr_with_type (t, build_pointer_type (TREE_TYPE (t)));
  }
  
! /* Given a pointer value OP0 and a type TYPE, return a simplified version
!    of an indirection through OP0, or NULL_TREE if no simplification is
!    possible.  */
  
  static tree
! fold_indirect_ref_1 (tree type, tree op0)
  {
!   tree sub = op0;
    tree subtype;
  
    STRIP_NOPS (sub);
*************** fold_indirect_ref_1 (tree t)
*** 11416,11426 ****
        tree op = TREE_OPERAND (sub, 0);
        tree optype = TREE_TYPE (op);
        /* *&p => p */
!       if (lang_hooks.types_compatible_p (type, optype))
  	return op;
        /* *(foo *)&fooarray => fooarray[0] */
        else if (TREE_CODE (optype) == ARRAY_TYPE
! 	       && lang_hooks.types_compatible_p (type, TREE_TYPE (optype)))
  	{
  	  tree type_domain = TYPE_DOMAIN (optype);
  	  tree min_val = size_zero_node;
--- 11416,11426 ----
        tree op = TREE_OPERAND (sub, 0);
        tree optype = TREE_TYPE (op);
        /* *&p => p */
!       if (type == optype)
  	return op;
        /* *(foo *)&fooarray => fooarray[0] */
        else if (TREE_CODE (optype) == ARRAY_TYPE
! 	       && type == TREE_TYPE (optype))
  	{
  	  tree type_domain = TYPE_DOMAIN (optype);
  	  tree min_val = size_zero_node;
*************** fold_indirect_ref_1 (tree t)
*** 11432,11438 ****
  
    /* *(foo *)fooarrptr => (*fooarrptr)[0] */
    if (TREE_CODE (TREE_TYPE (subtype)) == ARRAY_TYPE
!       && lang_hooks.types_compatible_p (type, TREE_TYPE (TREE_TYPE (subtype))))
      {
        tree type_domain;
        tree min_val = size_zero_node;
--- 11432,11438 ----
  
    /* *(foo *)fooarrptr => (*fooarrptr)[0] */
    if (TREE_CODE (TREE_TYPE (subtype)) == ARRAY_TYPE
!       && type == TREE_TYPE (TREE_TYPE (subtype)))
      {
        tree type_domain;
        tree min_val = size_zero_node;
*************** fold_indirect_ref_1 (tree t)
*** 11452,11463 ****
  tree
  build_fold_indirect_ref (tree t)
  {
!   tree sub = fold_indirect_ref_1 (t);
  
    if (sub)
      return sub;
    else
!     return build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (t)), t);
  }
  
  /* Given an INDIRECT_REF T, return either T or a simplified version.  */
--- 11452,11464 ----
  tree
  build_fold_indirect_ref (tree t)
  {
!   tree type = TREE_TYPE (TREE_TYPE (t));
!   tree sub = fold_indirect_ref_1 (type, t);
  
    if (sub)
      return sub;
    else
!     return build1 (INDIRECT_REF, type, t);
  }
  
  /* Given an INDIRECT_REF T, return either T or a simplified version.  */
*************** build_fold_indirect_ref (tree t)
*** 11465,11471 ****
  tree
  fold_indirect_ref (tree t)
  {
!   tree sub = fold_indirect_ref_1 (TREE_OPERAND (t, 0));
  
    if (sub)
      return sub;
--- 11466,11472 ----
  tree
  fold_indirect_ref (tree t)
  {
!   tree sub = fold_indirect_ref_1 (TREE_TYPE (t), TREE_OPERAND (t, 0));
  
    if (sub)
      return sub;

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