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)