aboutsummaryrefslogtreecommitdiff
path: root/gcc/c-family/c-gimplify.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/c-family/c-gimplify.c')
-rw-r--r--gcc/c-family/c-gimplify.c53
1 files changed, 48 insertions, 5 deletions
diff --git a/gcc/c-family/c-gimplify.c b/gcc/c-family/c-gimplify.c
index 737be4d..c797d99 100644
--- a/gcc/c-family/c-gimplify.c
+++ b/gcc/c-family/c-gimplify.c
@@ -45,6 +45,8 @@ along with GCC; see the file COPYING3. If not see
#include "c-pretty-print.h"
#include "cgraph.h"
#include "cilk.h"
+#include "c-ubsan.h"
+#include "pointer-set.h"
/* The gimplification pass converts the language-dependent trees
(ld-trees) emitted by the parser into language-independent trees
@@ -67,6 +69,39 @@ 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. */
+/* Callback for c_genericize. */
+
+static tree
+ubsan_walk_array_refs_r (tree *tp, int *walk_subtrees, void *data)
+{
+ struct pointer_set_t *pset = (struct pointer_set_t *) data;
+
+ /* Since walk_tree doesn't call the callback function on the decls
+ in BIND_EXPR_VARS, we have to walk them manually. */
+ if (TREE_CODE (*tp) == BIND_EXPR)
+ {
+ for (tree decl = BIND_EXPR_VARS (*tp); decl; decl = DECL_CHAIN (decl))
+ {
+ if (TREE_STATIC (decl))
+ {
+ *walk_subtrees = 0;
+ continue;
+ }
+ walk_tree (&DECL_INITIAL (decl), ubsan_walk_array_refs_r, pset,
+ pset);
+ walk_tree (&DECL_SIZE (decl), ubsan_walk_array_refs_r, pset, pset);
+ walk_tree (&DECL_SIZE_UNIT (decl), ubsan_walk_array_refs_r, pset,
+ pset);
+ }
+ }
+ else if (TREE_CODE (*tp) == ADDR_EXPR
+ && TREE_CODE (TREE_OPERAND (*tp, 0)) == ARRAY_REF)
+ ubsan_maybe_instrument_array_ref (&TREE_OPERAND (*tp, 0), true);
+ else if (TREE_CODE (*tp) == ARRAY_REF)
+ ubsan_maybe_instrument_array_ref (tp, false);
+ return NULL_TREE;
+}
+
/* Gimplification of statement trees. */
/* Convert the tree representation of FNDECL from C frontend trees to
@@ -79,6 +114,14 @@ c_genericize (tree fndecl)
int local_dump_flags;
struct cgraph_node *cgn;
+ if (flag_sanitize & SANITIZE_BOUNDS)
+ {
+ struct pointer_set_t *pset = pointer_set_create ();
+ walk_tree (&DECL_SAVED_TREE (fndecl), ubsan_walk_array_refs_r, pset,
+ pset);
+ pointer_set_destroy (pset);
+ }
+
/* Dump the C-specific tree IR. */
dump_orig = dump_begin (TDI_original, &local_dump_flags);
if (dump_orig)
@@ -207,16 +250,16 @@ c_gimplify_expr (tree *expr_p, gimple_seq *pre_p ATTRIBUTE_UNUSED,
}
break;
}
-
+
case CILK_SPAWN_STMT:
- gcc_assert
- (fn_contains_cilk_spawn_p (cfun)
+ gcc_assert
+ (fn_contains_cilk_spawn_p (cfun)
&& cilk_detect_spawn_and_unwrap (expr_p));
-
+
/* If errors are seen, then just process it as a CALL_EXPR. */
if (!seen_error ())
return (enum gimplify_status) gimplify_cilk_spawn (expr_p);
-
+
case MODIFY_EXPR:
case INIT_EXPR:
case CALL_EXPR: