https://github.com/tbaederr updated 
https://github.com/llvm/llvm-project/pull/136478

>From 8327fc0f0d06c39386b285b16902838b2dc0af0c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= <tbae...@redhat.com>
Date: Sat, 19 Apr 2025 17:29:16 +0200
Subject: [PATCH] [clang][bytecode] Start implementing
 __builtin_{,dynamic}_object_size

---
 clang/lib/AST/ByteCode/Descriptor.h           |  2 +-
 clang/lib/AST/ByteCode/InterpBuiltin.cpp      | 52 +++++++++++++++++++
 .../test/AST/ByteCode/builtin-object-size.cpp | 14 +++++
 3 files changed, 67 insertions(+), 1 deletion(-)
 create mode 100644 clang/test/AST/ByteCode/builtin-object-size.cpp

diff --git a/clang/lib/AST/ByteCode/Descriptor.h 
b/clang/lib/AST/ByteCode/Descriptor.h
index a0705cc8c377f..532b407c2c788 100644
--- a/clang/lib/AST/ByteCode/Descriptor.h
+++ b/clang/lib/AST/ByteCode/Descriptor.h
@@ -265,7 +265,7 @@ struct Descriptor final {
   bool isUnknownSizeArray() const { return Size == UnknownSizeMark; }
 
   /// Checks if the descriptor is of a primitive.
-  bool isPrimitive() const { return !IsArray && !ElemRecord && !IsDummy; }
+  bool isPrimitive() const { return !IsArray && !ElemRecord && PrimT; }
 
   /// Checks if the descriptor is of an array.
   bool isArray() const { return IsArray; }
diff --git a/clang/lib/AST/ByteCode/InterpBuiltin.cpp 
b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
index 34553301ef630..aaf0f3f019b94 100644
--- a/clang/lib/AST/ByteCode/InterpBuiltin.cpp
+++ b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
@@ -2179,6 +2179,52 @@ static bool interp__builtin_memchr(InterpState &S, 
CodePtr OpPC,
   return true;
 }
 
+static unsigned computeFullDescSize(const ASTContext &ASTCtx,
+                                    const Descriptor *Desc) {
+
+  if (Desc->isPrimitive())
+    return ASTCtx.getTypeSizeInChars(Desc->getType()).getQuantity();
+
+  if (Desc->isArray())
+    return ASTCtx.getTypeSizeInChars(Desc->getElemQualType()).getQuantity() *
+           Desc->getNumElems();
+
+  if (Desc->isRecord())
+    return ASTCtx.getTypeSizeInChars(Desc->getType()).getQuantity();
+
+  llvm_unreachable("Unhandled descriptor type");
+  return 0;
+}
+
+static bool interp__builtin_object_size(InterpState &S, CodePtr OpPC,
+                                        const InterpFrame *Frame,
+                                        const Function *Func,
+                                        const CallExpr *Call) {
+  PrimType KindT = *S.getContext().classify(Call->getArg(1));
+  [[maybe_unused]] unsigned Kind = peekToAPSInt(S.Stk, KindT).getZExtValue();
+
+  assert(Kind <= 3 && "unexpected kind");
+
+  const Pointer &Ptr =
+      S.Stk.peek<Pointer>(align(primSize(KindT)) + align(primSize(PT_Ptr)));
+
+  if (Ptr.isZero())
+    return false;
+
+  const Descriptor *DeclDesc = Ptr.getDeclDesc();
+  if (!DeclDesc)
+    return false;
+
+  const ASTContext &ASTCtx = S.getASTContext();
+
+  unsigned ByteOffset = 0;
+  unsigned FullSize = computeFullDescSize(ASTCtx, DeclDesc);
+
+  pushInteger(S, FullSize - ByteOffset, Call->getType());
+
+  return true;
+}
+
 bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const Function *F,
                       const CallExpr *Call, uint32_t BuiltinID) {
   if (!S.getASTContext().BuiltinInfo.isConstantEvaluated(BuiltinID))
@@ -2681,6 +2727,12 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, 
const Function *F,
       return false;
     break;
 
+  case Builtin::BI__builtin_object_size:
+  case Builtin::BI__builtin_dynamic_object_size:
+    if (!interp__builtin_object_size(S, OpPC, Frame, F, Call))
+      return false;
+    break;
+
   default:
     S.FFDiag(S.Current->getLocation(OpPC),
              diag::note_invalid_subexpr_in_const_expr)
diff --git a/clang/test/AST/ByteCode/builtin-object-size.cpp 
b/clang/test/AST/ByteCode/builtin-object-size.cpp
new file mode 100644
index 0000000000000..62bb1642c5301
--- /dev/null
+++ b/clang/test/AST/ByteCode/builtin-object-size.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -fexperimental-new-constant-interpreter 
-verify=both,expected %s
+// RUN: %clang_cc1                                         -verify=both,ref    
  %s
+
+// both-no-diagnostics
+
+int a;
+static_assert(__builtin_object_size(&a, 0) == sizeof(int), "");
+float f;
+static_assert(__builtin_object_size(&f, 0) == sizeof(float), "");
+int arr[2];
+static_assert(__builtin_object_size(&arr, 0) == (sizeof(int)*2), "");
+
+float arrf[2];
+static_assert(__builtin_object_size(&arrf, 0) == (sizeof(float)*2), "");

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

Reply via email to