diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 0eec2b3526376..2fcc31495cdb5 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -2163,14 +2163,14 @@ def fmemory_profile_use_EQ : Joined<["-"], "fmemory-profile-use=">, HelpText<"Use memory profile for profile-guided memory optimization">, MarshallingInfoString>; +def fsanitize_EQ : CommaJoined<["-"], "fsanitize=">, Group, + MetaVarName<"">, Visibility<[ClangOption, CC1Option, FlangOption, FC1Option]>, + HelpText<"Turn on runtime checks for various forms of undefined " + "or suspicious behavior. See user manual for available checks">; // Begin sanitizer flags. These should all be core options exposed in all driver // modes. let Visibility = [ClangOption, CC1Option, CLOption] in { -def fsanitize_EQ : CommaJoined<["-"], "fsanitize=">, Group, - MetaVarName<"">, - 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, Visibility<[ClangOption, CLOption]>; diff --git a/clang/lib/Driver/ToolChains/Flang.cpp b/clang/lib/Driver/ToolChains/Flang.cpp index 9b21fe952af7a..7d433455f24cc 100644 --- a/clang/lib/Driver/ToolChains/Flang.cpp +++ b/clang/lib/Driver/ToolChains/Flang.cpp @@ -38,6 +38,7 @@ void Flang::addFortranDialectOptions(const ArgList &Args, options::OPT_fopenmp, options::OPT_fopenmp_version_EQ, options::OPT_fopenacc, + options::OPT_fsanitize_EQ, options::OPT_finput_charset_EQ, options::OPT_fimplicit_none, options::OPT_fno_implicit_none, diff --git a/flang/include/flang/Common/Fortran-features.h b/flang/include/flang/Common/Fortran-features.h index a6b19e9833fc5..d3d4556b9cdbf 100644 --- a/flang/include/flang/Common/Fortran-features.h +++ b/flang/include/flang/Common/Fortran-features.h @@ -35,7 +35,7 @@ ENUM_CLASS(LanguageFeature, BackslashEscapes, OldDebugLines, ProgramReturn, ImplicitNoneTypeNever, ImplicitNoneTypeAlways, ForwardRefImplicitNone, OpenAccessAppend, BOZAsDefaultInteger, DistinguishableSpecifics, DefaultSave, PointerInSeqType, NonCharacterFormat, - SaveMainProgram, SaveBigMainProgramVariables, + SaveMainProgram, SaveBigMainProgramVariables, TSan, DistinctArrayConstructorLengths, PPCVector, RelaxedIntentInChecking, ForwardRefImplicitNoneData, NullActualForAllocatable, ActualIntegerConvertedToSmallerKind, HollerithOrCharacterAsBOZ, @@ -65,6 +65,7 @@ class LanguageFeatureControl { disable_.set(LanguageFeature::OldDebugLines); disable_.set(LanguageFeature::OpenACC); disable_.set(LanguageFeature::OpenMP); + disable_.set(LanguageFeature::TSan); disable_.set(LanguageFeature::CUDA); // !@cuf disable_.set(LanguageFeature::ImplicitNoneTypeNever); disable_.set(LanguageFeature::ImplicitNoneTypeAlways); diff --git a/flang/lib/Frontend/CompilerInvocation.cpp b/flang/lib/Frontend/CompilerInvocation.cpp index c623969a21e5e..6b3c0706c9273 100644 --- a/flang/lib/Frontend/CompilerInvocation.cpp +++ b/flang/lib/Frontend/CompilerInvocation.cpp @@ -862,6 +862,10 @@ static bool parseDialectArgs(CompilerInvocation &res, llvm::opt::ArgList &args, res.getFrontendOpts().features.Enable( Fortran::common::LanguageFeature::OpenACC); } + if (args.hasArg(clang::driver::options::OPT_fsanitize_EQ) && llvm::StringRef(args.getLastArg(clang::driver::options::OPT_fsanitize_EQ)->getValue()) == "thread" ) { + res.getFrontendOpts().features.Enable( + Fortran::common::LanguageFeature::TSan); + } if (args.hasArg(clang::driver::options::OPT_fopenmp)) { // By default OpenMP is set to 1.1 version res.getLangOpts().OpenMPVersion = 11; diff --git a/flang/lib/Frontend/FrontendActions.cpp b/flang/lib/Frontend/FrontendActions.cpp index 1be95cc27f42c..423e121cdf3dc 100644 --- a/flang/lib/Frontend/FrontendActions.cpp +++ b/flang/lib/Frontend/FrontendActions.cpp @@ -67,6 +67,9 @@ #include "llvm/Target/TargetMachine.h" #include "llvm/TargetParser/TargetParser.h" #include "llvm/Transforms/Utils/ModuleUtils.h" +#include "llvm/Transforms/Instrumentation.h" +#include "llvm/Transforms/Instrumentation/ThreadSanitizer.h" + #include #include @@ -1073,6 +1076,11 @@ void CodeGenAction::runOptimizationPipeline(llvm::raw_pwrite_stream &os) { else mpm = pb.buildPerModuleDefaultPipeline(level); + if (this->getInstance().getInvocation().getFrontendOpts().features.IsEnabled( + Fortran::common::LanguageFeature::TSan)) { + mpm.addPass(llvm::ModuleThreadSanitizerPass()); + mpm.addPass(llvm::createModuleToFunctionPassAdaptor(llvm::ThreadSanitizerPass())); + } if (action == BackendActionTy::Backend_EmitBC) mpm.addPass(llvm::BitcodeWriterPass(os)); diff --git a/flang/lib/Optimizer/CodeGen/CMakeLists.txt b/flang/lib/Optimizer/CodeGen/CMakeLists.txt index 0daa97b00dfa0..2d48c873ff4a1 100644 --- a/flang/lib/Optimizer/CodeGen/CMakeLists.txt +++ b/flang/lib/Optimizer/CodeGen/CMakeLists.txt @@ -1,3 +1,7 @@ +set(LLVM_LINK_COMPONENTS + Instrumentation +) + add_flang_library(FIRCodeGen BoxedProcedure.cpp CGOps.cpp diff --git a/llvm/lib/Transforms/Instrumentation/ThreadSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/ThreadSanitizer.cpp index 8ee0bca7e354f..bd720634e467e 100644 --- a/llvm/lib/Transforms/Instrumentation/ThreadSanitizer.cpp +++ b/llvm/lib/Transforms/Instrumentation/ThreadSanitizer.cpp @@ -511,7 +511,7 @@ bool ThreadSanitizer::sanitizeFunction(Function &F, SmallVector MemIntrinCalls; bool Res = false; bool HasCalls = false; - bool SanitizeFunction = F.hasFnAttribute(Attribute::SanitizeThread); + bool SanitizeFunction = F.hasFnAttribute(Attribute::SanitizeThread) || true; const DataLayout &DL = F.getParent()->getDataLayout(); // Traverse all instructions, collect loads/stores/returns, check for calls.