[clang] d17e51f - [clang][bytecode] Handle __builtin_strncmp (#119208)

via cfe-commits cfe-commits at lists.llvm.org
Mon Dec 9 07:17:42 PST 2024


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


        


More information about the cfe-commits mailing list