diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp | 3 | ||||
-rw-r--r-- | clang/lib/StaticAnalyzer/Core/CallEvent.cpp | 2 | ||||
-rw-r--r-- | clang/lib/StaticAnalyzer/Core/ExprEngine.cpp | 25 | ||||
-rw-r--r-- | clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp | 4 |
4 files changed, 31 insertions, 3 deletions
diff --git a/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp index 1fa15d09cbc..c7aa0fb150c 100644 --- a/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp @@ -1803,7 +1803,8 @@ bool MallocChecker::isReleased(SymbolRef Sym, CheckerContext &C) const { bool MallocChecker::checkUseAfterFree(SymbolRef Sym, CheckerContext &C, const Stmt *S) const { - if (isReleased(Sym, C)) { + // FIXME: Handle destructor called from delete more precisely. + if (isReleased(Sym, C) && S) { ReportUseAfterFree(C, S->getSourceRange(), Sym); return true; } diff --git a/clang/lib/StaticAnalyzer/Core/CallEvent.cpp b/clang/lib/StaticAnalyzer/Core/CallEvent.cpp index 556f93b7cfb..ce66363413f 100644 --- a/clang/lib/StaticAnalyzer/Core/CallEvent.cpp +++ b/clang/lib/StaticAnalyzer/Core/CallEvent.cpp @@ -964,6 +964,8 @@ CallEventManager::getCaller(const StackFrameContext *CalleeCtx, const Stmt *Trigger; if (Optional<CFGAutomaticObjDtor> AutoDtor = E.getAs<CFGAutomaticObjDtor>()) Trigger = AutoDtor->getTriggerStmt(); + else if (Optional<CFGDeleteDtor> DeleteDtor = E.getAs<CFGDeleteDtor>()) + Trigger = cast<Stmt>(DeleteDtor->getDeleteExpr()); else Trigger = Dtor->getBody(); diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp index 91acd55bc7f..411e2f6aea3 100644 --- a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp +++ b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp @@ -569,7 +569,30 @@ void ExprEngine::ProcessAutomaticObjDtor(const CFGAutomaticObjDtor Dtor, void ExprEngine::ProcessDeleteDtor(const CFGDeleteDtor Dtor, ExplodedNode *Pred, ExplodedNodeSet &Dst) { - //TODO: Handle DeleteDtor + ProgramStateRef State = Pred->getState(); + const LocationContext *LCtx = Pred->getLocationContext(); + const CXXDeleteExpr *DE = Dtor.getDeleteExpr(); + const Stmt *Arg = DE->getArgument(); + SVal ArgVal = State->getSVal(Arg, LCtx); + + // If the argument to delete is known to be a null value, + // don't run destructor. + if (State->isNull(ArgVal).isConstrainedTrue()) { + QualType DTy = DE->getDestroyedType(); + QualType BTy = getContext().getBaseElementType(DTy); + const CXXRecordDecl *RD = BTy->getAsCXXRecordDecl(); + const CXXDestructorDecl *Dtor = RD->getDestructor(); + + PostImplicitCall PP(Dtor, DE->getLocStart(), LCtx); + NodeBuilder Bldr(Pred, Dst, *currBldrCtx); + Bldr.generateNode(PP, Pred->getState(), Pred); + return; + } + + VisitCXXDestructor(DE->getDestroyedType(), + ArgVal.getAsRegion(), + DE, /*IsBase=*/ false, + Pred, Dst); } void ExprEngine::ProcessBaseDtor(const CFGBaseDtor D, diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp index b128bee1429..eba4f94d80e 100644 --- a/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp +++ b/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp @@ -296,7 +296,9 @@ void ExprEngine::VisitCXXDestructor(QualType ObjectType, // FIXME: We need to run the same destructor on every element of the array. // This workaround will just run the first destructor (which will still // invalidate the entire array). - SVal DestVal = loc::MemRegionVal(Dest); + SVal DestVal = UnknownVal(); + if (Dest) + DestVal = loc::MemRegionVal(Dest); DestVal = makeZeroElementRegion(State, DestVal, ObjectType); Dest = DestVal.getAsRegion(); |