c: introduce ubsan checking for assigment of VM types 3/4
Support instrumentation of function arguments for functions
called via a declaration. We can support only simple size
expressions without side effects, because the UBSan
instrumentation is done before the call, but the expressions
are evaluated in the callee.
gcc/c-family:
* c-ubsan.cc (ubsan_instrument_vm_assign): Add arguments
for size expressions.
* c-ubsan.h (ubsan_instrument_vm_assign): Dito.
gcc/c:
* c-typeck.cc (process_vm_constraints): Add support
for instrumenting function arguments.
gcc/testsuide/gcc.dg:
* ubsan/vm-bounds-2.c: Update.
* ubsan/vm-bounds-3.c: New test.
* ubsan/vm-bounds-4.c: New test.
diff --git a/gcc/c-family/c-ubsan.cc b/gcc/c-family/c-ubsan.cc
index 59ef9708188..a8f95aa39e8 100644
--- a/gcc/c-family/c-ubsan.cc
+++ b/gcc/c-family/c-ubsan.cc
@@ -337,19 +337,13 @@ ubsan_instrument_vla (location_t loc, tree size)
/* Instrument assignment of variably modified types. */
tree
-ubsan_instrument_vm_assign (location_t loc, tree a, tree b)
+ubsan_instrument_vm_assign (location_t loc, tree a, tree as, tree b, tree bs)
{
tree t, tt;
gcc_assert (TREE_CODE (a) == ARRAY_TYPE);
gcc_assert (TREE_CODE (b) == ARRAY_TYPE);
- tree as = TYPE_MAX_VALUE (TYPE_DOMAIN (a));
- tree bs = TYPE_MAX_VALUE (TYPE_DOMAIN (b));
-
- as = fold_build2 (PLUS_EXPR, sizetype, as, size_one_node);
- bs = fold_build2 (PLUS_EXPR, sizetype, bs, size_one_node);
-
t = build2 (NE_EXPR, boolean_type_node, as, bs);
if (flag_sanitize_trap & SANITIZE_VLA)
tt = build_call_expr_loc (loc, builtin_decl_explicit (BUILT_IN_TRAP), 0);
diff --git a/gcc/c-family/c-ubsan.h b/gcc/c-family/c-ubsan.h
index 1b07b0645f2..42be1d691a8 100644
--- a/gcc/c-family/c-ubsan.h
+++ b/gcc/c-family/c-ubsan.h
@@ -26,7 +26,7 @@ extern tree ubsan_instrument_shift (location_t, enum
tree_code, tree, tree);
extern tree ubsan_instrument_vla (location_t, tree);
extern tree ubsan_instrument_return (location_t);
extern tree ubsan_instrument_bounds (location_t, tree, tree *, bool);
-extern tree ubsan_instrument_vm_assign (location_t, tree, tree);
+extern tree ubsan_instrument_vm_assign (location_t, tree, tree, tree, tree);
extern bool ubsan_array_ref_instrumented_p (const_tree);
extern void ubsan_maybe_instrument_array_ref (tree *, bool);
extern void ubsan_maybe_instrument_reference (tree *);
diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc
index a8fccc6f6ed..aeddac315fc 100644
--- a/gcc/c/c-typeck.cc
+++ b/gcc/c/c-typeck.cc
@@ -3408,7 +3408,8 @@ static tree
convert_argument (location_t ploc, tree function, tree fundecl,
tree type, tree origtype, tree val, tree valtype,
bool npc, tree rname, int parmnum, int argnum,
- bool excess_precision, int warnopt)
+ bool excess_precision, int warnopt,
+ vec *instr_vec)
{
/* Formal parm type is specified by a function prototype. */
@@ -3567,7 +3568,7 @@ convert_argument (location_t ploc, tree function, tree
fundecl,
val, origtype, ic_argpass,
npc, fundecl, function,
parmnum + 1, warnopt,
- NULL);
+ instr_vec);
if (targetm.calls.promote_prototypes (fundecl ? TREE_TYPE (fundecl) : 0)
&& INTEGRAL_TYPE_P (type)
@@ -3582,15 +3583,111 @@ convert_argument (location_t ploc, tree function, tree
fundecl,
static tree
process_vm_constraints (location_t location,
- vec *instr_vec)
+ vec *instr_vec,
+ tree function, tree fundecl, vec *values)
{
unsigned int i;
struct instrument_data* d;
tree instr_expr = void_node;
+ tree args = NULL;
+
+ /* Find the arguments for the function declaration / type. */
+ if (function)
+{
+ if (FUNCTION_DECL == TREE_CODE (function))
+ {
+ fundecl = function;
+ args = DECL_ARGUMENTS (fundecl);
+ }
+ else
+ {
+ /* Functions called via pointers are not yet supported. */
+ return void_node;
+ }
+}
FOR_EACH_VEC_SAFE_ELT (instr_vec, i, d)
{
- tree in = ubsan_instrument_vm_assign (location, d->t1, d->t2);
+ tree t1 = d->t1;
+ tree t2 = d->t2;
+
+ gcc_assert (ARRAY_TYPE == TREE_CODE (t1));
+ gcc_assert (ARRAY_TYPE == TREE_CODE (t2));
+
+ tree as = TYPE_MAX_VALUE (TYPE_DOMAIN (t1));
+ tree bs = TYPE_MAX_VALUE (TYPE_DOMAIN (t2));
+
+ gcc_assert (as);
+ gcc_assert (bs);
+
+ as = fold_build2 (PLUS_EXPR, sizetype, as, size_one_node);
+ bs = fold_build2 (PLUS_EXPR, sizetype, bs, size_one_node);
+
+