diff --git a/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h b/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h --- a/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h +++ b/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h @@ -392,19 +392,19 @@ } // namespace bugreporter class TrackConstraintBRVisitor final : public BugReporterVisitor { - DefinedSVal Constraint; - bool Assumption; + const SmallString<64> Message; + const DefinedSVal Constraint; + const bool Assumption; bool IsSatisfied = false; - bool IsZeroCheck; /// We should start tracking from the last node along the path in which the /// value is constrained. bool IsTrackingTurnedOn = false; public: - TrackConstraintBRVisitor(DefinedSVal constraint, bool assumption) - : Constraint(constraint), Assumption(assumption), - IsZeroCheck(!Assumption && isa(Constraint)) {} + TrackConstraintBRVisitor(DefinedSVal constraint, bool assumption, + StringRef Message) + : Message(Message), Constraint(constraint), Assumption(assumption) {} void Profile(llvm::FoldingSetNodeID &ID) const override; @@ -417,6 +417,9 @@ PathSensitiveBugReport &BR) override; private: + /// Checks if the constraint refers to a null-location. + bool isZeroCheck() const; + /// Checks if the constraint is valid in the current state. bool isUnderconstrained(const ExplodedNode *N) const; }; diff --git a/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp b/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp --- a/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp +++ b/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp @@ -1786,6 +1786,7 @@ void TrackConstraintBRVisitor::Profile(llvm::FoldingSetNodeID &ID) const { static int tag = 0; ID.AddPointer(&tag); + ID.AddString(Message); ID.AddBoolean(Assumption); ID.Add(Constraint); } @@ -1796,8 +1797,12 @@ return "TrackConstraintBRVisitor"; } +bool TrackConstraintBRVisitor::isZeroCheck() const { + return !Assumption && Constraint.getAs(); +} + bool TrackConstraintBRVisitor::isUnderconstrained(const ExplodedNode *N) const { - if (IsZeroCheck) + if (isZeroCheck()) return N->getState()->isNull(Constraint).isUnderconstrained(); return (bool)N->getState()->assume(Constraint, !Assumption); } @@ -1827,19 +1832,6 @@ // the transition point. assert(!isUnderconstrained(N)); - // We found the transition point for the constraint. We now need to - // pretty-print the constraint. (work-in-progress) - SmallString<64> sbuf; - llvm::raw_svector_ostream os(sbuf); - - if (isa(Constraint)) { - os << "Assuming pointer value is "; - os << (Assumption ? "non-null" : "null"); - } - - if (os.str().empty()) - return nullptr; - // Construct a new PathDiagnosticPiece. ProgramPoint P = N->getLocation(); @@ -1854,7 +1846,7 @@ if (!L.isValid()) return nullptr; - auto X = std::make_shared(L, os.str()); + auto X = std::make_shared(L, Message); X->setTag(getTag()); return std::move(X); } @@ -2366,8 +2358,9 @@ // null. if (V.getAsLocSymbol(/*IncludeBaseRegions=*/true)) if (LVState->isNull(V).isConstrainedTrue()) - Report.addVisitor(V.castAs(), - false); + Report.addVisitor( + V.castAs(), + /*Assumption=*/false, "Assuming pointer value is null"); // Add visitor, which will suppress inline defensive checks. if (auto DV = V.getAs()) @@ -2531,7 +2524,7 @@ Report.markInteresting(RegionRVal, Opts.Kind); Report.addVisitor( loc::MemRegionVal(RegionRVal), - /*assumption=*/false); + /*Assumption=*/false, "Assuming pointer value is null"); Result.FoundSomethingToTrack = true; } }