From 647804a84a58b0b1742cab3cc6179ccdfc1dedcf Mon Sep 17 00:00:00 2001 From: Artem Dergachev Date: Tue, 28 Mar 2017 15:43:26 +0000 Subject: [analyzer] When creating a temporary object, properly copy the value into it. Adjustments should be considered properly; we should copy the unadjusted object over the whole temporary base region. If the unadjusted object is no longer available in the Environment, invalidate the temporary base region, and then copy the adjusted object into the adjusted sub-region of the temporary region. This fixes a regression introduced by r288263, that caused various false positives, due to copying only adjusted object into the adjusted region; the rest of the base region therefore remained undefined. Before r288263, the adjusted value was copied over the unadjusted region, which is incorrect, but accidentally worked better due to how region store disregards compound value bindings to non-base regions. An additional test machinery is introduced to make sure that despite making two binds, we only notify checkers once for both of them, without exposing the partially copied objects. This fix is a hack over a hack. The proper fix would be to model C++ temporaries in the CFG, and after that dealing with adjustments would no longer be necessary, and the values we need would no longer disappear from the Environment. rdar://problem/30658168 Differential Revision: https://reviews.llvm.org/D30534 llvm-svn: 298924 --- .../Checkers/AnalysisOrderChecker.cpp | 49 ++++++++++++++++++---- 1 file changed, 40 insertions(+), 9 deletions(-) (limited to 'clang/lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp') diff --git a/clang/lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp index e6592a285e4..90d5c0e36a4 100644 --- a/clang/lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp @@ -24,16 +24,29 @@ using namespace ento; namespace { -class AnalysisOrderChecker : public Checker< check::PreStmt, - check::PostStmt, - check::PreStmt, - check::PostStmt> { - bool isCallbackEnabled(CheckerContext &C, StringRef CallbackName) const { - AnalyzerOptions &Opts = C.getAnalysisManager().getAnalyzerOptions(); +class AnalysisOrderChecker + : public Checker, + check::PostStmt, + check::PreStmt, + check::PostStmt, + check::Bind, + check::RegionChanges> { + bool isCallbackEnabled(AnalyzerOptions &Opts, StringRef CallbackName) const { return Opts.getBooleanOption("*", false, this) || Opts.getBooleanOption(CallbackName, false, this); } + bool isCallbackEnabled(CheckerContext &C, StringRef CallbackName) const { + AnalyzerOptions &Opts = C.getAnalysisManager().getAnalyzerOptions(); + return isCallbackEnabled(Opts, CallbackName); + } + + bool isCallbackEnabled(ProgramStateRef State, StringRef CallbackName) const { + AnalyzerOptions &Opts = State->getStateManager().getOwningEngine() + ->getAnalysisManager().getAnalyzerOptions(); + return isCallbackEnabled(Opts, CallbackName); + } + public: void checkPreStmt(const CastExpr *CE, CheckerContext &C) const { if (isCallbackEnabled(C, "PreStmtCastExpr")) @@ -47,17 +60,35 @@ public: << ")\n"; } - void checkPreStmt(const ArraySubscriptExpr *SubExpr, CheckerContext &C) const { + void checkPreStmt(const ArraySubscriptExpr *SubExpr, + CheckerContext &C) const { if (isCallbackEnabled(C, "PreStmtArraySubscriptExpr")) llvm::errs() << "PreStmt\n"; } - void checkPostStmt(const ArraySubscriptExpr *SubExpr, CheckerContext &C) const { + void checkPostStmt(const ArraySubscriptExpr *SubExpr, + CheckerContext &C) const { if (isCallbackEnabled(C, "PostStmtArraySubscriptExpr")) llvm::errs() << "PostStmt\n"; } + + void checkBind(SVal Loc, SVal Val, const Stmt *S, CheckerContext &C) const { + if (isCallbackEnabled(C, "Bind")) + llvm::errs() << "Bind\n"; + } + + ProgramStateRef + checkRegionChanges(ProgramStateRef State, + const InvalidatedSymbols *Invalidated, + ArrayRef ExplicitRegions, + ArrayRef Regions, + const LocationContext *LCtx, const CallEvent *Call) const { + if (isCallbackEnabled(State, "RegionChanges")) + llvm::errs() << "RegionChanges\n"; + return State; + } }; -} +} // end anonymous namespace //===----------------------------------------------------------------------===// // Registration. -- cgit v1.2.3