[ifcombine] avoid creating out-of-bounds BIT_FIELD_REFs [PR118514]
If decode_field_reference finds a load that accesses past the inner object's size, bail out. Drop the too-strict assert. for gcc/ChangeLog PR tree-optimization/118514 PR tree-optimization/118706 * gimple-fold.cc (decode_field_reference): Refuse to consider merging out-of-bounds BIT_FIELD_REFs. (make_bit_field_load): Drop too-strict assert. * tree-eh.cc (bit_field_ref_in_bounds_p): Rename to... (access_in_bounds_of_type_p): ... this. Change interface, export. (tree_could_trap_p): Adjust. * tree-eh.h (access_in_bounds_of_type_p): Declare. for gcc/testsuite/ChangeLog PR tree-optimization/118514 PR tree-optimization/118706 * gcc.dg/field-merge-25.c: New.
This commit is contained in:
parent
b5a29a93ee
commit
075ddb5226
4 changed files with 31 additions and 21 deletions
|
@ -7686,10 +7686,8 @@ decode_field_reference (tree *pexp, HOST_WIDE_INT *pbitsize,
|
|||
|| bs <= shiftrt
|
||||
|| offset != 0
|
||||
|| TREE_CODE (inner) == PLACEHOLDER_EXPR
|
||||
/* Reject out-of-bound accesses (PR79731). */
|
||||
|| (! AGGREGATE_TYPE_P (TREE_TYPE (inner))
|
||||
&& compare_tree_int (TYPE_SIZE (TREE_TYPE (inner)),
|
||||
bp + bs) < 0)
|
||||
/* Reject out-of-bound accesses (PR79731, PR118514). */
|
||||
|| !access_in_bounds_of_type_p (TREE_TYPE (inner), bs, bp)
|
||||
|| (INTEGRAL_TYPE_P (TREE_TYPE (inner))
|
||||
&& !type_has_mode_precision_p (TREE_TYPE (inner))))
|
||||
return NULL_TREE;
|
||||
|
@ -7859,11 +7857,6 @@ make_bit_field_load (location_t loc, tree inner, tree orig_inner, tree type,
|
|||
gimple *new_stmt = gsi_stmt (i);
|
||||
if (gimple_has_mem_ops (new_stmt))
|
||||
gimple_set_vuse (new_stmt, reaching_vuse);
|
||||
gcc_checking_assert (! (gimple_assign_load_p (point)
|
||||
&& gimple_assign_load_p (new_stmt))
|
||||
|| (tree_could_trap_p (gimple_assign_rhs1 (point))
|
||||
== tree_could_trap_p (gimple_assign_rhs1
|
||||
(new_stmt))));
|
||||
}
|
||||
|
||||
gimple_stmt_iterator gsi = gsi_for_stmt (point);
|
||||
|
|
15
gcc/testsuite/gcc.dg/field-merge-25.c
Normal file
15
gcc/testsuite/gcc.dg/field-merge-25.c
Normal file
|
@ -0,0 +1,15 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "-O1 -fno-tree-fre" } */
|
||||
|
||||
/* PR tree-optimization/118706 */
|
||||
|
||||
int a[1][1][3], b;
|
||||
int main() {
|
||||
int c = -1;
|
||||
while (b) {
|
||||
if (a[c][c][6])
|
||||
break;
|
||||
if (a[0][0][0])
|
||||
break;
|
||||
}
|
||||
}
|
|
@ -2646,24 +2646,22 @@ range_in_array_bounds_p (tree ref)
|
|||
return true;
|
||||
}
|
||||
|
||||
/* Return true iff EXPR, a BIT_FIELD_REF, accesses a bit range that is known to
|
||||
be in bounds for the referred operand type. */
|
||||
/* Return true iff a BIT_FIELD_REF <(TYPE)???, SIZE, OFFSET> would access a bit
|
||||
range that is known to be in bounds for TYPE. */
|
||||
|
||||
static bool
|
||||
bit_field_ref_in_bounds_p (tree expr)
|
||||
bool
|
||||
access_in_bounds_of_type_p (tree type, poly_uint64 size, poly_uint64 offset)
|
||||
{
|
||||
tree size_tree;
|
||||
poly_uint64 size_max, min, wid, max;
|
||||
tree type_size_tree;
|
||||
poly_uint64 type_size_max, min = offset, wid = size, max;
|
||||
|
||||
size_tree = TYPE_SIZE (TREE_TYPE (TREE_OPERAND (expr, 0)));
|
||||
if (!size_tree || !poly_int_tree_p (size_tree, &size_max))
|
||||
type_size_tree = TYPE_SIZE (type);
|
||||
if (!type_size_tree || !poly_int_tree_p (type_size_tree, &type_size_max))
|
||||
return false;
|
||||
|
||||
min = bit_field_offset (expr);
|
||||
wid = bit_field_size (expr);
|
||||
max = min + wid;
|
||||
if (maybe_lt (max, min)
|
||||
|| maybe_lt (size_max, max))
|
||||
|| maybe_lt (type_size_max, max))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
@ -2712,7 +2710,10 @@ tree_could_trap_p (tree expr)
|
|||
switch (code)
|
||||
{
|
||||
case BIT_FIELD_REF:
|
||||
if (DECL_P (TREE_OPERAND (expr, 0)) && !bit_field_ref_in_bounds_p (expr))
|
||||
if (DECL_P (TREE_OPERAND (expr, 0))
|
||||
&& !access_in_bounds_of_type_p (TREE_TYPE (TREE_OPERAND (expr, 0)),
|
||||
bit_field_size (expr),
|
||||
bit_field_offset (expr)))
|
||||
return true;
|
||||
/* Fall through. */
|
||||
|
||||
|
|
|
@ -36,6 +36,7 @@ extern void redirect_eh_dispatch_edge (geh_dispatch *, edge, basic_block);
|
|||
extern bool operation_could_trap_helper_p (enum tree_code, bool, bool, bool,
|
||||
bool, tree, bool *);
|
||||
extern bool operation_could_trap_p (enum tree_code, bool, bool, tree);
|
||||
extern bool access_in_bounds_of_type_p (tree, poly_uint64, poly_uint64);
|
||||
extern bool tree_could_trap_p (tree);
|
||||
extern tree rewrite_to_non_trapping_overflow (tree);
|
||||
extern bool stmt_could_throw_p (function *, gimple *);
|
||||
|
|
Loading…
Add table
Reference in a new issue