SanitizerBlacklist: blacklist functions by their source location.
This commit changes the way we blacklist functions in ASan, TSan,
MSan and UBSan. We used to treat function as "blacklisted"
and turned off instrumentation in it in two cases:
1) Function is explicitly blacklisted by its mangled name.
This part is not changed.
2) Function is located in llvm::Module, whose identifier is
contained in the list of blacklisted sources. This is completely
wrong, as llvm::Module may not correspond to the actual source
file function is defined in. Also, function can be defined in
a header, in which case user had to blacklist the .cpp file
this header was #include'd into, not the header itself.
Such functions could cause other problems - for instance, if the
header was included in multiple source files, compiled
separately and linked into a single executable, we could end up
with both instrumented and non-instrumented version of the same
function participating in the same link.
After this change we will make blacklisting decision based on
the SourceLocation of a function definition. If a function is
not explicitly defined in the source file, (for example, the
function is compiler-generated and responsible for
initialization/destruction of a global variable), then it will
be blacklisted if the corresponding global variable is defined
in blacklisted source file, and will be instrumented otherwise.
After this commit, the active users of blacklist files may have
to revisit them. This is a backwards-incompatible change, but
I don't think it's possible or makes sense to support the
old incorrect behavior.
I plan to make similar change for blacklisting GlobalVariables
(which is ASan-specific).
llvm-svn: 219997
2014-10-17 08:20:19 +08:00
|
|
|
int DefinedInDifferentFile(int *a);
|
|
|
|
// RUN: echo "int DefinedInDifferentFile(int *a) { return *a; }" > %t.extra-source.cpp
|
|
|
|
// RUN: echo "struct S { S(){} ~S(){} };" >> %t.extra-source.cpp
|
|
|
|
// RUN: echo "S glob_array[5];" >> %t.extra-source.cpp
|
|
|
|
|
2017-05-29 13:38:20 +08:00
|
|
|
// RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin -disable-O0-optnone -emit-llvm -o - %s -include %t.extra-source.cpp | FileCheck -check-prefix=WITHOUT %s
|
|
|
|
// RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin -disable-O0-optnone -emit-llvm -o - %s -include %t.extra-source.cpp -fsanitize=address | FileCheck -check-prefix=ASAN %s
|
SanitizerBlacklist: blacklist functions by their source location.
This commit changes the way we blacklist functions in ASan, TSan,
MSan and UBSan. We used to treat function as "blacklisted"
and turned off instrumentation in it in two cases:
1) Function is explicitly blacklisted by its mangled name.
This part is not changed.
2) Function is located in llvm::Module, whose identifier is
contained in the list of blacklisted sources. This is completely
wrong, as llvm::Module may not correspond to the actual source
file function is defined in. Also, function can be defined in
a header, in which case user had to blacklist the .cpp file
this header was #include'd into, not the header itself.
Such functions could cause other problems - for instance, if the
header was included in multiple source files, compiled
separately and linked into a single executable, we could end up
with both instrumented and non-instrumented version of the same
function participating in the same link.
After this change we will make blacklisting decision based on
the SourceLocation of a function definition. If a function is
not explicitly defined in the source file, (for example, the
function is compiler-generated and responsible for
initialization/destruction of a global variable), then it will
be blacklisted if the corresponding global variable is defined
in blacklisted source file, and will be instrumented otherwise.
After this commit, the active users of blacklist files may have
to revisit them. This is a backwards-incompatible change, but
I don't think it's possible or makes sense to support the
old incorrect behavior.
I plan to make similar change for blacklisting GlobalVariables
(which is ASan-specific).
llvm-svn: 219997
2014-10-17 08:20:19 +08:00
|
|
|
|
2013-03-06 18:54:18 +08:00
|
|
|
// RUN: echo "fun:*BlacklistedFunction*" > %t.func.blacklist
|
2017-05-29 13:38:20 +08:00
|
|
|
// RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin -disable-O0-optnone -emit-llvm -o - %s -include %t.extra-source.cpp -fsanitize=address -fsanitize-blacklist=%t.func.blacklist | FileCheck -check-prefix=BLFUNC %s
|
SanitizerBlacklist: blacklist functions by their source location.
This commit changes the way we blacklist functions in ASan, TSan,
MSan and UBSan. We used to treat function as "blacklisted"
and turned off instrumentation in it in two cases:
1) Function is explicitly blacklisted by its mangled name.
This part is not changed.
2) Function is located in llvm::Module, whose identifier is
contained in the list of blacklisted sources. This is completely
wrong, as llvm::Module may not correspond to the actual source
file function is defined in. Also, function can be defined in
a header, in which case user had to blacklist the .cpp file
this header was #include'd into, not the header itself.
Such functions could cause other problems - for instance, if the
header was included in multiple source files, compiled
separately and linked into a single executable, we could end up
with both instrumented and non-instrumented version of the same
function participating in the same link.
After this change we will make blacklisting decision based on
the SourceLocation of a function definition. If a function is
not explicitly defined in the source file, (for example, the
function is compiler-generated and responsible for
initialization/destruction of a global variable), then it will
be blacklisted if the corresponding global variable is defined
in blacklisted source file, and will be instrumented otherwise.
After this commit, the active users of blacklist files may have
to revisit them. This is a backwards-incompatible change, but
I don't think it's possible or makes sense to support the
old incorrect behavior.
I plan to make similar change for blacklisting GlobalVariables
(which is ASan-specific).
llvm-svn: 219997
2014-10-17 08:20:19 +08:00
|
|
|
|
2016-10-21 07:11:45 +08:00
|
|
|
// The blacklist file uses regexps, so escape backslashes, which are common in
|
|
|
|
// Windows paths.
|
|
|
|
// RUN: echo "src:%s" | sed -e 's/\\/\\\\/g' > %t.file.blacklist
|
2017-05-29 13:38:20 +08:00
|
|
|
// RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin -disable-O0-optnone -emit-llvm -o - %s -include %t.extra-source.cpp -fsanitize=address -fsanitize-blacklist=%t.file.blacklist | FileCheck -check-prefix=BLFILE %s
|
2012-01-25 03:25:38 +08:00
|
|
|
|
2013-02-26 14:58:27 +08:00
|
|
|
// The sanitize_address attribute should be attached to functions
|
|
|
|
// when AddressSanitizer is enabled, unless no_sanitize_address attribute
|
2012-01-25 03:25:38 +08:00
|
|
|
// is present.
|
|
|
|
|
SanitizerBlacklist: blacklist functions by their source location.
This commit changes the way we blacklist functions in ASan, TSan,
MSan and UBSan. We used to treat function as "blacklisted"
and turned off instrumentation in it in two cases:
1) Function is explicitly blacklisted by its mangled name.
This part is not changed.
2) Function is located in llvm::Module, whose identifier is
contained in the list of blacklisted sources. This is completely
wrong, as llvm::Module may not correspond to the actual source
file function is defined in. Also, function can be defined in
a header, in which case user had to blacklist the .cpp file
this header was #include'd into, not the header itself.
Such functions could cause other problems - for instance, if the
header was included in multiple source files, compiled
separately and linked into a single executable, we could end up
with both instrumented and non-instrumented version of the same
function participating in the same link.
After this change we will make blacklisting decision based on
the SourceLocation of a function definition. If a function is
not explicitly defined in the source file, (for example, the
function is compiler-generated and responsible for
initialization/destruction of a global variable), then it will
be blacklisted if the corresponding global variable is defined
in blacklisted source file, and will be instrumented otherwise.
After this commit, the active users of blacklist files may have
to revisit them. This is a backwards-incompatible change, but
I don't think it's possible or makes sense to support the
old incorrect behavior.
I plan to make similar change for blacklisting GlobalVariables
(which is ASan-specific).
llvm-svn: 219997
2014-10-17 08:20:19 +08:00
|
|
|
// Attributes for function defined in different source file:
|
|
|
|
// WITHOUT: DefinedInDifferentFile{{.*}} [[NOATTR:#[0-9]+]]
|
|
|
|
// BLFILE: DefinedInDifferentFile{{.*}} [[WITH:#[0-9]+]]
|
|
|
|
// BLFUNC: DefinedInDifferentFile{{.*}} [[WITH:#[0-9]+]]
|
|
|
|
// ASAN: DefinedInDifferentFile{{.*}} [[WITH:#[0-9]+]]
|
|
|
|
|
|
|
|
// Check that functions generated for global in different source file are
|
|
|
|
// not blacklisted.
|
2015-04-23 05:14:25 +08:00
|
|
|
// WITHOUT: @__cxx_global_var_init{{.*}}[[NOATTR:#[0-9]+]]
|
|
|
|
// WITHOUT: @__cxx_global_array_dtor{{.*}}[[NOATTR]]
|
|
|
|
// BLFILE: @__cxx_global_var_init{{.*}}[[WITH:#[0-9]+]]
|
|
|
|
// BLFILE: @__cxx_global_array_dtor{{.*}}[[WITH]]
|
|
|
|
// BLFUNC: @__cxx_global_var_init{{.*}}[[WITH:#[0-9]+]]
|
|
|
|
// BLFUNC: @__cxx_global_array_dtor{{.*}}[[WITH]]
|
|
|
|
// ASAN: @__cxx_global_var_init{{.*}}[[WITH:#[0-9]+]]
|
|
|
|
// ASAN: @__cxx_global_array_dtor{{.*}}[[WITH]]
|
SanitizerBlacklist: blacklist functions by their source location.
This commit changes the way we blacklist functions in ASan, TSan,
MSan and UBSan. We used to treat function as "blacklisted"
and turned off instrumentation in it in two cases:
1) Function is explicitly blacklisted by its mangled name.
This part is not changed.
2) Function is located in llvm::Module, whose identifier is
contained in the list of blacklisted sources. This is completely
wrong, as llvm::Module may not correspond to the actual source
file function is defined in. Also, function can be defined in
a header, in which case user had to blacklist the .cpp file
this header was #include'd into, not the header itself.
Such functions could cause other problems - for instance, if the
header was included in multiple source files, compiled
separately and linked into a single executable, we could end up
with both instrumented and non-instrumented version of the same
function participating in the same link.
After this change we will make blacklisting decision based on
the SourceLocation of a function definition. If a function is
not explicitly defined in the source file, (for example, the
function is compiler-generated and responsible for
initialization/destruction of a global variable), then it will
be blacklisted if the corresponding global variable is defined
in blacklisted source file, and will be instrumented otherwise.
After this commit, the active users of blacklist files may have
to revisit them. This is a backwards-incompatible change, but
I don't think it's possible or makes sense to support the
old incorrect behavior.
I plan to make similar change for blacklisting GlobalVariables
(which is ASan-specific).
llvm-svn: 219997
2014-10-17 08:20:19 +08:00
|
|
|
|
2020-11-03 05:03:21 +08:00
|
|
|
// WITHOUT: NoAddressSafety1{{.*}}) [[NOATTR:#[0-9]+]]
|
2013-03-06 18:54:18 +08:00
|
|
|
// BLFILE: NoAddressSafety1{{.*}}) [[NOATTR:#[0-9]+]]
|
|
|
|
// BLFUNC: NoAddressSafety1{{.*}}) [[NOATTR:#[0-9]+]]
|
2013-03-01 06:49:57 +08:00
|
|
|
// ASAN: NoAddressSafety1{{.*}}) [[NOATTR:#[0-9]+]]
|
2013-02-26 14:58:27 +08:00
|
|
|
__attribute__((no_sanitize_address))
|
2012-01-25 03:25:38 +08:00
|
|
|
int NoAddressSafety1(int *a) { return *a; }
|
|
|
|
|
2013-03-01 06:49:57 +08:00
|
|
|
// WITHOUT: NoAddressSafety2{{.*}}) [[NOATTR]]
|
2013-03-06 18:54:18 +08:00
|
|
|
// BLFILE: NoAddressSafety2{{.*}}) [[NOATTR]]
|
|
|
|
// BLFUNC: NoAddressSafety2{{.*}}) [[NOATTR]]
|
2013-03-01 06:49:57 +08:00
|
|
|
// ASAN: NoAddressSafety2{{.*}}) [[NOATTR]]
|
2013-02-26 14:58:27 +08:00
|
|
|
__attribute__((no_sanitize_address))
|
2012-01-25 03:25:38 +08:00
|
|
|
int NoAddressSafety2(int *a);
|
|
|
|
int NoAddressSafety2(int *a) { return *a; }
|
|
|
|
|
2015-05-16 02:33:32 +08:00
|
|
|
// WITHOUT: NoAddressSafety3{{.*}}) [[NOATTR]]
|
|
|
|
// BLFILE: NoAddressSafety3{{.*}}) [[NOATTR]]
|
|
|
|
// BLFUNC: NoAddressSafety3{{.*}}) [[NOATTR]]
|
|
|
|
// ASAN: NoAddressSafety3{{.*}}) [[NOATTR]]
|
|
|
|
[[gnu::no_sanitize_address]]
|
|
|
|
int NoAddressSafety3(int *a) { return *a; }
|
|
|
|
|
|
|
|
// WITHOUT: NoAddressSafety4{{.*}}) [[NOATTR]]
|
|
|
|
// BLFILE: NoAddressSafety4{{.*}}) [[NOATTR]]
|
|
|
|
// BLFUNC: NoAddressSafety4{{.*}}) [[NOATTR]]
|
|
|
|
// ASAN: NoAddressSafety4{{.*}}) [[NOATTR]]
|
|
|
|
[[gnu::no_sanitize_address]]
|
|
|
|
int NoAddressSafety4(int *a);
|
|
|
|
int NoAddressSafety4(int *a) { return *a; }
|
|
|
|
|
|
|
|
// WITHOUT: NoAddressSafety5{{.*}}) [[NOATTR]]
|
|
|
|
// BLFILE: NoAddressSafety5{{.*}}) [[NOATTR]]
|
|
|
|
// BLFUNC: NoAddressSafety5{{.*}}) [[NOATTR]]
|
|
|
|
// ASAN: NoAddressSafety5{{.*}}) [[NOATTR]]
|
|
|
|
__attribute__((no_sanitize("address")))
|
|
|
|
int NoAddressSafety5(int *a) { return *a; }
|
|
|
|
|
|
|
|
// WITHOUT: NoAddressSafety6{{.*}}) [[NOATTR]]
|
|
|
|
// BLFILE: NoAddressSafety6{{.*}}) [[NOATTR]]
|
|
|
|
// BLFUNC: NoAddressSafety6{{.*}}) [[NOATTR]]
|
|
|
|
// ASAN: NoAddressSafety6{{.*}}) [[NOATTR]]
|
|
|
|
__attribute__((no_sanitize("address")))
|
|
|
|
int NoAddressSafety6(int *a);
|
|
|
|
int NoAddressSafety6(int *a) { return *a; }
|
|
|
|
|
2013-03-01 06:49:57 +08:00
|
|
|
// WITHOUT: AddressSafetyOk{{.*}}) [[NOATTR]]
|
2013-03-06 18:54:18 +08:00
|
|
|
// BLFILE: AddressSafetyOk{{.*}}) [[NOATTR]]
|
2020-11-03 05:03:21 +08:00
|
|
|
// BLFUNC: AddressSafetyOk{{.*}}) [[WITH:#[0-9]+]]
|
|
|
|
// ASAN: AddressSafetyOk{{.*}}) [[WITH:#[0-9]+]]
|
2012-01-25 03:25:38 +08:00
|
|
|
int AddressSafetyOk(int *a) { return *a; }
|
|
|
|
|
2013-03-06 18:54:18 +08:00
|
|
|
// WITHOUT: BlacklistedFunction{{.*}}) [[NOATTR]]
|
|
|
|
// BLFILE: BlacklistedFunction{{.*}}) [[NOATTR]]
|
|
|
|
// BLFUNC: BlacklistedFunction{{.*}}) [[NOATTR]]
|
|
|
|
// ASAN: BlacklistedFunction{{.*}}) [[WITH]]
|
|
|
|
int BlacklistedFunction(int *a) { return *a; }
|
|
|
|
|
2014-10-23 02:26:07 +08:00
|
|
|
#define GENERATE_FUNC(name) \
|
|
|
|
int name(int *a) { return *a; }
|
|
|
|
// WITHOUT: GeneratedFunction{{.*}}) [[NOATTR]]
|
|
|
|
// BLFILE: GeneratedFunction{{.*}}) [[NOATTR]]
|
|
|
|
// BLFUNC: GeneratedFunction{{.*}}) [[WITH]]
|
|
|
|
// ASAN: GeneratedFunction{{.*}}) [[WITH]]
|
|
|
|
GENERATE_FUNC(GeneratedFunction)
|
|
|
|
|
2014-10-23 03:34:25 +08:00
|
|
|
#define GENERATE_NAME(name) name##_generated
|
|
|
|
// WITHOUT: Function_generated{{.*}}) [[NOATTR]]
|
|
|
|
// BLFILE: Function_generated{{.*}}) [[NOATTR]]
|
|
|
|
// BLFUNC: Function_generated{{.*}}) [[WITH]]
|
|
|
|
// ASAN: Function_generated{{.*}}) [[WITH]]
|
|
|
|
int GENERATE_NAME(Function)(int *a) { return *a; }
|
|
|
|
|
2013-03-01 06:49:57 +08:00
|
|
|
// WITHOUT: TemplateAddressSafetyOk{{.*}}) [[NOATTR]]
|
2013-03-06 18:54:18 +08:00
|
|
|
// BLFILE: TemplateAddressSafetyOk{{.*}}) [[NOATTR]]
|
|
|
|
// BLFUNC: TemplateAddressSafetyOk{{.*}}) [[WITH]]
|
2013-03-01 06:49:57 +08:00
|
|
|
// ASAN: TemplateAddressSafetyOk{{.*}}) [[WITH]]
|
2012-01-25 03:25:38 +08:00
|
|
|
template<int i>
|
2013-02-20 15:22:19 +08:00
|
|
|
int TemplateAddressSafetyOk() { return i; }
|
2012-01-25 03:25:38 +08:00
|
|
|
|
2015-05-16 02:33:32 +08:00
|
|
|
// WITHOUT: TemplateNoAddressSafety1{{.*}}) [[NOATTR]]
|
|
|
|
// BLFILE: TemplateNoAddressSafety1{{.*}}) [[NOATTR]]
|
|
|
|
// BLFUNC: TemplateNoAddressSafety1{{.*}}) [[NOATTR]]
|
|
|
|
// ASAN: TemplateNoAddressSafety1{{.*}}) [[NOATTR]]
|
2012-01-25 03:25:38 +08:00
|
|
|
template<int i>
|
2013-02-26 14:58:27 +08:00
|
|
|
__attribute__((no_sanitize_address))
|
2015-05-16 02:33:32 +08:00
|
|
|
int TemplateNoAddressSafety1() { return i; }
|
|
|
|
|
|
|
|
// WITHOUT: TemplateNoAddressSafety2{{.*}}) [[NOATTR]]
|
|
|
|
// BLFILE: TemplateNoAddressSafety2{{.*}}) [[NOATTR]]
|
|
|
|
// BLFUNC: TemplateNoAddressSafety2{{.*}}) [[NOATTR]]
|
|
|
|
// ASAN: TemplateNoAddressSafety2{{.*}}) [[NOATTR]]
|
|
|
|
template<int i>
|
|
|
|
__attribute__((no_sanitize("address")))
|
|
|
|
int TemplateNoAddressSafety2() { return i; }
|
2012-01-25 03:25:38 +08:00
|
|
|
|
|
|
|
int force_instance = TemplateAddressSafetyOk<42>()
|
2015-05-16 02:33:32 +08:00
|
|
|
+ TemplateNoAddressSafety1<42>()
|
|
|
|
+ TemplateNoAddressSafety2<42>();
|
2012-06-26 16:56:33 +08:00
|
|
|
|
2013-02-26 14:58:27 +08:00
|
|
|
// Check that __cxx_global_var_init* get the sanitize_address attribute.
|
2012-06-26 16:56:33 +08:00
|
|
|
int global1 = 0;
|
|
|
|
int global2 = *(int*)((char*)&global1+1);
|
2020-11-03 05:03:21 +08:00
|
|
|
// WITHOUT: @__cxx_global_var_init{{.*}}[[NOATTR:#[0-9]+]]
|
2015-04-23 05:14:25 +08:00
|
|
|
// BLFILE: @__cxx_global_var_init{{.*}}[[NOATTR:#[0-9]+]]
|
2020-11-03 05:03:21 +08:00
|
|
|
// BLFUNC: @__cxx_global_var_init{{.*}}[[WITH:#[0-9]+]]
|
|
|
|
// ASAN: @__cxx_global_var_init{{.*}}[[WITH:#[0-9]+]]
|
2013-02-22 03:44:18 +08:00
|
|
|
|
Cleanup the handling of noinline function attributes, -fno-inline,
-fno-inline-functions, -O0, and optnone.
These were really, really tangled together:
- We used the noinline LLVM attribute for -fno-inline
- But not for -fno-inline-functions (breaking LTO)
- But we did use it for -finline-hint-functions (yay, LTO is happy!)
- But we didn't for -O0 (LTO is sad yet again...)
- We had weird structuring of CodeGenOpts with both an inlining
enumeration and a boolean. They interacted in weird ways and
needlessly.
- A *lot* of set smashing went on with setting these, and then got worse
when we considered optnone and other inlining-effecting attributes.
- A bunch of inline affecting attributes were managed in a completely
different place from -fno-inline.
- Even with -fno-inline we failed to put the LLVM noinline attribute
onto many generated function definitions because they didn't show up
as AST-level functions.
- If you passed -O0 but -finline-functions we would run the normal
inliner pass in LLVM despite it being in the O0 pipeline, which really
doesn't make much sense.
- Lastly, we used things like '-fno-inline' to manipulate the pass
pipeline which forced the pass pipeline to be much more
parameterizable than it really needs to be. Instead we can *just* use
the optimization level to select a pipeline and control the rest via
attributes.
Sadly, this causes a bunch of churn in tests because we don't run the
optimizer in the tests and check the contents of attribute sets. It
would be awesome if attribute sets were a bit more FileCheck friendly,
but oh well.
I think this is a significant improvement and should remove the semantic
need to change what inliner pass we run in order to comply with the
requested inlining semantics by relying completely on attributes. It
also cleans up tho optnone and related handling a bit.
One unfortunate aspect of this is that for generating alwaysinline
routines like those in OpenMP we end up removing noinline and then
adding alwaysinline. I tried a bunch of other approaches, but because we
recompute function attributes from scratch and don't have a declaration
here I couldn't find anything substantially cleaner than this.
Differential Revision: https://reviews.llvm.org/D28053
llvm-svn: 290398
2016-12-23 09:24:49 +08:00
|
|
|
// WITHOUT: attributes [[NOATTR]] = { noinline nounwind{{.*}} }
|
2013-02-22 03:44:18 +08:00
|
|
|
|
Cleanup the handling of noinline function attributes, -fno-inline,
-fno-inline-functions, -O0, and optnone.
These were really, really tangled together:
- We used the noinline LLVM attribute for -fno-inline
- But not for -fno-inline-functions (breaking LTO)
- But we did use it for -finline-hint-functions (yay, LTO is happy!)
- But we didn't for -O0 (LTO is sad yet again...)
- We had weird structuring of CodeGenOpts with both an inlining
enumeration and a boolean. They interacted in weird ways and
needlessly.
- A *lot* of set smashing went on with setting these, and then got worse
when we considered optnone and other inlining-effecting attributes.
- A bunch of inline affecting attributes were managed in a completely
different place from -fno-inline.
- Even with -fno-inline we failed to put the LLVM noinline attribute
onto many generated function definitions because they didn't show up
as AST-level functions.
- If you passed -O0 but -finline-functions we would run the normal
inliner pass in LLVM despite it being in the O0 pipeline, which really
doesn't make much sense.
- Lastly, we used things like '-fno-inline' to manipulate the pass
pipeline which forced the pass pipeline to be much more
parameterizable than it really needs to be. Instead we can *just* use
the optimization level to select a pipeline and control the rest via
attributes.
Sadly, this causes a bunch of churn in tests because we don't run the
optimizer in the tests and check the contents of attribute sets. It
would be awesome if attribute sets were a bit more FileCheck friendly,
but oh well.
I think this is a significant improvement and should remove the semantic
need to change what inliner pass we run in order to comply with the
requested inlining semantics by relying completely on attributes. It
also cleans up tho optnone and related handling a bit.
One unfortunate aspect of this is that for generating alwaysinline
routines like those in OpenMP we end up removing noinline and then
adding alwaysinline. I tried a bunch of other approaches, but because we
recompute function attributes from scratch and don't have a declaration
here I couldn't find anything substantially cleaner than this.
Differential Revision: https://reviews.llvm.org/D28053
llvm-svn: 290398
2016-12-23 09:24:49 +08:00
|
|
|
// BLFILE: attributes [[WITH]] = { noinline nounwind sanitize_address{{.*}} }
|
|
|
|
// BLFILE: attributes [[NOATTR]] = { noinline nounwind{{.*}} }
|
2013-03-06 18:54:18 +08:00
|
|
|
|
Cleanup the handling of noinline function attributes, -fno-inline,
-fno-inline-functions, -O0, and optnone.
These were really, really tangled together:
- We used the noinline LLVM attribute for -fno-inline
- But not for -fno-inline-functions (breaking LTO)
- But we did use it for -finline-hint-functions (yay, LTO is happy!)
- But we didn't for -O0 (LTO is sad yet again...)
- We had weird structuring of CodeGenOpts with both an inlining
enumeration and a boolean. They interacted in weird ways and
needlessly.
- A *lot* of set smashing went on with setting these, and then got worse
when we considered optnone and other inlining-effecting attributes.
- A bunch of inline affecting attributes were managed in a completely
different place from -fno-inline.
- Even with -fno-inline we failed to put the LLVM noinline attribute
onto many generated function definitions because they didn't show up
as AST-level functions.
- If you passed -O0 but -finline-functions we would run the normal
inliner pass in LLVM despite it being in the O0 pipeline, which really
doesn't make much sense.
- Lastly, we used things like '-fno-inline' to manipulate the pass
pipeline which forced the pass pipeline to be much more
parameterizable than it really needs to be. Instead we can *just* use
the optimization level to select a pipeline and control the rest via
attributes.
Sadly, this causes a bunch of churn in tests because we don't run the
optimizer in the tests and check the contents of attribute sets. It
would be awesome if attribute sets were a bit more FileCheck friendly,
but oh well.
I think this is a significant improvement and should remove the semantic
need to change what inliner pass we run in order to comply with the
requested inlining semantics by relying completely on attributes. It
also cleans up tho optnone and related handling a bit.
One unfortunate aspect of this is that for generating alwaysinline
routines like those in OpenMP we end up removing noinline and then
adding alwaysinline. I tried a bunch of other approaches, but because we
recompute function attributes from scratch and don't have a declaration
here I couldn't find anything substantially cleaner than this.
Differential Revision: https://reviews.llvm.org/D28053
llvm-svn: 290398
2016-12-23 09:24:49 +08:00
|
|
|
// BLFUNC: attributes [[WITH]] = { noinline nounwind sanitize_address{{.*}} }
|
|
|
|
// BLFUNC: attributes [[NOATTR]] = { noinline nounwind{{.*}} }
|
2013-03-01 06:49:57 +08:00
|
|
|
|
Cleanup the handling of noinline function attributes, -fno-inline,
-fno-inline-functions, -O0, and optnone.
These were really, really tangled together:
- We used the noinline LLVM attribute for -fno-inline
- But not for -fno-inline-functions (breaking LTO)
- But we did use it for -finline-hint-functions (yay, LTO is happy!)
- But we didn't for -O0 (LTO is sad yet again...)
- We had weird structuring of CodeGenOpts with both an inlining
enumeration and a boolean. They interacted in weird ways and
needlessly.
- A *lot* of set smashing went on with setting these, and then got worse
when we considered optnone and other inlining-effecting attributes.
- A bunch of inline affecting attributes were managed in a completely
different place from -fno-inline.
- Even with -fno-inline we failed to put the LLVM noinline attribute
onto many generated function definitions because they didn't show up
as AST-level functions.
- If you passed -O0 but -finline-functions we would run the normal
inliner pass in LLVM despite it being in the O0 pipeline, which really
doesn't make much sense.
- Lastly, we used things like '-fno-inline' to manipulate the pass
pipeline which forced the pass pipeline to be much more
parameterizable than it really needs to be. Instead we can *just* use
the optimization level to select a pipeline and control the rest via
attributes.
Sadly, this causes a bunch of churn in tests because we don't run the
optimizer in the tests and check the contents of attribute sets. It
would be awesome if attribute sets were a bit more FileCheck friendly,
but oh well.
I think this is a significant improvement and should remove the semantic
need to change what inliner pass we run in order to comply with the
requested inlining semantics by relying completely on attributes. It
also cleans up tho optnone and related handling a bit.
One unfortunate aspect of this is that for generating alwaysinline
routines like those in OpenMP we end up removing noinline and then
adding alwaysinline. I tried a bunch of other approaches, but because we
recompute function attributes from scratch and don't have a declaration
here I couldn't find anything substantially cleaner than this.
Differential Revision: https://reviews.llvm.org/D28053
llvm-svn: 290398
2016-12-23 09:24:49 +08:00
|
|
|
// ASAN: attributes [[WITH]] = { noinline nounwind sanitize_address{{.*}} }
|
|
|
|
// ASAN: attributes [[NOATTR]] = { noinline nounwind{{.*}} }
|