diff options
author | Jakub Jelinek <jakub@redhat.com> | 2017-09-21 14:26:34 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2017-09-21 14:26:34 +0200 |
commit | 765b3379354e3018b5440693625f8aace232f44a (patch) | |
tree | e299dda2a3c3c6838ec7d26db09180193bb65a36 /gcc | |
parent | c94f2d84e51b39f4f90c3cb3bf3c0d056080bc57 (diff) | |
download | gcc-765b3379354e3018b5440693625f8aace232f44a.zip gcc-765b3379354e3018b5440693625f8aace232f44a.tar.gz gcc-765b3379354e3018b5440693625f8aace232f44a.tar.bz2 |
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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/opt/pr81715.C | 36 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/tree-ssa/pr8781.C | 2 | ||||
-rw-r--r-- | gcc/tree-inline.c | 54 |
5 files changed, 105 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 736cc7f..c743c21 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +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> PR tree-optimization/82276 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 3db0548..1c241b9 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +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> PR tree-optimization/82276 diff --git a/gcc/testsuite/g++.dg/opt/pr81715.C b/gcc/testsuite/g++.dg/opt/pr81715.C new file mode 100644 index 0000000..c38b22b --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/pr81715.C @@ -0,0 +1,36 @@ +// 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); +} diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr8781.C b/gcc/testsuite/g++.dg/tree-ssa/pr8781.C index 1f33900..1f115b2 100644 --- a/gcc/testsuite/g++.dg/tree-ssa/pr8781.C +++ b/gcc/testsuite/g++.dg/tree-ssa/pr8781.C @@ -13,7 +13,7 @@ public: }; template<typename predicate> -inline noop_t<predicate> noop(const predicate pred) { +inline noop_t<predicate> noop(const predicate &pred) { return noop_t<predicate>(pred); } diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c index cce5dc7..a226096 100644 --- a/gcc/tree-inline.c +++ b/gcc/tree-inline.c @@ -4796,6 +4796,22 @@ expand_call_inline (basic_block bb, gimple *stmt, copy_body_data *id) 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. */ if (cfun->gimple_df) pt_solution_reset (&cfun->gimple_df->escaped); @@ -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); 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 + && 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) @@ -4884,8 +4917,25 @@ 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 + && 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. */ @@ -4934,6 +4984,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: |