================ @@ -1404,6 +1486,47 @@ void StreamChecker::evalFeofFerror(const FnDescription *Desc, } } +void StreamChecker::evalFileno(const FnDescription *Desc, const CallEvent &Call, + CheckerContext &C) const { + // Fileno should fail only if the passed pointer is invalid. + // Some of the preconditions are checked already in preDefault. + // Here we can assume that the operation does not fail. + // An added failure case causes many unexpected warnings because a file number + // becomes -1 that is not expected by the program. + // The stream error states are not modified by 'fileno', and not the 'errno'. + // (To ensure that errno is not changed, this evalCall is needed to not + // invalidate 'errno' like in a default case.) + ProgramStateRef State = C.getState(); + SymbolRef StreamSym = getStreamArg(Desc, Call).getAsSymbol(); + if (!StreamSym) + return; + + const CallExpr *CE = dyn_cast_or_null<CallExpr>(Call.getOriginExpr()); + if (!CE) + return; + + const StreamState *SS = State->get<StreamMap>(StreamSym); + if (!SS) + return; + + assertStreamStateOpened(SS); + + SValBuilder &SVB = C.getSValBuilder(); + NonLoc RetVal = makeRetVal(C, CE).castAs<NonLoc>(); + State = State->BindExpr(CE, C.getLocationContext(), RetVal); + auto Cond = + SVB.evalBinOp(State, BO_GE, RetVal, SVB.makeZeroVal(Call.getResultType()), ---------------- NagyDonat wrote:
It's a nice trick that you're creating the zero in the type of the other side to avoid surprising type conversion. There's a chance that I can borrow this solution to handle tricky issues in ArrayBoundCheckerV2 :smile: https://github.com/llvm/llvm-project/pull/81842 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits