This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH 5/5] Support BIT_FIELD_REF in MPX (PR ipa/79764).
- From: marxin <mliska at suse dot cz>
- To: gcc-patches at gcc dot gnu dot org
- Date: Thu, 2 Mar 2017 17:52:03 +0100
- Subject: [PATCH 5/5] Support BIT_FIELD_REF in MPX (PR ipa/79764).
- Authentication-results: sourceware.org; auth=none
- References: <cover.1488881229.git.mliska@suse.cz>
- Resent-user-agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.7.1
gcc/ChangeLog:
2017-03-06 Martin Liska <mliska@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 <mliska@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..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" } */
+
+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