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