diff options
Diffstat (limited to 'clang')
| -rw-r--r-- | clang/include/clang/Basic/Sanitizers.h | 3 | ||||
| -rw-r--r-- | clang/include/clang/Driver/ToolChain.h | 6 | ||||
| -rw-r--r-- | clang/lib/Basic/Sanitizers.cpp | 6 | ||||
| -rw-r--r-- | clang/lib/Driver/MSVCToolChain.cpp | 9 | ||||
| -rw-r--r-- | clang/lib/Driver/SanitizerArgs.cpp | 40 | ||||
| -rw-r--r-- | clang/lib/Driver/ToolChains.cpp | 75 | ||||
| -rw-r--r-- | clang/lib/Driver/ToolChains.h | 5 | ||||
| -rw-r--r-- | clang/test/Driver/asan.c | 8 | ||||
| -rw-r--r-- | clang/test/Driver/fsanitize.c | 10 | ||||
| -rw-r--r-- | clang/test/Driver/rtti-options.cpp | 16 |
10 files changed, 116 insertions, 62 deletions
diff --git a/clang/include/clang/Basic/Sanitizers.h b/clang/include/clang/Basic/Sanitizers.h index 3b1797e9f53..a3afcb12913 100644 --- a/clang/include/clang/Basic/Sanitizers.h +++ b/clang/include/clang/Basic/Sanitizers.h @@ -73,6 +73,9 @@ 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 4471f21f498..d6c5cfdcb75 100644 --- a/clang/include/clang/Driver/ToolChain.h +++ b/clang/include/clang/Driver/ToolChain.h @@ -10,6 +10,7 @@ #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" @@ -348,6 +349,11 @@ 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 8c4884b8ec3..527d7f0c70e 100644 --- a/clang/lib/Basic/Sanitizers.cpp +++ b/clang/lib/Basic/Sanitizers.cpp @@ -56,3 +56,9 @@ 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 d824fe4c108..72161213db0 100644 --- a/clang/lib/Driver/MSVCToolChain.cpp +++ b/clang/lib/Driver/MSVCToolChain.cpp @@ -522,3 +522,12 @@ 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 72530b442f5..8cbda7f34f0 100644 --- a/clang/lib/Driver/SanitizerArgs.cpp +++ b/clang/lib/Driver/SanitizerArgs.cpp @@ -74,27 +74,6 @@ 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; @@ -116,6 +95,17 @@ 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) && @@ -162,7 +152,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 NotSupported = getToolchainUnsupportedKinds(TC); + SanitizerMask Supported = setGroupBits(TC.getSupportedSanitizers()); ToolChain::RTTIMode RTTIMode = TC.getRTTIMode(); const Driver &D = TC.getDriver(); @@ -180,14 +170,14 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC, // sanitizers in Add are those which have been explicitly enabled. // Diagnose them. if (SanitizerMask KindsToDiagnose = - Add & NotSupported & ~DiagnosedKinds) { + Add & ~Supported & ~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 &= ~NotSupported; + Add &= Supported; // Test for -fno-rtti + explicit -fsanitizer=vptr before expanding groups // so we don't error out if -fno-rtti and -fsanitize=undefined were @@ -216,7 +206,7 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC, Add &= ~AllRemove; // Silently discard any unsupported sanitizers implicitly enabled through // group expansion. - Add &= ~NotSupported; + Add &= Supported; 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 e3dab2040fc..aaaab9cecd2 100644 --- a/clang/lib/Driver/ToolChains.cpp +++ b/clang/lib/Driver/ToolChains.cpp @@ -399,26 +399,10 @@ void DarwinClang::AddLinkRuntimeLibArgs(const ArgList &Args, const SanitizerArgs &Sanitize = getSanitizerArgs(); - - 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"); - } - } + if (Sanitize.needsAsanRt()) + AddLinkSanitizerLibArgs(Args, CmdArgs, "asan"); + if (Sanitize.needsUbsanRt()) + AddLinkSanitizerLibArgs(Args, CmdArgs, "ubsan"); // Otherwise link libSystem, then the dynamic runtime library, and finally any // target specific static runtime library. @@ -1097,6 +1081,18 @@ 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. @@ -2737,6 +2733,24 @@ 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) @@ -3641,6 +3655,27 @@ 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 0b7073f2ba0..401aa839c21 100644 --- a/clang/lib/Driver/ToolChains.h +++ b/clang/lib/Driver/ToolChains.h @@ -474,6 +474,8 @@ public: void CheckObjCARC() const override; bool UseSjLjExceptions() const override; + + SanitizerMask getSupportedSanitizers() const override; }; /// DarwinClang - The Darwin toolchain used by Clang. @@ -616,6 +618,7 @@ public: bool UseSjLjExceptions() const override; bool isPIEDefault() const override; + SanitizerMask getSupportedSanitizers() const override; protected: Tool *buildAssembler() const override; Tool *buildLinker() const override; @@ -679,6 +682,7 @@ 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<std::string> ExtraOpts; @@ -809,6 +813,7 @@ 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 f199e904e75..bea8544595d 100644 --- a/clang/test/Driver/asan.c +++ b/clang/test/Driver/asan.c @@ -1,7 +1,7 @@ -// 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 +// 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 // 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 964ad2b1d74..ceaca343fa3 100644 --- a/clang/test/Driver/fsanitize.c +++ b/clang/test/Driver/fsanitize.c @@ -1,5 +1,5 @@ -// 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 +// 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 // 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,6 +188,12 @@ // 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 46072ca6ea7..ba072345852 100644 --- a/clang/test/Driver/rtti-options.cpp +++ b/clang/test/Driver/rtti-options.cpp @@ -16,16 +16,11 @@ // 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-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 +// 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 // 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 @@ -51,7 +46,6 @@ // 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' |

