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.kumaramit2...@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.kumaramit2...@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)

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to