re PR sanitizer/59600 (no_sanitize_address mishandled when function is inlined)

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
This commit is contained in:
Yury Gribov 2014-02-05 05:22:29 +00:00 committed by Yury Gribov
parent 4bf2a588d4
commit 25a07c7ee9
5 changed files with 98 additions and 1 deletions

View 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

View 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"))

View 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

View 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.

View File

@ -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;
}