diff options
Diffstat (limited to 'clang/lib/StaticAnalyzer/Core')
-rw-r--r-- | clang/lib/StaticAnalyzer/Core/BugReporter.cpp | 1 | ||||
-rw-r--r-- | clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp | 53 |
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; +} |