================
@@ -2617,6 +2639,54 @@ void CStringChecker::evalStrsep(CheckerContext &C,
   C.addTransition(State);
 }
 
+void CStringChecker::evalStrchrCommon(CheckerContext &C, const CallEvent &Call,
+                                      StringRef FnName,
+                                      bool CanReturnNull) const {
+  CurrentFunctionDescription = FnName;
+  ProgramStateRef State = C.getState();
+  const StackFrame *SF = C.getStackFrame();
+  SValBuilder &SVB = C.getSValBuilder();
+  ASTContext &Ctx = C.getASTContext();
+  const Expr *CE = Call.getOriginExpr();
+  assert(CE);
+
+  // These functions always return a pointer.
+  if (!CE->getType()->isPointerType())
+    return;
+
+  // The first argument must be non-null for all functions in this family.
+  SourceArgExpr Src = {{Call.getArgExpr(0), 0}};
+  SVal SrcVal = State->getSVal(Src.Expression, SF);
+  State = checkNonNull(C, State, Src, SrcVal);
+  if (!State)
+    return;
+
+  // NULL (no-match) branch.
+  if (CanReturnNull) {
+    ProgramStateRef NullState =
+        State->BindExpr(CE, SF, SVB.makeNullWithType(CE->getType()));
+    C.addTransition(NullState);
+  }
+
+  // Found branch: a pointer within the source; needs a Loc for the arithmetic.
+  std::optional<Loc> SrcLoc = SrcVal.getAs<Loc>();
+  if (!SrcLoc) {
+    SVal Result = SVB.conjureSymbolVal(Call, C.blockCount());
+    State = State->BindExpr(CE, SF, Result);
+    C.addTransition(State);
+    return;
+  }
+
+  // The result is: Src + SymOffset
----------------
Xazax-hun wrote:

Could we add some reasonable bounds to this `SymOffset` based on the API 
contracts?

https://github.com/llvm/llvm-project/pull/207267
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to