diff options
Diffstat (limited to 'gcc/tree-eh.c')
-rw-r--r-- | gcc/tree-eh.c | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/gcc/tree-eh.c b/gcc/tree-eh.c index a91542d56aa..a489b61c3f2 100644 --- a/gcc/tree-eh.c +++ b/gcc/tree-eh.c @@ -2506,6 +2506,68 @@ operation_could_trap_p (enum tree_code op, bool fp_operation, bool honor_trapv, &handled); } + +/* Returns true if it is possible to prove that the index of + an array access REF (an ARRAY_REF expression) falls into the + array bounds. */ + +static bool +in_array_bounds_p (tree ref) +{ + tree idx = TREE_OPERAND (ref, 1); + tree min, max; + + if (TREE_CODE (idx) != INTEGER_CST) + return false; + + min = array_ref_low_bound (ref); + max = array_ref_up_bound (ref); + if (!min + || !max + || TREE_CODE (min) != INTEGER_CST + || TREE_CODE (max) != INTEGER_CST) + return false; + + if (tree_int_cst_lt (idx, min) + || tree_int_cst_lt (max, idx)) + return false; + + return true; +} + +/* Returns true if it is possible to prove that the range of + an array access REF (an ARRAY_RANGE_REF expression) falls + into the array bounds. */ + +static bool +range_in_array_bounds_p (tree ref) +{ + tree domain_type = TYPE_DOMAIN (TREE_TYPE (ref)); + tree range_min, range_max, min, max; + + range_min = TYPE_MIN_VALUE (domain_type); + range_max = TYPE_MAX_VALUE (domain_type); + if (!range_min + || !range_max + || TREE_CODE (range_min) != INTEGER_CST + || TREE_CODE (range_max) != INTEGER_CST) + return false; + + min = array_ref_low_bound (ref); + max = array_ref_up_bound (ref); + if (!min + || !max + || TREE_CODE (min) != INTEGER_CST + || TREE_CODE (max) != INTEGER_CST) + return false; + + if (tree_int_cst_lt (range_min, min) + || tree_int_cst_lt (max, range_max)) + return false; + + return true; +} + /* Return true if EXPR can trap, as in dereferencing an invalid pointer location or floating point arithmetic. C.f. the rtl version, may_trap_p. This routine expects only GIMPLE lhs or rhs input. */ |