@@ -245,10 +245,10 @@ class StreamChecker : public Checker<check::PreCall, eval::Call,
245
245
{{{" fclose" }, 1 },
246
246
{&StreamChecker::preDefault, &StreamChecker::evalFclose, 0 }},
247
247
{{{" fread" }, 4 },
248
- {&StreamChecker::preFread ,
248
+ {std::bind ( &StreamChecker::preFreadFwrite, _1, _2, _3, _4, true ) ,
249
249
std::bind (&StreamChecker::evalFreadFwrite, _1, _2, _3, _4, true ), 3 }},
250
250
{{{" fwrite" }, 4 },
251
- {&StreamChecker::preFwrite ,
251
+ {std::bind ( &StreamChecker::preFreadFwrite, _1, _2, _3, _4, false ) ,
252
252
std::bind (&StreamChecker::evalFreadFwrite, _1, _2, _3, _4, false ), 3 }},
253
253
{{{" fseek" }, 3 },
254
254
{&StreamChecker::preFseek, &StreamChecker::evalFseek, 0 }},
@@ -305,11 +305,8 @@ class StreamChecker : public Checker<check::PreCall, eval::Call,
305
305
void evalFclose (const FnDescription *Desc, const CallEvent &Call,
306
306
CheckerContext &C) const ;
307
307
308
- void preFread (const FnDescription *Desc, const CallEvent &Call,
309
- CheckerContext &C) const ;
310
-
311
- void preFwrite (const FnDescription *Desc, const CallEvent &Call,
312
- CheckerContext &C) const ;
308
+ void preFreadFwrite (const FnDescription *Desc, const CallEvent &Call,
309
+ CheckerContext &C, bool IsFread) const ;
313
310
314
311
void evalFreadFwrite (const FnDescription *Desc, const CallEvent &Call,
315
312
CheckerContext &C, bool IsFread) const ;
@@ -637,8 +634,9 @@ void StreamChecker::evalFclose(const FnDescription *Desc, const CallEvent &Call,
637
634
C.addTransition (StateFailure);
638
635
}
639
636
640
- void StreamChecker::preFread (const FnDescription *Desc, const CallEvent &Call,
641
- CheckerContext &C) const {
637
+ void StreamChecker::preFreadFwrite (const FnDescription *Desc,
638
+ const CallEvent &Call, CheckerContext &C,
639
+ bool IsFread) const {
642
640
ProgramStateRef State = C.getState ();
643
641
SVal StreamVal = getStreamArg (Desc, Call);
644
642
State = ensureStreamNonNull (StreamVal, Call.getArgExpr (Desc->StreamArgNo ), C,
@@ -652,6 +650,11 @@ void StreamChecker::preFread(const FnDescription *Desc, const CallEvent &Call,
652
650
if (!State)
653
651
return ;
654
652
653
+ if (!IsFread) {
654
+ C.addTransition (State);
655
+ return ;
656
+ }
657
+
655
658
SymbolRef Sym = StreamVal.getAsSymbol ();
656
659
if (Sym && State->get <StreamMap>(Sym)) {
657
660
const StreamState *SS = State->get <StreamMap>(Sym);
@@ -662,24 +665,6 @@ void StreamChecker::preFread(const FnDescription *Desc, const CallEvent &Call,
662
665
}
663
666
}
664
667
665
- void StreamChecker::preFwrite (const FnDescription *Desc, const CallEvent &Call,
666
- CheckerContext &C) const {
667
- ProgramStateRef State = C.getState ();
668
- SVal StreamVal = getStreamArg (Desc, Call);
669
- State = ensureStreamNonNull (StreamVal, Call.getArgExpr (Desc->StreamArgNo ), C,
670
- State);
671
- if (!State)
672
- return ;
673
- State = ensureStreamOpened (StreamVal, C, State);
674
- if (!State)
675
- return ;
676
- State = ensureNoFilePositionIndeterminate (StreamVal, C, State);
677
- if (!State)
678
- return ;
679
-
680
- C.addTransition (State);
681
- }
682
-
683
668
void StreamChecker::evalFreadFwrite (const FnDescription *Desc,
684
669
const CallEvent &Call, CheckerContext &C,
685
670
bool IsFread) const {
@@ -1222,7 +1207,7 @@ StreamChecker::reportLeaks(const SmallVector<SymbolRef, 2> &LeakedSyms,
1222
1207
1223
1208
PathDiagnosticLocation LocUsedForUniqueing;
1224
1209
if (const Stmt *StreamStmt = StreamOpenNode->getStmtForDiagnostics ())
1225
- LocUsedForUniqueing = PathDiagnosticLocation::createBegin (
1210
+ LocUsedForUniqueing = PathDiagnosticLocation::createBegin (
1226
1211
StreamStmt, C.getSourceManager (),
1227
1212
StreamOpenNode->getLocationContext ());
1228
1213
0 commit comments