On 03/07/2017 11:18 AM, Rainer Orth wrote: > marxin <mli...@suse.cz> writes: > >> diff --git a/gcc/testsuite/g++.dg/pr79764.C b/gcc/testsuite/g++.dg/pr79764.C >> new file mode 100644 >> index 00000000000..47fb88da19b >> --- /dev/null >> +++ b/gcc/testsuite/g++.dg/pr79764.C >> @@ -0,0 +1,12 @@ >> +/* { dg-do compile { target { ! x32 } } } */ >> +/* { dg-options "-fcheck-pointer-bounds -mmpx" } */ > > Same here. > > Rainer >
Thanks. I'm sending v2 of the patch. Martin
>From 7c54acbb0a2d36a3d1676533937d78b3e0a40874 Mon Sep 17 00:00:00 2001 From: marxin <mli...@suse.cz> Date: Thu, 2 Mar 2017 17:52:03 +0100 Subject: [PATCH 5/5] Support BIT_FIELD_REF in MPX (PR ipa/79764). gcc/ChangeLog: 2017-03-06 Martin Liska <mli...@suse.cz> PR ipa/79764 * tree-chkp.c (chkp_narrow_bounds_for_field): Fix typo in comment. (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. gcc/testsuite/ChangeLog: 2017-03-06 Martin Liska <mli...@suse.cz> PR ipa/79764 * g++.dg/pr79764.C: New test. --- gcc/testsuite/g++.dg/pr79764.C | 12 ++++++ gcc/tree-chkp.c | 90 ++++++++++++++++++++++++++++++++++-------- 2 files changed, 85 insertions(+), 17 deletions(-) create mode 100644 gcc/testsuite/g++.dg/pr79764.C diff --git a/gcc/testsuite/g++.dg/pr79764.C b/gcc/testsuite/g++.dg/pr79764.C new file mode 100644 index 00000000000..293aa337693 --- /dev/null +++ b/gcc/testsuite/g++.dg/pr79764.C @@ -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]; +} diff --git a/gcc/tree-chkp.c b/gcc/tree-chkp.c index d5683b1b9cf..14ebff294f9 100644 --- a/gcc/tree-chkp.c +++ b/gcc/tree-chkp.c @@ -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)) @@ -3266,7 +3268,7 @@ chkp_intersect_bounds (tree bounds1, tree bounds2, gimple_stmt_iterator *iter) } /* Return 1 if we are allowed to narrow bounds for addressed FIELD - and 0 othersize. */ + and 0 otherwise. */ static bool chkp_may_narrow_to_field (tree field) { @@ -3294,7 +3296,7 @@ chkp_narrow_bounds_for_field (tree field) if (!chkp_may_narrow_to_field (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; @@ -3308,9 +3310,36 @@ chkp_narrow_bounds_for_field (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) @@ -3363,7 +3392,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++; @@ -3382,9 +3412,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 @@ -3453,6 +3484,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. */ ; @@ -3467,6 +3509,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) @@ -3490,6 +3553,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; -- 2.11.1