llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang-codegen @llvm/pr-subscribers-clang Author: Joseph Huber (jhuber6) <details> <summary>Changes</summary> Summary: Add the frontend sanitizer kind, function attributes, pass pipeline integration, predefined macro, and driver handling for ConcurrencySanitizer. --- <sub>Stack created with <a href="https://github.com/github/gh-stack">GitHub Stacks CLI</a> • <a href="https://gh.io/stacks-feedback">Give Feedback 💬</a></sub> --- Patch is 21.06 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/225781.diff 15 Files Affected: - (modified) clang/include/clang/Basic/Features.def (+2) - (modified) clang/include/clang/Basic/Sanitizers.def (+3) - (modified) clang/include/clang/Driver/SanitizerArgs.h (+3) - (modified) clang/lib/CodeGen/BackendUtil.cpp (+7) - (modified) clang/lib/CodeGen/CGDeclCXX.cpp (+4) - (modified) clang/lib/CodeGen/CodeGenFunction.cpp (+10-3) - (modified) clang/lib/Driver/SanitizerArgs.cpp (+10-4) - (modified) clang/lib/Driver/ToolChains/AMDGPU.cpp (+2) - (modified) clang/lib/Driver/ToolChains/Clang.cpp (+1-1) - (modified) clang/lib/Driver/ToolChains/CommonArgs.cpp (+31-7) - (modified) clang/lib/Driver/ToolChains/Linux.cpp (+2) - (modified) clang/lib/Frontend/InitPreprocessor.cpp (+2) - (added) clang/test/CodeGen/sanitize-concurrency.c (+82) - (modified) clang/test/Driver/fsanitize.c (+15) - (modified) clang/test/Preprocessor/sanitizer-predefines.c (+3) ``````````diff diff --git a/clang/include/clang/Basic/Features.def b/clang/include/clang/Basic/Features.def index cfd5bf69f938c..461d8ee576278 100644 --- a/clang/include/clang/Basic/Features.def +++ b/clang/include/clang/Basic/Features.def @@ -146,6 +146,8 @@ FEATURE(memory_sanitizer, SanitizerKind::KernelMemory)) FEATURE(type_sanitizer, LangOpts.Sanitize.has(SanitizerKind::Type)) FEATURE(thread_sanitizer, LangOpts.Sanitize.has(SanitizerKind::Thread)) +FEATURE(concurrency_sanitizer, + LangOpts.Sanitize.has(SanitizerKind::Concurrency)) FEATURE(dataflow_sanitizer, LangOpts.Sanitize.has(SanitizerKind::DataFlow)) FEATURE(scudo, LangOpts.Sanitize.hasOneOf(SanitizerKind::Scudo)) FEATURE(ptrauth_intrinsics, LangOpts.PointerAuthIntrinsics && diff --git a/clang/include/clang/Basic/Sanitizers.def b/clang/include/clang/Basic/Sanitizers.def index da85431625026..8120c5842919b 100644 --- a/clang/include/clang/Basic/Sanitizers.def +++ b/clang/include/clang/Basic/Sanitizers.def @@ -198,6 +198,9 @@ SANITIZER("scudo", Scudo) // AllocToken SANITIZER("alloc-token", AllocToken) +// ConcurrencySanitizer. +SANITIZER("concurrency", Concurrency) + // Magic group, containing all sanitizers. For example, "-fno-sanitize=all" // can be used to disable all the sanitizers. SANITIZER_GROUP("all", All, ~SanitizerMask()) diff --git a/clang/include/clang/Driver/SanitizerArgs.h b/clang/include/clang/Driver/SanitizerArgs.h index 62f154bae3ffd..9d61165e94009 100644 --- a/clang/include/clang/Driver/SanitizerArgs.h +++ b/clang/include/clang/Driver/SanitizerArgs.h @@ -106,6 +106,9 @@ class SanitizerArgs { } bool needsTysanRt() const { return Sanitizers.has(SanitizerKind::Type); } bool needsTsanRt() const { return Sanitizers.has(SanitizerKind::Thread); } + bool needsCsanRt() const { + return Sanitizers.has(SanitizerKind::Concurrency); + } bool needsMsanRt() const { return Sanitizers.has(SanitizerKind::Memory); } bool needsFuzzer() const { return Sanitizers.has(SanitizerKind::Fuzzer); } bool needsLsanRt() const { diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp index 8103b72cf4e3a..8634cbd930d42 100644 --- a/clang/lib/CodeGen/BackendUtil.cpp +++ b/clang/lib/CodeGen/BackendUtil.cpp @@ -74,6 +74,7 @@ #include "llvm/Transforms/Instrumentation/AddressSanitizer.h" #include "llvm/Transforms/Instrumentation/AddressSanitizerOptions.h" #include "llvm/Transforms/Instrumentation/BoundsChecking.h" +#include "llvm/Transforms/Instrumentation/ConcurrencySanitizer.h" #include "llvm/Transforms/Instrumentation/DataFlowSanitizer.h" #include "llvm/Transforms/Instrumentation/GCOVProfiler.h" #include "llvm/Transforms/Instrumentation/HWAddressSanitizer.h" @@ -703,6 +704,12 @@ static void addSanitizers(const Triple &TargetTriple, MPM.addPass(createModuleToFunctionPassAdaptor(ThreadSanitizerPass())); } + if (LangOpts.Sanitize.has(SanitizerKind::Concurrency)) { + MPM.addPass(ModuleConcurrencySanitizerPass()); + MPM.addPass( + createModuleToFunctionPassAdaptor(ConcurrencySanitizerPass())); + } + if (LangOpts.Sanitize.has(SanitizerKind::Type)) MPM.addPass(TypeSanitizerPass()); diff --git a/clang/lib/CodeGen/CGDeclCXX.cpp b/clang/lib/CodeGen/CGDeclCXX.cpp index a54809c48037e..f58492f1f41e0 100644 --- a/clang/lib/CodeGen/CGDeclCXX.cpp +++ b/clang/lib/CodeGen/CGDeclCXX.cpp @@ -487,6 +487,10 @@ llvm::Function *CodeGenModule::CreateGlobalInitOrCleanUpFunction( !isInNoSanitizeList(SanitizerKind::Thread, Fn, Loc)) Fn->addFnAttr(llvm::Attribute::SanitizeThread); + if (getLangOpts().Sanitize.has(SanitizerKind::Concurrency) && + !isInNoSanitizeList(SanitizerKind::Concurrency, Fn, Loc)) + Fn->addFnAttr(llvm::Attribute::SanitizeConcurrency); + if (getLangOpts().Sanitize.has(SanitizerKind::NumericalStability) && !isInNoSanitizeList(SanitizerKind::NumericalStability, Fn, Loc)) Fn->addFnAttr(llvm::Attribute::SanitizeNumericalStability); diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp index fe39235fcd4f6..d01afed891593 100644 --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -705,6 +705,10 @@ void CodeGenFunction::markAsIgnoreThreadCheckingAtRuntime(llvm::Function *Fn) { Fn->addFnAttr("sanitize_thread_no_checking_at_run_time"); Fn->removeFnAttr(llvm::Attribute::SanitizeThread); } + if (SanOpts.has(SanitizerKind::Concurrency)) { + Fn->addFnAttr("sanitize_concurrency_no_checking_at_run_time"); + Fn->removeFnAttr(llvm::Attribute::SanitizeConcurrency); + } } /// Check if the return value of this function requires sanitization. @@ -841,6 +845,8 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy, Fn->addFnAttr(llvm::Attribute::SanitizeMemTag); if (SanOpts.has(SanitizerKind::Thread)) Fn->addFnAttr(llvm::Attribute::SanitizeThread); + if (SanOpts.has(SanitizerKind::Concurrency)) + Fn->addFnAttr(llvm::Attribute::SanitizeConcurrency); if (SanOpts.has(SanitizerKind::Type)) Fn->addFnAttr(llvm::Attribute::SanitizeType); if (SanOpts.has(SanitizerKind::NumericalStability)) @@ -868,9 +874,10 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy, if (SanOpts.hasOneOf(SanitizerKind::Fuzzer | SanitizerKind::FuzzerNoLink)) Fn->addFnAttr(llvm::Attribute::OptForFuzzing); - // Ignore TSan memory acesses from within ObjC/ObjC++ dealloc, initialize, - // .cxx_destruct, __destroy_helper_block_ and all of their calees at run time. - if (SanOpts.has(SanitizerKind::Thread)) { + // Ignore TSan/CSan memory accesses from within ObjC/ObjC++ dealloc, + // initialize, .cxx_destruct, __destroy_helper_block_ and all of their callees + // at run time. + if (SanOpts.hasOneOf(SanitizerKind::Thread | SanitizerKind::Concurrency)) { if (const auto *OMD = dyn_cast_or_null<ObjCMethodDecl>(D)) { const IdentifierInfo *II = OMD->getSelector().getIdentifierInfoForSlot(0); if (OMD->getMethodFamily() == OMF_dealloc || diff --git a/clang/lib/Driver/SanitizerArgs.cpp b/clang/lib/Driver/SanitizerArgs.cpp index 778cde8285aaf..418c403f3ecc7 100644 --- a/clang/lib/Driver/SanitizerArgs.cpp +++ b/clang/lib/Driver/SanitizerArgs.cpp @@ -40,8 +40,8 @@ static const SanitizerMask NotAllowedWithExecuteOnly = SanitizerKind::Function | SanitizerKind::KCFI; static const SanitizerMask NeedsUnwindTables = SanitizerKind::Address | SanitizerKind::HWAddress | SanitizerKind::Type | - SanitizerKind::Thread | SanitizerKind::Memory | SanitizerKind::DataFlow | - SanitizerKind::NumericalStability; + SanitizerKind::Thread | SanitizerKind::Concurrency | SanitizerKind::Memory | + SanitizerKind::DataFlow | SanitizerKind::NumericalStability; static const SanitizerMask SupportsCoverage = SanitizerKind::Address | SanitizerKind::HWAddress | SanitizerKind::KernelAddress | SanitizerKind::KernelHWAddress | @@ -53,7 +53,8 @@ static const SanitizerMask SupportsCoverage = SanitizerKind::DataFlow | SanitizerKind::Fuzzer | SanitizerKind::FuzzerNoLink | SanitizerKind::FloatDivideByZero | SanitizerKind::SafeStack | SanitizerKind::ShadowCallStack | - SanitizerKind::Thread | SanitizerKind::ObjCCast | SanitizerKind::KCFI | + SanitizerKind::Thread | SanitizerKind::Concurrency | + SanitizerKind::ObjCCast | SanitizerKind::KCFI | SanitizerKind::NumericalStability | SanitizerKind::Vptr | SanitizerKind::CFI | SanitizerKind::AllocToken; static const SanitizerMask RecoverableByDefault = @@ -738,7 +739,12 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC, SanitizerKind::Address | SanitizerKind::KernelAddress | SanitizerKind::Memory | SanitizerKind::Leak | SanitizerKind::Thread), - std::make_pair(SanitizerKind::Thread, SanitizerKind::Memory), + std::make_pair(SanitizerKind::Thread, + SanitizerKind::Memory | SanitizerKind::Concurrency), + std::make_pair(SanitizerKind::Concurrency, + SanitizerKind::Thread | SanitizerKind::Address | + SanitizerKind::Memory | SanitizerKind::Leak | + SanitizerKind::Undefined), std::make_pair(SanitizerKind::Leak, SanitizerKind::Thread | SanitizerKind::Memory), std::make_pair(SanitizerKind::KernelAddress, diff --git a/clang/lib/Driver/ToolChains/AMDGPU.cpp b/clang/lib/Driver/ToolChains/AMDGPU.cpp index d6dacb4ccba83..b66e5ac0ca8ae 100644 --- a/clang/lib/Driver/ToolChains/AMDGPU.cpp +++ b/clang/lib/Driver/ToolChains/AMDGPU.cpp @@ -1391,6 +1391,8 @@ SanitizerMask AMDGPUToolChain::getSupportedSanitizers( // arch xnack support. if (!BA || isXnackAvailable(getTriple(), BA.ArchName)) SupportedMask |= SanitizerKind::Address; + // Watchpoint probes do not require xnack. + SupportedMask |= SanitizerKind::Concurrency; return SupportedMask; } diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 6636a5fd6e655..274222cbed1f6 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -9809,7 +9809,7 @@ void LinkerWrapper::ConstructJob(Compilation &C, const JobAction &JA, // Don't forward sanitizer arguments if the toolchain doesn't support it. // Without this check using it on the host would result in linker errors. if (requiresUBSanRT(ID) && !ToolChainHasRT(TC, "ubsan_minimal") && - !ToolChainHasRT(TC, "ubsan_standalone")) + !ToolChainHasRT(TC, "ubsan_standalone") && !ToolChainHasRT(TC, "csan")) return false; // Don't forward -mllvm to toolchains that don't support LLVM. return TC.HasNativeLLVMSupport() || ID != OPT_mllvm; diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp index b07438542aae3..e038e211d339b 100644 --- a/clang/lib/Driver/ToolChains/CommonArgs.cpp +++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp @@ -1658,8 +1658,9 @@ void tools::linkSanitizerRuntimeDeps(const ToolChain &TC, CmdArgs.push_back("-lresolv"); } -// Host interceptor library for offload UBSan. -static bool hostNeedsUbsanOffloadRt(Compilation &C, const ToolChain &HostTC) { +template <typename Predicate> +static bool hostNeedsOffloadRt(Compilation &C, const ToolChain &HostTC, + Predicate NeedsRuntime) { if (HostTC.getTriple().isGPU()) return false; @@ -1677,7 +1678,7 @@ static bool hostNeedsUbsanOffloadRt(Compilation &C, const ToolChain &HostTC) { C.getDriver().getOffloadArchs(C, C.getArgs(), Kind, *DevTC)) { const ArgList &DevArgs = C.getArgsForToolChain(DevTC, BA, Kind); SanitizerArgs DevSan = DevTC->getSanitizerArgs(DevArgs, BA, Kind); - if (DevSan.needsUbsanRt() && !DevSan.requiresMinimalRuntime()) + if (NeedsRuntime(DevSan)) return true; } } @@ -1685,6 +1686,17 @@ static bool hostNeedsUbsanOffloadRt(Compilation &C, const ToolChain &HostTC) { return false; } +static bool hostNeedsUbsanOffloadRt(Compilation &C, const ToolChain &HostTC) { + return hostNeedsOffloadRt(C, HostTC, [](const SanitizerArgs &S) { + return S.needsUbsanRt() && !S.requiresMinimalRuntime(); + }); +} + +static bool hostNeedsCsanOffloadRt(Compilation &C, const ToolChain &HostTC) { + return hostNeedsOffloadRt( + C, HostTC, [](const SanitizerArgs &S) { return S.needsCsanRt(); }); +} + static void collectSanitizerRuntimes(Compilation &C, const ToolChain &TC, const ArgList &Args, @@ -1695,8 +1707,10 @@ collectSanitizerRuntimes(Compilation &C, const ToolChain &TC, SmallVectorImpl<StringRef> &RequiredSymbols) { assert(!TC.getTriple().isOSDarwin() && "it's not used by Darwin"); const SanitizerArgs &SanArgs = TC.getSanitizerArgs(Args); - const bool NeedsOffloadRt = hostNeedsUbsanOffloadRt(C, TC); - const bool NeedsUbsanRt = SanArgs.needsUbsanRt() || NeedsOffloadRt; + const bool NeedsUbsanOffloadRt = hostNeedsUbsanOffloadRt(C, TC); + const bool NeedsCsanOffloadRt = hostNeedsCsanOffloadRt(C, TC); + const bool NeedsUbsanRt = SanArgs.needsUbsanRt() || NeedsUbsanOffloadRt; + const bool NeedsCsanRt = SanArgs.needsCsanRt() || NeedsCsanOffloadRt; // Collect shared runtimes. if (SanArgs.needsSharedRt()) { if (SanArgs.needsAsanRt()) { @@ -1745,16 +1759,24 @@ collectSanitizerRuntimes(Compilation &C, const ToolChain &TC, HelperStaticRuntimes.push_back("asan_static"); // Offloading images can live in DSOs, the host interceptors must follow. - if (NeedsOffloadRt) { + if (NeedsUbsanOffloadRt) { NonWholeStaticRuntimes.push_back("ubsan_offload"); RequiredSymbols.push_back("__ubsan_offload_init"); } + if (NeedsCsanOffloadRt) { + NonWholeStaticRuntimes.push_back("csan_offload"); + RequiredSymbols.push_back("__csan_offload_init"); + } // Collect static runtimes. if (Args.hasArg(options::OPT_shared)) { // Don't link static runtimes into DSOs. - if (NeedsOffloadRt && !SanArgs.needsSharedRt() && !SanArgs.needsUbsanRt()) + if (NeedsUbsanOffloadRt && !SanArgs.needsSharedRt() && + !SanArgs.needsUbsanRt()) StaticRuntimes.push_back("ubsan_standalone"); + if (NeedsCsanOffloadRt && !SanArgs.needsSharedRt() && + !SanArgs.needsCsanRt()) + StaticRuntimes.push_back("csan"); return; } @@ -1813,6 +1835,8 @@ collectSanitizerRuntimes(Compilation &C, const ToolChain &TC, StaticRuntimes.push_back("ubsan_standalone"); } } + if (!SanArgs.needsSharedRt() && NeedsCsanRt) + StaticRuntimes.push_back("csan"); if (SanArgs.needsSafeStackRt()) { NonWholeStaticRuntimes.push_back("safestack"); RequiredSymbols.push_back("__safestack_init"); diff --git a/clang/lib/Driver/ToolChains/Linux.cpp b/clang/lib/Driver/ToolChains/Linux.cpp index e295b2516da16..43b48903fc053 100644 --- a/clang/lib/Driver/ToolChains/Linux.cpp +++ b/clang/lib/Driver/ToolChains/Linux.cpp @@ -1007,6 +1007,8 @@ Linux::getSupportedSanitizers(BoundArch BA, if (IsX86_64 || IsMIPS64 || IsAArch64 || IsPowerPC64 || IsSystemZ || IsLoongArch64 || IsRISCV64) Res |= SanitizerKind::Thread; + if (IsX86_64) + Res |= SanitizerKind::Concurrency; if (IsX86_64 || IsAArch64 || IsSystemZ || IsHexagon) Res |= SanitizerKind::Type; if (IsX86_64 || IsSystemZ || IsPowerPC64) diff --git a/clang/lib/Frontend/InitPreprocessor.cpp b/clang/lib/Frontend/InitPreprocessor.cpp index 784ff9951a25a..264412ea3f714 100644 --- a/clang/lib/Frontend/InitPreprocessor.cpp +++ b/clang/lib/Frontend/InitPreprocessor.cpp @@ -1535,6 +1535,8 @@ static void InitializePredefinedMacros(const TargetInfo &TI, Builder.defineMacro("__SANITIZE_HWADDRESS__"); if (LangOpts.Sanitize.has(SanitizerKind::Thread)) Builder.defineMacro("__SANITIZE_THREAD__"); + if (LangOpts.Sanitize.has(SanitizerKind::Concurrency)) + Builder.defineMacro("__SANITIZE_CONCURRENCY__"); if (LangOpts.Sanitize.has(SanitizerKind::AllocToken)) Builder.defineMacro("__SANITIZE_ALLOC_TOKEN__"); diff --git a/clang/test/CodeGen/sanitize-concurrency.c b/clang/test/CodeGen/sanitize-concurrency.c new file mode 100644 index 0000000000000..5d6e45ed5257a --- /dev/null +++ b/clang/test/CodeGen/sanitize-concurrency.c @@ -0,0 +1,82 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 6 +// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -o - %s | FileCheck -check-prefixes CHECK,WITHOUT %s +// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -o - %s -fsanitize=concurrency | FileCheck -check-prefixes CHECK,CSAN %s + +#if defined(__SANITIZE_CONCURRENCY__) +// CSAN-LABEL: define dso_local i32 @concurrency_macro_defined( +// CSAN-SAME: ) #[[ATTR0:[0-9]+]] { +// CSAN-NEXT: [[ENTRY:.*:]] +// CSAN-NEXT: ret i32 1 +// +int concurrency_macro_defined(void) { return 1; } +#endif + +#if __has_feature(concurrency_sanitizer) +// CSAN-LABEL: define dso_local i32 @concurrency_feature_defined( +// CSAN-SAME: ) #[[ATTR0]] { +// CSAN-NEXT: [[ENTRY:.*:]] +// CSAN-NEXT: ret i32 1 +// +int concurrency_feature_defined(void) { return 1; } +#endif + +// WITHOUT-LABEL: define dso_local i32 @instrumented1( +// WITHOUT-SAME: ptr noundef [[A:%.*]], ptr noundef [[B:%.*]]) #[[ATTR0:[0-9]+]] { +// WITHOUT-NEXT: [[ENTRY:.*:]] +// WITHOUT-NEXT: [[A_ADDR:%.*]] = alloca ptr, align 8 +// WITHOUT-NEXT: [[B_ADDR:%.*]] = alloca ptr, align 8 +// WITHOUT-NEXT: store ptr [[A]], ptr [[A_ADDR]], align 8 +// WITHOUT-NEXT: store ptr [[B]], ptr [[B_ADDR]], align 8 +// WITHOUT-NEXT: [[TMP0:%.*]] = load ptr, ptr [[A_ADDR]], align 8 +// WITHOUT-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// WITHOUT-NEXT: [[TMP2:%.*]] = load ptr, ptr [[B_ADDR]], align 8 +// WITHOUT-NEXT: [[ATOMIC_LOAD:%.*]] = load atomic i32, ptr [[TMP2]] seq_cst, align 4 +// WITHOUT-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP1]], [[ATOMIC_LOAD]] +// WITHOUT-NEXT: ret i32 [[ADD]] +// +// CSAN-LABEL: define dso_local i32 @instrumented1( +// CSAN-SAME: ptr noundef [[A:%.*]], ptr noundef [[B:%.*]]) #[[ATTR0]] { +// CSAN-NEXT: [[ENTRY:.*:]] +// CSAN-NEXT: [[TMP0:%.*]] = call ptr @llvm.returnaddress.p0(i32 0) +// CSAN-NEXT: call void @__csan_func_entry(ptr [[TMP0]]) +// CSAN-NEXT: [[A_ADDR:%.*]] = alloca ptr, align 8 +// CSAN-NEXT: [[B_ADDR:%.*]] = alloca ptr, align 8 +// CSAN-NEXT: store ptr [[A]], ptr [[A_ADDR]], align 8 +// CSAN-NEXT: store ptr [[B]], ptr [[B_ADDR]], align 8 +// CSAN-NEXT: [[TMP1:%.*]] = load ptr, ptr [[A_ADDR]], align 8 +// CSAN-NEXT: call void @__csan_read4(ptr [[TMP1]]) +// CSAN-NEXT: [[TMP2:%.*]] = load i32, ptr [[TMP1]], align 4 +// CSAN-NEXT: [[TMP3:%.*]] = load ptr, ptr [[B_ADDR]], align 8 +// CSAN-NEXT: call void @__csan_read4(ptr [[TMP3]]) +// CSAN-NEXT: [[ATOMIC_LOAD:%.*]] = load atomic i32, ptr [[TMP3]] seq_cst, align 4 +// CSAN-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP2]], [[ATOMIC_LOAD]] +// CSAN-NEXT: call void @__csan_func_exit() +// CSAN-NEXT: ret i32 [[ADD]] +// +int instrumented1(int *a, _Atomic int *b) { + return *a + *b; +} + +// WITHOUT-LABEL: define dso_local i32 @suppressed( +// WITHOUT-SAME: ptr noundef [[A:%.*]]) #[[ATTR0]] { +// WITHOUT-NEXT: [[ENTRY:.*:]] +// WITHOUT-NEXT: [[A_ADDR:%.*]] = alloca ptr, align 8 +// WITHOUT-NEXT: store ptr [[A]], ptr [[A_ADDR]], align 8 +// WITHOUT-NEXT: [[TMP0:%.*]] = load ptr, ptr [[A_ADDR]], align 8 +// WITHOUT-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// WITHOUT-NEXT: ret i32 [[TMP1]] +// +// CSAN-LABEL: define dso_local i32 @suppressed( +// CSAN-SAME: ptr noundef [[A:%.*]]) #[[ATTR1:[0-9]+]] { +// CSAN-NEXT: [[ENTRY:.*:]] +// CSAN-NEXT: [[A_ADDR:%.*]] = alloca ptr, align 8 +// CSAN-NEXT: store ptr [[A]], ptr [[A_ADDR]], align 8 +// CSAN-NEXT: [[TMP0:%.*]] = load ptr, ptr [[A_ADDR]], align 8 +// CSAN-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CSAN-NEXT: ret i32 [[TMP1]] +// +__attribute__((no_sanitize("concurrency"))) int suppressed(int *a) { + return *a; +} +//// NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line: +// CHECK: {{.*}} diff --git a/clang/test/Driver/fsanitize.c b/clang/test/Driver/fsanitize.c index 97dbee7c15bc8..55579be3ae1e2 100644 --- a/clang/test/Driver/fsanitize.c +++ b/clang/test/Driver/fsanitize.c @@ -23,6 +23,21 @@ // RUN: not %clang --target=x86_64-linux-gnu -fsanitize=leak,thread -pie -fno-rtti %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANL-SANT // CHECK-SANL-SANT: '-fsanitize=leak' not allowed with '-fsanitize=thread' +// RUN: %clang --target=x86_64-linux-gnu -fsanitize=concurrency %s -### 2>&1 \ +// RUN: -resource-dir=%S/Inputs/resource_dir \ +// RUN: | FileCheck %s --check-prefix=CHECK-SANC-X64 +// CHECK-SANC-X64: "-fsanitize=concurrency" +// CHECK-SANC-X64: libclang_rt.csan.a + +// RUN: %clang --target=amdgcn-amd-amdhsa -mcpu=gfx900 -nogpulib -fsanitize=concurrency %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANC-AMDGPU +// CHECK-SANC-AMDGPU: "-fsanitize=concurrency" + +// RUN: not %clang --target=amdgcn-amd-amdhsa -mcpu=gfx900:xnack+ -nogpulib -fsanitize=concurrency,address %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANC-SANA +// CHECK-SANC-SANA: '-fsanitize=concurr... [truncated] `````````` </details> https://github.com/llvm/llvm-project/pull/225781 _______________________________________________ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
