Support BIT_FIELD_REF in MPX (PR ipa/79764).
2017-03-09 Martin Liska <mliska@suse.cz> PR ipa/79764 (chkp_narrow_size_and_offset): New function. (chkp_parse_array_and_component_ref): Support BIT_FIELD_REF. (void chkp_parse_bit_field_ref): New function. (chkp_make_addressed_object_bounds): Add case for BIT_FIELD_REF. (chkp_process_stmt): Use chkp_parse_bit_field_ref. 2017-03-09 Martin Liska <mliska@suse.cz> PR ipa/79764 * g++.dg/pr79764.C: New test. From-SVN: r245994
This commit is contained in:
parent
8dc19053e1
commit
a278b1c38f
|
@ -1,3 +1,12 @@
|
|||
2017-03-09 Martin Liska <mliska@suse.cz>
|
||||
|
||||
PR ipa/79764
|
||||
(chkp_narrow_size_and_offset): New function.
|
||||
(chkp_parse_array_and_component_ref): Support BIT_FIELD_REF.
|
||||
(void chkp_parse_bit_field_ref): New function.
|
||||
(chkp_make_addressed_object_bounds): Add case for BIT_FIELD_REF.
|
||||
(chkp_process_stmt): Use chkp_parse_bit_field_ref.
|
||||
|
||||
2017-03-09 Martin Liska <mliska@suse.cz>
|
||||
|
||||
PR ipa/79761
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
2017-03-09 Martin Liska <mliska@suse.cz>
|
||||
|
||||
PR ipa/79764
|
||||
* g++.dg/pr79764.C: New test.
|
||||
|
||||
2017-03-09 Martin Liska <mliska@suse.cz>
|
||||
|
||||
PR ipa/79761
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
/* { dg-do compile { target { { i?86-*-* x86_64-*-* } && { ! x32 } } } } */
|
||||
/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
|
||||
|
||||
typedef float __m256 __attribute__ (( __vector_size__(32), __may_alias__ ));
|
||||
struct A {
|
||||
__m256 ymm;
|
||||
const float &f() const;
|
||||
};
|
||||
|
||||
const float &A::f() const {
|
||||
return ymm[1];
|
||||
}
|
|
@ -325,6 +325,8 @@ static void chkp_parse_array_and_component_ref (tree node, tree *ptr,
|
|||
tree *bounds,
|
||||
gimple_stmt_iterator *iter,
|
||||
bool innermost_bounds);
|
||||
static void chkp_parse_bit_field_ref (tree node, location_t loc,
|
||||
tree *offset, tree *size);
|
||||
|
||||
#define chkp_bndldx_fndecl \
|
||||
(targetm.builtin_chkp_function (BUILT_IN_CHKP_BNDLDX))
|
||||
|
@ -3295,7 +3297,7 @@ chkp_narrow_bounds_for_field (tree ref, tree field)
|
|||
if (!chkp_may_narrow_to_field (ref, field))
|
||||
return false;
|
||||
|
||||
/* Accesse to compiler generated fields should not cause
|
||||
/* Access to compiler generated fields should not cause
|
||||
bounds narrowing. */
|
||||
if (DECL_ARTIFICIAL (field))
|
||||
return false;
|
||||
|
@ -3309,9 +3311,36 @@ chkp_narrow_bounds_for_field (tree ref, tree field)
|
|||
|| bit_offs));
|
||||
}
|
||||
|
||||
/* Perform narrowing for BOUNDS of an INNER reference. Shift boundary
|
||||
by OFFSET bytes and limit to SIZE bytes. Newly created statements are
|
||||
added to ITER. */
|
||||
|
||||
static tree
|
||||
chkp_narrow_size_and_offset (tree bounds, tree inner, tree offset,
|
||||
tree size, gimple_stmt_iterator *iter)
|
||||
{
|
||||
tree addr = chkp_build_addr_expr (unshare_expr (inner));
|
||||
tree t = TREE_TYPE (addr);
|
||||
|
||||
gimple *stmt = gimple_build_assign (NULL_TREE, addr);
|
||||
addr = make_temp_ssa_name (t, stmt, CHKP_BOUND_TMP_NAME);
|
||||
gimple_assign_set_lhs (stmt, addr);
|
||||
gsi_insert_seq_before (iter, stmt, GSI_SAME_STMT);
|
||||
|
||||
stmt = gimple_build_assign (NULL_TREE, POINTER_PLUS_EXPR, addr, offset);
|
||||
tree shifted = make_temp_ssa_name (t, stmt, CHKP_BOUND_TMP_NAME);
|
||||
gimple_assign_set_lhs (stmt, shifted);
|
||||
gsi_insert_seq_before (iter, stmt, GSI_SAME_STMT);
|
||||
|
||||
tree bounds2 = chkp_make_bounds (shifted, size, iter, false);
|
||||
|
||||
return chkp_intersect_bounds (bounds, bounds2, iter);
|
||||
}
|
||||
|
||||
/* Perform narrowing for BOUNDS using bounds computed for field
|
||||
access COMPONENT. ITER meaning is the same as for
|
||||
chkp_intersect_bounds. */
|
||||
|
||||
static tree
|
||||
chkp_narrow_bounds_to_field (tree bounds, tree component,
|
||||
gimple_stmt_iterator *iter)
|
||||
|
@ -3364,7 +3393,8 @@ chkp_parse_array_and_component_ref (tree node, tree *ptr,
|
|||
len = 1;
|
||||
while (TREE_CODE (var) == COMPONENT_REF
|
||||
|| TREE_CODE (var) == ARRAY_REF
|
||||
|| TREE_CODE (var) == VIEW_CONVERT_EXPR)
|
||||
|| TREE_CODE (var) == VIEW_CONVERT_EXPR
|
||||
|| TREE_CODE (var) == BIT_FIELD_REF)
|
||||
{
|
||||
var = TREE_OPERAND (var, 0);
|
||||
len++;
|
||||
|
@ -3383,9 +3413,10 @@ chkp_parse_array_and_component_ref (tree node, tree *ptr,
|
|||
if (bounds)
|
||||
*bounds = NULL;
|
||||
*safe = true;
|
||||
*bitfield = (TREE_CODE (node) == COMPONENT_REF
|
||||
&& DECL_BIT_FIELD_TYPE (TREE_OPERAND (node, 1)));
|
||||
/* To get bitfield address we will need outer elemnt. */
|
||||
*bitfield = ((TREE_CODE (node) == COMPONENT_REF
|
||||
&& DECL_BIT_FIELD_TYPE (TREE_OPERAND (node, 1)))
|
||||
|| TREE_CODE (node) == BIT_FIELD_REF);
|
||||
/* To get bitfield address we will need outer element. */
|
||||
if (*bitfield)
|
||||
*elt = nodes[len - 2];
|
||||
else
|
||||
|
@ -3455,6 +3486,17 @@ chkp_parse_array_and_component_ref (tree node, tree *ptr,
|
|||
comp_to_narrow = NULL;
|
||||
}
|
||||
}
|
||||
else if (TREE_CODE (var) == BIT_FIELD_REF)
|
||||
{
|
||||
if (flag_chkp_narrow_bounds && bounds)
|
||||
{
|
||||
tree offset, size;
|
||||
chkp_parse_bit_field_ref (var, UNKNOWN_LOCATION, &offset, &size);
|
||||
*bounds
|
||||
= chkp_narrow_size_and_offset (*bounds, TREE_OPERAND (var, 0),
|
||||
offset, size, iter);
|
||||
}
|
||||
}
|
||||
else if (TREE_CODE (var) == VIEW_CONVERT_EXPR)
|
||||
/* Nothing to do for it. */
|
||||
;
|
||||
|
@ -3469,6 +3511,27 @@ chkp_parse_array_and_component_ref (tree node, tree *ptr,
|
|||
*bounds = chkp_find_bounds (*ptr, iter);
|
||||
}
|
||||
|
||||
/* Parse BIT_FIELD_REF to a NODE for a given location LOC. Return OFFSET
|
||||
and SIZE in bytes. */
|
||||
|
||||
static
|
||||
void chkp_parse_bit_field_ref (tree node, location_t loc, tree *offset,
|
||||
tree *size)
|
||||
{
|
||||
tree bpu = fold_convert (size_type_node, bitsize_int (BITS_PER_UNIT));
|
||||
tree offs = fold_convert (size_type_node, TREE_OPERAND (node, 2));
|
||||
tree rem = size_binop_loc (loc, TRUNC_MOD_EXPR, offs, bpu);
|
||||
offs = size_binop_loc (loc, TRUNC_DIV_EXPR, offs, bpu);
|
||||
|
||||
tree s = fold_convert (size_type_node, TREE_OPERAND (node, 1));
|
||||
s = size_binop_loc (loc, PLUS_EXPR, s, rem);
|
||||
s = size_binop_loc (loc, CEIL_DIV_EXPR, s, bpu);
|
||||
s = fold_convert (size_type_node, s);
|
||||
|
||||
*offset = offs;
|
||||
*size = s;
|
||||
}
|
||||
|
||||
/* Compute and return bounds for address of OBJ. */
|
||||
static tree
|
||||
chkp_make_addressed_object_bounds (tree obj, gimple_stmt_iterator *iter)
|
||||
|
@ -3492,6 +3555,7 @@ chkp_make_addressed_object_bounds (tree obj, gimple_stmt_iterator *iter)
|
|||
|
||||
case ARRAY_REF:
|
||||
case COMPONENT_REF:
|
||||
case BIT_FIELD_REF:
|
||||
{
|
||||
tree elt;
|
||||
tree ptr;
|
||||
|
@ -3993,23 +4057,15 @@ chkp_process_stmt (gimple_stmt_iterator *iter, tree node,
|
|||
|
||||
case BIT_FIELD_REF:
|
||||
{
|
||||
tree offs, rem, bpu;
|
||||
tree offset, size;
|
||||
|
||||
gcc_assert (!access_offs);
|
||||
gcc_assert (!access_size);
|
||||
|
||||
bpu = fold_convert (size_type_node, bitsize_int (BITS_PER_UNIT));
|
||||
offs = fold_convert (size_type_node, TREE_OPERAND (node, 2));
|
||||
rem = size_binop_loc (loc, TRUNC_MOD_EXPR, offs, bpu);
|
||||
offs = size_binop_loc (loc, TRUNC_DIV_EXPR, offs, bpu);
|
||||
|
||||
size = fold_convert (size_type_node, TREE_OPERAND (node, 1));
|
||||
size = size_binop_loc (loc, PLUS_EXPR, size, rem);
|
||||
size = size_binop_loc (loc, CEIL_DIV_EXPR, size, bpu);
|
||||
size = fold_convert (size_type_node, size);
|
||||
chkp_parse_bit_field_ref (node, loc, &offset, &size);
|
||||
|
||||
chkp_process_stmt (iter, TREE_OPERAND (node, 0), loc,
|
||||
dirflag, offs, size, safe);
|
||||
dirflag, offset, size, safe);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
|
Loading…
Reference in New Issue