aboutsummaryrefslogtreecommitdiff
path: root/gcc/c-family/c-gimplify.cc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/c-family/c-gimplify.cc')
-rw-r--r--gcc/c-family/c-gimplify.cc28
1 files changed, 28 insertions, 0 deletions
diff --git a/gcc/c-family/c-gimplify.cc b/gcc/c-family/c-gimplify.cc
index c6fb764..e905059 100644
--- a/gcc/c-family/c-gimplify.cc
+++ b/gcc/c-family/c-gimplify.cc
@@ -66,6 +66,20 @@ along with GCC; see the file COPYING3. If not see
walk back up, we check that they fit our constraints, and copy them
into temporaries if not. */
+
+/* Check whether TP is an address computation whose base is a call to
+ .ACCESS_WITH_SIZE. */
+
+static bool
+is_address_with_access_with_size (tree tp)
+{
+ if (TREE_CODE (tp) == POINTER_PLUS_EXPR
+ && (TREE_CODE (TREE_OPERAND (tp, 0)) == INDIRECT_REF)
+ && (is_access_with_size_p (TREE_OPERAND (TREE_OPERAND (tp, 0), 0))))
+ return true;
+ return false;
+}
+
/* Callback for c_genericize. */
static tree
@@ -121,6 +135,20 @@ ubsan_walk_array_refs_r (tree *tp, int *walk_subtrees, void *data)
walk_tree (&TREE_OPERAND (*tp, 1), ubsan_walk_array_refs_r, pset, pset);
walk_tree (&TREE_OPERAND (*tp, 0), ubsan_walk_array_refs_r, pset, pset);
}
+ else if (TREE_CODE (*tp) == INDIRECT_REF
+ && is_address_with_access_with_size (TREE_OPERAND (*tp, 0)))
+ {
+ ubsan_maybe_instrument_array_ref (&TREE_OPERAND (*tp, 0), false);
+ /* Make sure ubsan_maybe_instrument_array_ref is not called again on
+ the POINTER_PLUS_EXPR, so ensure it is not walked again and walk
+ its subtrees manually. */
+ tree aref = TREE_OPERAND (*tp, 0);
+ pset->add (aref);
+ *walk_subtrees = 0;
+ walk_tree (&TREE_OPERAND (aref, 0), ubsan_walk_array_refs_r, pset, pset);
+ }
+ else if (is_address_with_access_with_size (*tp))
+ ubsan_maybe_instrument_array_ref (tp, true);
return NULL_TREE;
}