[clang] [clang][analyzer] Add function 'fprintf' to StreamChecker. (PR #77613)
Balazs Benics via cfe-commits
cfe-commits at lists.llvm.org
Wed Jan 24 07:03:12 PST 2024
================
@@ -926,6 +932,49 @@ void StreamChecker::evalFputx(const FnDescription *Desc, const CallEvent &Call,
C.addTransition(StateFailed);
}
+void StreamChecker::evalFprintf(const FnDescription *Desc,
+ const CallEvent &Call,
+ CheckerContext &C) const {
+ ProgramStateRef State = C.getState();
+ if (Call.getNumArgs() < 2)
+ return;
+ SymbolRef StreamSym = getStreamArg(Desc, Call).getAsSymbol();
+ if (!StreamSym)
+ return;
+
+ const CallExpr *CE = dyn_cast_or_null<CallExpr>(Call.getOriginExpr());
+ if (!CE)
+ return;
+
+ const StreamState *OldSS = State->get<StreamMap>(StreamSym);
+ if (!OldSS)
+ return;
+
+ assertStreamStateOpened(OldSS);
+
+ NonLoc RetVal = makeRetVal(C, CE).castAs<NonLoc>();
+ State = State->BindExpr(CE, C.getLocationContext(), RetVal);
+ SValBuilder &SVB = C.getSValBuilder();
+ auto &ACtx = C.getASTContext();
+ auto Cond = SVB.evalBinOp(State, BO_GE, RetVal, SVB.makeZeroVal(ACtx.IntTy),
+ SVB.getConditionType())
+ .getAs<DefinedOrUnknownSVal>();
+ if (!Cond)
+ return;
+ ProgramStateRef StateNotFailed, StateFailed;
+ std::tie(StateNotFailed, StateFailed) = State->assume(*Cond);
----------------
steakhal wrote:
Downstream we used `State->assumeInclusiveRange()` for this.
As a sideffect, we bound an upperbound to the `RetVal` with the number of arguments we had for the call.
Have you considered setting the upperbound here too?
I was thinking if the std library functions checker applies this constraint, but AFAIK it does not, nor we have a proposed patch for doing so. And anyways I'd prefer setting both upper and lowerbounds at the same checker if possible. Thus, I write to this PR.
https://github.com/llvm/llvm-project/pull/77613
More information about the cfe-commits
mailing list