https://github.com/fhahn updated https://github.com/llvm/llvm-project/pull/76260
>From 96912aec51f6752d211d8bd091eaad6426037050 Mon Sep 17 00:00:00 2001 From: Florian Hahn <f...@fhahn.com> Date: Thu, 18 Apr 2024 23:01:03 +0100 Subject: [PATCH 1/2] [TySan] A Type Sanitizer (Clang) --- clang/include/clang/Basic/Features.def | 1 + clang/include/clang/Basic/Sanitizers.def | 3 ++ clang/include/clang/Driver/SanitizerArgs.h | 1 + clang/lib/CodeGen/BackendUtil.cpp | 6 +++ clang/lib/CodeGen/CGDecl.cpp | 3 +- clang/lib/CodeGen/CGDeclCXX.cpp | 4 ++ clang/lib/CodeGen/CodeGenFunction.cpp | 2 + clang/lib/CodeGen/CodeGenModule.cpp | 12 +++--- clang/lib/CodeGen/CodeGenTBAA.cpp | 6 ++- clang/lib/CodeGen/SanitizerMetadata.cpp | 44 +++++++++++++++++----- clang/lib/CodeGen/SanitizerMetadata.h | 13 ++++--- clang/lib/Driver/SanitizerArgs.cpp | 15 +++++--- clang/lib/Driver/ToolChains/CommonArgs.cpp | 6 ++- clang/lib/Driver/ToolChains/Darwin.cpp | 5 +++ clang/lib/Driver/ToolChains/Linux.cpp | 2 + clang/test/Driver/sanitizer-ld.c | 23 +++++++++++ 16 files changed, 116 insertions(+), 30 deletions(-) diff --git a/clang/include/clang/Basic/Features.def b/clang/include/clang/Basic/Features.def index fe4d1c4afcca65..589739eea2734d 100644 --- a/clang/include/clang/Basic/Features.def +++ b/clang/include/clang/Basic/Features.def @@ -99,6 +99,7 @@ FEATURE(nullability_nullable_result, true) FEATURE(memory_sanitizer, LangOpts.Sanitize.hasOneOf(SanitizerKind::Memory | SanitizerKind::KernelMemory)) +FEATURE(type_sanitizer, LangOpts.Sanitize.has(SanitizerKind::Type)) FEATURE(thread_sanitizer, LangOpts.Sanitize.has(SanitizerKind::Thread)) FEATURE(dataflow_sanitizer, LangOpts.Sanitize.has(SanitizerKind::DataFlow)) FEATURE(scudo, LangOpts.Sanitize.hasOneOf(SanitizerKind::Scudo)) diff --git a/clang/include/clang/Basic/Sanitizers.def b/clang/include/clang/Basic/Sanitizers.def index b228ffd07ee745..a482cf520620bc 100644 --- a/clang/include/clang/Basic/Sanitizers.def +++ b/clang/include/clang/Basic/Sanitizers.def @@ -73,6 +73,9 @@ SANITIZER("fuzzer", Fuzzer) // libFuzzer-required instrumentation, no linking. SANITIZER("fuzzer-no-link", FuzzerNoLink) +// TypeSanitizer +SANITIZER("type", Type) + // ThreadSanitizer SANITIZER("thread", Thread) diff --git a/clang/include/clang/Driver/SanitizerArgs.h b/clang/include/clang/Driver/SanitizerArgs.h index 07070ec4fc0653..52b482a0e8a1a9 100644 --- a/clang/include/clang/Driver/SanitizerArgs.h +++ b/clang/include/clang/Driver/SanitizerArgs.h @@ -86,6 +86,7 @@ class SanitizerArgs { bool needsHwasanAliasesRt() const { return needsHwasanRt() && HwasanUseAliases; } + bool needsTysanRt() const { return Sanitizers.has(SanitizerKind::Type); } bool needsTsanRt() const { return Sanitizers.has(SanitizerKind::Thread); } bool needsMsanRt() const { return Sanitizers.has(SanitizerKind::Memory); } bool needsFuzzer() const { return Sanitizers.has(SanitizerKind::Fuzzer); } diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp index 6cc00b85664f41..1db5aca770b259 100644 --- a/clang/lib/CodeGen/BackendUtil.cpp +++ b/clang/lib/CodeGen/BackendUtil.cpp @@ -80,6 +80,7 @@ #include "llvm/Transforms/Instrumentation/SanitizerBinaryMetadata.h" #include "llvm/Transforms/Instrumentation/SanitizerCoverage.h" #include "llvm/Transforms/Instrumentation/ThreadSanitizer.h" +#include "llvm/Transforms/Instrumentation/TypeSanitizer.h" #include "llvm/Transforms/ObjCARC.h" #include "llvm/Transforms/Scalar/EarlyCSE.h" #include "llvm/Transforms/Scalar/GVN.h" @@ -697,6 +698,11 @@ static void addSanitizers(const Triple &TargetTriple, MPM.addPass(createModuleToFunctionPassAdaptor(ThreadSanitizerPass())); } + if (LangOpts.Sanitize.has(SanitizerKind::Type)) { + MPM.addPass(ModuleTypeSanitizerPass()); + MPM.addPass(createModuleToFunctionPassAdaptor(TypeSanitizerPass())); + } + auto ASanPass = [&](SanitizerMask Mask, bool CompileKernel) { if (LangOpts.Sanitize.has(Mask)) { bool UseGlobalGC = asanUseGlobalsGC(TargetTriple, CodeGenOpts); diff --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp index ce6d6d8956076e..42516fa749c830 100644 --- a/clang/lib/CodeGen/CGDecl.cpp +++ b/clang/lib/CodeGen/CGDecl.cpp @@ -482,7 +482,8 @@ void CodeGenFunction::EmitStaticVarDecl(const VarDecl &D, LocalDeclMap.find(&D)->second = Address(castedAddr, elemTy, alignment); CGM.setStaticLocalDeclAddress(&D, castedAddr); - CGM.getSanitizerMetadata()->reportGlobal(var, D); + CGM.getSanitizerMetadata()->reportGlobalToASan(var, D); + CGM.getSanitizerMetadata()->reportGlobalToTySan(var, D); // Emit global variable debug descriptor for static vars. CGDebugInfo *DI = getDebugInfo(); diff --git a/clang/lib/CodeGen/CGDeclCXX.cpp b/clang/lib/CodeGen/CGDeclCXX.cpp index e08a1e5f42df20..08b3e06cb5a450 100644 --- a/clang/lib/CodeGen/CGDeclCXX.cpp +++ b/clang/lib/CodeGen/CGDeclCXX.cpp @@ -472,6 +472,10 @@ llvm::Function *CodeGenModule::CreateGlobalInitOrCleanUpFunction( !isInNoSanitizeList(SanitizerKind::MemtagStack, Fn, Loc)) Fn->addFnAttr(llvm::Attribute::SanitizeMemTag); + if (getLangOpts().Sanitize.has(SanitizerKind::Type) && + !isInNoSanitizeList(SanitizerKind::Type, Fn, Loc)) + Fn->addFnAttr(llvm::Attribute::SanitizeType); + if (getLangOpts().Sanitize.has(SanitizerKind::Thread) && !isInNoSanitizeList(SanitizerKind::Thread, Fn, Loc)) Fn->addFnAttr(llvm::Attribute::SanitizeThread); diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp index 86a6ddd80cc114..e9ef8424c2d1ae 100644 --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -806,6 +806,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::Type)) + Fn->addFnAttr(llvm::Attribute::SanitizeType); if (SanOpts.hasOneOf(SanitizerKind::Memory | SanitizerKind::KernelMemory)) Fn->addFnAttr(llvm::Attribute::SanitizeMemory); } diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 0c447b20cef40d..90a9388ed0122c 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -396,8 +396,8 @@ CodeGenModule::CodeGenModule(ASTContext &C, if (LangOpts.HLSL) createHLSLRuntime(); - // Enable TBAA unless it's suppressed. ThreadSanitizer needs TBAA even at O0. - if (LangOpts.Sanitize.has(SanitizerKind::Thread) || + // Enable TBAA unless it's suppressed. TSan and TySan need TBAA even at O0. + if (LangOpts.Sanitize.hasOneOf(SanitizerKind::Thread | SanitizerKind::Type) || (!CodeGenOpts.RelaxedAliasing && CodeGenOpts.OptimizationLevel > 0)) TBAA.reset(new CodeGenTBAA(Context, getTypes(), TheModule, CodeGenOpts, getLangOpts(), getCXXABI().getMangleContext())); @@ -4982,7 +4982,7 @@ CodeGenModule::GetOrCreateLLVMGlobal(StringRef MangledName, llvm::Type *Ty, } if (D) - SanitizerMD->reportGlobal(GV, *D); + SanitizerMD->reportGlobalToASan(GV, *D); LangAS ExpectedAS = D ? D->getType().getAddressSpace() @@ -5523,7 +5523,8 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D, if (NeedsGlobalCtor || NeedsGlobalDtor) EmitCXXGlobalVarDeclInitFunc(D, GV, NeedsGlobalCtor); - SanitizerMD->reportGlobal(GV, *D, NeedsGlobalCtor); + SanitizerMD->reportGlobalToASan(GV, *D, NeedsGlobalCtor); + SanitizerMD->reportGlobalToTySan(GV, *D); // Emit global variable debug information. if (CGDebugInfo *DI = getModuleDebugInfo()) @@ -6400,7 +6401,8 @@ CodeGenModule::GetAddrOfConstantStringFromLiteral(const StringLiteral *S, if (Entry) *Entry = GV; - SanitizerMD->reportGlobal(GV, S->getStrTokenLoc(0), "<string literal>"); + SanitizerMD->reportGlobalToASan(GV, S->getStrTokenLoc(0), "<string literal>"); + // FIXME: Should we also report to the TySan? return ConstantAddress(castStringLiteralToDefaultAddressSpace(*this, GV), GV->getValueType(), Alignment); diff --git a/clang/lib/CodeGen/CodeGenTBAA.cpp b/clang/lib/CodeGen/CodeGenTBAA.cpp index 284421f494711e..4144c0b6a40a60 100644 --- a/clang/lib/CodeGen/CodeGenTBAA.cpp +++ b/clang/lib/CodeGen/CodeGenTBAA.cpp @@ -227,8 +227,10 @@ llvm::MDNode *CodeGenTBAA::getTypeInfoHelper(const Type *Ty) { } llvm::MDNode *CodeGenTBAA::getTypeInfo(QualType QTy) { - // At -O0 or relaxed aliasing, TBAA is not emitted for regular types. - if (CodeGenOpts.OptimizationLevel == 0 || CodeGenOpts.RelaxedAliasing) + // At -O0 or relaxed aliasing, TBAA is not emitted for regular types (unless + // we're running TypeSanitizer). + if (!Features.Sanitize.has(SanitizerKind::Type) && + (CodeGenOpts.OptimizationLevel == 0 || CodeGenOpts.RelaxedAliasing)) return nullptr; // If the type has the may_alias attribute (even on a typedef), it is diff --git a/clang/lib/CodeGen/SanitizerMetadata.cpp b/clang/lib/CodeGen/SanitizerMetadata.cpp index 53161c316c58a4..c0d38d3c747dea 100644 --- a/clang/lib/CodeGen/SanitizerMetadata.cpp +++ b/clang/lib/CodeGen/SanitizerMetadata.cpp @@ -34,11 +34,11 @@ SanitizerMask expandKernelSanitizerMasks(SanitizerMask Mask) { return Mask; } -void SanitizerMetadata::reportGlobal(llvm::GlobalVariable *GV, - SourceLocation Loc, StringRef Name, - QualType Ty, - SanitizerMask NoSanitizeAttrMask, - bool IsDynInit) { +void SanitizerMetadata::reportGlobalToASan(llvm::GlobalVariable *GV, + SourceLocation Loc, StringRef Name, + QualType Ty, + SanitizerMask NoSanitizeAttrMask, + bool IsDynInit) { SanitizerSet FsanitizeArgument = CGM.getLangOpts().Sanitize; if (!isAsanHwasanOrMemTag(FsanitizeArgument)) return; @@ -75,8 +75,8 @@ void SanitizerMetadata::reportGlobal(llvm::GlobalVariable *GV, GV->setSanitizerMetadata(Meta); } -void SanitizerMetadata::reportGlobal(llvm::GlobalVariable *GV, const VarDecl &D, - bool IsDynInit) { +void SanitizerMetadata::reportGlobalToASan(llvm::GlobalVariable *GV, + const VarDecl &D, bool IsDynInit) { if (!isAsanHwasanOrMemTag(CGM.getLangOpts().Sanitize)) return; std::string QualName; @@ -94,10 +94,34 @@ void SanitizerMetadata::reportGlobal(llvm::GlobalVariable *GV, const VarDecl &D, return NoSanitizeMask; }; - reportGlobal(GV, D.getLocation(), OS.str(), D.getType(), getNoSanitizeMask(D), - IsDynInit); + reportGlobalToASan(GV, D.getLocation(), OS.str(), D.getType(), + getNoSanitizeMask(D), IsDynInit); +} + +void SanitizerMetadata::reportGlobalToTySan(llvm::GlobalVariable *GV, + const VarDecl &D) { + if (!CGM.getLangOpts().Sanitize.has(SanitizerKind::Type)) + return; + + for (auto Attr : D.specific_attrs<NoSanitizeAttr>()) + if (Attr->getMask() & SanitizerKind::Type) + return; + + QualType QTy = D.getType(); + llvm::MDNode *TBAAInfo = CGM.getTBAATypeInfo(QTy); + if (!TBAAInfo || TBAAInfo == CGM.getTBAATypeInfo(CGM.getContext().CharTy)) + return; + + llvm::Metadata *GlobalMetadata[] = {llvm::ConstantAsMetadata::get(GV), + TBAAInfo}; + + llvm::MDNode *ThisGlobal = + llvm::MDNode::get(CGM.getLLVMContext(), GlobalMetadata); + llvm::NamedMDNode *TysanGlobals = + CGM.getModule().getOrInsertNamedMetadata("llvm.tysan.globals"); + TysanGlobals->addOperand(ThisGlobal); } void SanitizerMetadata::disableSanitizerForGlobal(llvm::GlobalVariable *GV) { - reportGlobal(GV, SourceLocation(), "", QualType(), SanitizerKind::All); + reportGlobalToASan(GV, SourceLocation(), "", QualType(), SanitizerKind::All); } diff --git a/clang/lib/CodeGen/SanitizerMetadata.h b/clang/lib/CodeGen/SanitizerMetadata.h index 000f02cf8dcf11..9de087c518c6ad 100644 --- a/clang/lib/CodeGen/SanitizerMetadata.h +++ b/clang/lib/CodeGen/SanitizerMetadata.h @@ -37,12 +37,13 @@ class SanitizerMetadata { public: SanitizerMetadata(CodeGenModule &CGM); - void reportGlobal(llvm::GlobalVariable *GV, const VarDecl &D, - bool IsDynInit = false); - void reportGlobal(llvm::GlobalVariable *GV, SourceLocation Loc, - StringRef Name, QualType Ty = {}, - SanitizerMask NoSanitizeAttrMask = {}, - bool IsDynInit = false); + void reportGlobalToASan(llvm::GlobalVariable *GV, const VarDecl &D, + bool IsDynInit = false); + void reportGlobalToASan(llvm::GlobalVariable *GV, SourceLocation Loc, + StringRef Name, QualType Ty = {}, + SanitizerMask NoSanitizeAttrMask = {}, + bool IsDynInit = false); + void reportGlobalToTySan(llvm::GlobalVariable *GV, const VarDecl &D); void disableSanitizerForGlobal(llvm::GlobalVariable *GV); }; } // end namespace CodeGen diff --git a/clang/lib/Driver/SanitizerArgs.cpp b/clang/lib/Driver/SanitizerArgs.cpp index 8bfe9f02a091d1..b5aa16087a386c 100644 --- a/clang/lib/Driver/SanitizerArgs.cpp +++ b/clang/lib/Driver/SanitizerArgs.cpp @@ -40,14 +40,14 @@ static const SanitizerMask NotAllowedWithMinimalRuntime = SanitizerKind::Vptr; static const SanitizerMask NotAllowedWithExecuteOnly = SanitizerKind::Function | SanitizerKind::KCFI; static const SanitizerMask NeedsUnwindTables = - SanitizerKind::Address | SanitizerKind::HWAddress | SanitizerKind::Thread | - SanitizerKind::Memory | SanitizerKind::DataFlow; + SanitizerKind::Address | SanitizerKind::HWAddress | SanitizerKind::Type | + SanitizerKind::Thread | SanitizerKind::Memory | SanitizerKind::DataFlow; static const SanitizerMask SupportsCoverage = SanitizerKind::Address | SanitizerKind::HWAddress | SanitizerKind::KernelAddress | SanitizerKind::KernelHWAddress | - SanitizerKind::MemtagStack | SanitizerKind::MemtagHeap | - SanitizerKind::MemtagGlobals | SanitizerKind::Memory | - SanitizerKind::KernelMemory | SanitizerKind::Leak | + SanitizerKind::Type | SanitizerKind::MemtagStack | + SanitizerKind::MemtagHeap | SanitizerKind::MemtagGlobals | + SanitizerKind::Memory | SanitizerKind::KernelMemory | SanitizerKind::Leak | SanitizerKind::Undefined | SanitizerKind::Integer | SanitizerKind::Bounds | SanitizerKind::ImplicitConversion | SanitizerKind::Nullability | SanitizerKind::DataFlow | SanitizerKind::Fuzzer | @@ -176,6 +176,7 @@ static void addDefaultIgnorelists(const Driver &D, SanitizerMask Kinds, {"memtag_ignorelist.txt", SanitizerKind::MemTag}, {"msan_ignorelist.txt", SanitizerKind::Memory}, {"tsan_ignorelist.txt", SanitizerKind::Thread}, + {"tysan_blacklist.txt", SanitizerKind::Type}, {"dfsan_abilist.txt", SanitizerKind::DataFlow}, {"cfi_ignorelist.txt", SanitizerKind::CFI}, {"ubsan_ignorelist.txt", @@ -520,6 +521,10 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC, std::pair<SanitizerMask, SanitizerMask> IncompatibleGroups[] = { std::make_pair(SanitizerKind::Address, SanitizerKind::Thread | SanitizerKind::Memory), + std::make_pair(SanitizerKind::Type, + SanitizerKind::Address | SanitizerKind::KernelAddress | + SanitizerKind::Memory | SanitizerKind::Leak | + SanitizerKind::Thread | SanitizerKind::KernelAddress), std::make_pair(SanitizerKind::Thread, SanitizerKind::Memory), std::make_pair(SanitizerKind::Leak, SanitizerKind::Thread | SanitizerKind::Memory), diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp index f10aa4dfaa9ddd..26d25dee41d679 100644 --- a/clang/lib/Driver/ToolChains/CommonArgs.cpp +++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp @@ -1455,8 +1455,10 @@ collectSanitizerRuntimes(const ToolChain &TC, const ArgList &Args, if (SanArgs.needsScudoRt()) { SharedRuntimes.push_back("scudo_standalone"); } - if (SanArgs.needsTsanRt()) + if (SanArgs.needsTsanRt() && SanArgs.linkRuntimes()) SharedRuntimes.push_back("tsan"); + if (SanArgs.needsTysanRt()) + StaticRuntimes.push_back("tysan"); if (SanArgs.needsHwasanRt()) { if (SanArgs.needsHwasanAliasesRt()) SharedRuntimes.push_back("hwasan_aliases"); @@ -1521,6 +1523,8 @@ collectSanitizerRuntimes(const ToolChain &TC, const ArgList &Args, if (SanArgs.linkCXXRuntimes()) StaticRuntimes.push_back("tsan_cxx"); } + if (!SanArgs.needsSharedRt() && SanArgs.needsTysanRt()) + StaticRuntimes.push_back("tysan"); if (!SanArgs.needsSharedRt() && SanArgs.needsUbsanRt()) { if (SanArgs.requiresMinimalRuntime()) { StaticRuntimes.push_back("ubsan_minimal"); diff --git a/clang/lib/Driver/ToolChains/Darwin.cpp b/clang/lib/Driver/ToolChains/Darwin.cpp index caf6c4a444fdce..48f7750bfa295d 100644 --- a/clang/lib/Driver/ToolChains/Darwin.cpp +++ b/clang/lib/Driver/ToolChains/Darwin.cpp @@ -1523,6 +1523,8 @@ void DarwinClang::AddLinkRuntimeLibArgs(const ArgList &Args, "Static sanitizer runtimes not supported"); AddLinkSanitizerLibArgs(Args, CmdArgs, "tsan"); } + if (Sanitize.needsTysanRt()) + AddLinkSanitizerLibArgs(Args, CmdArgs, "tysan"); if (Sanitize.needsFuzzer() && !Args.hasArg(options::OPT_dynamiclib)) { AddLinkSanitizerLibArgs(Args, CmdArgs, "fuzzer", /*shared=*/false); @@ -3412,6 +3414,9 @@ SanitizerMask Darwin::getSupportedSanitizers() const { isTargetTvOSSimulator() || isTargetWatchOSSimulator())) { Res |= SanitizerKind::Thread; } + if ((IsX86_64 || IsAArch64) && isTargetMacOSBased()) { + Res |= SanitizerKind::Type; + } return Res; } diff --git a/clang/lib/Driver/ToolChains/Linux.cpp b/clang/lib/Driver/ToolChains/Linux.cpp index fb65881061effc..9002ca827d8dfe 100644 --- a/clang/lib/Driver/ToolChains/Linux.cpp +++ b/clang/lib/Driver/ToolChains/Linux.cpp @@ -815,6 +815,8 @@ SanitizerMask Linux::getSupportedSanitizers() const { if (IsX86_64 || IsMIPS64 || IsAArch64 || IsPowerPC64 || IsSystemZ || IsLoongArch64 || IsRISCV64) Res |= SanitizerKind::Thread; + if (IsX86_64 || IsAArch64) + Res |= SanitizerKind::Type; if (IsX86_64 || IsSystemZ) Res |= SanitizerKind::KernelMemory; if (IsX86_64 || IsMIPS64 || IsAArch64 || IsX86 || IsMIPS || IsArmArch || diff --git a/clang/test/Driver/sanitizer-ld.c b/clang/test/Driver/sanitizer-ld.c index f5657e47626e1d..1e2476e9ebd807 100644 --- a/clang/test/Driver/sanitizer-ld.c +++ b/clang/test/Driver/sanitizer-ld.c @@ -267,6 +267,29 @@ // CHECK-ASAN-ANDROID-SHARED-NOT: "-lpthread" // CHECK-ASAN-ANDROID-SHARED-NOT: "-lresolv" + +// RUN: %clangxx %s -### -o %t.o 2>&1 \ +// RUN: --target=x86_64-unknown-linux -fuse-ld=ld -stdlib=platform -lstdc++ \ +// RUN: -fsanitize=type \ +// RUN: -resource-dir=%S/Inputs/resource_dir \ +// RUN: --sysroot=%S/Inputs/basic_linux_tree \ +// RUN: | FileCheck --check-prefix=CHECK-TYSAN-LINUX-CXX %s +// +// CHECK-TYSAN-LINUX-CXX: "{{(.*[^-.0-9A-Z_a-z])?}}ld{{(.exe)?}}" +// CHECK-TYSAN-LINUX-CXX-NOT: stdc++ +// CHECK-TYSAN-LINUX-CXX: "--whole-archive" "{{.*}}libclang_rt.tysan{{[^.]*}}.a" "--no-whole-archive" +// CHECK-TYSAN-LINUX-CXX: stdc++ + +// RUN: %clangxx -fsanitize=type -### %s 2>&1 \ +// RUN: -mmacosx-version-min=10.6 \ +// RUN: --target=x86_64-apple-darwin13.4.0 -fuse-ld=ld -stdlib=platform \ +// RUN: -resource-dir=%S/Inputs/resource_dir \ +// RUN: --sysroot=%S/Inputs/basic_linux_tree \ +// RUN: | FileCheck --check-prefix=CHECK-TYSAN-DARWIN-CXX %s +// CHECK-TYSAN-DARWIN-CXX: "{{.*}}ld{{(.exe)?}}" +// CHECK-TYSAN-DARWIN-CXX: libclang_rt.tysan_osx_dynamic.dylib +// CHECK-TYSAN-DARWIN-CXX-NOT: -lc++abi + // RUN: %clangxx -### %s 2>&1 \ // RUN: --target=x86_64-unknown-linux -fuse-ld=ld -stdlib=platform -lstdc++ \ // RUN: -fsanitize=thread \ >From 7f93cb0754aeb221cfea86f67c442c946aef6c9d Mon Sep 17 00:00:00 2001 From: Florian Hahn <f...@fhahn.com> Date: Thu, 18 Apr 2024 23:03:05 +0100 Subject: [PATCH 2/2] !fixup: add test --- clang/test/CodeGen/sanitize-type-attr.cpp | 74 +++++++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 clang/test/CodeGen/sanitize-type-attr.cpp diff --git a/clang/test/CodeGen/sanitize-type-attr.cpp b/clang/test/CodeGen/sanitize-type-attr.cpp new file mode 100644 index 00000000000000..4da8488e1f9486 --- /dev/null +++ b/clang/test/CodeGen/sanitize-type-attr.cpp @@ -0,0 +1,74 @@ +// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -o - %s | FileCheck -check-prefix=WITHOUT %s +// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -o - %s -fsanitize=type | FileCheck -check-prefix=TYSAN %s +// RUN: echo "src:%s" | sed -e 's/\\/\\\\/g' > %t +// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -o - %s -fsanitize=type -fsanitize-blacklist=%t | FileCheck -check-prefix=BL %s + +// The sanitize_type attribute should be attached to functions +// when TypeSanitizer is enabled, unless no_sanitize("type") attribute +// is present. + +// WITHOUT: NoTYSAN1{{.*}}) [[NOATTR:#[0-9]+]] +// BL: NoTYSAN1{{.*}}) [[NOATTR:#[0-9]+]] +// TYSAN: NoTYSAN1{{.*}}) [[NOATTR:#[0-9]+]] +__attribute__((no_sanitize("type"))) int NoTYSAN1(int *a) { return *a; } + +// WITHOUT: NoTYSAN2{{.*}}) [[NOATTR]] +// BL: NoTYSAN2{{.*}}) [[NOATTR]] +// TYSAN: NoTYSAN2{{.*}}) [[NOATTR]] +__attribute__((no_sanitize("type"))) int NoTYSAN2(int *a); +int NoTYSAN2(int *a) { return *a; } + +// WITHOUT: NoTYSAN3{{.*}}) [[NOATTR:#[0-9]+]] +// BL: NoTYSAN3{{.*}}) [[NOATTR:#[0-9]+]] +// TYSAN: NoTYSAN3{{.*}}) [[NOATTR:#[0-9]+]] +__attribute__((no_sanitize("type"))) int NoTYSAN3(int *a) { return *a; } + +// WITHOUT: TYSANOk{{.*}}) [[NOATTR]] +// BL: TYSANOk{{.*}}) [[NOATTR]] +// TYSAN: TYSANOk{{.*}}) [[WITH:#[0-9]+]] +int TYSANOk(int *a) { return *a; } + +// WITHOUT: TemplateTYSANOk{{.*}}) [[NOATTR]] +// BL: TemplateTYSANOk{{.*}}) [[NOATTR]] +// TYSAN: TemplateTYSANOk{{.*}}) [[WITH]] +template <int i> +int TemplateTYSANOk() { return i; } + +// WITHOUT: TemplateNoTYSAN{{.*}}) [[NOATTR]] +// BL: TemplateNoTYSAN{{.*}}) [[NOATTR]] +// TYSAN: TemplateNoTYSAN{{.*}}) [[NOATTR]] +template <int i> +__attribute__((no_sanitize("type"))) int TemplateNoTYSAN() { return i; } + +int force_instance = TemplateTYSANOk<42>() + TemplateNoTYSAN<42>(); + +// Check that __cxx_global_var_init* get the sanitize_type attribute. +int global1 = 0; +int global2 = *(int *)((char *)&global1 + 1); +// WITHOUT: @__cxx_global_var_init{{.*}}[[NOATTR:#[0-9]+]] +// BL: @__cxx_global_var_init{{.*}}[[NOATTR:#[0-9]+]] +// TYSAN: @__cxx_global_var_init{{.*}}[[WITH:#[0-9]+]] + +// Make sure that we don't add globals to the list for which we don't have a +// specific type description. +// FIXME: We now have a type description for this type and a global is added. Should it? +struct SX { + int a, b; +}; +SX sx; + +// WITHOUT: attributes [[NOATTR]] = { noinline nounwind{{.*}} } + +// BL: attributes [[NOATTR]] = { noinline nounwind{{.*}} } + +// TYSAN: attributes [[NOATTR]] = { mustprogress noinline nounwind{{.*}} } +// TYSAN: attributes [[WITH]] = { noinline nounwind sanitize_type{{.*}} } + +// TYSAN-DAG: !llvm.tysan.globals = !{[[G1MD:![0-9]+]], [[G2MD:![0-9]+]], [[G3MD:![0-9]+]], [[SXMD:![0-9]+]]} +// TYSAN-DAG: [[G1MD]] = !{ptr @force_instance, [[INTMD:![0-9]+]]} +// TYSAN-DAG: [[INTMD]] = !{!"int", +// TYSAN-DAG: [[G2MD]] = !{ptr @global1, [[INTMD]]} +// TYSAN-DAG: [[G3MD]] = !{ptr @global2, [[INTMD]]} +// TYSAN-DAG: [[SXMD]] = !{ptr @sx, [[SXTYMD:![0-9]+]]} +// TYSAN-DAG: [[SXTYMD]] = !{!"_ZTS2SX", [[INTMD]], i64 0, !1, i64 4} +// TYSAN-DAG: Simple C++ TBAA _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits