follow SSA defs for asan base

Alexandre Oliva oliva@adacore.com
Thu Jan 21 21:35:48 GMT 2021


Ada makes extensive use of nested functions, which turn all automatic
variables of the enclosing function that are used in nested ones into
members of an artificial FRAME record type.

The address of a local variable is usually passed to asan marking
functions without using a temporary.  Taking the address of a member
of FRAME within a nested function, however, is not regarded as a
gimple val: while introducing FRAME variables, current_function_decl
is always the outermost function, even while processing a nested
function, so decl_address_invariant_p returns false for such
ADDR_EXPRs.  So, as automatic variables are moved into FRAME, any asan
call that marks such a variable has its ADDR_EXPR replaced with a
SSA_NAME set to the ADDR_EXPR of the FRAME member.

asan_expand_mark_ifn was not prepared to deal with ADDR_EXPRs split
out into SSA_NAMEs.  This patch deals with such cases.

[It does NOT deal with PHI nodes and whatnot.  I'm not even sure it
should.  Maybe we want the ADDR_EXPR to be a gimple val instead, but
this more conservative fix felt more appropriate for this stage.]

Regstrapped on x86_64-linux-gnu.  Ok to install?


for  gcc/ChangeLog

	* asan.c (asan_expand_mark_ifn): Follow SSA_NAME defs for
	an ADDR_EXPR base.

for  gcc/testsuite/ChangeLog

	* gcc.dg/asan/nested-1.c: New.
---
 gcc/asan.c                           |   21 +++++++++++++++++++++
 gcc/testsuite/gcc.dg/asan/nested-1.c |   24 ++++++++++++++++++++++++
 2 files changed, 45 insertions(+)
 create mode 100644 gcc/testsuite/gcc.dg/asan/nested-1.c

diff --git a/gcc/asan.c b/gcc/asan.c
index 89ecd99b18294..2d2fb97098b2f 100644
--- a/gcc/asan.c
+++ b/gcc/asan.c
@@ -3629,6 +3629,27 @@ asan_expand_mark_ifn (gimple_stmt_iterator *iter)
   bool is_poison = ((asan_mark_flags)flag) == ASAN_MARK_POISON;
 
   tree base = gimple_call_arg (g, 1);
+  while (TREE_CODE (base) == SSA_NAME)
+    {
+      gimple *def = SSA_NAME_DEF_STMT (base);
+      if (!def)
+	break;
+
+      if (!is_gimple_assign (def))
+	break;
+
+      if (!SINGLE_SSA_TREE_OPERAND (def, SSA_OP_DEF))
+	break;
+
+      if (gimple_num_ops (def) != 2)
+	break;
+
+      if (gimple_expr_code (def) == ADDR_EXPR
+	  || gimple_expr_code (def) == SSA_NAME)
+	base = gimple_assign_rhs1 (def);
+      else
+	break;
+    }
   gcc_checking_assert (TREE_CODE (base) == ADDR_EXPR);
   tree decl = TREE_OPERAND (base, 0);
 
diff --git a/gcc/testsuite/gcc.dg/asan/nested-1.c b/gcc/testsuite/gcc.dg/asan/nested-1.c
new file mode 100644
index 0000000000000..87e842098077c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/asan/nested-1.c
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+/* { dg-options "-fsanitize=address" } */
+
+int f(int i) {
+  auto int h() {
+    int r;
+    int *p;
+
+    {
+      int x[3];
+
+      auto int g() {
+	return x[i];
+      }
+
+      p = &r;
+      *p = g();
+    }
+
+    return *p;
+  }
+
+  return h();
+}


-- 
Alexandre Oliva, happy hacker  https://FSFLA.org/blogs/lxo/
   Free Software Activist         GNU Toolchain Engineer
        Vim, Vi, Voltei pro Emacs -- GNUlius Caesar


More information about the Gcc-patches mailing list