[clang] [clang][bytecode] Pass __builtin_memcpy size along (PR #118649)

Timm Baeder via cfe-commits cfe-commits at lists.llvm.org
Wed Dec 4 06:47:42 PST 2024


https://github.com/tbaederr created https://github.com/llvm/llvm-project/pull/118649

To DoBitCastPtr, so we know how many bytes we want to read.

>From 1430ff275074381f2ce8321e7e6e37aee0588c07 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= <tbaeder at redhat.com>
Date: Wed, 4 Dec 2024 13:30:51 +0100
Subject: [PATCH] [clang][bytecode] Pass __builtin_memcpy size along

To DoBitCastPtr, so we know how many bytes we want to read.
---
 clang/lib/AST/ByteCode/InterpBuiltin.cpp        |  2 +-
 clang/lib/AST/ByteCode/InterpBuiltinBitCast.cpp | 14 ++++++++++----
 clang/lib/AST/ByteCode/InterpBuiltinBitCast.h   |  2 ++
 clang/test/AST/ByteCode/builtin-functions.cpp   |  7 +++++++
 4 files changed, 20 insertions(+), 5 deletions(-)

diff --git a/clang/lib/AST/ByteCode/InterpBuiltin.cpp b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
index 85cffb0c4332df..24b630d0455e14 100644
--- a/clang/lib/AST/ByteCode/InterpBuiltin.cpp
+++ b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
@@ -1831,7 +1831,7 @@ static bool interp__builtin_memcpy(InterpState &S, CodePtr OpPC,
   if (DestPtr.isDummy() || SrcPtr.isDummy())
     return false;
 
-  if (!DoBitCastPtr(S, OpPC, SrcPtr, DestPtr))
+  if (!DoBitCastPtr(S, OpPC, SrcPtr, DestPtr, Size.getZExtValue()))
     return false;
 
   S.Stk.push<Pointer>(DestPtr);
diff --git a/clang/lib/AST/ByteCode/InterpBuiltinBitCast.cpp b/clang/lib/AST/ByteCode/InterpBuiltinBitCast.cpp
index 2fae7f873ab11b..16ea471c4ab8e4 100644
--- a/clang/lib/AST/ByteCode/InterpBuiltinBitCast.cpp
+++ b/clang/lib/AST/ByteCode/InterpBuiltinBitCast.cpp
@@ -305,9 +305,17 @@ bool clang::interp::DoBitCast(InterpState &S, CodePtr OpPC, const Pointer &Ptr,
 
   return Success;
 }
-
 bool clang::interp::DoBitCastPtr(InterpState &S, CodePtr OpPC,
                                  const Pointer &FromPtr, Pointer &ToPtr) {
+  const ASTContext &ASTCtx = S.getASTContext();
+  CharUnits ObjectReprChars = ASTCtx.getTypeSizeInChars(ToPtr.getType());
+
+  return DoBitCastPtr(S, OpPC, FromPtr, ToPtr, ObjectReprChars.getQuantity());
+}
+
+bool clang::interp::DoBitCastPtr(InterpState &S, CodePtr OpPC,
+                                 const Pointer &FromPtr, Pointer &ToPtr,
+                                 size_t Size) {
   assert(FromPtr.isLive());
   assert(FromPtr.isBlockPointer());
   assert(ToPtr.isBlockPointer());
@@ -321,9 +329,7 @@ bool clang::interp::DoBitCastPtr(InterpState &S, CodePtr OpPC,
     return false;
 
   const ASTContext &ASTCtx = S.getASTContext();
-
-  CharUnits ObjectReprChars = ASTCtx.getTypeSizeInChars(ToType);
-  BitcastBuffer Buffer(Bits(ASTCtx.toBits(ObjectReprChars)));
+  BitcastBuffer Buffer(Bytes(Size).toBits());
   readPointerToBuffer(S.getContext(), FromPtr, Buffer,
                       /*ReturnOnUninit=*/false);
 
diff --git a/clang/lib/AST/ByteCode/InterpBuiltinBitCast.h b/clang/lib/AST/ByteCode/InterpBuiltinBitCast.h
index 494c0880a9c453..8142e0bf28fcf2 100644
--- a/clang/lib/AST/ByteCode/InterpBuiltinBitCast.h
+++ b/clang/lib/AST/ByteCode/InterpBuiltinBitCast.h
@@ -21,6 +21,8 @@ bool DoBitCast(InterpState &S, CodePtr OpPC, const Pointer &Ptr,
                std::byte *Buff, size_t BuffSize, bool &HasIndeterminateBits);
 bool DoBitCastPtr(InterpState &S, CodePtr OpPC, const Pointer &FromPtr,
                   Pointer &ToPtr);
+bool DoBitCastPtr(InterpState &S, CodePtr OpPC, const Pointer &FromPtr,
+                  Pointer &ToPtr, size_t Size);
 
 } // namespace interp
 } // namespace clang
diff --git a/clang/test/AST/ByteCode/builtin-functions.cpp b/clang/test/AST/ByteCode/builtin-functions.cpp
index f70b77fe74636b..e2121a54e15768 100644
--- a/clang/test/AST/ByteCode/builtin-functions.cpp
+++ b/clang/test/AST/ByteCode/builtin-functions.cpp
@@ -1151,6 +1151,13 @@ namespace BuiltinMemcpy {
   }
   static_assert(simple() == 12);
 
+  constexpr bool arrayMemcpy() {
+    char src[] = "abc";
+    char dst[4] = {};
+    __builtin_memcpy(dst, src, 4);
+    return dst[0] == 'a' && dst[1] == 'b' && dst[2] == 'c' && dst[3] == '\0';
+  }
+  static_assert(arrayMemcpy());
 
   extern struct Incomplete incomplete;
   constexpr struct Incomplete *null_incomplete = 0;



More information about the cfe-commits mailing list