Author: Timm Baeder Date: 2024-12-09T16:17:39+01:00 New Revision: d17e51f306cb3522af7587bf1f3a2f4956ab3a19
URL: https://github.com/llvm/llvm-project/commit/d17e51f306cb3522af7587bf1f3a2f4956ab3a19 DIFF: https://github.com/llvm/llvm-project/commit/d17e51f306cb3522af7587bf1f3a2f4956ab3a19.diff LOG: [clang][bytecode] Handle __builtin_strncmp (#119208) Added: Modified: clang/lib/AST/ByteCode/InterpBuiltin.cpp clang/test/AST/ByteCode/builtin-functions.cpp Removed: ################################################################################ diff --git a/clang/lib/AST/ByteCode/InterpBuiltin.cpp b/clang/lib/AST/ByteCode/InterpBuiltin.cpp index f816373c4d3dcc..9f2e64b3faeff2 100644 --- a/clang/lib/AST/ByteCode/InterpBuiltin.cpp +++ b/clang/lib/AST/ByteCode/InterpBuiltin.cpp @@ -197,9 +197,19 @@ 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) + if (ID == Builtin::BIstrcmp || ID == Builtin::BIstrncmp) diagnoseNonConstexprBuiltin(S, OpPC, ID); + uint64_t Limit = ~static_cast<uint64_t>(0); + if (ID == Builtin::BIstrncmp || ID == Builtin::BI__builtin_strncmp) + Limit = peekToAPSInt(S.Stk, *S.getContext().classify(Call->getArg(2))) + .getZExtValue(); + + if (Limit == 0) { + pushInteger(S, 0, Call->getType()); + return true; + } + if (!CheckLive(S, OpPC, A, AK_Read) || !CheckLive(S, OpPC, B, AK_Read)) return false; @@ -212,7 +222,11 @@ static bool interp__builtin_strcmp(InterpState &S, CodePtr OpPC, unsigned IndexA = A.getIndex(); unsigned IndexB = B.getIndex(); int32_t Result = 0; - for (;; ++IndexA, ++IndexB) { + uint64_t Steps = 0; + for (;; ++IndexA, ++IndexB, ++Steps) { + + if (Steps >= Limit) + break; const Pointer &PA = A.atIndex(IndexA); const Pointer &PB = B.atIndex(IndexB); if (!CheckRange(S, OpPC, PA, AK_Read) || @@ -1873,6 +1887,8 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const Function *F, break; case Builtin::BI__builtin_strcmp: case Builtin::BIstrcmp: + case Builtin::BI__builtin_strncmp: + case Builtin::BIstrncmp: if (!interp__builtin_strcmp(S, OpPC, Frame, F, Call)) return false; break; diff --git a/clang/test/AST/ByteCode/builtin-functions.cpp b/clang/test/AST/ByteCode/builtin-functions.cpp index 4c21496d3972c9..bd453d6d342d3f 100644 --- a/clang/test/AST/ByteCode/builtin-functions.cpp +++ b/clang/test/AST/ByteCode/builtin-functions.cpp @@ -51,6 +51,15 @@ namespace strcmp { return __builtin_strcmp(buffer, "mutable") == 0; } static_assert(char_memchr_mutable(), ""); + + static_assert(__builtin_strncmp("abaa", "abba", 5) == -1); + static_assert(__builtin_strncmp("abaa", "abba", 4) == -1); + static_assert(__builtin_strncmp("abaa", "abba", 3) == -1); + static_assert(__builtin_strncmp("abaa", "abba", 2) == 0); + static_assert(__builtin_strncmp("abaa", "abba", 1) == 0); + static_assert(__builtin_strncmp("abaa", "abba", 0) == 0); + static_assert(__builtin_strncmp(0, 0, 0) == 0); + static_assert(__builtin_strncmp("abab\0banana", "abab\0canada", 100) == 0); } /// Copied from constant-expression-cxx11.cpp _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits