diff --git a/clang/include/clang/Basic/Sanitizers.h b/clang/include/clang/Basic/Sanitizers.h index a3afcb12913d..3b1797e9f539 100644 --- a/clang/include/clang/Basic/Sanitizers.h +++ b/clang/include/clang/Basic/Sanitizers.h @@ -73,9 +73,6 @@ SanitizerMask parseSanitizerValue(StringRef Value, bool AllowGroups); /// this group enables. SanitizerMask expandSanitizerGroups(SanitizerMask Kinds); -/// Returns the mask of sanitizers which can be used without runtime library. -SanitizerMask getSanitizersWithNoRequiredRuntime(); - } // end namespace clang #endif diff --git a/clang/include/clang/Driver/ToolChain.h b/clang/include/clang/Driver/ToolChain.h index d6c5cfdcb75c..4471f21f498d 100644 --- a/clang/include/clang/Driver/ToolChain.h +++ b/clang/include/clang/Driver/ToolChain.h @@ -10,7 +10,6 @@ #ifndef LLVM_CLANG_DRIVER_TOOLCHAIN_H #define LLVM_CLANG_DRIVER_TOOLCHAIN_H -#include "clang/Basic/Sanitizers.h" #include "clang/Driver/Action.h" #include "clang/Driver/Multilib.h" #include "clang/Driver/Types.h" @@ -349,11 +348,6 @@ public: virtual bool AddFastMathRuntimeIfAvailable(const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs) const; - - /// \brief Return sanitizers which are available in this toolchain. - virtual SanitizerMask getSupportedSanitizers() const { - return getSanitizersWithNoRequiredRuntime(); - } }; } // end namespace driver diff --git a/clang/lib/Basic/Sanitizers.cpp b/clang/lib/Basic/Sanitizers.cpp index 527d7f0c70e8..8c4884b8ec36 100644 --- a/clang/lib/Basic/Sanitizers.cpp +++ b/clang/lib/Basic/Sanitizers.cpp @@ -56,9 +56,3 @@ SanitizerMask clang::expandSanitizerGroups(SanitizerMask Kinds) { #include "clang/Basic/Sanitizers.def" return Kinds; } - -SanitizerMask clang::getSanitizersWithNoRequiredRuntime() { - return SanitizerKind::UndefinedTrap | SanitizerKind::CFI | - SanitizerKind::CFICastStrict | SanitizerKind::UnsignedIntegerOverflow | - SanitizerKind::LocalBounds; -} diff --git a/clang/lib/Driver/MSVCToolChain.cpp b/clang/lib/Driver/MSVCToolChain.cpp index 72161213db05..d824fe4c1083 100644 --- a/clang/lib/Driver/MSVCToolChain.cpp +++ b/clang/lib/Driver/MSVCToolChain.cpp @@ -522,12 +522,3 @@ MSVCToolChain::ComputeEffectiveClangTriple(const ArgList &Args, } return Triple.getTriple(); } - -SanitizerMask MSVCToolChain::getSupportedSanitizers() const { - SanitizerMask Res = ToolChain::getSupportedSanitizers(); - Res |= SanitizerKind::Address; - // CFI checks are not implemented for MSVC ABI for now. - Res &= ~SanitizerKind::CFI; - Res &= ~SanitizerKind::CFICastStrict; - return Res; -} diff --git a/clang/lib/Driver/SanitizerArgs.cpp b/clang/lib/Driver/SanitizerArgs.cpp index 8cbda7f34f00..72530b442f52 100644 --- a/clang/lib/Driver/SanitizerArgs.cpp +++ b/clang/lib/Driver/SanitizerArgs.cpp @@ -74,6 +74,27 @@ static std::string describeSanitizeArg(const llvm::opt::Arg *A, /// Sanitizers set. static std::string toString(const clang::SanitizerSet &Sanitizers); +static SanitizerMask getToolchainUnsupportedKinds(const ToolChain &TC) { + bool IsFreeBSD = TC.getTriple().getOS() == llvm::Triple::FreeBSD; + bool IsLinux = TC.getTriple().getOS() == llvm::Triple::Linux; + bool IsX86 = TC.getTriple().getArch() == llvm::Triple::x86; + bool IsX86_64 = TC.getTriple().getArch() == llvm::Triple::x86_64; + bool IsMIPS64 = TC.getTriple().getArch() == llvm::Triple::mips64 || + TC.getTriple().getArch() == llvm::Triple::mips64el; + + SanitizerMask Unsupported = 0; + if (!(IsLinux && (IsX86_64 || IsMIPS64))) { + Unsupported |= Memory | DataFlow; + } + if (!((IsLinux || IsFreeBSD) && (IsX86_64 || IsMIPS64))) { + Unsupported |= Thread; + } + if (!(IsLinux && (IsX86 || IsX86_64))) { + Unsupported |= Function; + } + return Unsupported; +} + static bool getDefaultBlacklist(const Driver &D, SanitizerMask Kinds, std::string &BLPath) { const char *BlacklistFile = nullptr; @@ -95,17 +116,6 @@ static bool getDefaultBlacklist(const Driver &D, SanitizerMask Kinds, return false; } -/// Sets group bits for every group that has at least one representative already -/// enabled in \p Kinds. -static SanitizerMask setGroupBits(SanitizerMask Kinds) { -#define SANITIZER(NAME, ID) -#define SANITIZER_GROUP(NAME, ID, ALIAS) \ - if (Kinds & SanitizerKind::ID) \ - Kinds |= SanitizerKind::ID##Group; -#include "clang/Basic/Sanitizers.def" - return Kinds; -} - bool SanitizerArgs::needsUbsanRt() const { return !UbsanTrapOnError && (Sanitizers.Mask & NeedsUbsanRt) && !Sanitizers.has(Address) && @@ -152,7 +162,7 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC, SanitizerMask DiagnosedKinds = 0; // All Kinds we have diagnosed up to now. // Used to deduplicate diagnostics. SanitizerMask Kinds = 0; - SanitizerMask Supported = setGroupBits(TC.getSupportedSanitizers()); + SanitizerMask NotSupported = getToolchainUnsupportedKinds(TC); ToolChain::RTTIMode RTTIMode = TC.getRTTIMode(); const Driver &D = TC.getDriver(); @@ -170,14 +180,14 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC, // sanitizers in Add are those which have been explicitly enabled. // Diagnose them. if (SanitizerMask KindsToDiagnose = - Add & ~Supported & ~DiagnosedKinds) { + Add & NotSupported & ~DiagnosedKinds) { // Only diagnose the new kinds. std::string Desc = describeSanitizeArg(*I, KindsToDiagnose); D.Diag(diag::err_drv_unsupported_opt_for_target) << Desc << TC.getTriple().str(); DiagnosedKinds |= KindsToDiagnose; } - Add &= Supported; + Add &= ~NotSupported; // Test for -fno-rtti + explicit -fsanitizer=vptr before expanding groups // so we don't error out if -fno-rtti and -fsanitize=undefined were @@ -206,7 +216,7 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC, Add &= ~AllRemove; // Silently discard any unsupported sanitizers implicitly enabled through // group expansion. - Add &= Supported; + Add &= ~NotSupported; Kinds |= Add; } else if (Arg->getOption().matches(options::OPT_fno_sanitize_EQ)) { diff --git a/clang/lib/Driver/ToolChains.cpp b/clang/lib/Driver/ToolChains.cpp index aaaab9cecd28..e3dab2040fc6 100644 --- a/clang/lib/Driver/ToolChains.cpp +++ b/clang/lib/Driver/ToolChains.cpp @@ -399,10 +399,26 @@ void DarwinClang::AddLinkRuntimeLibArgs(const ArgList &Args, const SanitizerArgs &Sanitize = getSanitizerArgs(); - if (Sanitize.needsAsanRt()) - AddLinkSanitizerLibArgs(Args, CmdArgs, "asan"); - if (Sanitize.needsUbsanRt()) - AddLinkSanitizerLibArgs(Args, CmdArgs, "ubsan"); + + if (Sanitize.needsAsanRt()) { + if (!isTargetMacOS() && !isTargetIOSSimulator()) { + // FIXME: Move this check to SanitizerArgs::filterUnsupportedKinds. + getDriver().Diag(diag::err_drv_clang_unsupported_per_platform) + << "-fsanitize=address"; + } else { + AddLinkSanitizerLibArgs(Args, CmdArgs, "asan"); + } + } + + if (Sanitize.needsUbsanRt()) { + if (!isTargetMacOS() && !isTargetIOSSimulator()) { + // FIXME: Move this check to SanitizerArgs::filterUnsupportedKinds. + getDriver().Diag(diag::err_drv_clang_unsupported_per_platform) + << "-fsanitize=undefined"; + } else { + AddLinkSanitizerLibArgs(Args, CmdArgs, "ubsan"); + } + } // Otherwise link libSystem, then the dynamic runtime library, and finally any // target specific static runtime library. @@ -1081,18 +1097,6 @@ void Darwin::CheckObjCARC() const { getDriver().Diag(diag::err_arc_unsupported_on_toolchain); } -SanitizerMask Darwin::getSupportedSanitizers() const { - SanitizerMask Res = ToolChain::getSupportedSanitizers(); - if (isTargetMacOS() || isTargetIOSSimulator()) { - // ASan and UBSan are available on Mac OS and on iOS simulator. - Res |= SanitizerKind::Address; - Res |= SanitizerKind::Vptr; - } - if (isTargetMacOS()) - Res |= SanitizerKind::SafeStack; - return Res; -} - /// Generic_GCC - A tool chain using the 'gcc' command to perform /// all subcommands; this relies on gcc translating the majority of /// command line options. @@ -2733,24 +2737,6 @@ bool FreeBSD::isPIEDefault() const { return getSanitizerArgs().requiresPIE(); } -SanitizerMask FreeBSD::getSupportedSanitizers() const { - const bool IsX86 = getTriple().getArch() == llvm::Triple::x86; - const bool IsX86_64 = getTriple().getArch() == llvm::Triple::x86_64; - const bool IsMIPS64 = getTriple().getArch() == llvm::Triple::mips64 || - getTriple().getArch() == llvm::Triple::mips64el; - SanitizerMask Res = ToolChain::getSupportedSanitizers(); - Res |= SanitizerKind::Address; - Res |= SanitizerKind::Vptr; - if (IsX86_64 || IsMIPS64) { - Res |= SanitizerKind::Leak; - Res |= SanitizerKind::Thread; - } - if (IsX86 || IsX86_64) { - Res |= SanitizerKind::SafeStack; - } - return Res; -} - /// NetBSD - NetBSD tool chain which can call as(1) and ld(1) directly. NetBSD::NetBSD(const Driver &D, const llvm::Triple& Triple, const ArgList &Args) @@ -3655,27 +3641,6 @@ bool Linux::isPIEDefault() const { return getSanitizerArgs().requiresPIE(); } -SanitizerMask Linux::getSupportedSanitizers() const { - const bool IsX86 = getTriple().getArch() == llvm::Triple::x86; - const bool IsX86_64 = getTriple().getArch() == llvm::Triple::x86_64; - const bool IsMIPS64 = getTriple().getArch() == llvm::Triple::mips64 || - getTriple().getArch() == llvm::Triple::mips64el; - SanitizerMask Res = ToolChain::getSupportedSanitizers(); - Res |= SanitizerKind::Address; - Res |= SanitizerKind::Vptr; - if (IsX86_64 || IsMIPS64) { - Res |= SanitizerKind::DataFlow; - Res |= SanitizerKind::Leak; - Res |= SanitizerKind::Memory; - Res |= SanitizerKind::Thread; - } - if (IsX86 || IsX86_64) { - Res |= SanitizerKind::Function; - Res |= SanitizerKind::SafeStack; - } - return Res; -} - /// DragonFly - DragonFly tool chain which can call as(1) and ld(1) directly. DragonFly::DragonFly(const Driver &D, const llvm::Triple& Triple, const ArgList &Args) diff --git a/clang/lib/Driver/ToolChains.h b/clang/lib/Driver/ToolChains.h index 401aa839c21c..0b7073f2ba0b 100644 --- a/clang/lib/Driver/ToolChains.h +++ b/clang/lib/Driver/ToolChains.h @@ -474,8 +474,6 @@ public: void CheckObjCARC() const override; bool UseSjLjExceptions() const override; - - SanitizerMask getSupportedSanitizers() const override; }; /// DarwinClang - The Darwin toolchain used by Clang. @@ -618,7 +616,6 @@ public: bool UseSjLjExceptions() const override; bool isPIEDefault() const override; - SanitizerMask getSupportedSanitizers() const override; protected: Tool *buildAssembler() const override; Tool *buildLinker() const override; @@ -682,7 +679,6 @@ public: AddClangCXXStdlibIncludeArgs(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const override; bool isPIEDefault() const override; - SanitizerMask getSupportedSanitizers() const override; std::string Linker; std::vector ExtraOpts; @@ -813,7 +809,6 @@ public: std::string ComputeEffectiveClangTriple(const llvm::opt::ArgList &Args, types::ID InputType) const override; - SanitizerMask getSupportedSanitizers() const override; protected: void AddSystemIncludeWithSubfolder(const llvm::opt::ArgList &DriverArgs, diff --git a/clang/test/Driver/asan.c b/clang/test/Driver/asan.c index bea8544595d7..f199e904e758 100644 --- a/clang/test/Driver/asan.c +++ b/clang/test/Driver/asan.c @@ -1,7 +1,7 @@ -// RUN: %clang -target i386-unknown-linux -fsanitize=address %s -S -emit-llvm -o - | FileCheck %s -// RUN: %clang -O1 -target i386-unknown-linux -fsanitize=address %s -S -emit-llvm -o - | FileCheck %s -// RUN: %clang -O2 -target i386-unknown-linux -fsanitize=address %s -S -emit-llvm -o - | FileCheck %s -// RUN: %clang -O3 -target i386-unknown-linux -fsanitize=address %s -S -emit-llvm -o - | FileCheck %s +// RUN: %clang -target i386-unknown-unknown -fsanitize=address %s -S -emit-llvm -o - | FileCheck %s +// RUN: %clang -O1 -target i386-unknown-unknown -fsanitize=address %s -S -emit-llvm -o - | FileCheck %s +// RUN: %clang -O2 -target i386-unknown-unknown -fsanitize=address %s -S -emit-llvm -o - | FileCheck %s +// RUN: %clang -O3 -target i386-unknown-unknown -fsanitize=address %s -S -emit-llvm -o - | FileCheck %s // Verify that -fsanitize=address invokes asan instrumentation. int foo(int *a) { return *a; } diff --git a/clang/test/Driver/fsanitize.c b/clang/test/Driver/fsanitize.c index ceaca343fa3c..964ad2b1d74d 100644 --- a/clang/test/Driver/fsanitize.c +++ b/clang/test/Driver/fsanitize.c @@ -1,5 +1,5 @@ -// RUN: %clang -target x86_64-pc-openbsd -fsanitize=undefined-trap -fsanitize-undefined-trap-on-error %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UNDEFINED-TRAP -// RUN: %clang -target x86_64-pc-openbsd -fsanitize-undefined-trap-on-error -fsanitize=undefined-trap %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UNDEFINED-TRAP +// RUN: %clang -target x86_64-linux-gnu -fsanitize=undefined-trap -fsanitize-undefined-trap-on-error %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UNDEFINED-TRAP +// RUN: %clang -target x86_64-linux-gnu -fsanitize-undefined-trap-on-error -fsanitize=undefined-trap %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UNDEFINED-TRAP // CHECK-UNDEFINED-TRAP: "-fsanitize={{((signed-integer-overflow|integer-divide-by-zero|float-divide-by-zero|shift-base|shift-exponent|unreachable|return|vla-bound|alignment|null|object-size|float-cast-overflow|array-bounds|enum|bool|returns-nonnull-attribute|nonnull-attribute),?){17}"}} // CHECK-UNDEFINED-TRAP: "-fsanitize-undefined-trap-on-error" @@ -188,12 +188,6 @@ // RUN: %clang -target x86_64-apple-darwin10 -fsanitize=function -fsanitize=undefined %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-FSAN-UBSAN-DARWIN // CHECK-FSAN-UBSAN-DARWIN: unsupported option '-fsanitize=function' for target 'x86_64-apple-darwin10' -// RUN: %clang -target armv7-apple-ios7 -miphoneos-version-min=7.0 -fsanitize=address %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ASAN-IOS -// CHECK-ASAN-IOS: unsupported option '-fsanitize=address' for target 'arm-apple-ios7' - -// RUN: %clang -target i386-pc-openbsd -fsanitize=address %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ASAN-OPENBSD -// CHECK-ASAN-OPENBSD: unsupported option '-fsanitize=address' for target 'i386-pc-openbsd' - // RUN: %clang -target x86_64-linux-gnu -fsanitize=cfi -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-CFI // RUN: %clang -target x86_64-linux-gnu -fsanitize=cfi-derived-cast -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-CFI-DCAST // RUN: %clang -target x86_64-linux-gnu -fsanitize=cfi-unrelated-cast -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-CFI-UCAST diff --git a/clang/test/Driver/rtti-options.cpp b/clang/test/Driver/rtti-options.cpp index ba072345852a..46072ca6ea74 100644 --- a/clang/test/Driver/rtti-options.cpp +++ b/clang/test/Driver/rtti-options.cpp @@ -16,11 +16,16 @@ // Make sure we only error/warn once, when trying to enable vptr and // undefined and have -fno-rtti // RUN: %clang -### -c -fsanitize=undefined -fsanitize=vptr -fno-rtti %s 2>&1 | FileCheck -check-prefix=CHECK-SAN-ERROR -check-prefix=CHECK-OK %s -// RUN: %clang -### -c -target x86_64-unknown-linux -fsanitize=vptr %s 2>&1 | FileCheck -check-prefix=CHECK-OK %s -// RUN: %clang -### -c -target x86_64-unknown-linux -fsanitize=vptr -frtti %s 2>&1 | FileCheck -check-prefix=CHECK-OK %s -// RUN: %clang -### -c -target x86_64-unknown-linux -fsanitize=vptr -fno-rtti %s 2>&1 | FileCheck -check-prefix=CHECK-SAN-ERROR %s -// RUN: %clang -### -c -target x86_64-unknown-linux -fsanitize=undefined %s 2>&1 | FileCheck -check-prefix=CHECK-OK %s -// RUN: %clang -### -c -target x86_64-unknown-linux -fsanitize=undefined -frtti %s 2>&1 | FileCheck -check-prefix=CHECK-OK %s + +// RUN: %clang -### -c -target x86_64-scei-ps4 -fsanitize=vptr %s 2>&1 | FileCheck -check-prefix=CHECK-SAN-WARN %s +// RUN: %clang -### -c -target x86_64-scei-ps4 -fsanitize=vptr -frtti %s 2>&1 | FileCheck -check-prefix=CHECK-OK %s +// RUN: %clang -### -c -target x86_64-scei-ps4 -fsanitize=vptr -fno-rtti %s 2>&1 | FileCheck -check-prefix=CHECK-SAN-ERROR %s +// RUN: %clang -### -c -target x86_64-scei-ps4 -fsanitize=undefined -frtti %s 2>&1 | FileCheck -check-prefix=CHECK-OK %s +// RUN: %clang -### -c -target x86_64-unknown-unknown -fsanitize=vptr %s 2>&1 | FileCheck -check-prefix=CHECK-OK %s +// RUN: %clang -### -c -target x86_64-unknown-unknown -fsanitize=vptr -frtti %s 2>&1 | FileCheck -check-prefix=CHECK-OK %s +// RUN: %clang -### -c -target x86_64-unknown-unknown -fsanitize=vptr -fno-rtti %s 2>&1 | FileCheck -check-prefix=CHECK-SAN-ERROR %s +// RUN: %clang -### -c -target x86_64-unknown-unknown -fsanitize=undefined %s 2>&1 | FileCheck -check-prefix=CHECK-OK %s +// RUN: %clang -### -c -target x86_64-unknown-unknown -fsanitize=undefined -frtti %s 2>&1 | FileCheck -check-prefix=CHECK-OK %s // Exceptions + no/default rtti // RUN: %clang -### -c -target x86_64-scei-ps4 -fcxx-exceptions -fno-rtti %s 2>&1 | FileCheck -check-prefix=CHECK-EXC-ERROR-CXX %s @@ -46,6 +51,7 @@ // RUN: %clang -### -c -target x86_64-unknown-unknown %s 2>&1 | FileCheck -check-prefix=CHECK-RTTI %s // CHECK-UNUSED: warning: argument unused during compilation: '-fcxx-exceptions' +// CHECK-SAN-WARN: implicitly disabling vptr sanitizer because rtti wasn't enabled // CHECK-SAN-ERROR: invalid argument '-fsanitize=vptr' not allowed with '-fno-rtti' // CHECK-EXC-WARN: implicitly enabling rtti for exception handling // CHECK-EXC-ERROR: invalid argument '-fno-rtti' not allowed with '-fexceptions'