[clang] 90c845f - [clang][bytecode] Start implementing __builtin_{,dynamic}_object_size (#136478)
via cfe-commits
cfe-commits at lists.llvm.org
Sun Apr 20 03:20:25 PDT 2025
Author: Timm Baeder
Date: 2025-04-20T12:20:21+02:00
New Revision: 90c845fb3babac387688dfa6d560d3ba8ed8e340
URL: https://github.com/llvm/llvm-project/commit/90c845fb3babac387688dfa6d560d3ba8ed8e340
DIFF: https://github.com/llvm/llvm-project/commit/90c845fb3babac387688dfa6d560d3ba8ed8e340.diff
LOG: [clang][bytecode] Start implementing __builtin_{,dynamic}_object_size (#136478)
Added:
clang/test/AST/ByteCode/builtin-object-size.cpp
Modified:
clang/lib/AST/ByteCode/Descriptor.h
clang/lib/AST/ByteCode/InterpBuiltin.cpp
Removed:
################################################################################
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), "");
More information about the cfe-commits
mailing list