This introduces a ptrofftype_p function to replace sizetype compatibility
checks throughout the compiler (of there are not too many).

Bootstrapped and tested on x86_64-unknonw-linux-gnu some time ago,
currently re-testing.

Patch 3/n will (finally) introduce "real" ptrofftype and uptrofftype.

Richard.

2011-08-16  Richard Guenther  <rguent...@suse.de>

        * tree.h (ptrofftype_p): New helper function.
        * tree-cfg.c (verify_expr): Use ptrofftype_p for POINTER_PLUS_EXPR
        offset verification.
        (verify_gimple_assign_binary): Likewise.
        * tree.c (build2_stat): Likewise.
        * tree-chrec.c (chrec_fold_plus_poly_poly): Likewise.
        (reset_evolution_in_loop): Likewise.
        * tree-chrec.h (build_polynomial_chrec): Likewise.

Index: trunk/gcc/tree-cfg.c
===================================================================
*** trunk.orig/gcc/tree-cfg.c   2011-07-19 14:08:55.000000000 +0200
--- trunk/gcc/tree-cfg.c        2011-07-19 16:06:23.000000000 +0200
*************** verify_expr (tree *tp, int *walk_subtree
*** 2845,2857 ****
          error ("invalid operand to pointer plus, first operand is not a 
pointer");
          return t;
        }
!       /* Check to make sure the second operand is an integer with type of
!        sizetype.  */
!       if (!useless_type_conversion_p (sizetype,
!                                    TREE_TYPE (TREE_OPERAND (t, 1))))
        {
          error ("invalid operand to pointer plus, second operand is not an "
!                "integer with type of sizetype");
          return t;
        }
        /* FALLTHROUGH */
--- 2845,2855 ----
          error ("invalid operand to pointer plus, first operand is not a 
pointer");
          return t;
        }
!       /* Check to make sure the second operand is a ptrofftype.  */
!       if (!ptrofftype_p (TREE_TYPE (TREE_OPERAND (t, 1))))
        {
          error ("invalid operand to pointer plus, second operand is not an "
!                "integer type of appropriate width");
          return t;
        }
        /* FALLTHROUGH */
*************** verify_gimple_assign_binary (gimple stmt
*** 3596,3602 ****
  do_pointer_plus_expr_check:
        if (!POINTER_TYPE_P (rhs1_type)
            || !useless_type_conversion_p (lhs_type, rhs1_type)
!           || !useless_type_conversion_p (sizetype, rhs2_type))
          {
            error ("type mismatch in pointer plus expression");
            debug_generic_stmt (lhs_type);
--- 3594,3600 ----
  do_pointer_plus_expr_check:
        if (!POINTER_TYPE_P (rhs1_type)
            || !useless_type_conversion_p (lhs_type, rhs1_type)
!           || !ptrofftype_p (rhs2_type))
          {
            error ("type mismatch in pointer plus expression");
            debug_generic_stmt (lhs_type);
Index: trunk/gcc/tree.c
===================================================================
*** trunk.orig/gcc/tree.c       2011-07-19 15:57:25.000000000 +0200
--- trunk/gcc/tree.c    2011-07-19 16:13:04.000000000 +0200
*************** build2_stat (enum tree_code code, tree t
*** 3780,3787 ****
  
    if (code == POINTER_PLUS_EXPR && arg0 && arg1 && tt)
      gcc_assert (POINTER_TYPE_P (tt) && POINTER_TYPE_P (TREE_TYPE (arg0))
!               && INTEGRAL_TYPE_P (TREE_TYPE (arg1))
!               && useless_type_conversion_p (sizetype, TREE_TYPE (arg1)));
  
    t = make_node_stat (code PASS_MEM_STAT);
    TREE_TYPE (t) = tt;
--- 3780,3786 ----
  
    if (code == POINTER_PLUS_EXPR && arg0 && arg1 && tt)
      gcc_assert (POINTER_TYPE_P (tt) && POINTER_TYPE_P (TREE_TYPE (arg0))
!               && ptrofftype_p (TREE_TYPE (arg1)));
  
    t = make_node_stat (code PASS_MEM_STAT);
    TREE_TYPE (t) = tt;
Index: trunk/gcc/tree-chrec.c
===================================================================
*** trunk.orig/gcc/tree-chrec.c 2011-07-11 17:02:51.000000000 +0200
--- trunk/gcc/tree-chrec.c      2011-07-19 16:24:42.000000000 +0200
*************** chrec_fold_plus_poly_poly (enum tree_cod
*** 95,108 ****
    tree left, right;
    struct loop *loop0 = get_chrec_loop (poly0);
    struct loop *loop1 = get_chrec_loop (poly1);
!   tree rtype = code == POINTER_PLUS_EXPR ? sizetype : type;
  
    gcc_assert (poly0);
    gcc_assert (poly1);
    gcc_assert (TREE_CODE (poly0) == POLYNOMIAL_CHREC);
    gcc_assert (TREE_CODE (poly1) == POLYNOMIAL_CHREC);
    if (POINTER_TYPE_P (chrec_type (poly0)))
!     gcc_assert (chrec_type (poly1) == sizetype);
    else
      gcc_assert (chrec_type (poly0) == chrec_type (poly1));
    gcc_assert (type == chrec_type (poly0));
--- 95,108 ----
    tree left, right;
    struct loop *loop0 = get_chrec_loop (poly0);
    struct loop *loop1 = get_chrec_loop (poly1);
!   tree rtype = code == POINTER_PLUS_EXPR ? chrec_type (poly1) : type;
  
    gcc_assert (poly0);
    gcc_assert (poly1);
    gcc_assert (TREE_CODE (poly0) == POLYNOMIAL_CHREC);
    gcc_assert (TREE_CODE (poly1) == POLYNOMIAL_CHREC);
    if (POINTER_TYPE_P (chrec_type (poly0)))
!     gcc_assert (ptrofftype_p (chrec_type (poly1)));
    else
      gcc_assert (chrec_type (poly0) == chrec_type (poly1));
    gcc_assert (type == chrec_type (poly0));
*************** reset_evolution_in_loop (unsigned loop_n
*** 831,837 ****
    struct loop *loop = get_loop (loop_num);
  
    if (POINTER_TYPE_P (chrec_type (chrec)))
!     gcc_assert (sizetype == chrec_type (new_evol));
    else
      gcc_assert (chrec_type (chrec) == chrec_type (new_evol));
  
--- 831,837 ----
    struct loop *loop = get_loop (loop_num);
  
    if (POINTER_TYPE_P (chrec_type (chrec)))
!     gcc_assert (ptrofftype_p (chrec_type (new_evol)));
    else
      gcc_assert (chrec_type (chrec) == chrec_type (new_evol));
  
Index: trunk/gcc/tree-chrec.h
===================================================================
*** trunk.orig/gcc/tree-chrec.h 2011-07-11 12:57:40.000000000 +0200
--- trunk/gcc/tree-chrec.h      2011-07-19 16:11:55.000000000 +0200
*************** build_polynomial_chrec (unsigned loop_nu
*** 145,151 ****
  
    /* Types of left and right sides of a chrec should be compatible.  */
    if (POINTER_TYPE_P (TREE_TYPE (left)))
!     gcc_assert (sizetype == TREE_TYPE (right));
    else
      gcc_assert (TREE_TYPE (left) == TREE_TYPE (right));
  
--- 145,151 ----
  
    /* Types of left and right sides of a chrec should be compatible.  */
    if (POINTER_TYPE_P (TREE_TYPE (left)))
!     gcc_assert (ptrofftype_p (TREE_TYPE (right)));
    else
      gcc_assert (TREE_TYPE (left) == TREE_TYPE (right));
  
Index: trunk/gcc/tree.h
===================================================================
*** trunk.orig/gcc/tree.h       2011-07-19 16:02:24.000000000 +0200
--- trunk/gcc/tree.h    2011-07-19 16:08:17.000000000 +0200
*************** truth_value_p (enum tree_code code)
*** 5305,5310 ****
--- 5305,5320 ----
          || code == TRUTH_XOR_EXPR || code == TRUTH_NOT_EXPR);
  }
  
+ /* Return whether TYPE is a type suitable for an offset for
+    a POINTER_PLUS_EXPR.  */
+ static inline bool
+ ptrofftype_p (tree type)
+ {
+   return (INTEGRAL_TYPE_P (type)
+         && TYPE_PRECISION (type) == TYPE_PRECISION (sizetype)
+         && TYPE_UNSIGNED (type) == TYPE_UNSIGNED (sizetype));
+ }
+ 
  /* Build and fold a POINTER_PLUS_EXPR at LOC offsetting PTR by OFF.  */
  static inline tree
  fold_build_pointer_plus_loc (location_t loc, tree ptr, tree off)

Reply via email to