Author: Timm Baeder
Date: 2025-07-01T15:45:50+02:00
New Revision: 1fe993c251966697d75123eb38fa710cdb346c8d

URL: 
https://github.com/llvm/llvm-project/commit/1fe993c251966697d75123eb38fa710cdb346c8d
DIFF: 
https://github.com/llvm/llvm-project/commit/1fe993c251966697d75123eb38fa710cdb346c8d.diff

LOG: [clang][bytecode] Allocate operator new data as array (#146471)

Even if we only allocate one element, we still need to allocate it as a
single-element array. This matches what the current interpreter does.

Added: 
    

Modified: 
    clang/lib/AST/ByteCode/InterpBuiltin.cpp
    clang/lib/AST/ByteCode/Pointer.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/AST/ByteCode/InterpBuiltin.cpp 
b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
index 5c49e13a581e2..a73fc6c7bf2b3 100644
--- a/clang/lib/AST/ByteCode/InterpBuiltin.cpp
+++ b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
@@ -1531,34 +1531,21 @@ static bool interp__builtin_operator_new(InterpState 
&S, CodePtr OpPC,
   std::optional<PrimType> ElemT = S.getContext().classify(ElemType);
   DynamicAllocator &Allocator = S.getAllocator();
   if (ElemT) {
-    if (IsArray) {
-      Block *B = Allocator.allocate(NewCall, *ElemT, NumElems.getZExtValue(),
-                                    S.Ctx.getEvalID(),
-                                    DynamicAllocator::Form::Operator);
-      assert(B);
-      S.Stk.push<Pointer>(Pointer(B).atIndex(0));
-      return true;
-    }
-
-    const Descriptor *Desc = S.P.createDescriptor(
-        NewCall, *ElemT, ElemType.getTypePtr(), Descriptor::InlineDescMD,
-        /*IsConst=*/false, /*IsTemporary=*/false,
-        /*IsMutable=*/false);
-    Block *B = Allocator.allocate(Desc, S.getContext().getEvalID(),
-                                  DynamicAllocator::Form::Operator);
+    Block *B =
+        Allocator.allocate(NewCall, *ElemT, NumElems.getZExtValue(),
+                           S.Ctx.getEvalID(), 
DynamicAllocator::Form::Operator);
     assert(B);
-
-    S.Stk.push<Pointer>(B);
+    S.Stk.push<Pointer>(Pointer(B).atIndex(0));
     return true;
   }
 
   assert(!ElemT);
-  // Structs etc.
-  const Descriptor *Desc =
-      S.P.createDescriptor(NewCall, ElemType.getTypePtr(),
-                           IsArray ? std::nullopt : Descriptor::InlineDescMD);
 
+  // Composite arrays
   if (IsArray) {
+    const Descriptor *Desc =
+        S.P.createDescriptor(NewCall, ElemType.getTypePtr(),
+                             IsArray ? std::nullopt : 
Descriptor::InlineDescMD);
     Block *B =
         Allocator.allocate(Desc, NumElems.getZExtValue(), S.Ctx.getEvalID(),
                            DynamicAllocator::Form::Operator);
@@ -1567,10 +1554,17 @@ static bool interp__builtin_operator_new(InterpState 
&S, CodePtr OpPC,
     return true;
   }
 
+  // Records. Still allocate them as single-element arrays.
+  QualType AllocType = S.getASTContext().getConstantArrayType(
+      ElemType, NumElems, nullptr, ArraySizeModifier::Normal, 0);
+
+  const Descriptor *Desc =
+      S.P.createDescriptor(NewCall, AllocType.getTypePtr(),
+                           IsArray ? std::nullopt : Descriptor::InlineDescMD);
   Block *B = Allocator.allocate(Desc, S.getContext().getEvalID(),
                                 DynamicAllocator::Form::Operator);
   assert(B);
-  S.Stk.push<Pointer>(B);
+  S.Stk.push<Pointer>(Pointer(B).atIndex(0));
   return true;
 }
 

diff  --git a/clang/lib/AST/ByteCode/Pointer.cpp 
b/clang/lib/AST/ByteCode/Pointer.cpp
index f0b0384f32ac8..0ad47645d39cc 100644
--- a/clang/lib/AST/ByteCode/Pointer.cpp
+++ b/clang/lib/AST/ByteCode/Pointer.cpp
@@ -176,19 +176,8 @@ APValue Pointer::toAPValue(const ASTContext &ASTCtx) const 
{
   if (const auto *VD = Desc->asValueDecl())
     Base = VD;
   else if (const auto *E = Desc->asExpr()) {
-    // Create a DynamicAlloc base of the right type.
-    if (const auto *NewExpr = dyn_cast<CXXNewExpr>(E)) {
-      QualType AllocatedType;
-      if (NewExpr->isArray()) {
-        assert(Desc->isArray());
-        APInt ArraySize(64, static_cast<uint64_t>(Desc->getNumElems()),
-                        /*IsSigned=*/false);
-        AllocatedType =
-            ASTCtx.getConstantArrayType(NewExpr->getAllocatedType(), ArraySize,
-                                        nullptr, ArraySizeModifier::Normal, 0);
-      } else {
-        AllocatedType = NewExpr->getAllocatedType();
-      }
+    if (block()->isDynamic()) {
+      QualType AllocatedType = 
getDeclPtr().getFieldDesc()->getDataType(ASTCtx);
       // FIXME: Suboptimal counting of dynamic allocations. Move this to 
Context
       // or InterpState?
       static int ReportedDynamicAllocs = 0;


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

Reply via email to