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:
parent
4bf2a588d4
commit
25a07c7ee9
|
@ -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
|
||||
|
|
|
@ -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"))
|
||||
|
|
|
@ -234,6 +234,24 @@ report_inline_failed_reason (struct cgraph_edge *e)
|
|||
}
|
||||
}
|
||||
|
||||
/* 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
|
||||
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
}
|
Loading…
Reference in New Issue