@@ -99,6 +99,11 @@ class BuiltinFunctionChecker : public Checker<eval::Call> {
9999 const NoteTag *createBuiltinOverflowNoteTag (CheckerContext &C,
100100 bool BothFeasible, SVal Arg1,
101101 SVal Arg2, SVal Result) const ;
102+ ProgramStateRef initStateAftetBuiltinOverflow (CheckerContext &C,
103+ ProgramStateRef State,
104+ const CallEvent &Call,
105+ SVal RetCal,
106+ bool IsOverflow) const ;
102107 std::pair<bool , bool > checkOverflow (CheckerContext &C, SVal RetVal,
103108 QualType Res) const ;
104109
@@ -167,6 +172,29 @@ BuiltinFunctionChecker::checkOverflow(CheckerContext &C, SVal RetVal,
167172 return {MayOverflow || MayUnderflow, MayNotOverflow && MayNotUnderflow};
168173}
169174
175+ ProgramStateRef BuiltinFunctionChecker::initStateAftetBuiltinOverflow (
176+ CheckerContext &C, ProgramStateRef State, const CallEvent &Call,
177+ SVal RetVal, bool IsOverflow) const {
178+ SValBuilder &SVB = C.getSValBuilder ();
179+ SVal Arg1 = Call.getArgSVal (0 );
180+ SVal Arg2 = Call.getArgSVal (1 );
181+ auto BoolTy = C.getASTContext ().BoolTy ;
182+
183+ ProgramStateRef NewState =
184+ State->BindExpr (Call.getOriginExpr (), C.getLocationContext (),
185+ SVB.makeTruthVal (IsOverflow, BoolTy));
186+
187+ if (auto L = Call.getArgSVal (2 ).getAs <Loc>()) {
188+ NewState = NewState->bindLoc (*L, RetVal, C.getLocationContext ());
189+
190+ // Propagate taint if any of the arguments were tainted
191+ if (isTainted (State, Arg1) || isTainted (State, Arg2))
192+ NewState = addTaint (NewState, *L);
193+ }
194+
195+ return NewState;
196+ }
197+
170198void BuiltinFunctionChecker::handleOverflowBuiltin (const CallEvent &Call,
171199 CheckerContext &C,
172200 BinaryOperator::Opcode Op,
@@ -176,8 +204,6 @@ void BuiltinFunctionChecker::handleOverflowBuiltin(const CallEvent &Call,
176204
177205 ProgramStateRef State = C.getState ();
178206 SValBuilder &SVB = C.getSValBuilder ();
179- const Expr *CE = Call.getOriginExpr ();
180- auto BoolTy = C.getASTContext ().BoolTy ;
181207
182208 SVal Arg1 = Call.getArgSVal (0 );
183209 SVal Arg2 = Call.getArgSVal (1 );
@@ -187,28 +213,21 @@ void BuiltinFunctionChecker::handleOverflowBuiltin(const CallEvent &Call,
187213 SVal RetVal = SVB.evalBinOp (State, Op, Arg1, Arg2, ResultType);
188214
189215 auto [Overflow, NotOverflow] = checkOverflow (C, RetValMax, ResultType);
190- auto initializeState = [&](bool isOverflow) {
191- ProgramStateRef NewState = State->BindExpr (
192- CE, C.getLocationContext (), SVB.makeTruthVal (isOverflow, BoolTy));
193216
194- if (auto L = Call.getArgSVal (2 ).getAs <Loc>()) {
195- NewState = NewState->bindLoc (*L, RetVal, C.getLocationContext ());
217+ if (NotOverflow) {
218+ auto NewState =
219+ initStateAftetBuiltinOverflow (C, State, Call, RetVal, false );
196220
197- // Propagate taint if any of the arguments were tainted
198- if (isTainted (State, Arg1) || isTainted (State, Arg2))
199- NewState = addTaint (NewState, *L);
200- }
201-
202- C.addTransition (NewState,
203- createBuiltinOverflowNoteTag (C, /* overflow=*/ isOverflow,
204- Arg1, Arg2, RetVal));
205- };
221+ C.addTransition (NewState, createBuiltinOverflowNoteTag (
222+ C, /* overflow=*/ false , Arg1, Arg2, RetVal));
223+ }
206224
207- if (NotOverflow)
208- initializeState ( false );
225+ if (Overflow) {
226+ auto NewState = initStateAftetBuiltinOverflow (C, State, Call, RetVal, true );
209227
210- if (Overflow)
211- initializeState (true );
228+ C.addTransition (NewState, createBuiltinOverflowNoteTag (C, /* overflow=*/ true ,
229+ Arg1, Arg2, RetVal));
230+ }
212231}
213232
214233bool BuiltinFunctionChecker::isBuiltinLikeFunction (
0 commit comments