summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen/CGExprCXX.cpp
diff options
context:
space:
mode:
authorVedant Kumar <vsk@apple.com>2017-02-17 23:22:59 +0000
committerVedant Kumar <vsk@apple.com>2017-02-17 23:22:59 +0000
commit34b1fd6aaaf7e31ddcf65437ba8e274fe79bb7d2 (patch)
tree2faba601747f6814bed2cf9e4d8c23265000bacc /clang/lib/CodeGen/CGExprCXX.cpp
parent18348ea9b9d991ce70664187576a13f773496144 (diff)
downloadbcm5719-llvm-34b1fd6aaaf7e31ddcf65437ba8e274fe79bb7d2.tar.gz
bcm5719-llvm-34b1fd6aaaf7e31ddcf65437ba8e274fe79bb7d2.zip
Retry^2: [ubsan] Reduce null checking of C++ object pointers (PR27581)
This patch teaches ubsan to insert exactly one null check for the 'this' pointer per method/lambda. Previously, given a load of a member variable from an instance method ('this->x'), ubsan would insert a null check for 'this', and another null check for '&this->x', before allowing the load to occur. Similarly, given a call to a method from another method bound to the same instance ('this->foo()'), ubsan would a redundant null check for 'this'. There is also a redundant null check in the case where the object pointer is a reference ('Ref.foo()'). This patch teaches ubsan to remove the redundant null checks identified above. Testing: check-clang, check-ubsan, and a stage2 ubsan build. I also compiled X86FastISel.cpp with -fsanitize=null using patched/unpatched clangs based on r293572. Here are the number of null checks emitted: ------------------------------------- | Setup | # of null checks | ------------------------------------- | unpatched, -O0 | 21767 | | patched, -O0 | 10758 | ------------------------------------- Changes since the initial commit: - Don't introduce any unintentional object-size or alignment checks. - Don't rely on IRGen of C labels in the test. Differential Revision: https://reviews.llvm.org/D29530 llvm-svn: 295515
Diffstat (limited to 'clang/lib/CodeGen/CGExprCXX.cpp')
-rw-r--r--clang/lib/CodeGen/CGExprCXX.cpp13
1 files changed, 9 insertions, 4 deletions
diff --git a/clang/lib/CodeGen/CGExprCXX.cpp b/clang/lib/CodeGen/CGExprCXX.cpp
index ebe0841b3c2..3751ef116a8 100644
--- a/clang/lib/CodeGen/CGExprCXX.cpp
+++ b/clang/lib/CodeGen/CGExprCXX.cpp
@@ -290,10 +290,15 @@ RValue CodeGenFunction::EmitCXXMemberOrOperatorMemberCallExpr(
if (CE)
CallLoc = CE->getExprLoc();
- EmitTypeCheck(isa<CXXConstructorDecl>(CalleeDecl)
- ? CodeGenFunction::TCK_ConstructorCall
- : CodeGenFunction::TCK_MemberCall,
- CallLoc, This.getPointer(), C.getRecordType(CalleeDecl->getParent()));
+ SanitizerSet SkippedChecks;
+ if (const auto *CMCE = dyn_cast<CXXMemberCallExpr>(CE))
+ if (CanElideObjectPointerNullCheck(CMCE->getImplicitObjectArgument()))
+ SkippedChecks.set(SanitizerKind::Null, true);
+ EmitTypeCheck(
+ isa<CXXConstructorDecl>(CalleeDecl) ? CodeGenFunction::TCK_ConstructorCall
+ : CodeGenFunction::TCK_MemberCall,
+ CallLoc, This.getPointer(), C.getRecordType(CalleeDecl->getParent()),
+ /*Alignment=*/CharUnits::Zero(), SkippedChecks);
// FIXME: Uses of 'MD' past this point need to be audited. We may need to use
// 'CalleeDecl' instead.
OpenPOWER on IntegriCloud