sanitizer: do not inline no-sanitize into sanitizer fn

gcc/ChangeLog:

	* cif-code.def (ATTRIBUTE_MISMATCH): Rename to...
	(SANITIZE_ATTRIBUTE_MISMATCH): ...this.
	* ipa-inline.c (sanitize_attrs_match_for_inline_p):
	Handle all sanitizer options.
	(can_inline_edge_p): Use renamed CIF_* enum value.

gcc/testsuite/ChangeLog:

	* c-c++-common/asan/inline.c: New test.
	* c-c++-common/asan/inline-kernel.c: New test.
	* c-c++-common/tsan/inline.c: New test.
	* c-c++-common/ubsan/inline.c: New test.
This commit is contained in:
Martin Liska 2020-06-09 13:03:55 +02:00
parent bb3ab62a8b
commit 4089df8ef4
No known key found for this signature in database
GPG key ID: 4DC182DC0FA73785
6 changed files with 103 additions and 14 deletions

View file

@ -128,9 +128,10 @@ DEFCIFCODE(OPTIMIZATION_MISMATCH, CIF_FINAL_ERROR,
DEFCIFCODE(USES_COMDAT_LOCAL, CIF_FINAL_ERROR,
N_("callee refers to comdat-local symbols"))
/* We can't inline because of mismatched caller/callee attributes. */
DEFCIFCODE(ATTRIBUTE_MISMATCH, CIF_FINAL_ERROR,
N_("function attribute mismatch"))
/* We can't inline because of mismatched caller/callee
sanitizer attributes. */
DEFCIFCODE(SANITIZE_ATTRIBUTE_MISMATCH, CIF_FINAL_ERROR,
N_("sanitizer function attribute mismatch"))
/* We can't inline because the user requests only static functions
but the function has external linkage for live patching purpose. */

View file

@ -264,18 +264,26 @@ sanitize_attrs_match_for_inline_p (const_tree caller, const_tree callee)
if (!caller || !callee)
return true;
/* Allow inlining always_inline functions into no_sanitize_address
functions. */
if (!sanitize_flags_p (SANITIZE_ADDRESS, caller)
&& lookup_attribute ("always_inline", DECL_ATTRIBUTES (callee)))
/* Follow clang and allow inlining for always_inline functions. */
if (lookup_attribute ("always_inline", DECL_ATTRIBUTES (callee)))
return true;
return ((sanitize_flags_p (SANITIZE_ADDRESS, caller)
== sanitize_flags_p (SANITIZE_ADDRESS, callee))
&& (sanitize_flags_p (SANITIZE_POINTER_COMPARE, caller)
== sanitize_flags_p (SANITIZE_POINTER_COMPARE, callee))
&& (sanitize_flags_p (SANITIZE_POINTER_SUBTRACT, caller)
== sanitize_flags_p (SANITIZE_POINTER_SUBTRACT, callee)));
const sanitize_code codes[] =
{
SANITIZE_ADDRESS,
SANITIZE_THREAD,
SANITIZE_UNDEFINED,
SANITIZE_UNDEFINED_NONDEFAULT,
SANITIZE_POINTER_COMPARE,
SANITIZE_POINTER_SUBTRACT
};
for (unsigned i = 0; i < sizeof (codes) / sizeof (codes[0]); i++)
if (sanitize_flags_p (codes[i], caller)
!= sanitize_flags_p (codes[i], callee))
return false;
return true;
}
/* Used for flags where it is safe to inline when caller's value is
@ -382,7 +390,7 @@ can_inline_edge_p (struct cgraph_edge *e, bool report,
/* Don't inline a function with mismatched sanitization attributes. */
else if (!sanitize_attrs_match_for_inline_p (caller->decl, callee->decl))
{
e->inline_failed = CIF_ATTRIBUTE_MISMATCH;
e->inline_failed = CIF_SANITIZE_ATTRIBUTE_MISMATCH;
inlinable = false;
}
if (!inlinable && report)

View file

@ -0,0 +1,20 @@
/* { dg-do compile } */
/* { dg-options "-fsanitize=kernel-address -c -O3 -fdump-tree-optimized" } */
int x;
static inline
__attribute__((no_sanitize("kernel-address")))
void do_not_sanitize(void)
{
x++;
}
void
sanitize_this(void)
{
x++;
do_not_sanitize();
}
/* { dg-final { scan-tree-dump-times "Function do_not_sanitize" 1 "optimized" } } */

View file

@ -0,0 +1,20 @@
/* { dg-do compile } */
/* { dg-options "-fsanitize=address -c -O3 -fdump-tree-optimized" } */
int x;
static inline
__attribute__((no_sanitize("address")))
void do_not_sanitize(void)
{
x++;
}
void
sanitize_this(void)
{
x++;
do_not_sanitize();
}
/* { dg-final { scan-tree-dump-times "Function do_not_sanitize" 1 "optimized" } } */

View file

@ -0,0 +1,20 @@
/* { dg-do compile } */
/* { dg-options "-fsanitize=thread -c -O3 -fdump-tree-optimized" } */
int x;
static inline
__attribute__((no_sanitize("thread")))
void do_not_sanitize(void)
{
x++;
}
void
sanitize_this(void)
{
x++;
do_not_sanitize();
}
/* { dg-final { scan-tree-dump-times "Function do_not_sanitize" 1 "optimized" } } */

View file

@ -0,0 +1,20 @@
/* { dg-do compile } */
/* { dg-options "-fsanitize=vla-bound -c -O3 -fdump-tree-optimized" } */
int x;
static inline
__attribute__((no_sanitize("undefined")))
void do_not_sanitize(void)
{
x++;
}
void
sanitize_this(void)
{
x++;
do_not_sanitize();
}
/* { dg-final { scan-tree-dump-times "Function do_not_sanitize" 1 "optimized" } } */