[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