re PR sanitizer/81715 (asan-stack=1 redzone allocation is too inflexible)
authorJakub Jelinek <jakub@redhat.com>
Thu, 21 Sep 2017 12:26:34 +0000 (14:26 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Thu, 21 Sep 2017 12:26:34 +0000 (14:26 +0200)
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

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/opt/pr81715.C [new file with mode: 0644]
gcc/testsuite/g++.dg/tree-ssa/pr8781.C
gcc/tree-inline.c

index 736cc7f29f4d7e5374dec5bee3255c5f2ef2c4ea..c743c21f9e8a24e007a29e6ba3fb7a7d047b8e4e 100644 (file)
@@ -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
index 3db0548a8389da996838cb57363fe5b48808a97a..1c241b921daf53ffd82ec5be1ca302079a658ac3 100644 (file)
@@ -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 (file)
index 0000000..c38b22b
--- /dev/null
@@ -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);
+}
index 1f339003adec62dd41662f90a9c131801bbfb967..1f115b2b26d10075bb7358c470c6036eeebe0823 100644 (file)
@@ -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);
 }
 
index cce5dc7b7bcce4fae1bc112362e40b8859c0901d..a226096504f2d3575a6c6ba1a2a24c79e1fbd2db 100644 (file)
@@ -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: