diff --git a/clang/include/clang/Analysis/ProgramPoint.h b/clang/include/clang/Analysis/ProgramPoint.h --- a/clang/include/clang/Analysis/ProgramPoint.h +++ b/clang/include/clang/Analysis/ProgramPoint.h @@ -84,7 +84,8 @@ MinImplicitCallKind = PreImplicitCallKind, MaxImplicitCallKind = PostImplicitCallKind, LoopExitKind, - EpsilonKind}; + EpsilonKind, + DestructorCallKind}; private: const void *Data1; @@ -332,6 +333,12 @@ } }; +class DestructorCallPoint : public ProgramPoint { +public: + explicit DestructorCallPoint(const LocationContext *L, const ProgramPointTag *tag = nullptr) + : ProgramPoint(nullptr, DestructorCallKind, L, tag) {} +}; + class FunctionExitPoint : public ProgramPoint { public: explicit FunctionExitPoint(const ReturnStmt *S, diff --git a/clang/lib/StaticAnalyzer/Checkers/SmartPtrModeling.cpp b/clang/lib/StaticAnalyzer/Checkers/SmartPtrModeling.cpp --- a/clang/lib/StaticAnalyzer/Checkers/SmartPtrModeling.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/SmartPtrModeling.cpp @@ -29,6 +29,7 @@ #include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h" #include "clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h" #include "clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h" +#include "llvm/Support/raw_ostream.h" #include using namespace clang; @@ -177,7 +178,9 @@ bool SmartPtrModeling::evalCall(const CallEvent &Call, CheckerContext &C) const { + ProgramStateRef State = C.getState(); + Call.dump(); if (!smartptr::isStdSmartPtrCall(Call)) return false; @@ -261,6 +264,11 @@ return true; } + if (const auto *DC = dyn_cast(&Call)) { + llvm::errs() << "Wohoo\n"; + return true; + } + if (handleAssignOp(Call, C)) return true; diff --git a/clang/lib/StaticAnalyzer/Core/CheckerManager.cpp b/clang/lib/StaticAnalyzer/Core/CheckerManager.cpp --- a/clang/lib/StaticAnalyzer/Core/CheckerManager.cpp +++ b/clang/lib/StaticAnalyzer/Core/CheckerManager.cpp @@ -664,14 +664,20 @@ for (const auto &EvalCallChecker : EvalCallCheckers) { // TODO: Support the situation when the call doesn't correspond // to any Expr. - ProgramPoint L = ProgramPoint::getProgramPoint( - Call.getOriginExpr(), ProgramPoint::PostStmtKind, + llvm::Optional LOpt; + const Expr *OriginExpr = Call.getOriginExpr(); + if (OriginExpr) { + LOpt = ProgramPoint::getProgramPoint( + OriginExpr, ProgramPoint::PostStmtKind, Pred->getLocationContext(), EvalCallChecker.Checker); + } else { + LOpt = DestructorCallPoint(Pred->getLocationContext(), EvalCallChecker.Checker); + } bool evaluated = false; { // CheckerContext generates transitions(populates checkDest) on // destruction, so introduce the scope to make sure it gets properly // populated. - CheckerContext C(B, Eng, Pred, L); + CheckerContext C(B, Eng, Pred, *LOpt); evaluated = EvalCallChecker(Call, C); } assert(!(evaluated && anyEvaluated) diff --git a/clang/lib/StaticAnalyzer/Core/CoreEngine.cpp b/clang/lib/StaticAnalyzer/Core/CoreEngine.cpp --- a/clang/lib/StaticAnalyzer/Core/CoreEngine.cpp +++ b/clang/lib/StaticAnalyzer/Core/CoreEngine.cpp @@ -181,6 +181,10 @@ dispatchWorkItem(Pred, PNode->getLocation(), WU); break; } + case ProgramPoint::DestructorCallKind: + // Literally do nothing, since there is no real statement + // So there is nothing to be done. + break; default: assert(Loc.getAs() || Loc.getAs() || diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp --- a/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp +++ b/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp @@ -19,6 +19,7 @@ #include "clang/StaticAnalyzer/Core/CheckerManager.h" #include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h" #include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h" +#include "llvm/Support/raw_ostream.h" using namespace clang; using namespace ento; @@ -757,6 +758,7 @@ for (ExplodedNodeSet::iterator I = DstPreCall.begin(), E = DstPreCall.end(); I != E; ++I) defaultEvalCall(Bldr, *I, *Call, CallOpts); + // getCheckerManager().runCheckersForEvalCall(DstInvalidated, DstPreCall, *Call, *this, CallOpts); getCheckerManager().runCheckersForPostCall(Dst, DstInvalidated, *Call, *this);