180412c4e28c8247ad9c8d30d04c94938f01b21fbAnna Zaks//===--- NonNullParamChecker.cpp - Undefined arguments checker -*- C++ -*--===// 294943b6d913718216a95a91864040ffc11a1d779Zhongxing Xu// 394943b6d913718216a95a91864040ffc11a1d779Zhongxing Xu// The LLVM Compiler Infrastructure 494943b6d913718216a95a91864040ffc11a1d779Zhongxing Xu// 594943b6d913718216a95a91864040ffc11a1d779Zhongxing Xu// This file is distributed under the University of Illinois Open Source 694943b6d913718216a95a91864040ffc11a1d779Zhongxing Xu// License. See LICENSE.TXT for details. 794943b6d913718216a95a91864040ffc11a1d779Zhongxing Xu// 894943b6d913718216a95a91864040ffc11a1d779Zhongxing Xu//===----------------------------------------------------------------------===// 994943b6d913718216a95a91864040ffc11a1d779Zhongxing Xu// 1080412c4e28c8247ad9c8d30d04c94938f01b21fbAnna Zaks// This defines NonNullParamChecker, which checks for arguments expected not to 1180412c4e28c8247ad9c8d30d04c94938f01b21fbAnna Zaks// be null due to: 1280412c4e28c8247ad9c8d30d04c94938f01b21fbAnna Zaks// - the corresponding parameters being declared to have nonnull attribute 1380412c4e28c8247ad9c8d30d04c94938f01b21fbAnna Zaks// - the corresponding parameters being references; since the call would form 1480412c4e28c8247ad9c8d30d04c94938f01b21fbAnna Zaks// a reference to a null pointer 1594943b6d913718216a95a91864040ffc11a1d779Zhongxing Xu// 1694943b6d913718216a95a91864040ffc11a1d779Zhongxing Xu//===----------------------------------------------------------------------===// 1794943b6d913718216a95a91864040ffc11a1d779Zhongxing Xu 18bd90076671c8012244bb7e3fd84b6789e47cb199Argyrios Kyrtzidis#include "ClangSACheckers.h" 192fa67efeaf66a9332c30a026dc1c21bef6c33a6cBenjamin Kramer#include "clang/AST/Attr.h" 2055fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" 21ec8605f1d7ec846dbf51047bfd5c56d32d1ff91cArgyrios Kyrtzidis#include "clang/StaticAnalyzer/Core/Checker.h" 22bd90076671c8012244bb7e3fd84b6789e47cb199Argyrios Kyrtzidis#include "clang/StaticAnalyzer/Core/CheckerManager.h" 23f540c54701e3eeb34cb619a3a4eb18f1ac70ef2dJordan Rose#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h" 24bd90076671c8012244bb7e3fd84b6789e47cb199Argyrios Kyrtzidis#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h" 2594943b6d913718216a95a91864040ffc11a1d779Zhongxing Xu 2694943b6d913718216a95a91864040ffc11a1d779Zhongxing Xuusing namespace clang; 279ef6537a894c33003359b1f9b9676e9178e028b7Ted Kremenekusing namespace ento; 2894943b6d913718216a95a91864040ffc11a1d779Zhongxing Xu 29f493f49fae3ab242ae055ae00b24fa5512655e15Ted Kremeneknamespace { 3080412c4e28c8247ad9c8d30d04c94938f01b21fbAnna Zaksclass NonNullParamChecker 3187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar : public Checker< check::PreCall, EventDispatcher<ImplicitNullDerefEvent> > { 32651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines mutable std::unique_ptr<BugType> BTAttrNonNull; 33651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines mutable std::unique_ptr<BugType> BTNullRefArg; 34651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 35f493f49fae3ab242ae055ae00b24fa5512655e15Ted Kremenekpublic: 36bd90076671c8012244bb7e3fd84b6789e47cb199Argyrios Kyrtzidis 37fe6a011a113b3ddcb32f42af152d7476054e7f79Jordan Rose void checkPreCall(const CallEvent &Call, CheckerContext &C) const; 38018e9aa033ff7363797c62fc3b14669d0558284bAnna Zaks 3987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar std::unique_ptr<BugReport> 4087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar genReportNullAttrNonNull(const ExplodedNode *ErrorN, const Expr *ArgE) const; 4187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar std::unique_ptr<BugReport> 4287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar genReportReferenceToNullPointer(const ExplodedNode *ErrorN, 4387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar const Expr *ArgE) const; 44f493f49fae3ab242ae055ae00b24fa5512655e15Ted Kremenek}; 45f493f49fae3ab242ae055ae00b24fa5512655e15Ted Kremenek} // end anonymous namespace 46f493f49fae3ab242ae055ae00b24fa5512655e15Ted Kremenek 4780412c4e28c8247ad9c8d30d04c94938f01b21fbAnna Zaksvoid NonNullParamChecker::checkPreCall(const CallEvent &Call, 48651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines CheckerContext &C) const { 49fe6a011a113b3ddcb32f42af152d7476054e7f79Jordan Rose const Decl *FD = Call.getDecl(); 5094943b6d913718216a95a91864040ffc11a1d779Zhongxing Xu if (!FD) 5194943b6d913718216a95a91864040ffc11a1d779Zhongxing Xu return; 5294943b6d913718216a95a91864040ffc11a1d779Zhongxing Xu 53176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // Merge all non-null attributes 54176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines unsigned NumArgs = Call.getNumArgs(); 55176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines llvm::SmallBitVector AttrNonNull(NumArgs); 56176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines for (const auto *NonNull : FD->specific_attrs<NonNullAttr>()) { 57176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines if (!NonNull->args_size()) { 58176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines AttrNonNull.set(0, NumArgs); 59176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines break; 60176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } 61176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines for (unsigned Val : NonNull->args()) { 62176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines if (Val >= NumArgs) 63176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines continue; 64176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines AttrNonNull.set(Val); 65176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } 66176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } 6794943b6d913718216a95a91864040ffc11a1d779Zhongxing Xu 68fe6a011a113b3ddcb32f42af152d7476054e7f79Jordan Rose ProgramStateRef state = C.getState(); 6994943b6d913718216a95a91864040ffc11a1d779Zhongxing Xu 70018e9aa033ff7363797c62fc3b14669d0558284bAnna Zaks CallEvent::param_type_iterator TyI = Call.param_type_begin(), 71018e9aa033ff7363797c62fc3b14669d0558284bAnna Zaks TyE = Call.param_type_end(); 72018e9aa033ff7363797c62fc3b14669d0558284bAnna Zaks 73176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines for (unsigned idx = 0; idx < NumArgs; ++idx) { 74018e9aa033ff7363797c62fc3b14669d0558284bAnna Zaks 75018e9aa033ff7363797c62fc3b14669d0558284bAnna Zaks // Check if the parameter is a reference. We want to report when reference 76018e9aa033ff7363797c62fc3b14669d0558284bAnna Zaks // to a null pointer is passed as a paramter. 77018e9aa033ff7363797c62fc3b14669d0558284bAnna Zaks bool haveRefTypeParam = false; 78018e9aa033ff7363797c62fc3b14669d0558284bAnna Zaks if (TyI != TyE) { 79018e9aa033ff7363797c62fc3b14669d0558284bAnna Zaks haveRefTypeParam = (*TyI)->isReferenceType(); 80018e9aa033ff7363797c62fc3b14669d0558284bAnna Zaks TyI++; 81018e9aa033ff7363797c62fc3b14669d0558284bAnna Zaks } 82018e9aa033ff7363797c62fc3b14669d0558284bAnna Zaks 83176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines bool haveAttrNonNull = AttrNonNull[idx]; 84651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (!haveAttrNonNull) { 85651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // Check if the parameter is also marked 'nonnull'. 86651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ArrayRef<ParmVarDecl*> parms = Call.parameters(); 87651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (idx < parms.size()) 88651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines haveAttrNonNull = parms[idx]->hasAttr<NonNullAttr>(); 89651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 90018e9aa033ff7363797c62fc3b14669d0558284bAnna Zaks 91018e9aa033ff7363797c62fc3b14669d0558284bAnna Zaks if (!haveRefTypeParam && !haveAttrNonNull) 9294943b6d913718216a95a91864040ffc11a1d779Zhongxing Xu continue; 9394943b6d913718216a95a91864040ffc11a1d779Zhongxing Xu 94018e9aa033ff7363797c62fc3b14669d0558284bAnna Zaks // If the value is unknown or undefined, we can't perform this check. 95018e9aa033ff7363797c62fc3b14669d0558284bAnna Zaks const Expr *ArgE = Call.getArgExpr(idx); 96fe6a011a113b3ddcb32f42af152d7476054e7f79Jordan Rose SVal V = Call.getArgSVal(idx); 97dc84cd5efdd3430efb22546b4ac656aa0540b210David Blaikie Optional<DefinedSVal> DV = V.getAs<DefinedSVal>(); 989a126850968b0aa25f7c6f214e7309e33f2d800aJordy Rose if (!DV) 999a126850968b0aa25f7c6f214e7309e33f2d800aJordy Rose continue; 10094943b6d913718216a95a91864040ffc11a1d779Zhongxing Xu 101018e9aa033ff7363797c62fc3b14669d0558284bAnna Zaks // Process the case when the argument is not a location. 102018e9aa033ff7363797c62fc3b14669d0558284bAnna Zaks assert(!haveRefTypeParam || DV->getAs<Loc>()); 103018e9aa033ff7363797c62fc3b14669d0558284bAnna Zaks 104018e9aa033ff7363797c62fc3b14669d0558284bAnna Zaks if (haveAttrNonNull && !DV->getAs<Loc>()) { 105bb0ba0bca7896e76f8ce9b709ee881cc505e4d5eTed Kremenek // If the argument is a union type, we want to handle a potential 106fe6a011a113b3ddcb32f42af152d7476054e7f79Jordan Rose // transparent_union GCC extension. 107fe6a011a113b3ddcb32f42af152d7476054e7f79Jordan Rose if (!ArgE) 108fe6a011a113b3ddcb32f42af152d7476054e7f79Jordan Rose continue; 109fe6a011a113b3ddcb32f42af152d7476054e7f79Jordan Rose 110fe6a011a113b3ddcb32f42af152d7476054e7f79Jordan Rose QualType T = ArgE->getType(); 111bb0ba0bca7896e76f8ce9b709ee881cc505e4d5eTed Kremenek const RecordType *UT = T->getAsUnionType(); 112bb0ba0bca7896e76f8ce9b709ee881cc505e4d5eTed Kremenek if (!UT || !UT->getDecl()->hasAttr<TransparentUnionAttr>()) 113bb0ba0bca7896e76f8ce9b709ee881cc505e4d5eTed Kremenek continue; 114fe6a011a113b3ddcb32f42af152d7476054e7f79Jordan Rose 115dc84cd5efdd3430efb22546b4ac656aa0540b210David Blaikie if (Optional<nonloc::CompoundVal> CSV = 1165251abea41b446c26e3239c8dd6c7edea6fc335dDavid Blaikie DV->getAs<nonloc::CompoundVal>()) { 117bb0ba0bca7896e76f8ce9b709ee881cc505e4d5eTed Kremenek nonloc::CompoundVal::iterator CSV_I = CSV->begin(); 118bb0ba0bca7896e76f8ce9b709ee881cc505e4d5eTed Kremenek assert(CSV_I != CSV->end()); 119bb0ba0bca7896e76f8ce9b709ee881cc505e4d5eTed Kremenek V = *CSV_I; 1205251abea41b446c26e3239c8dd6c7edea6fc335dDavid Blaikie DV = V.getAs<DefinedSVal>(); 121bb0ba0bca7896e76f8ce9b709ee881cc505e4d5eTed Kremenek assert(++CSV_I == CSV->end()); 122651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // FIXME: Handle (some_union){ some_other_union_val }, which turns into 123651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // a LazyCompoundVal inside a CompoundVal. 124651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (!V.getAs<Loc>()) 12542773d64f98db0dd5cc80181c3b2d561851668f7Anna Zaks continue; 12642773d64f98db0dd5cc80181c3b2d561851668f7Anna Zaks // Retrieve the corresponding expression. 12742773d64f98db0dd5cc80181c3b2d561851668f7Anna Zaks if (const CompoundLiteralExpr *CE = dyn_cast<CompoundLiteralExpr>(ArgE)) 12842773d64f98db0dd5cc80181c3b2d561851668f7Anna Zaks if (const InitListExpr *IE = 12942773d64f98db0dd5cc80181c3b2d561851668f7Anna Zaks dyn_cast<InitListExpr>(CE->getInitializer())) 13042773d64f98db0dd5cc80181c3b2d561851668f7Anna Zaks ArgE = dyn_cast<Expr>(*(IE->begin())); 13142773d64f98db0dd5cc80181c3b2d561851668f7Anna Zaks 132fe6a011a113b3ddcb32f42af152d7476054e7f79Jordan Rose } else { 133bb0ba0bca7896e76f8ce9b709ee881cc505e4d5eTed Kremenek // FIXME: Handle LazyCompoundVals? 134bb0ba0bca7896e76f8ce9b709ee881cc505e4d5eTed Kremenek continue; 135bb0ba0bca7896e76f8ce9b709ee881cc505e4d5eTed Kremenek } 136bb0ba0bca7896e76f8ce9b709ee881cc505e4d5eTed Kremenek } 137bb0ba0bca7896e76f8ce9b709ee881cc505e4d5eTed Kremenek 13894943b6d913718216a95a91864040ffc11a1d779Zhongxing Xu ConstraintManager &CM = C.getConstraintManager(); 1398bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek ProgramStateRef stateNotNull, stateNull; 140651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines std::tie(stateNotNull, stateNull) = CM.assumeDual(state, *DV); 14194943b6d913718216a95a91864040ffc11a1d779Zhongxing Xu 14287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (stateNull) { 14387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (!stateNotNull) { 14487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // Generate an error node. Check for a null node in case 14587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // we cache out. 14687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (ExplodedNode *errorNode = C.generateErrorNode(stateNull)) { 14794943b6d913718216a95a91864040ffc11a1d779Zhongxing Xu 14887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar std::unique_ptr<BugReport> R; 14987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (haveAttrNonNull) 15087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar R = genReportNullAttrNonNull(errorNode, ArgE); 15187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar else if (haveRefTypeParam) 15287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar R = genReportReferenceToNullPointer(errorNode, ArgE); 15394943b6d913718216a95a91864040ffc11a1d779Zhongxing Xu 15487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // Highlight the range of the argument that was null. 15587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar R->addRange(Call.getArgSourceRange(idx)); 156018e9aa033ff7363797c62fc3b14669d0558284bAnna Zaks 15787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // Emit the bug report. 15887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar C.emitReport(std::move(R)); 15987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } 16094943b6d913718216a95a91864040ffc11a1d779Zhongxing Xu 16187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // Always return. Either we cached out or we just emitted an error. 16287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar return; 16387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } 16487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (ExplodedNode *N = C.generateSink(stateNull, C.getPredecessor())) { 16587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar ImplicitNullDerefEvent event = { 16687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar V, false, N, &C.getBugReporter(), 16787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar /*IsDirectDereference=*/haveRefTypeParam}; 16887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar dispatchEvent(event); 16987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } 17094943b6d913718216a95a91864040ffc11a1d779Zhongxing Xu } 17194943b6d913718216a95a91864040ffc11a1d779Zhongxing Xu 17294943b6d913718216a95a91864040ffc11a1d779Zhongxing Xu // If a pointer value passed the check we should assume that it is 17394943b6d913718216a95a91864040ffc11a1d779Zhongxing Xu // indeed not null from this point forward. 17494943b6d913718216a95a91864040ffc11a1d779Zhongxing Xu assert(stateNotNull); 17594943b6d913718216a95a91864040ffc11a1d779Zhongxing Xu state = stateNotNull; 17694943b6d913718216a95a91864040ffc11a1d779Zhongxing Xu } 17794943b6d913718216a95a91864040ffc11a1d779Zhongxing Xu 17894943b6d913718216a95a91864040ffc11a1d779Zhongxing Xu // If we reach here all of the arguments passed the nonnull check. 17994943b6d913718216a95a91864040ffc11a1d779Zhongxing Xu // If 'state' has been updated generated a new node. 1800bd6b110e908892d4b5c8671a9f435a1d72ad16aAnna Zaks C.addTransition(state); 18194943b6d913718216a95a91864040ffc11a1d779Zhongxing Xu} 182bd90076671c8012244bb7e3fd84b6789e47cb199Argyrios Kyrtzidis 18387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainarstd::unique_ptr<BugReport> 18487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga NainarNonNullParamChecker::genReportNullAttrNonNull(const ExplodedNode *ErrorNode, 18587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar const Expr *ArgE) const { 186018e9aa033ff7363797c62fc3b14669d0558284bAnna Zaks // Lazily allocate the BugType object if it hasn't already been 187018e9aa033ff7363797c62fc3b14669d0558284bAnna Zaks // created. Ownership is transferred to the BugReporter object once 188018e9aa033ff7363797c62fc3b14669d0558284bAnna Zaks // the BugReport is passed to 'EmitWarning'. 189018e9aa033ff7363797c62fc3b14669d0558284bAnna Zaks if (!BTAttrNonNull) 190018e9aa033ff7363797c62fc3b14669d0558284bAnna Zaks BTAttrNonNull.reset(new BugType( 191651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines this, "Argument with 'nonnull' attribute passed null", "API")); 192018e9aa033ff7363797c62fc3b14669d0558284bAnna Zaks 19387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar auto R = llvm::make_unique<BugReport>( 19487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar *BTAttrNonNull, 19587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar "Null pointer passed as an argument to a 'nonnull' parameter", ErrorNode); 196018e9aa033ff7363797c62fc3b14669d0558284bAnna Zaks if (ArgE) 197018e9aa033ff7363797c62fc3b14669d0558284bAnna Zaks bugreporter::trackNullOrUndefValue(ErrorNode, ArgE, *R); 198018e9aa033ff7363797c62fc3b14669d0558284bAnna Zaks 199018e9aa033ff7363797c62fc3b14669d0558284bAnna Zaks return R; 200018e9aa033ff7363797c62fc3b14669d0558284bAnna Zaks} 201018e9aa033ff7363797c62fc3b14669d0558284bAnna Zaks 20287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainarstd::unique_ptr<BugReport> NonNullParamChecker::genReportReferenceToNullPointer( 20387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar const ExplodedNode *ErrorNode, const Expr *ArgE) const { 204018e9aa033ff7363797c62fc3b14669d0558284bAnna Zaks if (!BTNullRefArg) 205651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines BTNullRefArg.reset(new BuiltinBug(this, "Dereference of null pointer")); 206018e9aa033ff7363797c62fc3b14669d0558284bAnna Zaks 20787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar auto R = llvm::make_unique<BugReport>( 20887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar *BTNullRefArg, "Forming reference to null pointer", ErrorNode); 209018e9aa033ff7363797c62fc3b14669d0558284bAnna Zaks if (ArgE) { 210018e9aa033ff7363797c62fc3b14669d0558284bAnna Zaks const Expr *ArgEDeref = bugreporter::getDerefExpr(ArgE); 2116bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (!ArgEDeref) 212018e9aa033ff7363797c62fc3b14669d0558284bAnna Zaks ArgEDeref = ArgE; 213018e9aa033ff7363797c62fc3b14669d0558284bAnna Zaks bugreporter::trackNullOrUndefValue(ErrorNode, 214018e9aa033ff7363797c62fc3b14669d0558284bAnna Zaks ArgEDeref, 215018e9aa033ff7363797c62fc3b14669d0558284bAnna Zaks *R); 216018e9aa033ff7363797c62fc3b14669d0558284bAnna Zaks } 217018e9aa033ff7363797c62fc3b14669d0558284bAnna Zaks return R; 218018e9aa033ff7363797c62fc3b14669d0558284bAnna Zaks 219018e9aa033ff7363797c62fc3b14669d0558284bAnna Zaks} 220018e9aa033ff7363797c62fc3b14669d0558284bAnna Zaks 22180412c4e28c8247ad9c8d30d04c94938f01b21fbAnna Zaksvoid ento::registerNonNullParamChecker(CheckerManager &mgr) { 22280412c4e28c8247ad9c8d30d04c94938f01b21fbAnna Zaks mgr.registerChecker<NonNullParamChecker>(); 223bd90076671c8012244bb7e3fd84b6789e47cb199Argyrios Kyrtzidis} 224