re PR sanitizer/63316 (False asan positive)
authorJakub Jelinek <jakub@redhat.com>
Wed, 24 Sep 2014 09:14:17 +0000 (11:14 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Wed, 24 Sep 2014 09:14:17 +0000 (11:14 +0200)
PR sanitizer/63316
* asan.c (asan_expand_check_ifn): Fix up align >= 8 optimization.

* c-c++-common/asan/pr63316.c: New test.

From-SVN: r215547

gcc/ChangeLog
gcc/asan.c
gcc/testsuite/ChangeLog
gcc/testsuite/c-c++-common/asan/pr63316.c [new file with mode: 0644]

index d5f1b1b..ec34528 100644 (file)
@@ -1,3 +1,8 @@
+2014-09-24  Jakub Jelinek  <jakub@redhat.com>
+
+       PR sanitizer/63316
+       * asan.c (asan_expand_check_ifn): Fix up align >= 8 optimization.
+
 2014-09-24  Thomas Preud'homme  <thomas.preudhomme@arm.com>
 
        PR tree-optimization/63266
index 6917950..fef4b73 100644 (file)
@@ -2585,19 +2585,26 @@ asan_expand_check_ifn (gimple_stmt_iterator *iter, bool use_calls)
          gimple shadow_test = build_assign (NE_EXPR, shadow, 0);
          gimple_seq seq = NULL;
          gimple_seq_add_stmt (&seq, shadow_test);
-         /* Aligned (>= 8 bytes) access do not need & 7.  */
+         /* Aligned (>= 8 bytes) can test just
+            (real_size_in_bytes - 1 >= shadow), as base_addr & 7 is known
+            to be 0.  */
          if (align < 8)
-           gimple_seq_add_stmt (&seq, build_assign (BIT_AND_EXPR,
-                                                    base_addr, 7));
-         gimple_seq_add_stmt (&seq, build_type_cast (shadow_type,
-                                                     gimple_seq_last (seq)));
-         if (real_size_in_bytes > 1)
-           gimple_seq_add_stmt (&seq,
-                                build_assign (PLUS_EXPR, gimple_seq_last (seq),
-                                              real_size_in_bytes - 1));
-         gimple_seq_add_stmt (&seq, build_assign (GE_EXPR,
+           {
+             gimple_seq_add_stmt (&seq, build_assign (BIT_AND_EXPR,
+                                                      base_addr, 7));
+             gimple_seq_add_stmt (&seq,
+                                  build_type_cast (shadow_type,
+                                                   gimple_seq_last (seq)));
+             if (real_size_in_bytes > 1)
+               gimple_seq_add_stmt (&seq,
+                                    build_assign (PLUS_EXPR,
                                                   gimple_seq_last (seq),
-                                                  shadow));
+                                                  real_size_in_bytes - 1));
+             t = gimple_assign_lhs (gimple_seq_last_stmt (seq));
+           }
+         else
+           t = build_int_cst (shadow_type, real_size_in_bytes - 1);
+         gimple_seq_add_stmt (&seq, build_assign (GE_EXPR, t, shadow));
          gimple_seq_add_stmt (&seq, build_assign (BIT_AND_EXPR, shadow_test,
                                                   gimple_seq_last (seq)));
          t = gimple_assign_lhs (gimple_seq_last (seq));
index 69d9b3d..357b049 100644 (file)
@@ -1,3 +1,8 @@
+2014-09-24  Jakub Jelinek  <jakub@redhat.com>
+
+       PR sanitizer/63316
+       * c-c++-common/asan/pr63316.c: New test.
+
 2014-09-24  Thomas Preud'homme  <thomas.preudhomme@arm.com>
 
        PR tree-optimization/63266
diff --git a/gcc/testsuite/c-c++-common/asan/pr63316.c b/gcc/testsuite/c-c++-common/asan/pr63316.c
new file mode 100644 (file)
index 0000000..d07093a
--- /dev/null
@@ -0,0 +1,22 @@
+/* PR sanitizer/63316 */
+/* { dg-do run } */
+/* { dg-options "-fsanitize=address -O2" } */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+extern void *malloc (__SIZE_TYPE__);
+extern void free (void *);
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+  int *p = (int *) malloc (sizeof (int));
+  *p = 3;
+  asm volatile ("" : : "r" (p) : "memory");
+  free (p);
+  return 0;
+}