diff options
author | Alexey Samsonov <vonosmas@gmail.com> | 2014-09-08 17:22:45 +0000 |
---|---|---|
committer | Alexey Samsonov <vonosmas@gmail.com> | 2014-09-08 17:22:45 +0000 |
commit | 8e1162c71d40ada37c358d17182c68d8d9fad41d (patch) | |
tree | 6f0f54eaa85f0668b41b63a9e6a1340822c5003d /clang/lib/CodeGen/CGExprCXX.cpp | |
parent | ea65e37beea96207b6fa64959112dc7ba6e44b3c (diff) | |
download | bcm5719-llvm-8e1162c71d40ada37c358d17182c68d8d9fad41d.tar.gz bcm5719-llvm-8e1162c71d40ada37c358d17182c68d8d9fad41d.zip |
Implement nonnull-attribute sanitizer
Summary:
This patch implements a new UBSan check, which verifies
that function arguments declared to be nonnull with __attribute__((nonnull))
are actually nonnull in runtime.
To implement this check, we pass FunctionDecl to CodeGenFunction::EmitCallArgs
(where applicable) and if function declaration has nonnull attribute specified
for a certain formal parameter, we compare the corresponding RValue to null as
soon as it's calculated.
Test Plan: regression test suite
Reviewers: rsmith
Reviewed By: rsmith
Subscribers: cfe-commits, rnk
Differential Revision: http://reviews.llvm.org/D5082
llvm-svn: 217389
Diffstat (limited to 'clang/lib/CodeGen/CGExprCXX.cpp')
-rw-r--r-- | clang/lib/CodeGen/CGExprCXX.cpp | 23 |
1 files changed, 11 insertions, 12 deletions
diff --git a/clang/lib/CodeGen/CGExprCXX.cpp b/clang/lib/CodeGen/CGExprCXX.cpp index 937a0438ad3..a3e444a3f51 100644 --- a/clang/lib/CodeGen/CGExprCXX.cpp +++ b/clang/lib/CodeGen/CGExprCXX.cpp @@ -55,20 +55,18 @@ RValue CodeGenFunction::EmitCXXMemberOrOperatorCall( const FunctionProtoType *FPT = MD->getType()->castAs<FunctionProtoType>(); RequiredArgs required = RequiredArgs::forPrototypePlus(FPT, Args.size()); - + // And the rest of the call args. - CallExpr::const_arg_iterator ArgBeg, ArgEnd; - if (CE == nullptr) { - ArgBeg = ArgEnd = nullptr; - } else if (auto OCE = dyn_cast<CXXOperatorCallExpr>(CE)) { + if (CE) { // Special case: skip first argument of CXXOperatorCall (it is "this"). - ArgBeg = OCE->arg_begin() + 1; - ArgEnd = OCE->arg_end(); + unsigned ArgsToSkip = isa<CXXOperatorCallExpr>(CE) ? 1 : 0; + EmitCallArgs(Args, FPT, CE->arg_begin() + ArgsToSkip, CE->arg_end(), + CE->getDirectCallee()); } else { - ArgBeg = CE->arg_begin(); - ArgEnd = CE->arg_end(); + assert( + FPT->getNumParams() == 0 && + "No CallExpr specified for function with non-zero number of arguments"); } - EmitCallArgs(Args, FPT, ArgBeg, ArgEnd); return EmitCall(CGM.getTypes().arrangeCXXMethodCall(Args, FPT, required), Callee, ReturnValue, Args, MD); @@ -284,7 +282,7 @@ CodeGenFunction::EmitCXXMemberPointerCallExpr(const CXXMemberCallExpr *E, RequiredArgs required = RequiredArgs::forPrototypePlus(FPT, 1); // And the rest of the call args - EmitCallArgs(Args, FPT, E->arg_begin(), E->arg_end()); + EmitCallArgs(Args, FPT, E->arg_begin(), E->arg_end(), E->getDirectCallee()); return EmitCall(CGM.getTypes().arrangeCXXMethodCall(Args, FPT, required), Callee, ReturnValue, Args); } @@ -1238,7 +1236,8 @@ llvm::Value *CodeGenFunction::EmitCXXNewExpr(const CXXNewExpr *E) { // We start at 1 here because the first argument (the allocation size) // has already been emitted. EmitCallArgs(allocatorArgs, allocatorType, E->placement_arg_begin(), - E->placement_arg_end(), /*ParamsToSkip*/ 1); + E->placement_arg_end(), /* CalleeDecl */ nullptr, + /*ParamsToSkip*/ 1); // Emit the allocation call. If the allocator is a global placement // operator, just "inline" it directly. |