re PR sanitizer/59600 (no_sanitize_address mishandled when function is inlined)
authorYury Gribov <y.gribov@samsung.com>
Wed, 5 Feb 2014 05:22:29 +0000 (05:22 +0000)
committerYury Gribov <ygribov@gcc.gnu.org>
Wed, 5 Feb 2014 05:22:29 +0000 (05:22 +0000)
PR sanitizer/59600

gcc/
* cif-code.def (ATTRIBUTE_MISMATCH): New CIF code.
* ipa-inline.c (report_inline_failed_reason): Handle mismatched
sanitization attributes.
(can_inline_edge_p): Likewise.
(sanitize_attrs_match_for_inline_p): New function.

gcc/testsuite/
* gcc.dg/asan/nosanitize-and-inline.c: : New test.

From-SVN: r207497

gcc/ChangeLog
gcc/cif-code.def
gcc/ipa-inline.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/asan/nosanitize-and-inline.c [new file with mode: 0644]

index 47b8a7c5f322d747dedc32305192bd8e9dd39933..28d171caefca97f8efb429784bacff496adb1c57 100644 (file)
@@ -1,3 +1,11 @@
+2014-02-05  Yury Gribov  <y.gribov@samsung.com>
+
+       * cif-code.def (ATTRIBUTE_MISMATCH): New CIF code.
+       * ipa-inline.c (report_inline_failed_reason): Handle mismatched
+       sanitization attributes.
+       (can_inline_edge_p): Likewise.
+       (sanitize_attrs_match_for_inline_p): New function.
+
 2014-02-04  Jan Hubicka  <hubicka@ucw.cz>
 
        * ipa-prop.c (detect_type_change): Shor circuit testing of
index 5591f9a9a5f75be91f5f2c9bd97efa8760770487..71f3e39a6da6fba00c89d1b0680eeddc79970a59 100644 (file)
@@ -123,3 +123,7 @@ DEFCIFCODE(OPTIMIZATION_MISMATCH, CIF_FINAL_ERROR,
 /* We can't inline because the callee refers to comdat-local symbols.  */
 DEFCIFCODE(USES_COMDAT_LOCAL, CIF_FINAL_NORMAL,
           N_("callee refers to comdat-local symbols"))
+
+/* We can't inline because of mismatched caller/callee attributes.  */
+DEFCIFCODE(ATTRIBUTE_MISMATCH, CIF_FINAL_NORMAL,
+          N_("function attribute mismatch"))
index 5f47e0b4e1ac84f13d49bc18b947e665f9abe90f..ce24ea50a37ca8b4666a951b8c41077311e5a710 100644 (file)
@@ -234,7 +234,25 @@ report_inline_failed_reason (struct cgraph_edge *e)
     }
 }
 
-/* Decide if we can inline the edge and possibly update
+ /* Decide whether sanitizer-related attributes allow inlining. */
+
+static bool
+sanitize_attrs_match_for_inline_p (const_tree caller, const_tree callee)
+{
+  /* Don't care if sanitizer is disabled */
+  if (!(flag_sanitize & SANITIZE_ADDRESS))
+    return true;
+
+  if (!caller || !callee)
+    return true;
+
+  return !!lookup_attribute ("no_sanitize_address",
+      DECL_ATTRIBUTES (caller)) == 
+      !!lookup_attribute ("no_sanitize_address",
+      DECL_ATTRIBUTES (callee));
+}
+
+ /* Decide if we can inline the edge and possibly update
    inline_failed reason.  
    We check whether inlining is possible at all and whether
    caller growth limits allow doing so.  
@@ -327,6 +345,12 @@ can_inline_edge_p (struct cgraph_edge *e, bool report,
       e->inline_failed = CIF_TARGET_OPTION_MISMATCH;
       inlinable = false;
     }
+  /* Don't inline a function with mismatched sanitization attributes. */
+  else if (!sanitize_attrs_match_for_inline_p (e->caller->decl, callee->decl))
+    {
+      e->inline_failed = CIF_ATTRIBUTE_MISMATCH;
+      inlinable = false;
+    }
   /* Check if caller growth allows the inlining.  */
   else if (!DECL_DISREGARD_INLINE_LIMITS (callee->decl)
           && !disregard_limits
index 4409d870363a9ef682ef42ad388dffecf299d25a..2f154f44e27e74f6f9078af3a278a5590e2206e2 100644 (file)
@@ -1,3 +1,7 @@
+2014-02-05  Yury Gribov  <y.gribov@samsung.com>
+
+       * gcc.dg/asan/nosanitize-and-inline.c: : New test.
+
 2014-02-04  Jan Hubicka  <hubicka@ucw.cz>
 
        * g++.dg/ipa/devirrt-22.C: Fix template.
diff --git a/gcc/testsuite/gcc.dg/asan/nosanitize-and-inline.c b/gcc/testsuite/gcc.dg/asan/nosanitize-and-inline.c
new file mode 100644 (file)
index 0000000..5853801
--- /dev/null
@@ -0,0 +1,57 @@
+/* { dg-do run } */
+
+/* This is a simplified version of what Emacs does internally,
+   when marking its stack.  */
+
+static unsigned long sum;
+static void *stack_base;
+
+/* A simple substitute for what Emacs actually does.  */
+static void
+mark_maybe_pointer (void *p)
+{
+  sum ^= (unsigned long) p;
+}
+
+static inline void __attribute__ ((no_sanitize_address))
+mark_memory (void **start, void **end)
+{
+  void **pp;
+
+  if (end < start)
+    {
+      void **tem = start;
+      start = end;
+      end = tem;
+    }
+
+  for (pp = start; pp < end; pp++)
+    {
+      /* This is the dereference that we don't want sanitized.  */
+      void *p = *pp;
+
+      mark_maybe_pointer (p);
+    }
+}
+
+static void
+mark_stack (void)
+{
+  void *end;
+  mark_memory (stack_base, &end);
+}
+
+void
+garbage_collect (void)
+{
+  mark_stack ();
+}
+
+int
+main (void)
+{
+  void *dummy;
+  stack_base = &dummy;
+  garbage_collect ();
+  return 0;
+}