From: Alexey Samsonov Date: Thu, 25 Jun 2015 23:14:32 +0000 (+0000) Subject: [CFI] Diagnose when we CFI in diagnostic mode is unavailable on a toolchain. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=8212d5b5e884ea2e4d01edab485def5e0631bba9;p=clang [CFI] Diagnose when we CFI in diagnostic mode is unavailable on a toolchain. Summary: Namely, we must have proper C++ABI support in UBSan runtime. We don't have a good way to check for that, so just assume that C++ABI support is there whenever -fsanitize=vptr is supported (i.e. only on handful of platforms). Exact diagnostic is also tricky. It's not "cfi" that is unsupported, just the diagnostic mode. So, I suggest to report that "-fno-sanitize-trap=cfi-foobar" is incompatible with a given target toolchain. Test Plan: regression test suite Reviewers: pcc Subscribers: cfe-commits Differential Revision: http://reviews.llvm.org/D10751 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@240716 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Driver/SanitizerArgs.cpp b/lib/Driver/SanitizerArgs.cpp index 14c37025eb..e203aac582 100644 --- a/lib/Driver/SanitizerArgs.cpp +++ b/lib/Driver/SanitizerArgs.cpp @@ -26,6 +26,7 @@ using namespace llvm::opt; enum : SanitizerMask { NeedsUbsanRt = Undefined | Integer | CFI, + NeedsUbsanCxxRt = Vptr | CFI, NotAllowedWithTrap = Vptr, RequiresPIE = Memory | DataFlow, NeedsUnwindTables = Address | Thread | Memory | DataFlow, @@ -194,7 +195,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()); + const SanitizerMask Supported = setGroupBits(TC.getSupportedSanitizers()); ToolChain::RTTIMode RTTIMode = TC.getRTTIMode(); const Driver &D = TC.getDriver(); @@ -282,6 +283,21 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC, << lastArgumentForMask(D, Args, Kinds & NeedsLTO) << "-flto"; } + // Report error if there are non-trapping sanitizers that require + // c++abi-specific parts of UBSan runtime, and they are not provided by the + // toolchain. We don't have a good way to check the latter, so we just + // check if the toolchan supports vptr. + if (~Supported & Vptr) { + if (SanitizerMask KindsToDiagnose = + Kinds & ~TrappingKinds & NeedsUbsanCxxRt) { + SanitizerSet S; + S.Mask = KindsToDiagnose; + D.Diag(diag::err_drv_unsupported_opt_for_target) + << ("-fno-sanitize-trap=" + toString(S)) << TC.getTriple().str(); + Kinds &= ~KindsToDiagnose; + } + } + // Warn about incompatible groups of sanitizers. std::pair IncompatibleGroups[] = { std::make_pair(Address, Thread), std::make_pair(Address, Memory), diff --git a/test/Driver/fsanitize.c b/test/Driver/fsanitize.c index b124b5b4b7..b473e86bf2 100644 --- a/test/Driver/fsanitize.c +++ b/test/Driver/fsanitize.c @@ -234,6 +234,9 @@ // RUN: %clang -target x86_64-linux-gnu -fsanitize-trap=address -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ASAN-TRAP // CHECK-ASAN-TRAP: error: unsupported argument 'address' to option '-fsanitize-trap' +// RUN: %clang -target x86_64-apple-darwin10 -mmacosx-version-min=10.7 -flto -fsanitize=cfi-vcall -fno-sanitize-trap=cfi -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-CFI-NOTRAP-OLD-MACOS +// CHECK-CFI-NOTRAP-OLD-MACOS: error: unsupported option '-fno-sanitize-trap=cfi-vcall' for target 'x86_64-apple-darwin10' + // RUN: %clang_cl -fsanitize=address -c -MDd -### -- %s 2>&1 | FileCheck %s -check-prefix=CHECK-ASAN-DEBUGRTL // RUN: %clang_cl -fsanitize=address -c -MTd -### -- %s 2>&1 | FileCheck %s -check-prefix=CHECK-ASAN-DEBUGRTL // RUN: %clang_cl -fsanitize=address -c -LDd -### -- %s 2>&1 | FileCheck %s -check-prefix=CHECK-ASAN-DEBUGRTL