summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorVedant Kumar <vsk@apple.com>2017-08-02 18:10:31 +0000
committerVedant Kumar <vsk@apple.com>2017-08-02 18:10:31 +0000
commita0c3671b204564ac0c746e22312828643e8d4b11 (patch)
tree31fb0892ff56cddc4bdd1bad76435815bcaca495 /clang/lib
parent1f9ab16c4e0634d85098d41f83cd949fcf616dac (diff)
downloadbcm5719-llvm-a0c3671b204564ac0c746e22312828643e8d4b11.tar.gz
bcm5719-llvm-a0c3671b204564ac0c746e22312828643e8d4b11.zip
[ubsan] Have -fsanitize=vptr emit a null check if -fsanitize=null isn't available
In r309007, I made -fsanitize=null a hard prerequisite for -fsanitize=vptr. I did not see the need for the two checks to have separate null checking logic for the same pointer. I expected the two checks to either always be enabled together, or to be mutually compatible. In the mailing list discussion re: r309007 it became clear that that isn't the case. If a codebase is -fsanitize=vptr clean but not -fsanitize=null clean, it's useful to have -fsanitize=vptr emit its own null check. That's what this patch does: with it, -fsanitize=vptr can be used without -fsanitize=null. Differential Revision: https://reviews.llvm.org/D36112 llvm-svn: 309846
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/CodeGen/CGExpr.cpp8
-rw-r--r--clang/lib/Driver/SanitizerArgs.cpp7
2 files changed, 4 insertions, 11 deletions
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index e9ad05cf666..ec48b2cc86e 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -694,17 +694,17 @@ void CodeGenFunction::EmitTypeCheck(TypeCheckKind TCK, SourceLocation Loc,
// -- the [pointer or glvalue] is used to access a non-static data member
// or call a non-static member function
CXXRecordDecl *RD = Ty->getAsCXXRecordDecl();
- bool HasNullCheck = IsGuaranteedNonNull || IsNonNull;
if (SanOpts.has(SanitizerKind::Vptr) &&
- !SkippedChecks.has(SanitizerKind::Vptr) && HasNullCheck &&
+ !SkippedChecks.has(SanitizerKind::Vptr) &&
(TCK == TCK_MemberAccess || TCK == TCK_MemberCall ||
TCK == TCK_DowncastPointer || TCK == TCK_DowncastReference ||
TCK == TCK_UpcastToVirtualBase) &&
RD && RD->hasDefinition() && RD->isDynamicClass()) {
// Ensure that the pointer is non-null before loading it. If there is no
- // compile-time guarantee, reuse the run-time null check.
+ // compile-time guarantee, reuse the run-time null check or emit a new one.
if (!IsGuaranteedNonNull) {
- assert(IsNonNull && "Missing run-time null check");
+ if (!IsNonNull)
+ IsNonNull = Builder.CreateIsNotNull(Ptr);
if (!Done)
Done = createBasicBlock("vptr.null");
llvm::BasicBlock *VptrNotNull = createBasicBlock("vptr.not.null");
diff --git a/clang/lib/Driver/SanitizerArgs.cpp b/clang/lib/Driver/SanitizerArgs.cpp
index f4fe06af25f..2a3ae51734d 100644
--- a/clang/lib/Driver/SanitizerArgs.cpp
+++ b/clang/lib/Driver/SanitizerArgs.cpp
@@ -307,13 +307,6 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC,
Kinds &= ~Vptr;
}
- // Disable -fsanitize=vptr if -fsanitize=null is not enabled (the vptr
- // instrumentation is broken without run-time null checks).
- if ((Kinds & Vptr) && !(Kinds & Null)) {
- Kinds &= ~Vptr;
- D.Diag(diag::warn_drv_disabling_vptr_no_null_check);
- }
-
// Check that LTO is enabled if we need it.
if ((Kinds & NeedsLTO) && !D.isUsingLTO()) {
D.Diag(diag::err_drv_argument_only_allowed_with)
OpenPOWER on IntegriCloud