@@ -197,9 +197,19 @@ static bool interp__builtin_strcmp(InterpState &S, CodePtr OpPC,
197
197
const Pointer &A = getParam<Pointer>(Frame, 0 );
198
198
const Pointer &B = getParam<Pointer>(Frame, 1 );
199
199
200
- if (ID == Builtin::BIstrcmp)
200
+ if (ID == Builtin::BIstrcmp || ID == Builtin::BIstrncmp )
201
201
diagnoseNonConstexprBuiltin (S, OpPC, ID);
202
202
203
+ uint64_t Limit = ~static_cast <uint64_t >(0 );
204
+ if (ID == Builtin::BIstrncmp || ID == Builtin::BI__builtin_strncmp)
205
+ Limit = peekToAPSInt (S.Stk , *S.getContext ().classify (Call->getArg (2 )))
206
+ .getZExtValue ();
207
+
208
+ if (Limit == 0 ) {
209
+ pushInteger (S, 0 , Call->getType ());
210
+ return true ;
211
+ }
212
+
203
213
if (!CheckLive (S, OpPC, A, AK_Read) || !CheckLive (S, OpPC, B, AK_Read))
204
214
return false ;
205
215
@@ -212,7 +222,11 @@ static bool interp__builtin_strcmp(InterpState &S, CodePtr OpPC,
212
222
unsigned IndexA = A.getIndex ();
213
223
unsigned IndexB = B.getIndex ();
214
224
int32_t Result = 0 ;
215
- for (;; ++IndexA, ++IndexB) {
225
+ uint64_t Steps = 0 ;
226
+ for (;; ++IndexA, ++IndexB, ++Steps) {
227
+
228
+ if (Steps >= Limit)
229
+ break ;
216
230
const Pointer &PA = A.atIndex (IndexA);
217
231
const Pointer &PB = B.atIndex (IndexB);
218
232
if (!CheckRange (S, OpPC, PA, AK_Read) ||
@@ -1873,6 +1887,8 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const Function *F,
1873
1887
break ;
1874
1888
case Builtin::BI__builtin_strcmp:
1875
1889
case Builtin::BIstrcmp:
1890
+ case Builtin::BI__builtin_strncmp:
1891
+ case Builtin::BIstrncmp:
1876
1892
if (!interp__builtin_strcmp (S, OpPC, Frame, F, Call))
1877
1893
return false ;
1878
1894
break ;
0 commit comments