Commit 765b3379 by Jakub Jelinek Committed by Jakub Jelinek

re PR sanitizer/81715 (asan-stack=1 redzone allocation is too inflexible)

	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.  Clear
	id->retval and id->retbnd after inlining.

	* g++.dg/tree-ssa/pr8781.C (noop): Change argument type from
	const predicate to const predicate & to avoid UB.
	* g++.dg/opt/pr81715.C: New test.

From-SVN: r253065
parent c94f2d84
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. Clear
id->retval and id->retbnd after inlining.
2017-09-21 Richard Biener <rguenther@suse.de> 2017-09-21 Richard Biener <rguenther@suse.de>
PR tree-optimization/82276 PR tree-optimization/82276
2017-09-21 Jakub Jelinek <jakub@redhat.com>
PR sanitizer/81715
* g++.dg/tree-ssa/pr8781.C (noop): Change argument type from
const predicate to const predicate & to avoid UB.
* g++.dg/opt/pr81715.C: New test.
2017-09-21 Richard Biener <rguenther@suse.de> 2017-09-21 Richard Biener <rguenther@suse.de>
PR tree-optimization/82276 PR tree-optimization/82276
......
// PR sanitizer/81715
// { dg-do compile }
// Verify the variables for inlined foo parameters are reused
// { dg-options "-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);
}
...@@ -13,7 +13,7 @@ public: ...@@ -13,7 +13,7 @@ public:
}; };
template<typename predicate> template<typename predicate>
inline noop_t<predicate> noop(const predicate pred) { inline noop_t<predicate> noop(const predicate &pred) {
return noop_t<predicate>(pred); return noop_t<predicate>(pred);
} }
......
...@@ -4796,6 +4796,22 @@ expand_call_inline (basic_block bb, gimple *stmt, copy_body_data *id) ...@@ -4796,6 +4796,22 @@ expand_call_inline (basic_block bb, gimple *stmt, copy_body_data *id)
reset_debug_bindings (id, stmt_gsi); reset_debug_bindings (id, stmt_gsi);
if (flag_stack_reuse != SR_NONE)
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. */ /* Reset the escaped solution. */
if (cfun->gimple_df) if (cfun->gimple_df)
pt_solution_reset (&cfun->gimple_df->escaped); pt_solution_reset (&cfun->gimple_df->escaped);
...@@ -4846,6 +4862,23 @@ expand_call_inline (basic_block bb, gimple *stmt, copy_body_data *id) ...@@ -4846,6 +4862,23 @@ expand_call_inline (basic_block bb, gimple *stmt, copy_body_data *id)
stmt = gimple_build_assign (gimple_call_lhs (stmt), use_retvar); stmt = gimple_build_assign (gimple_call_lhs (stmt), use_retvar);
gsi_replace (&stmt_gsi, stmt, false); gsi_replace (&stmt_gsi, stmt, false);
maybe_clean_or_replace_eh_stmt (old_stmt, stmt); maybe_clean_or_replace_eh_stmt (old_stmt, stmt);
/* Append a clobber for id->retvar if easily possible. */
if (flag_stack_reuse != SR_NONE
&& 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. */ /* Copy bounds if we copy structure with bounds. */
if (chkp_function_instrumented_p (id->dst_fn) if (chkp_function_instrumented_p (id->dst_fn)
...@@ -4884,8 +4917,25 @@ expand_call_inline (basic_block bb, gimple *stmt, copy_body_data *id) ...@@ -4884,8 +4917,25 @@ expand_call_inline (basic_block bb, gimple *stmt, copy_body_data *id)
SSA_NAME_DEF_STMT (name) = gimple_build_nop (); SSA_NAME_DEF_STMT (name) = gimple_build_nop ();
} }
} }
/* Replace with a clobber for id->retvar. */
else if (flag_stack_reuse != SR_NONE
&& 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 else
gsi_remove (&stmt_gsi, true); gsi_remove (&stmt_gsi, true);
} }
/* Put returned bounds into the correct place if required. */ /* Put returned bounds into the correct place if required. */
...@@ -4934,6 +4984,8 @@ expand_call_inline (basic_block bb, gimple *stmt, copy_body_data *id) ...@@ -4934,6 +4984,8 @@ expand_call_inline (basic_block bb, gimple *stmt, copy_body_data *id)
cg_edge->callee->remove (); cg_edge->callee->remove ();
id->block = NULL_TREE; id->block = NULL_TREE;
id->retvar = NULL_TREE;
id->retbnd = NULL_TREE;
successfully_inlined = true; successfully_inlined = true;
egress: egress:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment