summaryrefslogtreecommitdiffstats
path: root/clang/lib/StaticAnalyzer/Core
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/StaticAnalyzer/Core')
-rw-r--r--clang/lib/StaticAnalyzer/Core/BugReporter.cpp1
-rw-r--r--clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp53
2 files changed, 54 insertions, 0 deletions
diff --git a/clang/lib/StaticAnalyzer/Core/BugReporter.cpp b/clang/lib/StaticAnalyzer/Core/BugReporter.cpp
index 488126b0088..e04aa395d49 100644
--- a/clang/lib/StaticAnalyzer/Core/BugReporter.cpp
+++ b/clang/lib/StaticAnalyzer/Core/BugReporter.cpp
@@ -3104,6 +3104,7 @@ bool GRBugReporter::generatePathDiagnostic(PathDiagnostic& PD,
R->addVisitor(llvm::make_unique<NilReceiverBRVisitor>());
R->addVisitor(llvm::make_unique<ConditionBRVisitor>());
R->addVisitor(llvm::make_unique<LikelyFalsePositiveSuppressionBRVisitor>());
+ R->addVisitor(llvm::make_unique<CXXSelfAssignmentBRVisitor>());
BugReport::VisitorList visitors;
unsigned origReportConfigToken, finalReportConfigToken;
diff --git a/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp b/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
index 0e505463bb5..3b72244a52c 100644
--- a/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
+++ b/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
@@ -1693,3 +1693,56 @@ UndefOrNullArgVisitor::VisitNode(const ExplodedNode *N,
}
return nullptr;
}
+
+PathDiagnosticPiece *
+CXXSelfAssignmentBRVisitor::VisitNode(const ExplodedNode *Succ,
+ const ExplodedNode *Pred,
+ BugReporterContext &BRC, BugReport &BR) {
+ if (Satisfied)
+ return nullptr;
+
+ 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->getCurrentStackFrame()));
+
+ 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 = new PathDiagnosticEventPiece(L, Out.str());
+ Piece->addRange(Met->getSourceRange());
+
+ return Piece;
+}
OpenPOWER on IntegriCloud