diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2019-01-19 10:04:05 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2019-01-19 10:04:05 +0000 |
commit | 676fbe8105eeb6ff4bb2ed261cb212fcfdbe7b63 (patch) | |
tree | 02a1ac369cb734d0abfa5000dd86e5b7797e6a74 /lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp | |
parent | c7e70c433efc6953dc3888b9fbf9f3512d7da2b0 (diff) |
Notes
Diffstat (limited to 'lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp')
-rw-r--r-- | lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp | 103 |
1 files changed, 53 insertions, 50 deletions
diff --git a/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp b/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp index 20a46843e23e..ef30dc74c39d 100644 --- a/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp @@ -12,7 +12,7 @@ // //===----------------------------------------------------------------------===// -#include "ClangSACheckers.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/AST/ParentMap.h" #include "clang/Basic/TargetInfo.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" @@ -108,7 +108,7 @@ void CallAndMessageChecker::emitBadCall(BugType *BT, CheckerContext &C, R->addRange(BadE->getSourceRange()); if (BadE->isGLValue()) BadE = bugreporter::getDerefExpr(BadE); - bugreporter::trackNullOrUndefValue(N, BadE, *R); + bugreporter::trackExpressionValue(N, BadE, *R); } C.emitReport(std::move(R)); } @@ -185,9 +185,9 @@ bool CallAndMessageChecker::uninitRefOrPointer( LazyInit_BT(BD, BT); auto R = llvm::make_unique<BugReport>(*BT, Os.str(), N); R->addRange(ArgRange); - if (ArgEx) { - bugreporter::trackNullOrUndefValue(N, ArgEx, *R); - } + if (ArgEx) + bugreporter::trackExpressionValue(N, ArgEx, *R); + C.emitReport(std::move(R)); } return true; @@ -196,6 +196,47 @@ bool CallAndMessageChecker::uninitRefOrPointer( return false; } +namespace { +class FindUninitializedField { +public: + SmallVector<const FieldDecl *, 10> FieldChain; + +private: + StoreManager &StoreMgr; + MemRegionManager &MrMgr; + Store store; + +public: + FindUninitializedField(StoreManager &storeMgr, MemRegionManager &mrMgr, + Store s) + : StoreMgr(storeMgr), MrMgr(mrMgr), store(s) {} + + bool Find(const TypedValueRegion *R) { + QualType T = R->getValueType(); + if (const RecordType *RT = T->getAsStructureType()) { + const RecordDecl *RD = RT->getDecl()->getDefinition(); + assert(RD && "Referred record has no definition"); + for (const auto *I : RD->fields()) { + const FieldRegion *FR = MrMgr.getFieldRegion(I, R); + FieldChain.push_back(I); + T = I->getType(); + if (T->getAsStructureType()) { + if (Find(FR)) + return true; + } else { + const SVal &V = StoreMgr.getBinding(store, loc::MemRegionVal(FR)); + if (V.isUndef()) + return true; + } + FieldChain.pop_back(); + } + } + + return false; + } +}; +} // namespace + bool CallAndMessageChecker::PreVisitProcessArg(CheckerContext &C, SVal V, SourceRange ArgRange, @@ -223,7 +264,7 @@ bool CallAndMessageChecker::PreVisitProcessArg(CheckerContext &C, R->addRange(ArgRange); if (ArgEx) - bugreporter::trackNullOrUndefValue(N, ArgEx, *R); + bugreporter::trackExpressionValue(N, ArgEx, *R); C.emitReport(std::move(R)); } return true; @@ -232,47 +273,7 @@ bool CallAndMessageChecker::PreVisitProcessArg(CheckerContext &C, if (!CheckUninitFields) return false; - if (Optional<nonloc::LazyCompoundVal> LV = - V.getAs<nonloc::LazyCompoundVal>()) { - - class FindUninitializedField { - public: - SmallVector<const FieldDecl *, 10> FieldChain; - private: - StoreManager &StoreMgr; - MemRegionManager &MrMgr; - Store store; - public: - FindUninitializedField(StoreManager &storeMgr, - MemRegionManager &mrMgr, Store s) - : StoreMgr(storeMgr), MrMgr(mrMgr), store(s) {} - - bool Find(const TypedValueRegion *R) { - QualType T = R->getValueType(); - if (const RecordType *RT = T->getAsStructureType()) { - const RecordDecl *RD = RT->getDecl()->getDefinition(); - assert(RD && "Referred record has no definition"); - for (const auto *I : RD->fields()) { - const FieldRegion *FR = MrMgr.getFieldRegion(I, R); - FieldChain.push_back(I); - T = I->getType(); - if (T->getAsStructureType()) { - if (Find(FR)) - return true; - } - else { - const SVal &V = StoreMgr.getBinding(store, loc::MemRegionVal(FR)); - if (V.isUndef()) - return true; - } - FieldChain.pop_back(); - } - } - - return false; - } - }; - + if (auto LV = V.getAs<nonloc::LazyCompoundVal>()) { const LazyCompoundValData *D = LV->getCVData(); FindUninitializedField F(C.getState()->getStateManager().getStoreManager(), C.getSValBuilder().getRegionManager(), @@ -305,6 +306,8 @@ bool CallAndMessageChecker::PreVisitProcessArg(CheckerContext &C, auto R = llvm::make_unique<BugReport>(*BT, os.str(), N); R->addRange(ArgRange); + if (ArgEx) + bugreporter::trackExpressionValue(N, ArgEx, *R); // FIXME: enhance track back for uninitialized value for arbitrary // memregions C.emitReport(std::move(R)); @@ -364,7 +367,7 @@ void CallAndMessageChecker::checkPreStmt(const CXXDeleteExpr *DE, Desc = "Argument to 'delete' is uninitialized"; BugType *BT = BT_cxx_delete_undef.get(); auto R = llvm::make_unique<BugReport>(*BT, Desc, N); - bugreporter::trackNullOrUndefValue(N, DE, *R); + bugreporter::trackExpressionValue(N, DE, *R); C.emitReport(std::move(R)); return; } @@ -493,7 +496,7 @@ void CallAndMessageChecker::checkPreObjCMessage(const ObjCMethodCall &msg, // FIXME: getTrackNullOrUndefValueVisitor can't handle "super" yet. if (const Expr *ReceiverE = ME->getInstanceReceiver()) - bugreporter::trackNullOrUndefValue(N, ReceiverE, *R); + bugreporter::trackExpressionValue(N, ReceiverE, *R); C.emitReport(std::move(R)); } return; @@ -534,7 +537,7 @@ void CallAndMessageChecker::emitNilReceiverBug(CheckerContext &C, report->addRange(ME->getReceiverRange()); // FIXME: This won't track "self" in messages to super. if (const Expr *receiver = ME->getInstanceReceiver()) { - bugreporter::trackNullOrUndefValue(N, receiver, *report); + bugreporter::trackExpressionValue(N, receiver, *report); } C.emitReport(std::move(report)); } |