Skip to content

Commit 6d440b7

Browse files
Refactor so ensureStreamNonNull calls ensurePtrNotNull
1 parent f048c55 commit 6d440b7

File tree

1 file changed

+24
-41
lines changed

1 file changed

+24
-41
lines changed

clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp

Lines changed: 24 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,7 @@ class StreamChecker : public Checker<check::PreCall, eval::Call,
235235
BugType BT_StreamEof{this, "Stream already in EOF", "Stream handling error"};
236236
BugType BT_ResourceLeak{this, "Resource leak", "Stream handling error",
237237
/*SuppressOnSink =*/true};
238-
BugType BT_SizeNull{this, "NULL size pointer", "Stream handling error"};
238+
BugType BT_ArgumentNull{this, "NULL pointer", categories::UnixAPI};
239239
BugType BT_IllegalSize{this, "Invalid buffer size", categories::MemoryError};
240240

241241
public:
@@ -502,6 +502,12 @@ class StreamChecker : public Checker<check::PreCall, eval::Call,
502502
CheckerContext &C,
503503
ProgramStateRef State) const;
504504

505+
ProgramStateRef
506+
ensurePtrNotNull(SVal PtrVal, const Expr *PtrExpr, CheckerContext &C,
507+
ProgramStateRef State, const StringRef PtrDescr,
508+
std::optional<std::reference_wrapper<const BugType>> BT =
509+
std::nullopt) const;
510+
505511
/// Check that the stream is the opened state.
506512
/// If the stream is known to be not opened an error is generated
507513
/// and nullptr returned, otherwise the original state is returned.
@@ -525,9 +531,6 @@ class StreamChecker : public Checker<check::PreCall, eval::Call,
525531
ProgramStateRef ensureFseekWhenceCorrect(SVal WhenceVal, CheckerContext &C,
526532
ProgramStateRef State) const;
527533

528-
ProgramStateRef ensurePtrNotNull(SVal PtrVal, const Expr *PtrExpr,
529-
CheckerContext &C, ProgramStateRef State,
530-
const StringRef PtrDescr) const;
531534
ProgramStateRef ensureGetdelimBufferAndSizeCorrect(
532535
SVal LinePtrPtrSVal, SVal SizePtrSVal, const Expr *LinePtrPtrExpr,
533536
const Expr *SizePtrExpr, CheckerContext &C, ProgramStateRef State) const;
@@ -1192,30 +1195,6 @@ void StreamChecker::evalUngetc(const FnDescription *Desc, const CallEvent &Call,
11921195
C.addTransition(StateFailed);
11931196
}
11941197

1195-
ProgramStateRef
1196-
StreamChecker::ensurePtrNotNull(SVal PtrVal, const Expr *PtrExpr,
1197-
CheckerContext &C, ProgramStateRef State,
1198-
const StringRef PtrDescr) const {
1199-
const auto Ptr = PtrVal.getAs<DefinedSVal>();
1200-
if (!Ptr)
1201-
return nullptr;
1202-
1203-
assert(PtrExpr && "Expected an argument");
1204-
1205-
const auto [PtrNotNull, PtrNull] = State->assume(*Ptr);
1206-
if (!PtrNotNull && PtrNull) {
1207-
if (ExplodedNode *N = C.generateErrorNode(PtrNull)) {
1208-
auto R = std::make_unique<PathSensitiveBugReport>(
1209-
BT_SizeNull, (PtrDescr + " pointer might be NULL.").str(), N);
1210-
bugreporter::trackExpressionValue(N, PtrExpr, *R);
1211-
C.emitReport(std::move(R));
1212-
}
1213-
return nullptr;
1214-
}
1215-
1216-
return PtrNotNull;
1217-
}
1218-
12191198
ProgramStateRef StreamChecker::ensureGetdelimBufferAndSizeCorrect(
12201199
SVal LinePtrPtrSVal, SVal SizePtrSVal, const Expr *LinePtrPtrExpr,
12211200
const Expr *SizePtrExpr, CheckerContext &C, ProgramStateRef State) const {
@@ -1697,27 +1676,31 @@ ProgramStateRef
16971676
StreamChecker::ensureStreamNonNull(SVal StreamVal, const Expr *StreamE,
16981677
CheckerContext &C,
16991678
ProgramStateRef State) const {
1700-
auto Stream = StreamVal.getAs<DefinedSVal>();
1701-
if (!Stream)
1702-
return State;
1703-
1704-
ConstraintManager &CM = C.getConstraintManager();
1679+
return ensurePtrNotNull(StreamVal, StreamE, C, State, "Stream", BT_FileNull);
1680+
}
17051681

1706-
ProgramStateRef StateNotNull, StateNull;
1707-
std::tie(StateNotNull, StateNull) = CM.assumeDual(State, *Stream);
1682+
ProgramStateRef StreamChecker::ensurePtrNotNull(
1683+
SVal PtrVal, const Expr *PtrExpr, CheckerContext &C, ProgramStateRef State,
1684+
const StringRef PtrDescr,
1685+
std::optional<std::reference_wrapper<const BugType>> BT) const {
1686+
const auto Ptr = PtrVal.getAs<DefinedSVal>();
1687+
if (!Ptr)
1688+
return State;
17081689

1709-
if (!StateNotNull && StateNull) {
1710-
if (ExplodedNode *N = C.generateErrorNode(StateNull)) {
1690+
const auto [PtrNotNull, PtrNull] = State->assume(*Ptr);
1691+
if (!PtrNotNull && PtrNull) {
1692+
if (ExplodedNode *N = C.generateErrorNode(PtrNull)) {
17111693
auto R = std::make_unique<PathSensitiveBugReport>(
1712-
BT_FileNull, "Stream pointer might be NULL.", N);
1713-
if (StreamE)
1714-
bugreporter::trackExpressionValue(N, StreamE, *R);
1694+
BT.value_or(std::cref(BT_ArgumentNull)),
1695+
(PtrDescr + " pointer might be NULL.").str(), N);
1696+
if (PtrExpr)
1697+
bugreporter::trackExpressionValue(N, PtrExpr, *R);
17151698
C.emitReport(std::move(R));
17161699
}
17171700
return nullptr;
17181701
}
17191702

1720-
return StateNotNull;
1703+
return PtrNotNull;
17211704
}
17221705

17231706
ProgramStateRef StreamChecker::ensureStreamOpened(SVal StreamVal,

0 commit comments

Comments
 (0)