aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/AST/ByteCode/InterpBuiltin.cpp
diff options
context:
space:
mode:
authorTimm Baeder <tbaeder@redhat.com>2025-03-24 15:03:49 +0100
committerGitHub <noreply@github.com>2025-03-24 15:03:49 +0100
commitf7aea4d081f77dba48b0fc019f59b678fb679aa8 (patch)
tree7852cd4ab4c9d389bbe8e54b39b401ac92fca6ed /clang/lib/AST/ByteCode/InterpBuiltin.cpp
parent7ada6f111f133ef2a749c7f395cf337acdaf0f31 (diff)
downloadllvm-f7aea4d081f77dba48b0fc019f59b678fb679aa8.zip
llvm-f7aea4d081f77dba48b0fc019f59b678fb679aa8.tar.gz
llvm-f7aea4d081f77dba48b0fc019f59b678fb679aa8.tar.bz2
[clang][bytecode] Implement __builtin_{wcscmp,wcsncmp} (#132723)
Diffstat (limited to 'clang/lib/AST/ByteCode/InterpBuiltin.cpp')
-rw-r--r--clang/lib/AST/ByteCode/InterpBuiltin.cpp28
1 files changed, 26 insertions, 2 deletions
diff --git a/clang/lib/AST/ByteCode/InterpBuiltin.cpp b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
index 285ea71..5ea1d36 100644
--- a/clang/lib/AST/ByteCode/InterpBuiltin.cpp
+++ b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
@@ -212,11 +212,13 @@ static bool interp__builtin_strcmp(InterpState &S, CodePtr OpPC,
const Pointer &A = getParam<Pointer>(Frame, 0);
const Pointer &B = getParam<Pointer>(Frame, 1);
- if (ID == Builtin::BIstrcmp || ID == Builtin::BIstrncmp)
+ if (ID == Builtin::BIstrcmp || ID == Builtin::BIstrncmp ||
+ ID == Builtin::BIwcscmp || ID == Builtin::BIwcsncmp)
diagnoseNonConstexprBuiltin(S, OpPC, ID);
uint64_t Limit = ~static_cast<uint64_t>(0);
- if (ID == Builtin::BIstrncmp || ID == Builtin::BI__builtin_strncmp)
+ if (ID == Builtin::BIstrncmp || ID == Builtin::BI__builtin_strncmp ||
+ ID == Builtin::BIwcsncmp || ID == Builtin::BI__builtin_wcsncmp)
Limit = peekToAPSInt(S.Stk, *S.getContext().classify(Call->getArg(2)))
.getZExtValue();
@@ -231,6 +233,9 @@ static bool interp__builtin_strcmp(InterpState &S, CodePtr OpPC,
if (A.isDummy() || B.isDummy())
return false;
+ bool IsWide = ID == Builtin::BIwcscmp || ID == Builtin::BIwcsncmp ||
+ ID == Builtin::BI__builtin_wcscmp ||
+ ID == Builtin::BI__builtin_wcsncmp;
assert(A.getFieldDesc()->isPrimitiveArray());
assert(B.getFieldDesc()->isPrimitiveArray());
@@ -248,6 +253,21 @@ static bool interp__builtin_strcmp(InterpState &S, CodePtr OpPC,
!CheckRange(S, OpPC, PB, AK_Read)) {
return false;
}
+
+ if (IsWide)
+ INT_TYPE_SWITCH(
+ *S.getContext().classify(S.getASTContext().getWCharType()), {
+ T A = PA.deref<T>();
+ T B = PB.deref<T>();
+ if (A < B) {
+ pushInteger(S, -1, Call->getType());
+ return true;
+ } else if (A > B) {
+ pushInteger(S, 1, Call->getType());
+ return true;
+ }
+ });
+
uint8_t CA = PA.deref<uint8_t>();
uint8_t CB = PB.deref<uint8_t>();
@@ -2120,6 +2140,10 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const Function *F,
case Builtin::BIstrcmp:
case Builtin::BI__builtin_strncmp:
case Builtin::BIstrncmp:
+ case Builtin::BI__builtin_wcsncmp:
+ case Builtin::BIwcsncmp:
+ case Builtin::BI__builtin_wcscmp:
+ case Builtin::BIwcscmp:
if (!interp__builtin_strcmp(S, OpPC, Frame, F, Call))
return false;
break;