================ @@ -1191,6 +1199,49 @@ void StreamChecker::evalSetFeofFerror(const FnDescription *Desc, C.addTransition(State); } +void StreamChecker::preFflush(const FnDescription *Desc, const CallEvent &Call, + CheckerContext &C) const { + ProgramStateRef State = C.getState(); + SVal StreamVal = getStreamArg(Desc, Call); + std::optional<DefinedSVal> Stream = StreamVal.getAs<DefinedSVal>(); + if (!Stream) + return; + + ConstraintManager::ProgramStatePair SP = + C.getConstraintManager().assumeDual(State, *Stream); + if (State = SP.first) + if (State = ensureStreamOpened(StreamVal, C, State)) + C.addTransition(State); +} + +void StreamChecker::evalFflush(const FnDescription *Desc, const CallEvent &Call, + CheckerContext &C) const { + ProgramStateRef State = C.getState(); + + // We will check the result even if the input is `NULL`, + // but do nothing if the input state is unknown. + SymbolRef StreamSym = getStreamArg(Desc, Call).getAsSymbol(); + if (StreamSym) { + const StreamState *OldSS = State->get<StreamMap>(StreamSym); + if (!OldSS) + return; + assertStreamStateOpened(OldSS); + } + + const CallExpr *CE = dyn_cast_or_null<CallExpr>(Call.getOriginExpr()); + if (!CE) + return; + + // `fflush` returns 0 on success, otherwise returns EOF. + ProgramStateRef StateNotFailed = bindInt(0, State, C, CE); + ProgramStateRef StateFailed = bindInt(*EofVal, State, C, CE); + + // This function does not affect the stream state. + // Still we add success and failure state with the appropriate return value. ---------------- balazske wrote:
The stream state can be affected in some way, if the stream was in failed (`ferror`) state or the position is indeterminate, probably the `fflush` can be allowed but the error (and indeterminate position) should be reset to non-error. If the argument is null we can do this reset for all of the known streams. It is somewhat questionable what should happen at a failing `fflush`, but probably it is OK to leave the error flags as it was before. https://github.com/llvm/llvm-project/pull/74296 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits