summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexey Samsonov <vonosmas@gmail.com>2015-06-17 22:07:28 +0000
committerAlexey Samsonov <vonosmas@gmail.com>2015-06-17 22:07:28 +0000
commit9170efdc0d6274b0d7438dcee929243fcca77e95 (patch)
tree1ad88f95c7dbe0a1391d845f4d6d3093ec761e96
parente0d4037c6a0bcbdadf080e7a2ccd9846370d5f4c (diff)
downloadbcm5719-llvm-9170efdc0d6274b0d7438dcee929243fcca77e95.tar.gz
bcm5719-llvm-9170efdc0d6274b0d7438dcee929243fcca77e95.zip
[Sanitizers] Provide better diagnostic for sanitizers unsupported for target triple.
Summary: Introduce ToolChain::getSupportedSanitizers() that would return the set of sanitizers available on given toolchain. By default, these are sanitizers which don't necessarily require runtime support (i.e. set from -fsanitize=undefined-trap). Sanitizers (ASan, DFSan, TSan, MSan etc.) which cannot function without runtime library are marked as supported only on platforms for which we actually build these runtimes. This would allow more fine-grained checks in the future: for instance, we have to restrict availability of -fsanitize=vptr to Mac OS 10.9+ (PR23539) Update test cases accrodingly: add tests for certain unsupported configurations, remove test cases for -fsanitize=vptr + PS4 integration, as we don't build the runtime for PS4 at the moment. Test Plan: regression test suite Reviewers: pcc Subscribers: cfe-commits, filcab, eugenis, thakis, kubabrecka, emaste, rsmith Differential Revision: http://reviews.llvm.org/D10467 llvm-svn: 239953
-rw-r--r--clang/include/clang/Basic/Sanitizers.h3
-rw-r--r--clang/include/clang/Driver/ToolChain.h6
-rw-r--r--clang/lib/Basic/Sanitizers.cpp6
-rw-r--r--clang/lib/Driver/MSVCToolChain.cpp9
-rw-r--r--clang/lib/Driver/SanitizerArgs.cpp40
-rw-r--r--clang/lib/Driver/ToolChains.cpp75
-rw-r--r--clang/lib/Driver/ToolChains.h5
-rw-r--r--clang/test/Driver/asan.c8
-rw-r--r--clang/test/Driver/fsanitize.c10
-rw-r--r--clang/test/Driver/rtti-options.cpp16
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'
OpenPOWER on IntegriCloud