Author: Timm Baeder
Date: 2025-04-29T08:06:31+02:00
New Revision: 0ddb5794b7b47481ed713af0add392de324d5cd2

URL: 
https://github.com/llvm/llvm-project/commit/0ddb5794b7b47481ed713af0add392de324d5cd2
DIFF: 
https://github.com/llvm/llvm-project/commit/0ddb5794b7b47481ed713af0add392de324d5cd2.diff

LOG: [clang][bytecode] Remove base casts before doing memcpy (#137754)

We have to copy the entire thing, not just one of the bases.

Added: 
    

Modified: 
    clang/lib/AST/ByteCode/Disasm.cpp
    clang/lib/AST/ByteCode/InterpBuiltin.cpp
    clang/test/AST/ByteCode/builtin-functions.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/AST/ByteCode/Disasm.cpp 
b/clang/lib/AST/ByteCode/Disasm.cpp
index 83b9af9de0796..46c5cb96fa9f4 100644
--- a/clang/lib/AST/ByteCode/Disasm.cpp
+++ b/clang/lib/AST/ByteCode/Disasm.cpp
@@ -422,6 +422,7 @@ LLVM_DUMP_METHOD void 
InlineDescriptor::dump(llvm::raw_ostream &OS) const {
   OS << "IsActive: " << IsActive << "\n";
   OS << "InUnion: " << InUnion << "\n";
   OS << "IsFieldMutable: " << IsFieldMutable << "\n";
+  OS << "IsArrayElement: " << IsArrayElement << "\n";
   OS << "Desc: ";
   if (Desc)
     Desc->dump(OS);

diff  --git a/clang/lib/AST/ByteCode/InterpBuiltin.cpp 
b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
index 0b4585a10a3d5..b6e5b5ffd16ad 100644
--- a/clang/lib/AST/ByteCode/InterpBuiltin.cpp
+++ b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
@@ -1854,8 +1854,17 @@ static bool interp__builtin_memcpy(InterpState &S, 
CodePtr OpPC,
 
   // Check for overlapping memory regions.
   if (!Move && Pointer::pointToSameBlock(SrcPtr, DestPtr)) {
-    unsigned SrcIndex = SrcPtr.getIndex() * SrcPtr.elemSize();
-    unsigned DstIndex = DestPtr.getIndex() * DestPtr.elemSize();
+    // Remove base casts.
+    Pointer SrcP = SrcPtr;
+    while (SrcP.isBaseClass())
+      SrcP = SrcP.getBase();
+
+    Pointer DestP = DestPtr;
+    while (DestP.isBaseClass())
+      DestP = DestP.getBase();
+
+    unsigned SrcIndex = SrcP.expand().getIndex() * SrcP.elemSize();
+    unsigned DstIndex = DestP.expand().getIndex() * DestP.elemSize();
     unsigned N = Size.getZExtValue();
 
     if ((SrcIndex <= DstIndex && (SrcIndex + N) > DstIndex) ||

diff  --git a/clang/test/AST/ByteCode/builtin-functions.cpp 
b/clang/test/AST/ByteCode/builtin-functions.cpp
index a4c8ec4856ecc..f879360c5357f 100644
--- a/clang/test/AST/ByteCode/builtin-functions.cpp
+++ b/clang/test/AST/ByteCode/builtin-functions.cpp
@@ -1383,7 +1383,19 @@ namespace BuiltinMemcpy {
   static_assert(type_pun(0x3f800000) == 1.0f); // both-error {{constant}} \
                                                // both-note {{in call}}
 
-
+  struct Base { int a; };
+  struct Derived : Base { int b; };
+  constexpr int test_derived_to_base(int n) {
+    Derived arr[2] = {1, 2, 3, 4};
+    Base *p = &arr[0];
+    Base *q = &arr[1];
+    __builtin_memcpy(p, q, sizeof(Base) * n); // both-note {{source is not a 
contiguous array of at least 2 elements of type 'BuiltinMemcpy::Base'}}
+    return arr[0].a * 1000 + arr[0].b * 100 + arr[1].a * 10 + arr[1].b;
+  }
+  static_assert(test_derived_to_base(0) == 1234);
+  static_assert(test_derived_to_base(1) == 3234);
+  static_assert(test_derived_to_base(2) == 3434); // both-error {{constant}} \
+                                                  // both-note {{in call}}
 }
 
 namespace Memcmp {


        
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to