Skip to content

Commit d17e51f

Browse files
authored
[clang][bytecode] Handle __builtin_strncmp (#119208)
1 parent d1cf86f commit d17e51f

File tree

2 files changed

+27
-2
lines changed

2 files changed

+27
-2
lines changed

clang/lib/AST/ByteCode/InterpBuiltin.cpp

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -197,9 +197,19 @@ static bool interp__builtin_strcmp(InterpState &S, CodePtr OpPC,
197197
const Pointer &A = getParam<Pointer>(Frame, 0);
198198
const Pointer &B = getParam<Pointer>(Frame, 1);
199199

200-
if (ID == Builtin::BIstrcmp)
200+
if (ID == Builtin::BIstrcmp || ID == Builtin::BIstrncmp)
201201
diagnoseNonConstexprBuiltin(S, OpPC, ID);
202202

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+
203213
if (!CheckLive(S, OpPC, A, AK_Read) || !CheckLive(S, OpPC, B, AK_Read))
204214
return false;
205215

@@ -212,7 +222,11 @@ static bool interp__builtin_strcmp(InterpState &S, CodePtr OpPC,
212222
unsigned IndexA = A.getIndex();
213223
unsigned IndexB = B.getIndex();
214224
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;
216230
const Pointer &PA = A.atIndex(IndexA);
217231
const Pointer &PB = B.atIndex(IndexB);
218232
if (!CheckRange(S, OpPC, PA, AK_Read) ||
@@ -1873,6 +1887,8 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const Function *F,
18731887
break;
18741888
case Builtin::BI__builtin_strcmp:
18751889
case Builtin::BIstrcmp:
1890+
case Builtin::BI__builtin_strncmp:
1891+
case Builtin::BIstrncmp:
18761892
if (!interp__builtin_strcmp(S, OpPC, Frame, F, Call))
18771893
return false;
18781894
break;

clang/test/AST/ByteCode/builtin-functions.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,15 @@ namespace strcmp {
5151
return __builtin_strcmp(buffer, "mutable") == 0;
5252
}
5353
static_assert(char_memchr_mutable(), "");
54+
55+
static_assert(__builtin_strncmp("abaa", "abba", 5) == -1);
56+
static_assert(__builtin_strncmp("abaa", "abba", 4) == -1);
57+
static_assert(__builtin_strncmp("abaa", "abba", 3) == -1);
58+
static_assert(__builtin_strncmp("abaa", "abba", 2) == 0);
59+
static_assert(__builtin_strncmp("abaa", "abba", 1) == 0);
60+
static_assert(__builtin_strncmp("abaa", "abba", 0) == 0);
61+
static_assert(__builtin_strncmp(0, 0, 0) == 0);
62+
static_assert(__builtin_strncmp("abab\0banana", "abab\0canada", 100) == 0);
5463
}
5564

5665
/// Copied from constant-expression-cxx11.cpp

0 commit comments

Comments
 (0)