[clang] [flang] [Flang][Sanitizer] Support sanitizer flag for Flang Driver. (PR #137759)
Amit Kumar Pandey via cfe-commits
cfe-commits at lists.llvm.org
Thu May 15 03:34:42 PDT 2025
https://github.com/ampandey-1995 updated https://github.com/llvm/llvm-project/pull/137759
>From aa3caaeaa72ab2f0de8beac416875dc466ac1051 Mon Sep 17 00:00:00 2001
From: Amit Pandey <pandey.kumaramit2023 at gmail.com>
Date: Thu, 1 May 2025 13:51:12 +0530
Subject: [PATCH 1/2] [Flang][Sanitizer] Support sanitizer flag for Flang
Driver.
Flang Driver currently dosen't support option sanitizer flags such as
'-fsanitize='. This patch currently supports enabling sanitizer flags
for the flang driver apart from clang independently.
---
clang/include/clang/Driver/Options.td | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index e69cd6b833c3a..32cd93f9a5e36 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -1555,11 +1555,15 @@ defm xl_pragma_pack : BoolFOption<"xl-pragma-pack",
"Enable IBM XL #pragma pack handling">,
NegFlag<SetFalse>>;
def shared_libsan : Flag<["-"], "shared-libsan">,
+ Visibility<[ClangOption, CC1Option, FlangOption, FC1Option]>,
HelpText<"Dynamically link the sanitizer runtime">;
def static_libsan : Flag<["-"], "static-libsan">,
+ Visibility<[ClangOption, CC1Option, FlangOption, FC1Option]>,
HelpText<"Statically link the sanitizer runtime (Not supported for ASan, TSan or UBSan on darwin)">;
-def : Flag<["-"], "shared-libasan">, Alias<shared_libsan>;
-def : Flag<["-"], "static-libasan">, Alias<static_libsan>;
+def : Flag<["-"], "shared-libasan">, Alias<shared_libsan>,
+ Visibility<[ClangOption, CC1Option, FlangOption, FC1Option]>;
+def : Flag<["-"], "static-libasan">, Alias<static_libsan>,
+ Visibility<[ClangOption, CC1Option, FlangOption, FC1Option]>;
def fasm : Flag<["-"], "fasm">, Group<f_Group>;
defm assume_unique_vtables : BoolFOption<"assume-unique-vtables",
@@ -2309,7 +2313,7 @@ def fmemory_profile_use_EQ : Joined<["-"], "fmemory-profile-use=">,
// Begin sanitizer flags. These should all be core options exposed in all driver
// modes.
-let Visibility = [ClangOption, CC1Option, CLOption] in {
+let Visibility = [ClangOption, CC1Option, CLOption, FlangOption, FC1Option] in {
def fsanitize_EQ : CommaJoined<["-"], "fsanitize=">, Group<f_clang_Group>,
MetaVarName<"<check>">,
>From f938acc7557bd37edac3b7a38ecb32e069a13a97 Mon Sep 17 00:00:00 2001
From: Amit Pandey <pandey.kumaramit2023 at gmail.com>
Date: Wed, 14 May 2025 21:44:15 +0530
Subject: [PATCH 2/2] Support ASan in LLVM Flang.
---
clang/include/clang/Driver/Options.td | 92 +++++++++----------
clang/lib/Driver/ToolChains/Flang.cpp | 13 +++
clang/lib/Driver/ToolChains/Flang.h | 9 ++
.../include/flang/Frontend/CodeGenOptions.def | 67 ++++++++++++++
flang/include/flang/Frontend/CodeGenOptions.h | 47 ++++++++++
flang/include/flang/Support/LangOptions.def | 1 +
flang/include/flang/Support/LangOptions.h | 11 ++-
flang/lib/Frontend/CodeGenOptions.cpp | 29 ++++++
flang/lib/Frontend/CompilerInvocation.cpp | 82 +++++++++++++++++
flang/lib/Frontend/FrontendActions.cpp | 37 ++++++++
10 files changed, 341 insertions(+), 47 deletions(-)
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index f4307f02d9175..3e89a1f7b28aa 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -2339,7 +2339,7 @@ def fsanitize_EQ : CommaJoined<["-"], "fsanitize=">, Group<f_clang_Group>,
HelpText<"Turn on runtime checks for various forms of undefined "
"or suspicious behavior. See user manual for available checks">;
def fno_sanitize_EQ : CommaJoined<["-"], "fno-sanitize=">, Group<f_clang_Group>,
- Visibility<[ClangOption, CLOption]>;
+ Visibility<[ClangOption, CLOption, FlangOption]>;
def fsanitize_ignorelist_EQ : Joined<["-"], "fsanitize-ignorelist=">,
Group<f_clang_Group>, HelpText<"Path to ignorelist file for sanitizers">;
@@ -2349,7 +2349,7 @@ def : Joined<["-"], "fsanitize-blacklist=">,
def fsanitize_system_ignorelist_EQ : Joined<["-"], "fsanitize-system-ignorelist=">,
HelpText<"Path to system ignorelist file for sanitizers">,
- Visibility<[ClangOption, CC1Option]>;
+ Visibility<[ClangOption, CC1Option, FlangOption, FC1Option]>;
def fno_sanitize_ignorelist : Flag<["-"], "fno-sanitize-ignorelist">,
Group<f_clang_Group>, HelpText<"Don't use ignorelist file for sanitizers">;
@@ -2360,17 +2360,17 @@ def fsanitize_coverage : CommaJoined<["-"], "fsanitize-coverage=">,
Group<f_clang_Group>,
HelpText<"Specify the type of coverage instrumentation for Sanitizers">;
def fno_sanitize_coverage : CommaJoined<["-"], "fno-sanitize-coverage=">,
- Group<f_clang_Group>, Visibility<[ClangOption, CLOption]>,
+ Group<f_clang_Group>, Visibility<[ClangOption, CLOption, FlangOption]>,
HelpText<"Disable features of coverage instrumentation for Sanitizers">,
Values<"func,bb,edge,indirect-calls,trace-bb,trace-cmp,trace-div,trace-gep,"
"8bit-counters,trace-pc,trace-pc-guard,no-prune,inline-8bit-counters,"
"inline-bool-flag">;
def fsanitize_coverage_allowlist : Joined<["-"], "fsanitize-coverage-allowlist=">,
- Group<f_clang_Group>, Visibility<[ClangOption, CLOption]>,
+ Group<f_clang_Group>, Visibility<[ClangOption, CLOption, FlangOption]>,
HelpText<"Restrict sanitizer coverage instrumentation exclusively to modules and functions that match the provided special case list, except the blocked ones">,
MarshallingInfoStringVector<CodeGenOpts<"SanitizeCoverageAllowlistFiles">>;
def fsanitize_coverage_ignorelist : Joined<["-"], "fsanitize-coverage-ignorelist=">,
- Group<f_clang_Group>, Visibility<[ClangOption, CLOption]>,
+ Group<f_clang_Group>, Visibility<[ClangOption, CLOption, FlangOption]>,
HelpText<"Disable sanitizer coverage instrumentation for modules and functions "
"that match the provided special case list, even the allowed ones">,
MarshallingInfoStringVector<CodeGenOpts<"SanitizeCoverageIgnorelistFiles">>;
@@ -2385,10 +2385,10 @@ def fexperimental_sanitize_metadata_EQ : CommaJoined<["-"], "fexperimental-sanit
Group<f_Group>,
HelpText<"Specify the type of metadata to emit for binary analysis sanitizers">;
def fno_experimental_sanitize_metadata_EQ : CommaJoined<["-"], "fno-experimental-sanitize-metadata=">,
- Group<f_Group>, Visibility<[ClangOption, CLOption]>,
+ Group<f_Group>, Visibility<[ClangOption, CLOption,FlangOption]>,
HelpText<"Disable emitting metadata for binary analysis sanitizers">;
def fexperimental_sanitize_metadata_ignorelist_EQ : Joined<["-"], "fexperimental-sanitize-metadata-ignorelist=">,
- Group<f_Group>, Visibility<[ClangOption, CLOption]>,
+ Group<f_Group>, Visibility<[ClangOption, CLOption, FlangOption]>,
HelpText<"Disable sanitizer metadata for modules and functions that match the provided special case list">,
MarshallingInfoStringVector<CodeGenOpts<"SanitizeMetadataIgnorelistFiles">>;
def fsanitize_memory_track_origins_EQ : Joined<["-"], "fsanitize-memory-track-origins=">,
@@ -2401,7 +2401,7 @@ def fsanitize_memory_track_origins : Flag<["-"], "fsanitize-memory-track-origins
HelpText<"Enable origins tracking in MemorySanitizer">;
def fno_sanitize_memory_track_origins : Flag<["-"], "fno-sanitize-memory-track-origins">,
Group<f_clang_Group>,
- Visibility<[ClangOption, CLOption]>,
+ Visibility<[ClangOption, CLOption, FlangOption]>,
HelpText<"Disable origins tracking in MemorySanitizer">;
def fsanitize_address_outline_instrumentation : Flag<["-"], "fsanitize-address-outline-instrumentation">,
Group<f_clang_Group>,
@@ -2423,13 +2423,13 @@ def fsanitize_hwaddress_experimental_aliasing
def fno_sanitize_hwaddress_experimental_aliasing
: Flag<["-"], "fno-sanitize-hwaddress-experimental-aliasing">,
Group<f_clang_Group>,
- Visibility<[ClangOption, CLOption]>,
+ Visibility<[ClangOption, CLOption, FlangOption]>,
HelpText<"Disable aliasing mode in HWAddressSanitizer">;
defm sanitize_memory_use_after_dtor : BoolOption<"f", "sanitize-memory-use-after-dtor",
CodeGenOpts<"SanitizeMemoryUseAfterDtor">, DefaultFalse,
- PosFlag<SetTrue, [], [ClangOption, CC1Option], "Enable">,
- NegFlag<SetFalse, [], [ClangOption], "Disable">,
- BothFlags<[], [ClangOption], " use-after-destroy detection in MemorySanitizer">>,
+ PosFlag<SetTrue, [], [ClangOption, CC1Option, FlangOption, FC1Option], "Enable">,
+ NegFlag<SetFalse, [], [ClangOption, FlangOption], "Disable">,
+ BothFlags<[], [ClangOption, FlangOption], " use-after-destroy detection in MemorySanitizer">>,
Group<f_clang_Group>;
def fsanitize_address_field_padding : Joined<["-"], "fsanitize-address-field-padding=">,
Group<f_clang_Group>,
@@ -2437,15 +2437,15 @@ def fsanitize_address_field_padding : Joined<["-"], "fsanitize-address-field-pad
MarshallingInfoInt<LangOpts<"SanitizeAddressFieldPadding">>;
defm sanitize_address_use_after_scope : BoolOption<"f", "sanitize-address-use-after-scope",
CodeGenOpts<"SanitizeAddressUseAfterScope">, DefaultFalse,
- PosFlag<SetTrue, [], [ClangOption], "Enable">,
- NegFlag<SetFalse, [], [ClangOption, CLOption],
+ PosFlag<SetTrue, [], [ClangOption, FlangOption], "Enable">,
+ NegFlag<SetFalse, [], [ClangOption, CLOption, FlangOption],
"Disable">,
- BothFlags<[], [ClangOption], " use-after-scope detection in AddressSanitizer">>,
+ BothFlags<[], [ClangOption, FlangOption], " use-after-scope detection in AddressSanitizer">>,
Group<f_clang_Group>;
def sanitize_address_use_after_return_EQ
: Joined<["-"], "fsanitize-address-use-after-return=">,
MetaVarName<"<mode>">,
- Visibility<[ClangOption, CC1Option]>,
+ Visibility<[ClangOption, CC1Option, FlangOption]>,
HelpText<"Select the mode of detecting stack use-after-return in AddressSanitizer">,
Group<f_clang_Group>,
Values<"never,runtime,always">,
@@ -2454,9 +2454,9 @@ def sanitize_address_use_after_return_EQ
MarshallingInfoEnum<CodeGenOpts<"SanitizeAddressUseAfterReturn">, "Runtime">;
defm sanitize_address_poison_custom_array_cookie : BoolOption<"f", "sanitize-address-poison-custom-array-cookie",
CodeGenOpts<"SanitizeAddressPoisonCustomArrayCookie">, DefaultFalse,
- PosFlag<SetTrue, [], [ClangOption], "Enable">,
- NegFlag<SetFalse, [], [ClangOption], "Disable">,
- BothFlags<[], [ClangOption], " poisoning array cookies when using custom operator new[] in AddressSanitizer">>,
+ PosFlag<SetTrue, [], [ClangOption, FlangOption], "Enable">,
+ NegFlag<SetFalse, [], [ClangOption, FlangOption], "Disable">,
+ BothFlags<[], [ClangOption, FlangOption], " poisoning array cookies when using custom operator new[] in AddressSanitizer">>,
DocBrief<[{Enable "poisoning" array cookies when allocating arrays with a
custom operator new\[\] in Address Sanitizer, preventing accesses to the
cookies from user code. An array cookie is a small implementation-defined
@@ -2471,18 +2471,18 @@ functions are always poisoned.}]>,
Group<f_clang_Group>;
defm sanitize_address_globals_dead_stripping : BoolOption<"f", "sanitize-address-globals-dead-stripping",
CodeGenOpts<"SanitizeAddressGlobalsDeadStripping">, DefaultFalse,
- PosFlag<SetTrue, [], [ClangOption], "Enable linker dead stripping of globals in AddressSanitizer">,
- NegFlag<SetFalse, [], [ClangOption], "Disable linker dead stripping of globals in AddressSanitizer">>,
+ PosFlag<SetTrue, [], [ClangOption, FlangOption], "Enable linker dead stripping of globals in AddressSanitizer">,
+ NegFlag<SetFalse, [], [ClangOption, FlangOption], "Disable linker dead stripping of globals in AddressSanitizer">>,
Group<f_clang_Group>;
defm sanitize_address_use_odr_indicator : BoolOption<"f", "sanitize-address-use-odr-indicator",
CodeGenOpts<"SanitizeAddressUseOdrIndicator">, DefaultTrue,
- PosFlag<SetTrue, [], [ClangOption], "Enable ODR indicator globals to avoid false ODR violation"
+ PosFlag<SetTrue, [], [ClangOption, FlangOption], "Enable ODR indicator globals to avoid false ODR violation"
" reports in partially sanitized programs at the cost of an increase in binary size">,
- NegFlag<SetFalse, [], [ClangOption], "Disable ODR indicator globals">>,
+ NegFlag<SetFalse, [], [ClangOption, FlangOption], "Disable ODR indicator globals">>,
Group<f_clang_Group>;
def sanitize_address_destructor_EQ
: Joined<["-"], "fsanitize-address-destructor=">,
- Visibility<[ClangOption, CC1Option]>,
+ Visibility<[ClangOption, CC1Option, FlangOption, FC1Option]>,
HelpText<"Set the kind of module destructors emitted by "
"AddressSanitizer instrumentation. These destructors are "
"emitted to unregister instrumented global variables when "
@@ -2496,9 +2496,9 @@ defm sanitize_memory_param_retval
: BoolFOption<"sanitize-memory-param-retval",
CodeGenOpts<"SanitizeMemoryParamRetval">,
DefaultTrue,
- PosFlag<SetTrue, [], [ClangOption, CC1Option], "Enable">,
- NegFlag<SetFalse, [], [ClangOption], "Disable">,
- BothFlags<[], [ClangOption], " detection of uninitialized parameters and return values">>;
+ PosFlag<SetTrue, [], [ClangOption, CC1Option, FlangOption, FC1Option], "Enable">,
+ NegFlag<SetFalse, [], [ClangOption, FlangOption], "Disable">,
+ BothFlags<[], [ClangOption, FlangOption], " detection of uninitialized parameters and return values">>;
//// Note: This flag was introduced when it was necessary to distinguish between
// ABI for correct codegen. This is no longer needed, but the flag is
// not removed since targeting either ABI will behave the same.
@@ -2514,25 +2514,25 @@ def fsanitize_recover_EQ : CommaJoined<["-"], "fsanitize-recover=">,
HelpText<"Enable recovery for specified sanitizers">;
def fno_sanitize_recover_EQ : CommaJoined<["-"], "fno-sanitize-recover=">,
Group<f_clang_Group>,
- Visibility<[ClangOption, CLOption]>,
+ Visibility<[ClangOption, CLOption, FlangOption]>,
HelpText<"Disable recovery for specified sanitizers">;
def fsanitize_recover : Flag<["-"], "fsanitize-recover">, Group<f_clang_Group>,
Alias<fsanitize_recover_EQ>, AliasArgs<["all"]>;
def fno_sanitize_recover : Flag<["-"], "fno-sanitize-recover">,
- Visibility<[ClangOption, CLOption]>,
+ Visibility<[ClangOption, CLOption, FlangOption]>,
Group<f_clang_Group>,
Alias<fno_sanitize_recover_EQ>, AliasArgs<["all"]>;
def fsanitize_trap_EQ : CommaJoined<["-"], "fsanitize-trap=">, Group<f_clang_Group>,
HelpText<"Enable trapping for specified sanitizers">;
def fno_sanitize_trap_EQ : CommaJoined<["-"], "fno-sanitize-trap=">, Group<f_clang_Group>,
- Visibility<[ClangOption, CLOption]>,
+ Visibility<[ClangOption, CLOption, FlangOption]>,
HelpText<"Disable trapping for specified sanitizers">;
def fsanitize_trap : Flag<["-"], "fsanitize-trap">, Group<f_clang_Group>,
Alias<fsanitize_trap_EQ>, AliasArgs<["all"]>,
HelpText<"Enable trapping for all sanitizers">;
def fno_sanitize_trap : Flag<["-"], "fno-sanitize-trap">, Group<f_clang_Group>,
Alias<fno_sanitize_trap_EQ>, AliasArgs<["all"]>,
- Visibility<[ClangOption, CLOption]>,
+ Visibility<[ClangOption, CLOption, FlangOption]>,
HelpText<"Disable trapping for all sanitizers">;
def fsanitize_merge_handlers_EQ
: CommaJoined<["-"], "fsanitize-merge=">,
@@ -2547,7 +2547,7 @@ def fsanitize_merge_handlers : Flag<["-"], "fsanitize-merge">, Group<f_clang_Gro
HelpText<"Allow compiler to merge handlers for all sanitizers">;
def fno_sanitize_merge_handlers : Flag<["-"], "fno-sanitize-merge">, Group<f_clang_Group>,
Alias<fno_sanitize_merge_handlers_EQ>, AliasArgs<["all"]>,
- Visibility<[ClangOption, CLOption]>,
+ Visibility<[ClangOption, CLOption, FlangOption]>,
HelpText<"Do not allow compiler to merge handlers for any sanitizers">;
def fsanitize_annotate_debug_info_EQ
: CommaJoined<["-"], "fsanitize-annotate-debug-info=">,
@@ -2595,10 +2595,10 @@ def fno_sanitize_link_cxx_runtime : Flag<["-"], "fno-sanitize-link-c++-runtime">
Group<f_clang_Group>;
defm sanitize_cfi_cross_dso : BoolOption<"f", "sanitize-cfi-cross-dso",
CodeGenOpts<"SanitizeCfiCrossDso">, DefaultFalse,
- PosFlag<SetTrue, [], [ClangOption], "Enable">,
- NegFlag<SetFalse, [], [ClangOption, CLOption],
+ PosFlag<SetTrue, [], [ClangOption, FlangOption], "Enable">,
+ NegFlag<SetFalse, [], [ClangOption, CLOption, FlangOption],
"Disable">,
- BothFlags<[], [ClangOption], " control flow integrity (CFI) checks for cross-DSO calls.">>,
+ BothFlags<[], [ClangOption, FlangOption], " control flow integrity (CFI) checks for cross-DSO calls.">>,
Group<f_clang_Group>;
def fsanitize_cfi_icall_generalize_pointers : Flag<["-"], "fsanitize-cfi-icall-generalize-pointers">,
Group<f_clang_Group>,
@@ -2610,10 +2610,10 @@ def fsanitize_cfi_icall_normalize_integers : Flag<["-"], "fsanitize-cfi-icall-ex
MarshallingInfoFlag<CodeGenOpts<"SanitizeCfiICallNormalizeIntegers">>;
defm sanitize_cfi_canonical_jump_tables : BoolOption<"f", "sanitize-cfi-canonical-jump-tables",
CodeGenOpts<"SanitizeCfiCanonicalJumpTables">, DefaultFalse,
- PosFlag<SetTrue, [], [ClangOption], "Make">,
- NegFlag<SetFalse, [], [ClangOption, CLOption],
+ PosFlag<SetTrue, [], [ClangOption, FlangOption], "Make">,
+ NegFlag<SetFalse, [], [ClangOption, CLOption, FlangOption],
"Do not make">,
- BothFlags<[], [ClangOption], " the jump table addresses canonical in the symbol table">>,
+ BothFlags<[], [ClangOption, FlangOption], " the jump table addresses canonical in the symbol table">>,
Group<f_clang_Group>;
def fsanitize_kcfi_arity : Flag<["-"], "fsanitize-kcfi-arity">,
Group<f_clang_Group>,
@@ -2621,14 +2621,14 @@ def fsanitize_kcfi_arity : Flag<["-"], "fsanitize-kcfi-arity">,
MarshallingInfoFlag<CodeGenOpts<"SanitizeKcfiArity">>;
defm sanitize_stats : BoolOption<"f", "sanitize-stats",
CodeGenOpts<"SanitizeStats">, DefaultFalse,
- PosFlag<SetTrue, [], [ClangOption], "Enable">,
- NegFlag<SetFalse, [], [ClangOption, CLOption],
+ PosFlag<SetTrue, [], [ClangOption, FlangOption], "Enable">,
+ NegFlag<SetFalse, [], [ClangOption, CLOption, FlangOption],
"Disable">,
- BothFlags<[], [ClangOption], " sanitizer statistics gathering.">>,
+ BothFlags<[], [ClangOption, FlangOption], " sanitizer statistics gathering.">>,
Group<f_clang_Group>;
def fsanitize_undefined_ignore_overflow_pattern_EQ : CommaJoined<["-"], "fsanitize-undefined-ignore-overflow-pattern=">,
HelpText<"Specify the overflow patterns to exclude from arithmetic sanitizer instrumentation">,
- Visibility<[ClangOption, CC1Option]>,
+ Visibility<[ClangOption, CC1Option, FlangOption, FC1Option]>,
Values<"none,all,add-unsigned-overflow-test,add-signed-overflow-test,negated-unsigned-const,unsigned-post-decr-while">,
MarshallingInfoStringVector<LangOpts<"OverflowPatternExclusionValues">>;
def fsanitize_thread_memory_access : Flag<["-"], "fsanitize-thread-memory-access">,
@@ -2636,21 +2636,21 @@ def fsanitize_thread_memory_access : Flag<["-"], "fsanitize-thread-memory-access
HelpText<"Enable memory access instrumentation in ThreadSanitizer (default)">;
def fno_sanitize_thread_memory_access : Flag<["-"], "fno-sanitize-thread-memory-access">,
Group<f_clang_Group>,
- Visibility<[ClangOption, CLOption]>,
+ Visibility<[ClangOption, CLOption, FlangOption]>,
HelpText<"Disable memory access instrumentation in ThreadSanitizer">;
def fsanitize_thread_func_entry_exit : Flag<["-"], "fsanitize-thread-func-entry-exit">,
Group<f_clang_Group>,
HelpText<"Enable function entry/exit instrumentation in ThreadSanitizer (default)">;
def fno_sanitize_thread_func_entry_exit : Flag<["-"], "fno-sanitize-thread-func-entry-exit">,
Group<f_clang_Group>,
- Visibility<[ClangOption, CLOption]>,
+ Visibility<[ClangOption, CLOption, FlangOption]>,
HelpText<"Disable function entry/exit instrumentation in ThreadSanitizer">;
def fsanitize_thread_atomics : Flag<["-"], "fsanitize-thread-atomics">,
Group<f_clang_Group>,
HelpText<"Enable atomic operations instrumentation in ThreadSanitizer (default)">;
def fno_sanitize_thread_atomics : Flag<["-"], "fno-sanitize-thread-atomics">,
Group<f_clang_Group>,
- Visibility<[ClangOption, CLOption]>,
+ Visibility<[ClangOption, CLOption, FlangOption]>,
HelpText<"Disable atomic operations instrumentation in ThreadSanitizer">;
def fsanitize_undefined_strip_path_components_EQ : Joined<["-"], "fsanitize-undefined-strip-path-components=">,
Group<f_clang_Group>, MetaVarName<"<number>">,
@@ -3448,7 +3448,7 @@ def fno_asm : Flag<["-"], "fno-asm">, Group<f_Group>;
def fno_asynchronous_unwind_tables : Flag<["-"], "fno-asynchronous-unwind-tables">, Group<f_Group>;
def fno_assume_sane_operator_new : Flag<["-"], "fno-assume-sane-operator-new">, Group<f_Group>,
HelpText<"Don't assume that C++'s global operator new can't alias any pointer">,
- Visibility<[ClangOption, CC1Option]>,
+ Visibility<[ClangOption, CC1Option, FlangOption, FC1Option]>,
MarshallingInfoNegativeFlag<CodeGenOpts<"AssumeSaneOperatorNew">>;
def fno_builtin : Flag<["-"], "fno-builtin">, Group<f_Group>,
Visibility<[ClangOption, CC1Option, CLOption, DXCOption]>,
diff --git a/clang/lib/Driver/ToolChains/Flang.cpp b/clang/lib/Driver/ToolChains/Flang.cpp
index b1ca747e68b89..52608715e7d4f 100644
--- a/clang/lib/Driver/ToolChains/Flang.cpp
+++ b/clang/lib/Driver/ToolChains/Flang.cpp
@@ -12,6 +12,7 @@
#include "clang/Basic/CodeGenOptions.h"
#include "clang/Driver/Options.h"
+#include "clang/Driver/SanitizerArgs.h"
#include "llvm/Frontend/Debug/Options.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Path.h"
@@ -143,6 +144,15 @@ void Flang::addOtherOptions(const ArgList &Args, ArgStringList &CmdArgs) const {
addDebugInfoKind(CmdArgs, DebugInfoKind);
}
+void Flang::addSanitizerOptions(const ToolChain &TC, const ArgList &Args,
+ ArgStringList &CmdArgs,
+ types::ID InputType) const {
+ SanitizerArgs SanArgs = TC.getSanitizerArgs(Args);
+ SanArgs.addArgs(TC, Args, CmdArgs, InputType);
+ // If Tc.getTriple() == amdgpu search for only allow -fsanitize=address for
+ // that target
+}
+
void Flang::addCodegenOptions(const ArgList &Args,
ArgStringList &CmdArgs) const {
Arg *stackArrays =
@@ -869,6 +879,9 @@ void Flang::ConstructJob(Compilation &C, const JobAction &JA,
// Add Codegen options
addCodegenOptions(Args, CmdArgs);
+ // Add Sanitizer Options
+ addSanitizerOptions(TC, Args, CmdArgs, InputType);
+
// Add R Group options
Args.AddAllArgs(CmdArgs, options::OPT_R_Group);
diff --git a/clang/lib/Driver/ToolChains/Flang.h b/clang/lib/Driver/ToolChains/Flang.h
index 7c24a623af393..2b61955af7764 100644
--- a/clang/lib/Driver/ToolChains/Flang.h
+++ b/clang/lib/Driver/ToolChains/Flang.h
@@ -117,6 +117,15 @@ class LLVM_LIBRARY_VISIBILITY Flang : public Tool {
void addCodegenOptions(const llvm::opt::ArgList &Args,
llvm::opt::ArgStringList &CmdArgs) const;
+ /// Extract sanitizer options for code generation from the driver arguments
+ /// and add them to the command arguments.
+ ///
+ /// \param [in] Args The list of input driver arguments
+ /// \param [out] CmdArgs The list of output command arguments
+ void addSanitizerOptions(const ToolChain &TC, const llvm::opt::ArgList &Args,
+ llvm::opt::ArgStringList &CmdArgs,
+ types::ID InputType) const;
+
/// Extract other compilation options from the driver arguments and add them
/// to the command arguments.
///
diff --git a/flang/include/flang/Frontend/CodeGenOptions.def b/flang/include/flang/Frontend/CodeGenOptions.def
index d9dbd274e83e5..fa707c4ddbfcc 100644
--- a/flang/include/flang/Frontend/CodeGenOptions.def
+++ b/flang/include/flang/Frontend/CodeGenOptions.def
@@ -47,5 +47,72 @@ ENUM_CODEGENOPT(FramePointer, llvm::FramePointerKind, 2, llvm::FramePointerKind:
ENUM_CODEGENOPT(DoConcurrentMapping, DoConcurrentMappingKind, 2, DoConcurrentMappingKind::DCMK_None) ///< Map `do concurrent` to OpenMP
+CODEGENOPT(SanitizeAddressUseAfterScope , 1, 0) ///< Enable use-after-scope detection
+ ///< in AddressSanitizer
+ENUM_CODEGENOPT(SanitizeAddressUseAfterReturn,
+ llvm::AsanDetectStackUseAfterReturnMode, 2,
+ llvm::AsanDetectStackUseAfterReturnMode::Runtime
+ ) ///< Set detection mode for stack-use-after-return.
+CODEGENOPT(SanitizeAddressPoisonCustomArrayCookie, 1,
+ 0) ///< Enable poisoning operator new[] which is not a replaceable
+ ///< global allocation function in AddressSanitizer
+CODEGENOPT(SanitizeAddressGlobalsDeadStripping, 1, 0) ///< Enable linker dead stripping
+ ///< of globals in AddressSanitizer
+CODEGENOPT(SanitizeAddressUseOdrIndicator, 1, 0) ///< Enable ODR indicator globals
+CODEGENOPT(SanitizeMemoryTrackOrigins, 2, 0) ///< Enable tracking origins in
+ ///< MemorySanitizer
+ENUM_CODEGENOPT(SanitizeAddressDtor, llvm::AsanDtorKind, 2,
+ llvm::AsanDtorKind::Global) ///< Set how ASan global
+ ///< destructors are emitted.
+CODEGENOPT(SanitizeMemoryParamRetval, 1, 0) ///< Enable detection of uninitialized
+ ///< parameters and return values
+ ///< in MemorySanitizer
+CODEGENOPT(SanitizeMemoryUseAfterDtor, 1, 0) ///< Enable use-after-delete detection
+ ///< in MemorySanitizer
+CODEGENOPT(SanitizeCfiCrossDso, 1, 0) ///< Enable cross-dso support in CFI.
+CODEGENOPT(SanitizeMinimalRuntime, 1, 0) ///< Use "_minimal" sanitizer runtime for
+ ///< diagnostics.
+CODEGENOPT(SanitizeCfiICallGeneralizePointers, 1, 0) ///< Generalize pointer types in
+ ///< CFI icall function signatures
+CODEGENOPT(SanitizeCfiICallNormalizeIntegers, 1, 0) ///< Normalize integer types in
+ ///< CFI icall function signatures
+CODEGENOPT(SanitizeCfiCanonicalJumpTables, 1, 0) ///< Make jump table symbols canonical
+ ///< instead of creating a local jump table.
+CODEGENOPT(UniqueSourceFileNames, 1, 0) ///< Allow the compiler to assume that TUs
+ ///< have unique source file names at link time
+CODEGENOPT(SanitizeKcfiArity, 1, 0) ///< Embed arity in KCFI patchable function prefix
+CODEGENOPT(SanitizeCoverageType, 2, 0) ///< Type of sanitizer coverage
+ ///< instrumentation.
+CODEGENOPT(SanitizeCoverageIndirectCalls, 1, 0) ///< Enable sanitizer coverage
+ ///< for indirect calls.
+CODEGENOPT(SanitizeCoverageTraceBB, 1, 0) ///< Enable basic block tracing in
+ ///< in sanitizer coverage.
+CODEGENOPT(SanitizeCoverageTraceCmp, 1, 0) ///< Enable cmp instruction tracing
+ ///< in sanitizer coverage.
+CODEGENOPT(SanitizeCoverageTraceDiv, 1, 0) ///< Enable div instruction tracing
+ ///< in sanitizer coverage.
+CODEGENOPT(SanitizeCoverageTraceGep, 1, 0) ///< Enable GEP instruction tracing
+ ///< in sanitizer coverage.
+CODEGENOPT(SanitizeCoverage8bitCounters, 1, 0) ///< Use 8-bit frequency counters
+ ///< in sanitizer coverage.
+CODEGENOPT(SanitizeCoverageTracePC, 1, 0) ///< Enable PC tracing
+ ///< in sanitizer coverage.
+CODEGENOPT(SanitizeCoverageTracePCGuard, 1, 0) ///< Enable PC tracing with guard
+ ///< in sanitizer coverage.
+CODEGENOPT(SanitizeCoverageInline8bitCounters, 1, 0) ///< Use inline 8bit counters.
+CODEGENOPT(SanitizeCoverageInlineBoolFlag, 1, 0) ///< Use inline bool flag.
+CODEGENOPT(SanitizeCoveragePCTable, 1, 0) ///< Create a PC Table.
+CODEGENOPT(SanitizeCoverageControlFlow, 1, 0) ///< Collect control flow
+CODEGENOPT(SanitizeCoverageNoPrune, 1, 0) ///< Disable coverage pruning.
+CODEGENOPT(SanitizeCoverageStackDepth, 1, 0) ///< Enable max stack depth tracing
+CODEGENOPT(SanitizeCoverageTraceLoads, 1, 0) ///< Enable tracing of loads.
+CODEGENOPT(SanitizeCoverageTraceStores, 1, 0) ///< Enable tracing of stores.
+CODEGENOPT(SanitizeBinaryMetadataCovered, 1, 0) ///< Emit PCs for covered functions.
+CODEGENOPT(SanitizeBinaryMetadataAtomics, 1, 0) ///< Emit PCs for atomic operations.
+CODEGENOPT(SanitizeBinaryMetadataUAR, 1, 0) ///< Emit PCs for start of functions
+ ///< that are subject for use-after-return checking.
+CODEGENOPT(SanitizeStats , 1, 0) ///< Collect statistics for sanitizers.
+CODEGENOPT(DisableIntegratedAS, 1, 0) ///< -no-integrated-as
+
#undef CODEGENOPT
#undef ENUM_CODEGENOPT
diff --git a/flang/include/flang/Frontend/CodeGenOptions.h b/flang/include/flang/Frontend/CodeGenOptions.h
index 2b4e823b3fef4..b2a799682dfe1 100644
--- a/flang/include/flang/Frontend/CodeGenOptions.h
+++ b/flang/include/flang/Frontend/CodeGenOptions.h
@@ -16,6 +16,7 @@
#define FORTRAN_FRONTEND_CODEGENOPTIONS_H
#include "flang/Optimizer/OpenMP/Utils.h"
+#include "clang/Basic/Sanitizers.h"
#include "llvm/Frontend/Debug/Options.h"
#include "llvm/Frontend/Driver/CodeGenOptions.h"
#include "llvm/Support/CodeGen.h"
@@ -148,6 +149,50 @@ class CodeGenOptions : public CodeGenOptionsBase {
/// OpenMP is enabled.
using DoConcurrentMappingKind = flangomp::DoConcurrentMappingKind;
+ /// Set of sanitizer checks that are non-fatal (i.e. execution should be
+ /// continued when possible).
+ clang::SanitizerSet SanitizeRecover;
+
+ /// Set of sanitizer checks that trap rather than diagnose.
+ clang::SanitizerSet SanitizeTrap;
+
+ /// Set of sanitizer checks that can merge handlers (smaller code size at
+ /// the expense of debuggability).
+ clang::SanitizerSet SanitizeMergeHandlers;
+
+ /// Set of thresholds in a range [0.0, 1.0]: the top hottest code responsible
+ /// for the given fraction of PGO counters will be excluded from sanitization
+ /// (0.0 [default] to skip none, 1.0 to skip all).
+ clang::SanitizerMaskCutoffs SanitizeSkipHotCutoffs;
+
+ /// Path to allowlist file specifying which objects
+ /// (files, functions) should exclusively be instrumented
+ /// by sanitizer coverage pass.
+ std::vector<std::string> SanitizeCoverageAllowlistFiles;
+
+ /// Path to ignorelist file specifying which objects
+ /// (files, functions) listed for instrumentation by sanitizer
+ /// coverage pass should actually not be instrumented.
+ std::vector<std::string> SanitizeCoverageIgnorelistFiles;
+
+ /// Path to ignorelist file specifying which objects
+ /// (files, functions) listed for instrumentation by sanitizer
+ /// binary metadata pass should not be instrumented.
+ std::vector<std::string> SanitizeMetadataIgnorelistFiles;
+
+ // Check if any one of SanitizeCoverage* is enabled.
+ bool hasSanitizeCoverage() const {
+ return SanitizeCoverageType || SanitizeCoverageIndirectCalls ||
+ SanitizeCoverageTraceCmp || SanitizeCoverageTraceLoads ||
+ SanitizeCoverageTraceStores || SanitizeCoverageControlFlow;
+ }
+
+ // Check if any one of SanitizeBinaryMetadata* is enabled.
+ bool hasSanitizeBinaryMetadata() const {
+ return SanitizeBinaryMetadataCovered || SanitizeBinaryMetadataAtomics ||
+ SanitizeBinaryMetadataUAR;
+ }
+
// Define accessors/mutators for code generation options of enumeration type.
#define CODEGENOPT(Name, Bits, Default)
#define ENUM_CODEGENOPT(Name, Type, Bits, Default) \
@@ -158,6 +203,8 @@ class CodeGenOptions : public CodeGenOptionsBase {
CodeGenOptions();
};
+bool asanUseGlobalsGC(const llvm::Triple &T, const CodeGenOptions &CGOpts);
+
std::optional<llvm::CodeModel::Model> getCodeModel(llvm::StringRef string);
} // end namespace Fortran::frontend
diff --git a/flang/include/flang/Support/LangOptions.def b/flang/include/flang/Support/LangOptions.def
index d5bf7a2ecc036..9bc2c6ca5b10d 100644
--- a/flang/include/flang/Support/LangOptions.def
+++ b/flang/include/flang/Support/LangOptions.def
@@ -62,5 +62,6 @@ LANGOPT(OpenMPNoNestedParallelism, 1, 0)
LANGOPT(VScaleMin, 32, 0) ///< Minimum vscale range value
LANGOPT(VScaleMax, 32, 0) ///< Maximum vscale range value
+LANGOPT(SanitizeAddressFieldPadding, 2, 0)
#undef LANGOPT
#undef ENUM_LANGOPT
diff --git a/flang/include/flang/Support/LangOptions.h b/flang/include/flang/Support/LangOptions.h
index 1dd676e62a9e5..00c6bf743ce60 100644
--- a/flang/include/flang/Support/LangOptions.h
+++ b/flang/include/flang/Support/LangOptions.h
@@ -18,10 +18,10 @@
#include <string>
#include <vector>
+#include "clang/Basic/Sanitizers.h"
#include "llvm/TargetParser/Triple.h"
namespace Fortran::common {
-
/// Bitfields of LangOptions, split out from LangOptions to ensure
/// that this large collection of bitfields is a trivial class type.
class LangOptionsBase {
@@ -72,6 +72,15 @@ class LangOptions : public LangOptionsBase {
/// host code generation.
std::string OMPHostIRFile;
+ /// Set of enabled sanitizers.
+ clang::SanitizerSet Sanitize;
+ /// Is at least one coverage instrumentation type enabled.
+ bool SanitizeCoverage = false;
+
+ /// Paths to files specifying which objects
+ /// (files, functions, variables) should not be instrumented.
+ std::vector<std::string> NoSanitizeFiles;
+
/// List of triples passed in using -fopenmp-targets.
std::vector<llvm::Triple> OMPTargetTriples;
diff --git a/flang/lib/Frontend/CodeGenOptions.cpp b/flang/lib/Frontend/CodeGenOptions.cpp
index 8a9d3c27c8bc3..18988ec5d3f78 100644
--- a/flang/lib/Frontend/CodeGenOptions.cpp
+++ b/flang/lib/Frontend/CodeGenOptions.cpp
@@ -11,17 +11,46 @@
//===----------------------------------------------------------------------===//
#include "flang/Frontend/CodeGenOptions.h"
+#include "llvm/TargetParser/Triple.h"
#include <optional>
#include <string.h>
namespace Fortran::frontend {
+using namespace llvm;
+
CodeGenOptions::CodeGenOptions() {
#define CODEGENOPT(Name, Bits, Default) Name = Default;
#define ENUM_CODEGENOPT(Name, Type, Bits, Default) set##Name(Default);
#include "flang/Frontend/CodeGenOptions.def"
}
+// Check if ASan should use GC-friendly instrumentation for globals.
+// First of all, there is no point if -fdata-sections is off (expect for MachO,
+// where this is not a factor). Also, on ELF this feature requires an assembler
+// extension that only works with -integrated-as at the moment.
+bool asanUseGlobalsGC(const Triple &T, const CodeGenOptions &CGOpts) {
+ if (!CGOpts.SanitizeAddressGlobalsDeadStripping)
+ return false;
+ switch (T.getObjectFormat()) {
+ case Triple::MachO:
+ case Triple::COFF:
+ return true;
+ case Triple::ELF:
+ return !CGOpts.DisableIntegratedAS;
+ case Triple::GOFF:
+ llvm::report_fatal_error("ASan not implemented for GOFF");
+ case Triple::XCOFF:
+ llvm::report_fatal_error("ASan not implemented for XCOFF.");
+ case Triple::Wasm:
+ case Triple::DXContainer:
+ case Triple::SPIRV:
+ case Triple::UnknownObjectFormat:
+ break;
+ }
+ return false;
+}
+
std::optional<llvm::CodeModel::Model> getCodeModel(llvm::StringRef string) {
return llvm::StringSwitch<std::optional<llvm::CodeModel::Model>>(string)
.Case("tiny", llvm::CodeModel::Model::Tiny)
diff --git a/flang/lib/Frontend/CompilerInvocation.cpp b/flang/lib/Frontend/CompilerInvocation.cpp
index 238079a09ef3a..7283cd90843d0 100644
--- a/flang/lib/Frontend/CompilerInvocation.cpp
+++ b/flang/lib/Frontend/CompilerInvocation.cpp
@@ -23,6 +23,7 @@
#include "clang/Basic/AllDiagnostics.h"
#include "clang/Basic/DiagnosticDriver.h"
#include "clang/Basic/DiagnosticOptions.h"
+#include "clang/Basic/Sanitizers.h"
#include "clang/Driver/Driver.h"
#include "clang/Driver/DriverDiagnostic.h"
#include "clang/Driver/OptionUtils.h"
@@ -256,6 +257,82 @@ parseOptimizationRemark(clang::DiagnosticsEngine &diags,
return result;
}
+static void parseSanitizerKinds(llvm::StringRef FlagName,
+ const std::vector<std::string> &Sanitizers,
+ clang::DiagnosticsEngine &Diags,
+ clang::SanitizerSet &S) {
+ for (const auto &Sanitizer : Sanitizers) {
+ clang::SanitizerMask K =
+ clang::parseSanitizerValue(Sanitizer, /*AllowGroups=*/false);
+ if (K == clang::SanitizerMask())
+ Diags.Report(clang::diag::err_drv_invalid_value) << FlagName << Sanitizer;
+ else
+ S.set(K, true);
+ }
+}
+
+static llvm::SmallVector<llvm::StringRef, 4>
+serializeSanitizerKinds(clang::SanitizerSet S) {
+ llvm::SmallVector<llvm::StringRef, 4> Values;
+ serializeSanitizerSet(S, Values);
+ return Values;
+}
+
+static clang::SanitizerMaskCutoffs
+parseSanitizerWeightedKinds(llvm::StringRef FlagName,
+ const std::vector<std::string> &Sanitizers,
+ clang::DiagnosticsEngine &Diags) {
+ clang::SanitizerMaskCutoffs Cutoffs;
+ for (const auto &Sanitizer : Sanitizers) {
+ if (!parseSanitizerWeightedValue(Sanitizer, /*AllowGroups=*/false, Cutoffs))
+ Diags.Report(clang::diag::err_drv_invalid_value) << FlagName << Sanitizer;
+ }
+ return Cutoffs;
+}
+
+static bool parseSanitizerArgs(CompilerInvocation &res,
+ llvm::opt::ArgList &args,
+ clang::DiagnosticsEngine &diags) {
+ auto &LangOpts = res.getLangOpts();
+ auto &CodeGenOpts = res.getCodeGenOpts();
+
+ parseSanitizerKinds(
+ "-fsanitize-recover=",
+ args.getAllArgValues(clang::driver::options::OPT_fsanitize_recover_EQ),
+ diags, CodeGenOpts.SanitizeRecover);
+ parseSanitizerKinds(
+ "-fsanitize-trap=",
+ args.getAllArgValues(clang::driver::options::OPT_fsanitize_trap_EQ),
+ diags, CodeGenOpts.SanitizeTrap);
+ parseSanitizerKinds(
+ "-fsanitize-merge=",
+ args.getAllArgValues(
+ clang::driver::options::OPT_fsanitize_merge_handlers_EQ),
+ diags, CodeGenOpts.SanitizeMergeHandlers);
+
+ // Parse -fsanitize-skip-hot-cutoff= arguments.
+ CodeGenOpts.SanitizeSkipHotCutoffs = parseSanitizerWeightedKinds(
+ "-fsanitize-skip-hot-cutoff=",
+ args.getAllArgValues(
+ clang::driver::options::OPT_fsanitize_skip_hot_cutoff_EQ),
+ diags);
+
+ // Parse -fsanitize= arguments.
+ parseSanitizerKinds(
+ "-fsanitize=",
+ args.getAllArgValues(clang::driver::options::OPT_fsanitize_EQ), diags,
+ LangOpts.Sanitize);
+
+ LangOpts.NoSanitizeFiles =
+ args.getAllArgValues(clang::driver::options::OPT_fsanitize_ignorelist_EQ);
+ std::vector<std::string> systemIgnorelists = args.getAllArgValues(
+ clang::driver::options::OPT_fsanitize_system_ignorelist_EQ);
+ LangOpts.NoSanitizeFiles.insert(LangOpts.NoSanitizeFiles.end(),
+ systemIgnorelists.begin(),
+ systemIgnorelists.end());
+ return true;
+}
+
static void parseCodeGenArgs(Fortran::frontend::CodeGenOptions &opts,
llvm::opt::ArgList &args,
clang::DiagnosticsEngine &diags) {
@@ -395,6 +472,10 @@ static void parseCodeGenArgs(Fortran::frontend::CodeGenOptions &opts,
opts.RecordCommandLine = a->getValue();
}
+ // -mlink-bitcode-file
+ for (auto *a : args.filtered(clang::driver::options::OPT_mlink_bitcode_file))
+ opts.BuiltinBCLibs.push_back(a->getValue());
+
// -mlink-builtin-bitcode
for (auto *a :
args.filtered(clang::driver::options::OPT_mlink_builtin_bitcode))
@@ -1500,6 +1581,7 @@ bool CompilerInvocation::createFromArgs(
success &= parseVectorLibArg(invoc.getCodeGenOpts(), args, diags);
success &= parseSemaArgs(invoc, args, diags);
success &= parseDialectArgs(invoc, args, diags);
+ success &= parseSanitizerArgs(invoc, args, diags);
success &= parseOpenMPArgs(invoc, args, diags);
success &= parseDiagArgs(invoc, args, diags);
diff --git a/flang/lib/Frontend/FrontendActions.cpp b/flang/lib/Frontend/FrontendActions.cpp
index e5a15c555fa5e..e6ab0402ce6b2 100644
--- a/flang/lib/Frontend/FrontendActions.cpp
+++ b/flang/lib/Frontend/FrontendActions.cpp
@@ -26,6 +26,7 @@
#include "flang/Optimizer/Transforms/Passes.h"
#include "flang/Semantics/runtime-type-info.h"
#include "flang/Semantics/unparse-with-symbols.h"
+#include "flang/Support/LangOptions.h"
#include "flang/Support/default-kinds.h"
#include "flang/Tools/CrossToolHelpers.h"
@@ -67,7 +68,10 @@
#include "llvm/TargetParser/RISCVISAInfo.h"
#include "llvm/TargetParser/RISCVTargetParser.h"
#include "llvm/Transforms/IPO/Internalize.h"
+#include "llvm/Transforms/Instrumentation/AddressSanitizer.h"
+#include "llvm/Transforms/Instrumentation/AddressSanitizerOptions.h"
#include "llvm/Transforms/Utils/ModuleUtils.h"
+#include <clang/Basic/Sanitizers.h>
#include <memory>
#include <system_error>
@@ -714,6 +718,7 @@ void CodeGenAction::generateLLVMIR() {
CompilerInstance &ci = this->getInstance();
CompilerInvocation &invoc = ci.getInvocation();
const CodeGenOptions &opts = invoc.getCodeGenOpts();
+ const common::LangOptions &langopts = invoc.getLangOpts();
const auto &mathOpts = invoc.getLoweringOpts().getMathOptions();
llvm::OptimizationLevel level = mapToLevel(opts);
mlir::DefaultTimingManager &timingMgr = ci.getTimingManager();
@@ -787,6 +792,11 @@ void CodeGenAction::generateLLVMIR() {
return;
}
+ for (llvm::Function &F : llvmModule->getFunctionList()) {
+ if (langopts.Sanitize.has(clang::SanitizerKind::Address))
+ F.addFnAttr(llvm::Attribute::SanitizeAddress);
+ }
+
// Set PIC/PIE level LLVM module flags.
if (opts.PICLevel > 0) {
llvmModule->setPICLevel(static_cast<llvm::PICLevel::Level>(opts.PICLevel));
@@ -899,9 +909,34 @@ static void generateMachineCodeOrAssemblyImpl(clang::DiagnosticsEngine &diags,
delete tlii;
}
+void addSanitizers(const llvm::Triple &Triple,
+ const CodeGenOptions &flangCodeGenOpts,
+ const Fortran::common::LangOptions &flangLangOpts,
+ llvm::PassBuilder &PB, llvm::ModulePassManager &MPM) {
+ auto ASanPass = [&](clang::SanitizerMask Mask, bool CompileKernel) {
+ if (flangLangOpts.Sanitize.has(Mask)) {
+ bool UseGlobalGC = asanUseGlobalsGC(Triple, flangCodeGenOpts);
+ bool UseOdrIndicator = flangCodeGenOpts.SanitizeAddressUseOdrIndicator;
+ llvm::AsanDtorKind DestructorKind =
+ flangCodeGenOpts.getSanitizeAddressDtor();
+ llvm::AddressSanitizerOptions Opts;
+ Opts.CompileKernel = CompileKernel;
+ Opts.Recover = flangCodeGenOpts.SanitizeRecover.has(Mask);
+ Opts.UseAfterScope = flangCodeGenOpts.SanitizeAddressUseAfterScope;
+ Opts.UseAfterReturn = flangCodeGenOpts.getSanitizeAddressUseAfterReturn();
+ MPM.addPass(llvm::AddressSanitizerPass(Opts, UseGlobalGC, UseOdrIndicator,
+ DestructorKind));
+ }
+ };
+ ASanPass(clang::SanitizerKind::Address, false);
+ ASanPass(clang::SanitizerKind::KernelAddress, true);
+}
+
void CodeGenAction::runOptimizationPipeline(llvm::raw_pwrite_stream &os) {
CompilerInstance &ci = getInstance();
const CodeGenOptions &opts = ci.getInvocation().getCodeGenOpts();
+ const Fortran::common::LangOptions &langopts =
+ ci.getInvocation().getLangOpts();
clang::DiagnosticsEngine &diags = ci.getDiagnostics();
llvm::OptimizationLevel level = mapToLevel(opts);
@@ -966,6 +1001,8 @@ void CodeGenAction::runOptimizationPipeline(llvm::raw_pwrite_stream &os) {
else
mpm = pb.buildPerModuleDefaultPipeline(level);
+ addSanitizers(triple, opts, langopts, pb, mpm);
+
if (action == BackendActionTy::Backend_EmitBC)
mpm.addPass(llvm::BitcodeWriterPass(os));
else if (action == BackendActionTy::Backend_EmitLL)
More information about the cfe-commits
mailing list