summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h14
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/CXXSelfAssignmentChecker.cpp20
-rw-r--r--clang/lib/StaticAnalyzer/Core/BugReporter.cpp1
-rw-r--r--clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp53
-rw-r--r--clang/lib/StaticAnalyzer/Core/PathDiagnostic.cpp9
5 files changed, 27 insertions, 70 deletions
diff --git a/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h b/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h
index e624d0fc026..1a09714a65b 100644
--- a/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h
+++ b/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h
@@ -294,20 +294,6 @@ public:
BugReport &BR) override;
};
-class CXXSelfAssignmentBRVisitor final : public BugReporterVisitor {
- bool Satisfied = false;
-
-public:
- CXXSelfAssignmentBRVisitor() = default;
-
- void Profile(llvm::FoldingSetNodeID &ID) const override {}
-
- std::shared_ptr<PathDiagnosticPiece> VisitNode(const ExplodedNode *Succ,
- BugReporterContext &BRC,
- BugReport &BR) override;
-};
-
-
/// The bug visitor will walk all the nodes in a path and collect all the
/// constraints. When it reaches the root node, will create a refutation
/// manager and check if the constraints are satisfiable
diff --git a/clang/lib/StaticAnalyzer/Checkers/CXXSelfAssignmentChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/CXXSelfAssignmentChecker.cpp
index 1233849b173..01f5b9c889e 100644
--- a/clang/lib/StaticAnalyzer/Checkers/CXXSelfAssignmentChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/CXXSelfAssignmentChecker.cpp
@@ -50,10 +50,26 @@ void CXXSelfAssignmentChecker::checkBeginFunction(CheckerContext &C) const {
State->getSVal(SVB.getCXXThis(MD, LCtx->getStackFrame()));
auto Param = SVB.makeLoc(State->getRegion(MD->getParamDecl(0), LCtx));
auto ParamVal = State->getSVal(Param);
+
ProgramStateRef SelfAssignState = State->bindLoc(Param, ThisVal, LCtx);
- C.addTransition(SelfAssignState);
+ const NoteTag *SelfAssignTag =
+ C.getNoteTag([MD](BugReport &BR) -> std::string {
+ SmallString<256> Msg;
+ llvm::raw_svector_ostream Out(Msg);
+ Out << "Assuming " << MD->getParamDecl(0)->getName() << " == *this";
+ return Out.str();
+ });
+ C.addTransition(SelfAssignState, SelfAssignTag);
+
ProgramStateRef NonSelfAssignState = State->bindLoc(Param, ParamVal, LCtx);
- C.addTransition(NonSelfAssignState);
+ const NoteTag *NonSelfAssignTag =
+ C.getNoteTag([MD](BugReport &BR) -> std::string {
+ SmallString<256> Msg;
+ llvm::raw_svector_ostream Out(Msg);
+ Out << "Assuming " << MD->getParamDecl(0)->getName() << " != *this";
+ return Out.str();
+ });
+ C.addTransition(NonSelfAssignState, NonSelfAssignTag);
}
void ento::registerCXXSelfAssignmentChecker(CheckerManager &Mgr) {
diff --git a/clang/lib/StaticAnalyzer/Core/BugReporter.cpp b/clang/lib/StaticAnalyzer/Core/BugReporter.cpp
index cc93675344e..738ad9a062f 100644
--- a/clang/lib/StaticAnalyzer/Core/BugReporter.cpp
+++ b/clang/lib/StaticAnalyzer/Core/BugReporter.cpp
@@ -2610,7 +2610,6 @@ std::pair<BugReport*, std::unique_ptr<VisitorsDiagnosticsTy>> findValidReport(
// Register additional node visitors.
R->addVisitor(llvm::make_unique<NilReceiverBRVisitor>());
R->addVisitor(llvm::make_unique<ConditionBRVisitor>());
- R->addVisitor(llvm::make_unique<CXXSelfAssignmentBRVisitor>());
R->addVisitor(llvm::make_unique<TagVisitor>());
BugReporterContext BRC(Reporter, ErrorGraph.BackMap);
diff --git a/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp b/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
index 21320b1cdd8..d11ecd95802 100644
--- a/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
+++ b/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
@@ -2371,59 +2371,6 @@ UndefOrNullArgVisitor::VisitNode(const ExplodedNode *N,
return nullptr;
}
-std::shared_ptr<PathDiagnosticPiece>
-CXXSelfAssignmentBRVisitor::VisitNode(const ExplodedNode *Succ,
- BugReporterContext &BRC, BugReport &) {
- if (Satisfied)
- return nullptr;
-
- const auto Edge = Succ->getLocation().getAs<BlockEdge>();
- if (!Edge.hasValue())
- return nullptr;
-
- auto Tag = Edge->getTag();
- if (!Tag)
- return nullptr;
-
- if (Tag->getTagDescription() != "cplusplus.SelfAssignment")
- return nullptr;
-
- Satisfied = true;
-
- const auto *Met =
- dyn_cast<CXXMethodDecl>(Succ->getCodeDecl().getAsFunction());
- assert(Met && "Not a C++ method.");
- assert((Met->isCopyAssignmentOperator() || Met->isMoveAssignmentOperator()) &&
- "Not a copy/move assignment operator.");
-
- const auto *LCtx = Edge->getLocationContext();
-
- const auto &State = Succ->getState();
- auto &SVB = State->getStateManager().getSValBuilder();
-
- const auto Param =
- State->getSVal(State->getRegion(Met->getParamDecl(0), LCtx));
- const auto This =
- State->getSVal(SVB.getCXXThis(Met, LCtx->getStackFrame()));
-
- auto L = PathDiagnosticLocation::create(Met, BRC.getSourceManager());
-
- if (!L.isValid() || !L.asLocation().isValid())
- return nullptr;
-
- SmallString<256> Buf;
- llvm::raw_svector_ostream Out(Buf);
-
- Out << "Assuming " << Met->getParamDecl(0)->getName() <<
- ((Param == This) ? " == " : " != ") << "*this";
-
- auto Piece = std::make_shared<PathDiagnosticEventPiece>(L, Out.str());
- Piece->addRange(Met->getSourceRange());
-
- return std::move(Piece);
-}
-
-
FalsePositiveRefutationBRVisitor::FalsePositiveRefutationBRVisitor()
: Constraints(ConstraintRangeTy::Factory().getEmptyMap()) {}
diff --git a/clang/lib/StaticAnalyzer/Core/PathDiagnostic.cpp b/clang/lib/StaticAnalyzer/Core/PathDiagnostic.cpp
index b3008479fe3..5889a979661 100644
--- a/clang/lib/StaticAnalyzer/Core/PathDiagnostic.cpp
+++ b/clang/lib/StaticAnalyzer/Core/PathDiagnostic.cpp
@@ -732,6 +732,15 @@ PathDiagnosticLocation::create(const ProgramPoint& P,
} else {
S = BSrc->getTerminatorCondition();
+ if (!S) {
+ // If the BlockEdge has no terminator condition statement but its
+ // source is the entry of the CFG (e.g. a checker crated the branch at
+ // the beginning of a function), use the function's declaration instead.
+ assert(BSrc == &BSrc->getParent()->getEntry() && "CFGBlock has no "
+ "TerminatorCondition and is not the enrty block of the CFG");
+ return PathDiagnosticLocation::createBegin(
+ P.getLocationContext()->getDecl(), SMng);
+ }
}
} else if (Optional<StmtPoint> SP = P.getAs<StmtPoint>()) {
S = SP->getStmt();
OpenPOWER on IntegriCloud