-------- Original Message --------
Subject: [PATCH][PING] Fix for PR59600 (prohibit inlining if
no_sanitize_address)
Date: Tue, 28 Jan 2014 09:13:10 +0400
From: Yury Gribov <y.gri...@samsung.com>
To: GCC Patches <gcc-patches@gcc.gnu.org>
-------- Original Message --------
Subject: [PATCH] Fix for PR59600
Date: Tue, 21 Jan 2014 14:42:31 +0400
From: Yury Gribov <y.gri...@samsung.com>
To: GCC Patches <gcc-patches@gcc.gnu.org>
Hi,
This patch fixes the problem reported in
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59600 : functions with
mismatching no_sanitize_address attributes should not be considered for
inlining, otherwise the meaning of no_sanitize_address will not be
preserved.
I didn't get feedback in Bugzilla so I'm sending the patch here.
Bootstrapped/regtested on x64.
-Y
gcc/ChangeLog:
2014-01-21 ygribov <ygri...@samsung.com>
* cif-code.def (OPTION_MISMATCH): New CIF code.
* ipa-inline.c (report_inline_failed_reason): Handle mismatched
sanitization attributes.
(sanitize_attrs_match_for_inline_p): New function.
(can_inline_edge_p): Likewise.
gcc/testsuite/ChangeLog:
2014-01-21 ygribov <ygri...@samsung.com>
* gcc.dg/asan/nosanitize-and-inline.c: : New test.
diff --git a/gcc/cif-code.def b/gcc/cif-code.def
index f1df5a0..1418f8e 100644
--- a/gcc/cif-code.def
+++ b/gcc/cif-code.def
@@ -109,3 +109,6 @@ DEFCIFCODE(OPTIMIZATION_MISMATCH, N_("optimization level attribute mismatch"))
/* We can't inline because the callee refers to comdat-local symbols. */
DEFCIFCODE(USES_COMDAT_LOCAL, N_("callee refers to comdat-local symbols"))
+
+/* We can't inline because of mismatched options. */
+DEFCIFCODE(OPTION_MISMATCH, N_("option mismatch"))
diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c
index 12ee84c..9118561 100644
--- a/gcc/ipa-inline.c
+++ b/gcc/ipa-inline.c
@@ -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_OPTION_MISMATCH;
+ inlinable = false;
+ }
/* Check if caller growth allows the inlining. */
else if (!DECL_DISREGARD_INLINE_LIMITS (callee->decl)
&& !disregard_limits
diff --git a/gcc/testsuite/gcc.dg/asan/nosanitize-and-inline.c b/gcc/testsuite/gcc.dg/asan/nosanitize-and-inline.c
index e69de29..5853801 100644
--- a/gcc/testsuite/gcc.dg/asan/nosanitize-and-inline.c
+++ b/gcc/testsuite/gcc.dg/asan/nosanitize-and-inline.c
@@ -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;
+}