@@ -235,7 +235,7 @@ class StreamChecker : public Checker<check::PreCall, eval::Call,
235
235
BugType BT_StreamEof{this , " Stream already in EOF" , " Stream handling error" };
236
236
BugType BT_ResourceLeak{this , " Resource leak" , " Stream handling error" ,
237
237
/* SuppressOnSink =*/ true };
238
- BugType BT_SizeNull {this , " NULL size pointer" , " Stream handling error " };
238
+ BugType BT_ArgumentNull {this , " NULL pointer" , categories::UnixAPI };
239
239
BugType BT_IllegalSize{this , " Invalid buffer size" , categories::MemoryError};
240
240
241
241
public:
@@ -502,6 +502,12 @@ class StreamChecker : public Checker<check::PreCall, eval::Call,
502
502
CheckerContext &C,
503
503
ProgramStateRef State) const ;
504
504
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
+
505
511
// / Check that the stream is the opened state.
506
512
// / If the stream is known to be not opened an error is generated
507
513
// / and nullptr returned, otherwise the original state is returned.
@@ -525,9 +531,6 @@ class StreamChecker : public Checker<check::PreCall, eval::Call,
525
531
ProgramStateRef ensureFseekWhenceCorrect (SVal WhenceVal, CheckerContext &C,
526
532
ProgramStateRef State) const ;
527
533
528
- ProgramStateRef ensurePtrNotNull (SVal PtrVal, const Expr *PtrExpr,
529
- CheckerContext &C, ProgramStateRef State,
530
- const StringRef PtrDescr) const ;
531
534
ProgramStateRef ensureGetdelimBufferAndSizeCorrect (
532
535
SVal LinePtrPtrSVal, SVal SizePtrSVal, const Expr *LinePtrPtrExpr,
533
536
const Expr *SizePtrExpr, CheckerContext &C, ProgramStateRef State) const ;
@@ -1192,30 +1195,6 @@ void StreamChecker::evalUngetc(const FnDescription *Desc, const CallEvent &Call,
1192
1195
C.addTransition (StateFailed);
1193
1196
}
1194
1197
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
-
1219
1198
ProgramStateRef StreamChecker::ensureGetdelimBufferAndSizeCorrect (
1220
1199
SVal LinePtrPtrSVal, SVal SizePtrSVal, const Expr *LinePtrPtrExpr,
1221
1200
const Expr *SizePtrExpr, CheckerContext &C, ProgramStateRef State) const {
@@ -1697,27 +1676,31 @@ ProgramStateRef
1697
1676
StreamChecker::ensureStreamNonNull (SVal StreamVal, const Expr *StreamE,
1698
1677
CheckerContext &C,
1699
1678
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
+ }
1705
1681
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;
1708
1689
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)) {
1711
1693
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);
1715
1698
C.emitReport (std::move (R));
1716
1699
}
1717
1700
return nullptr ;
1718
1701
}
1719
1702
1720
- return StateNotNull ;
1703
+ return PtrNotNull ;
1721
1704
}
1722
1705
1723
1706
ProgramStateRef StreamChecker::ensureStreamOpened (SVal StreamVal,
0 commit comments