Commit 5e0568ca authored by Joachim Jenke's avatar Joachim Jenke
Browse files

[Flang][WIP/RFC] Enable TSan for Flang

This patch enables ThreadSanitizer analysis for Fortran codes compiled with Flang.
The patch is marked as WIP/RFC since it is at the moment a proof of concept.

This patch as is cannot be the final solution, as it disables the blacklisting of
functions and any no-sanitize function attribute applied in C/C++

Under review as #74643
parent f8575ff4
Loading
Loading
Loading
Loading
+4 −4
Original line number Diff line number Diff line
@@ -1786,14 +1786,14 @@ def fmemory_profile_use_EQ : Joined<["-"], "fmemory-profile-use=">,
    HelpText<"Use memory profile for profile-guided memory optimization">,
    MarshallingInfoString<CodeGenOpts<"MemoryProfileUsePath">>;

def fsanitize_EQ : CommaJoined<["-"], "fsanitize=">, Group<f_clang_Group>,
                   MetaVarName<"<check>">, 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 Flags = [CC1Option, CoreOption] in {

def fsanitize_EQ : CommaJoined<["-"], "fsanitize=">, Group<f_clang_Group>,
                   MetaVarName<"<check>">,
                   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>,
                      Flags<[CoreOption, NoXarchOption]>;

+1 −0
Original line number Diff line number Diff line
@@ -36,6 +36,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,
+2 −1
Original line number Diff line number Diff line
@@ -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)

@@ -56,6 +56,7 @@ public:
    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);
+4 −0
Original line number Diff line number Diff line
@@ -726,6 +726,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;
+8 −0
Original line number Diff line number Diff line
@@ -63,6 +63,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 <memory>
#include <system_error>

@@ -913,6 +916,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));

Loading