} // 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<Loc>(Constraint)) {}
+ TrackConstraintBRVisitor(DefinedSVal constraint, bool assumption,
+ StringRef Message)
+ : Message(Message), Constraint(constraint), Assumption(assumption) {}
void Profile(llvm::FoldingSetNodeID &ID) const override;
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;
};
void TrackConstraintBRVisitor::Profile(llvm::FoldingSetNodeID &ID) const {
static int tag = 0;
ID.AddPointer(&tag);
+ ID.AddString(Message);
ID.AddBoolean(Assumption);
ID.Add(Constraint);
}
return "TrackConstraintBRVisitor";
}
+bool TrackConstraintBRVisitor::isZeroCheck() const {
+ return !Assumption && Constraint.getAs<Loc>();
+}
+
bool TrackConstraintBRVisitor::isUnderconstrained(const ExplodedNode *N) const {
- if (IsZeroCheck)
+ if (isZeroCheck())
return N->getState()->isNull(Constraint).isUnderconstrained();
return (bool)N->getState()->assume(Constraint, !Assumption);
}
// 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<Loc>(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();
if (!L.isValid())
return nullptr;
- auto X = std::make_shared<PathDiagnosticEventPiece>(L, os.str());
+ auto X = std::make_shared<PathDiagnosticEventPiece>(L, Message);
X->setTag(getTag());
return std::move(X);
}
// null.
if (V.getAsLocSymbol(/*IncludeBaseRegions=*/true))
if (LVState->isNull(V).isConstrainedTrue())
- Report.addVisitor<TrackConstraintBRVisitor>(V.castAs<DefinedSVal>(),
- false);
+ Report.addVisitor<TrackConstraintBRVisitor>(
+ V.castAs<DefinedSVal>(),
+ /*Assumption=*/false, "Assuming pointer value is null");
// Add visitor, which will suppress inline defensive checks.
if (auto DV = V.getAs<DefinedSVal>())
Report.markInteresting(RegionRVal, Opts.Kind);
Report.addVisitor<TrackConstraintBRVisitor>(
loc::MemRegionVal(RegionRVal),
- /*assumption=*/false);
+ /*Assumption=*/false, "Assuming pointer value is null");
Result.FoundSomethingToTrack = true;
}
}