From 25a07c7ee9e1a2e595efa48740ce5144d005e9ac Mon Sep 17 00:00:00 2001 From: Yury Gribov Date: Wed, 5 Feb 2014 05:22:29 +0000 Subject: [PATCH] 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 --- gcc/ChangeLog | 8 +++ gcc/cif-code.def | 4 ++ gcc/ipa-inline.c | 26 ++++++++- gcc/testsuite/ChangeLog | 4 ++ .../gcc.dg/asan/nosanitize-and-inline.c | 57 +++++++++++++++++++ 5 files changed, 98 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gcc.dg/asan/nosanitize-and-inline.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 47b8a7c5f32..28d171caefc 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2014-02-05 Yury Gribov + + * 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 * ipa-prop.c (detect_type_change): Shor circuit testing of diff --git a/gcc/cif-code.def b/gcc/cif-code.def index 5591f9a9a5f..71f3e39a6da 100644 --- a/gcc/cif-code.def +++ b/gcc/cif-code.def @@ -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")) diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c index 5f47e0b4e1a..ce24ea50a37 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_ATTRIBUTE_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/ChangeLog b/gcc/testsuite/ChangeLog index 4409d870363..2f154f44e27 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2014-02-05 Yury Gribov + + * gcc.dg/asan/nosanitize-and-inline.c: : New test. + 2014-02-04 Jan Hubicka * 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 index 00000000000..58538016216 --- /dev/null +++ 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; +} -- 2.30.2