Skip to content

Conversation

@tbaederr
Copy link
Contributor

@tbaederr tbaederr commented Dec 4, 2024

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

To DoBitCastPtr, so we know how many bytes we want to read.
@llvmbot llvmbot added clang Clang issues not falling into any other category clang:frontend Language frontend issues, e.g. anything involving "Sema" labels Dec 4, 2024
@llvmbot
Copy link
Member

llvmbot commented Dec 4, 2024

@llvm/pr-subscribers-clang

Author: Timm Baeder (tbaederr)

Changes

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


Full diff: https://github.com/llvm/llvm-project/pull/118649.diff

4 Files Affected:

  • (modified) clang/lib/AST/ByteCode/InterpBuiltin.cpp (+1-1)
  • (modified) clang/lib/AST/ByteCode/InterpBuiltinBitCast.cpp (+10-4)
  • (modified) clang/lib/AST/ByteCode/InterpBuiltinBitCast.h (+2)
  • (modified) clang/test/AST/ByteCode/builtin-functions.cpp (+7)
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;

@tbaederr tbaederr merged commit abc2703 into llvm:main Dec 5, 2024
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

clang:frontend Language frontend issues, e.g. anything involving "Sema" clang Clang issues not falling into any other category

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants