summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/asan/pr81715.C36
-rw-r--r--gcc/tree-inline.c57
4 files changed, 106 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 92a961cd0f6..7fc6aaeaa33 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,6 +1,15 @@
2017-10-27 Jakub Jelinek <jakub@redhat.com>
Backported from mainline
+ 2017-09-21 Jakub Jelinek <jakub@redhat.com>
+
+ PR sanitizer/81715
+ * tree-inline.c (expand_call_inline): Emit clobber stmts for
+ VAR_DECLs to which addressable non-volatile parameters are mapped
+ and for id->retvar after the return value assignment, though
+ for -fsanitize=kernel-address only. Clear id->retval and id->retbnd
+ after inlining.
+
2017-09-18 Jakub Jelinek <jakub@redhat.com>
PR c/82234
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 150a09e7d74..4a37df1dca7 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,6 +1,11 @@
2017-10-27 Jakub Jelinek <jakub@redhat.com>
Backported from mainline
+ 2017-09-21 Jakub Jelinek <jakub@redhat.com>
+
+ PR sanitizer/81715
+ * g++.dg/asan/pr81715.C: New test.
+
2017-09-15 Jakub Jelinek <jakub@redhat.com>
PR rtl-optimization/82192
diff --git a/gcc/testsuite/g++.dg/asan/pr81715.C b/gcc/testsuite/g++.dg/asan/pr81715.C
new file mode 100644
index 00000000000..b492706a46a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/asan/pr81715.C
@@ -0,0 +1,36 @@
+// PR sanitizer/81715
+// { dg-do compile }
+// Verify the variables for inlined foo parameters are reused
+// { dg-options "-fno-sanitize=address -fsanitize=kernel-address -O2 -Wframe-larger-than=16384" }
+
+struct S { int a, b, c, d, e; char f[1024]; };
+void baz (int *, int *, int *, struct S *, int *, int *);
+
+static inline struct S
+foo (int a, int b, int c, struct S d, int e, int f)
+{
+ struct S s;
+ baz (&a, &b, &c, &d, &e, &f);
+ s = d;
+ return s;
+}
+
+struct S g[64];
+
+void
+bar (int a, int b, int c, struct S d, int e, int f)
+{
+#define A(N) \
+ g[N+0] = foo (a, b, c, d, e, f); \
+ g[N+1] = foo (a, b, c, d, e, f); \
+ g[N+2] = foo (a, b, c, d, e, f); \
+ g[N+3] = foo (a, b, c, d, e, f); \
+ g[N+4] = foo (a, b, c, d, e, f); \
+ g[N+5] = foo (a, b, c, d, e, f); \
+ g[N+6] = foo (a, b, c, d, e, f); \
+ g[N+7] = foo (a, b, c, d, e, f); \
+ foo (a, b, c, d, e, f); \
+ foo (a, b, c, d, e, f)
+ A(0); A(8); A(16); A(24);
+ A(32); A(40); A(48); A(56);
+}
diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
index bfaaede0c32..f56d09e1bdb 100644
--- a/gcc/tree-inline.c
+++ b/gcc/tree-inline.c
@@ -4752,6 +4752,23 @@ expand_call_inline (basic_block bb, gimple *stmt, copy_body_data *id)
reset_debug_bindings (id, stmt_gsi);
+ if (flag_stack_reuse != SR_NONE
+ && (flag_sanitize & SANITIZE_KERNEL_ADDRESS) != 0)
+ for (tree p = DECL_ARGUMENTS (id->src_fn); p; p = DECL_CHAIN (p))
+ if (!TREE_THIS_VOLATILE (p))
+ {
+ tree *varp = id->decl_map->get (p);
+ if (varp && VAR_P (*varp) && !is_gimple_reg (*varp))
+ {
+ tree clobber = build_constructor (TREE_TYPE (*varp), NULL);
+ gimple *clobber_stmt;
+ TREE_THIS_VOLATILE (clobber) = 1;
+ clobber_stmt = gimple_build_assign (*varp, clobber);
+ gimple_set_location (clobber_stmt, gimple_location (stmt));
+ gsi_insert_before (&stmt_gsi, clobber_stmt, GSI_SAME_STMT);
+ }
+ }
+
/* Reset the escaped solution. */
if (cfun->gimple_df)
pt_solution_reset (&cfun->gimple_df->escaped);
@@ -4802,6 +4819,24 @@ expand_call_inline (basic_block bb, gimple *stmt, copy_body_data *id)
stmt = gimple_build_assign (gimple_call_lhs (stmt), use_retvar);
gsi_replace (&stmt_gsi, stmt, false);
maybe_clean_or_replace_eh_stmt (old_stmt, stmt);
+ /* Append a clobber for id->retvar if easily possible. */
+ if (flag_stack_reuse != SR_NONE
+ && (flag_sanitize & SANITIZE_KERNEL_ADDRESS) != 0
+ && id->retvar
+ && VAR_P (id->retvar)
+ && id->retvar != return_slot
+ && id->retvar != modify_dest
+ && !TREE_THIS_VOLATILE (id->retvar)
+ && !is_gimple_reg (id->retvar)
+ && !stmt_ends_bb_p (stmt))
+ {
+ tree clobber = build_constructor (TREE_TYPE (id->retvar), NULL);
+ gimple *clobber_stmt;
+ TREE_THIS_VOLATILE (clobber) = 1;
+ clobber_stmt = gimple_build_assign (id->retvar, clobber);
+ gimple_set_location (clobber_stmt, gimple_location (old_stmt));
+ gsi_insert_after (&stmt_gsi, clobber_stmt, GSI_SAME_STMT);
+ }
/* Copy bounds if we copy structure with bounds. */
if (chkp_function_instrumented_p (id->dst_fn)
@@ -4840,8 +4875,26 @@ expand_call_inline (basic_block bb, gimple *stmt, copy_body_data *id)
SSA_NAME_DEF_STMT (name) = gimple_build_nop ();
}
}
+ /* Replace with a clobber for id->retvar. */
+ else if (flag_stack_reuse != SR_NONE
+ && (flag_sanitize & SANITIZE_KERNEL_ADDRESS) != 0
+ && id->retvar
+ && VAR_P (id->retvar)
+ && id->retvar != return_slot
+ && id->retvar != modify_dest
+ && !TREE_THIS_VOLATILE (id->retvar)
+ && !is_gimple_reg (id->retvar))
+ {
+ tree clobber = build_constructor (TREE_TYPE (id->retvar), NULL);
+ gimple *clobber_stmt;
+ TREE_THIS_VOLATILE (clobber) = 1;
+ clobber_stmt = gimple_build_assign (id->retvar, clobber);
+ gimple_set_location (clobber_stmt, gimple_location (stmt));
+ gsi_replace (&stmt_gsi, clobber_stmt, false);
+ maybe_clean_or_replace_eh_stmt (stmt, clobber_stmt);
+ }
else
- gsi_remove (&stmt_gsi, true);
+ gsi_remove (&stmt_gsi, true);
}
/* Put returned bounds into the correct place if required. */
@@ -4890,6 +4943,8 @@ expand_call_inline (basic_block bb, gimple *stmt, copy_body_data *id)
cg_edge->callee->remove ();
id->block = NULL_TREE;
+ id->retvar = NULL_TREE;
+ id->retbnd = NULL_TREE;
successfully_inlined = true;
egress: