Hello.

While reading and trying to understand sanopt code, I've noticed that we can 
possibly
optimize out a ASAN_CHECK when there's a BB in between DOM(BB) and BB which can
call a freeing function.

Ready to be installed after it survives regression tests?
Martin
>From d8ed43c1f8e29cfe63ebd7c40a76715c9c644522 Mon Sep 17 00:00:00 2001
From: marxin <mli...@suse.cz>
Date: Tue, 25 Oct 2016 13:29:47 +0200
Subject: [PATCH] Fix not caught use-after-scope with -O1 (PR sanitize/78106)

gcc/ChangeLog:

2016-10-25  Martin Liska  <mli...@suse.cz>

	PR sanitizer/78106
	* sanopt.c (imm_dom_path_with_freeing_call): Handle gasm
	statements as they can also contain possibly a freeing call.

gcc/testsuite/ChangeLog:

2016-10-25  Martin Liska  <mli...@suse.cz>

	PR sanitizer/78106
	* gcc.dg/asan/pr78106.c: New test.
---
 gcc/sanopt.c                        |  6 +++++-
 gcc/testsuite/gcc.dg/asan/pr78106.c | 34 ++++++++++++++++++++++++++++++++++
 2 files changed, 39 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/gcc.dg/asan/pr78106.c

diff --git a/gcc/sanopt.c b/gcc/sanopt.c
index 27c43da..8a6fbe9 100644
--- a/gcc/sanopt.c
+++ b/gcc/sanopt.c
@@ -211,8 +211,12 @@ imm_dom_path_with_freeing_call (basic_block bb, basic_block dom)
       for (gsi = gsi_start_bb (e->src); !gsi_end_p (gsi); gsi_next (&gsi))
 	{
 	  gimple *stmt = gsi_stmt (gsi);
+	  gasm *asm_stmt;
 
-	  if (is_gimple_call (stmt) && !nonfreeing_call_p (stmt))
+	  if ((is_gimple_call (stmt) && !nonfreeing_call_p (stmt))
+	      || ((asm_stmt = dyn_cast <gasm *> (stmt))
+		  && (gimple_asm_clobbers_memory_p (asm_stmt)
+		      || gimple_asm_volatile_p (asm_stmt))))
 	    {
 	      pred_info->has_freeing_call_p = true;
 	      break;
diff --git a/gcc/testsuite/gcc.dg/asan/pr78106.c b/gcc/testsuite/gcc.dg/asan/pr78106.c
new file mode 100644
index 0000000..7c0e05e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/asan/pr78106.c
@@ -0,0 +1,34 @@
+/* PR sanitizer/78106 */
+/* { dg-do run } */
+/* { dg-options "-fsanitize=address" } */
+/* { dg-shouldfail "asan" } */
+
+int *variable;
+
+void __attribute__((used)) release()
+{
+  __builtin_free (variable);
+}
+
+int main2(int argc)
+{
+  *variable = 2;
+
+  if (argc <= 5)
+    asm volatile ("call release");
+
+  *variable = 2;
+  __builtin_abort ();
+
+  return 0;
+}
+
+int main(int argc, char **argv)
+{
+  variable = __builtin_malloc (sizeof(int));
+  return main2(argc);
+}
+
+/* { dg-output "ERROR: AddressSanitizer:? heap-use-after-free on address.*(\n|\r\n|\r)" } */
+/* { dg-output "WRITE of size 4 at.*" } */
+/* { dg-output "    #0 0x\[0-9a-f\]+ +in _*main2 .*" } */
-- 
2.10.1

Reply via email to