Index: clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h =================================================================== --- clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h +++ clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h @@ -36,6 +36,7 @@ namespace ento { +class AnalysisManager; class CallEvent; class CallEventManager; @@ -111,6 +112,8 @@ return *stateMgr; } + AnalysisManager &getAnalysisManager() const; + /// Return the ConstraintManager. ConstraintManager &getConstraintManager() const; Index: clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp =================================================================== --- clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp +++ clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp @@ -269,6 +269,8 @@ /// pointer dereference outside. class NoStoreFuncVisitor final : public BugReporterVisitor { const SubRegion *RegionOfInterest; + const SourceManager &SM; + const PrintingPolicy &PP; static constexpr const char *DiagnosticsMsg = "Returning without writing to '"; @@ -284,7 +286,9 @@ llvm::SmallPtrSet FramesModifyingCalculated; public: - NoStoreFuncVisitor(const SubRegion *R) : RegionOfInterest(R) {} + NoStoreFuncVisitor(const SubRegion *R, const ASTContext &Ctx, + SourceManager &SM) + : RegionOfInterest(R), SM(SM), PP(Ctx.getPrintingPolicy()) {} void Profile(llvm::FoldingSetNodeID &ID) const override { static int Tag = 0; @@ -307,8 +311,6 @@ CallEventRef<> Call = BRC.getStateManager().getCallEventManager().getCaller(SCtx, State); - const PrintingPolicy &PP = BRC.getASTContext().getPrintingPolicy(); - const SourceManager &SM = BRC.getSourceManager(); // Region of interest corresponds to an IVar, exiting a method // which could have written into that IVar, but did not. @@ -318,16 +320,14 @@ IvarR->getDecl()) && !isRegionOfInterestModifiedInFrame(N)) return notModifiedMemberDiagnostics( - Ctx, SM, PP, *CallExitLoc, Call, - MC->getReceiverSVal().getAsRegion()); + Ctx, *CallExitLoc, Call, MC->getReceiverSVal().getAsRegion()); if (const auto *CCall = dyn_cast(Call)) { - const MemRegion *ThisRegion = CCall->getCXXThisVal().getAsRegion(); - if (RegionOfInterest->isSubRegionOf(ThisRegion) + const MemRegion *ThisR = CCall->getCXXThisVal().getAsRegion(); + if (RegionOfInterest->isSubRegionOf(ThisR) && !CCall->getDecl()->isImplicit() && !isRegionOfInterestModifiedInFrame(N)) - return notModifiedMemberDiagnostics(Ctx, SM, PP, *CallExitLoc, - CCall, ThisRegion); + return notModifiedMemberDiagnostics(Ctx, *CallExitLoc, Call, ThisR); } ArrayRef parameters = getCallParameters(Call); @@ -344,7 +344,7 @@ return nullptr; return notModifiedParameterDiagnostics( - Ctx, SM, PP, *CallExitLoc, Call, PVD, R, IndirectionLevel); + Ctx, *CallExitLoc, Call, PVD, R, IndirectionLevel); } QualType PT = T->getPointeeType(); if (PT.isNull() || PT->isVoidType()) break; @@ -446,8 +446,6 @@ /// in a given function. std::shared_ptr notModifiedMemberDiagnostics( const LocationContext *Ctx, - const SourceManager &SM, - const PrintingPolicy &PP, CallExitBegin &CallExitLoc, CallEventRef<> Call, const MemRegion *ArgRegion) { @@ -474,8 +472,6 @@ /// before we get to the super region of \c RegionOfInterest std::shared_ptr notModifiedParameterDiagnostics(const LocationContext *Ctx, - const SourceManager &SM, - const PrintingPolicy &PP, CallExitBegin &CallExitLoc, CallEventRef<> Call, const ParmVarDecl *PVD, @@ -612,8 +608,7 @@ const ExplodedNode *N, const MemRegion *R, bool EnableNullFPSuppression, BugReport &BR, const SVal V) { - AnalyzerOptions &Options = N->getState()->getStateManager() - .getOwningEngine()->getAnalysisManager().options; + AnalyzerOptions &Options = N->getState()->getAnalysisManager().options; if (EnableNullFPSuppression && Options.shouldSuppressNullReturnPaths() && V.getAs()) BR.addVisitor(llvm::make_unique( @@ -740,9 +735,7 @@ RetVal = State->getSVal(*LValue); // See if the return value is NULL. If so, suppress the report. - SubEngine *Eng = State->getStateManager().getOwningEngine(); - assert(Eng && "Cannot file a bug report without an owning engine"); - AnalyzerOptions &Options = Eng->getAnalysisManager().options; + AnalyzerOptions &Options = State->getAnalysisManager().options; bool EnableNullFPSuppression = false; if (InEnableNullFPSuppression && Options.shouldSuppressNullReturnPaths()) @@ -1321,9 +1314,7 @@ SuppressInlineDefensiveChecksVisitor(DefinedSVal Value, const ExplodedNode *N) : V(Value) { // Check if the visitor is disabled. - SubEngine *Eng = N->getState()->getStateManager().getOwningEngine(); - assert(Eng && "Cannot file a bug report without an owning engine"); - AnalyzerOptions &Options = Eng->getAnalysisManager().options; + AnalyzerOptions &Options = N->getState()->getAnalysisManager().options; if (!Options.shouldSuppressInlinedDefensiveChecks()) IsSatisfied = true; @@ -1603,10 +1594,14 @@ LVNode->getSVal(Inner).getAsRegion(); if (R) { + // Mark both the variable region and its contents as interesting. SVal V = LVState->getRawSVal(loc::MemRegionVal(R)); report.addVisitor( - llvm::make_unique(cast(R))); + llvm::make_unique( + cast(R), + N->getState()->getStateManager().getContext(), + N->getState()->getAnalysisManager().getSourceManager())); MacroNullReturnSuppressionVisitor::addMacroVisitorIfNecessary( N, R, EnableNullFPSuppression, report, V); Index: clang/lib/StaticAnalyzer/Core/ProgramState.cpp =================================================================== --- clang/lib/StaticAnalyzer/Core/ProgramState.cpp +++ clang/lib/StaticAnalyzer/Core/ProgramState.cpp @@ -11,6 +11,7 @@ // //===----------------------------------------------------------------------===// +#include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h" #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h" #include "clang/Analysis/CFG.h" #include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h" @@ -494,6 +495,11 @@ printTaint(llvm::errs()); } +AnalysisManager& ProgramState::getAnalysisManager() const { + return stateMgr->getOwningEngine()->getAnalysisManager(); + +} + //===----------------------------------------------------------------------===// // Generic Data Map. //===----------------------------------------------------------------------===//