diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2017-08-24 20:10:33 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2017-08-24 20:10:33 +0000 |
commit | 376c28e296b708586bbfd6293519341c6ef911ee (patch) | |
tree | d945f6b4c79434cc6596a4c554931fd7679f43d6 /clang/lib/CodeGen/CodeGenFunction.cpp | |
parent | 68107657d40f9871724f9f61098d0c2e115bb64f (diff) | |
download | bcm5719-llvm-376c28e296b708586bbfd6293519341c6ef911ee.tar.gz bcm5719-llvm-376c28e296b708586bbfd6293519341c6ef911ee.zip |
[ubsan] PR34266: When sanitizing the 'this' value for a member function that happens to be a lambda call operator, use the lambda's 'this' pointer, not the captured enclosing 'this' pointer (if any).
Do not sanitize the 'this' pointer of a member call operator for a lambda with
no capture-default, since that call operator can legitimately be called with a
null this pointer from the static invoker function. Any actual call with a null
this pointer should still be caught in the caller (if it is being sanitized).
This reinstates r311589 (reverted in r311680) with the above fix.
llvm-svn: 311695
Diffstat (limited to 'clang/lib/CodeGen/CodeGenFunction.cpp')
-rw-r--r-- | clang/lib/CodeGen/CodeGenFunction.cpp | 16 |
1 files changed, 14 insertions, 2 deletions
diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp index 4201804e185..17295ae2be8 100644 --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -22,6 +22,7 @@ #include "CodeGenPGO.h" #include "TargetInfo.h" #include "clang/AST/ASTContext.h" +#include "clang/AST/ASTLambda.h" #include "clang/AST/Decl.h" #include "clang/AST/DeclCXX.h" #include "clang/AST/StmtCXX.h" @@ -1014,11 +1015,22 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, } // Check the 'this' pointer once per function, if it's available. - if (CXXThisValue) { + if (CXXABIThisValue) { SanitizerSet SkippedChecks; SkippedChecks.set(SanitizerKind::ObjectSize, true); QualType ThisTy = MD->getThisType(getContext()); - EmitTypeCheck(TCK_Load, Loc, CXXThisValue, ThisTy, + + // If this is the call operator of a lambda with no capture-default, it + // may have a static invoker function, which may call this operator with + // a null 'this' pointer. + if (isLambdaCallOperator(MD) && + cast<CXXRecordDecl>(MD->getParent())->getLambdaCaptureDefault() == + LCD_None) + SkippedChecks.set(SanitizerKind::Null, true); + + EmitTypeCheck(isa<CXXConstructorDecl>(MD) ? TCK_ConstructorCall + : TCK_MemberCall, + Loc, CXXABIThisValue, ThisTy, getContext().getTypeAlignInChars(ThisTy->getPointeeType()), SkippedChecks); } |