Skip to content

[clang][bytecode] Start implementing __builtin_{,dynamic}_object_size #136478

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 20, 2025

Conversation

tbaederr
Copy link
Contributor

No description provided.

@llvmbot llvmbot added clang Clang issues not falling into any other category clang:frontend Language frontend issues, e.g. anything involving "Sema" clang:bytecode Issues for the clang bytecode constexpr interpreter labels Apr 20, 2025
@llvmbot
Copy link
Member

llvmbot commented Apr 20, 2025

@llvm/pr-subscribers-clang

Author: Timm Baeder (tbaederr)

Changes

Full diff: https://github.com/llvm/llvm-project/pull/136478.diff

3 Files Affected:

  • (modified) clang/lib/AST/ByteCode/Descriptor.h (+1-1)
  • (modified) clang/lib/AST/ByteCode/InterpBuiltin.cpp (+52)
  • (added) clang/test/AST/ByteCode/builtin-object-size.cpp (+14)
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..1eb210c0cac4f 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));
+  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), "");

@tbaederr tbaederr merged commit 90c845f into llvm:main Apr 20, 2025
11 checks passed
@llvm-ci
Copy link
Collaborator

llvm-ci commented Apr 20, 2025

LLVM Buildbot has detected a new failure on builder fuchsia-x86_64-linux running on fuchsia-debian-64-us-central1-a-1 while building clang at step 4 "annotate".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/11/builds/13415

Here is the relevant piece of the build log for the reference
Step 4 (annotate) failure: 'python ../llvm-zorg/zorg/buildbot/builders/annotated/fuchsia-linux.py ...' (failure)
...
[193/2494] Copying CXX header __type_traits/alignment_of.h
[194/2494] Copying CXX header __type_traits/can_extract_key.h
[195/2494] Copying CXX header __type_traits/common_reference.h
[196/2494] Generating header assert.h from /var/lib/buildbot/fuchsia-x86_64-linux/llvm-project/runtimes/../libc/include/assert.yaml
[197/2494] Generating header errno.h from /var/lib/buildbot/fuchsia-x86_64-linux/llvm-project/runtimes/../libc/include/errno.yaml
[198/2494] Generating header features.h from /var/lib/buildbot/fuchsia-x86_64-linux/llvm-project/runtimes/../libc/include/features.yaml
[199/2494] Generating header limits.h from /var/lib/buildbot/fuchsia-x86_64-linux/llvm-project/runtimes/../libc/include/limits.yaml
[200/2494] Generating header stdint.h from /var/lib/buildbot/fuchsia-x86_64-linux/llvm-project/runtimes/../libc/include/stdint.yaml
[201/2494] Generating header float.h from /var/lib/buildbot/fuchsia-x86_64-linux/llvm-project/runtimes/../libc/include/float.yaml
[202/2494] Building CXX object libc/src/stdlib/CMakeFiles/libc.src.stdlib.a64l.dir/a64l.cpp.obj
FAILED: libc/src/stdlib/CMakeFiles/libc.src.stdlib.a64l.dir/a64l.cpp.obj 
/var/lib/buildbot/fuchsia-x86_64-linux/build/llvm-build-_n9qsms1/./bin/clang++ --target=armv7em-none-eabi -DLIBC_NAMESPACE=__llvm_libc_21_0_0_git -I/var/lib/buildbot/fuchsia-x86_64-linux/llvm-project/libc -isystem /var/lib/buildbot/fuchsia-x86_64-linux/build/llvm-build-_n9qsms1/include/armv7em-unknown-none-eabi --target=armv7em-none-eabi -Wno-atomic-alignment "-Dvfprintf(stream, format, vlist)=vprintf(format, vlist)" "-Dfprintf(stream, format, ...)=printf(format)" -D_LIBCPP_PRINT=1 -mthumb -fPIC -fno-semantic-interposition -fvisibility-inlines-hidden -Werror=date-time -Werror=unguarded-availability-new -Wall -Wextra -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wmissing-field-initializers -Wimplicit-fallthrough -Wcovered-switch-default -Wno-noexcept-type -Wnon-virtual-dtor -Wdelete-non-virtual-dtor -Wsuggest-override -Wstring-conversion -Wmisleading-indentation -Wctad-maybe-unsupported -ffunction-sections -fdata-sections -ffile-prefix-map=/var/lib/buildbot/fuchsia-x86_64-linux/build/llvm-build-_n9qsms1/runtimes/runtimes-armv7em-none-eabi-bins=../../../../llvm-project -ffile-prefix-map=/var/lib/buildbot/fuchsia-x86_64-linux/llvm-project/= -no-canonical-prefixes -Os -DNDEBUG --target=armv7em-none-eabi -DLIBC_QSORT_IMPL=LIBC_QSORT_HEAP_SORT -DLIBC_TYPES_TIME_T_IS_32_BIT -DLIBC_ADD_NULL_CHECKS "-DLIBC_MATH=(LIBC_MATH_SKIP_ACCURATE_PASS | LIBC_MATH_SMALL_TABLES)" -fpie -ffreestanding -DLIBC_FULL_BUILD -nostdlibinc -ffixed-point -fno-builtin -fno-exceptions -fno-lax-vector-conversions -fno-unwind-tables -fno-asynchronous-unwind-tables -fno-rtti -ftrivial-auto-var-init=pattern -fno-omit-frame-pointer -Wall -Wextra -Werror -Wconversion -Wno-sign-conversion -Wdeprecated -Wno-c99-extensions -Wno-gnu-imaginary-constant -Wno-pedantic -Wimplicit-fallthrough -Wwrite-strings -Wextra-semi -Wnewline-eof -Wnonportable-system-include-path -Wstrict-prototypes -Wthread-safety -Wglobal-constructors -DLIBC_COPT_PUBLIC_PACKAGING -MD -MT libc/src/stdlib/CMakeFiles/libc.src.stdlib.a64l.dir/a64l.cpp.obj -MF libc/src/stdlib/CMakeFiles/libc.src.stdlib.a64l.dir/a64l.cpp.obj.d -o libc/src/stdlib/CMakeFiles/libc.src.stdlib.a64l.dir/a64l.cpp.obj -c /var/lib/buildbot/fuchsia-x86_64-linux/llvm-project/libc/src/stdlib/a64l.cpp
/var/lib/buildbot/fuchsia-x86_64-linux/llvm-project/libc/src/stdlib/a64l.cpp:22:18: error: unknown type name 'int32_t'
   22 | constexpr static int32_t b64_char_to_int(char ch) {
      |                  ^
/var/lib/buildbot/fuchsia-x86_64-linux/llvm-project/libc/src/stdlib/a64l.cpp:47:3: error: unknown type name 'int32_t'
   47 |   int32_t result = 0;
      |   ^
/var/lib/buildbot/fuchsia-x86_64-linux/llvm-project/libc/src/stdlib/a64l.cpp:50:5: error: unknown type name 'int32_t'
   50 |     int32_t cur_val = b64_char_to_int(s[i]);
      |     ^
3 errors generated.
[203/2494] Generating header setjmp.h from /var/lib/buildbot/fuchsia-x86_64-linux/llvm-project/runtimes/../libc/include/setjmp.yaml
[204/2494] Building CXX object libc/src/stdlib/baremetal/CMakeFiles/libc.src.stdlib.baremetal.abort.dir/abort.cpp.obj
[205/2494] Building CXX object libc/src/string/CMakeFiles/libc.src.string.strcmp.dir/strcmp.cpp.obj
[206/2494] Building CXX object libc/src/string/CMakeFiles/libc.src.string.memccpy.dir/memccpy.cpp.obj
[207/2494] Building CXX object libc/src/string/CMakeFiles/libc.src.string.strcoll.dir/strcoll.cpp.obj
[208/2494] Generating header stdckdint.h from /var/lib/buildbot/fuchsia-x86_64-linux/llvm-project/runtimes/../libc/include/stdckdint.yaml
[209/2494] Copying CXX header __algorithm/ranges_copy_if.h
[210/2494] Copying CXX header __algorithm/ranges_copy.h
[211/2494] Building CXX object libc/src/string/CMakeFiles/libc.src.string.memmem.dir/memmem.cpp.obj
[212/2494] Building CXX object libc/src/string/CMakeFiles/libc.src.string.memrchr.dir/memrchr.cpp.obj
[213/2494] Copying CXX header __algorithm/ranges_copy_backward.h
[214/2494] Building CXX object libc/src/math/generic/CMakeFiles/libc.src.math.generic.inv_trigf_utils.dir/inv_trigf_utils.cpp.obj
[215/2494] Building CXX object libc/startup/baremetal/CMakeFiles/libc.startup.baremetal.fini.dir/fini.cpp.obj
[216/2494] Copying CXX header __algorithm/shift_left.h
[217/2494] Copying CXX header __algorithm/ranges_find_if_not.h
[218/2494] Copying CXX header __bit/bit_floor.h
[219/2494] Copying CXX header __algorithm/make_projected.h
[220/2494] Generating header complex.h from /var/lib/buildbot/fuchsia-x86_64-linux/llvm-project/runtimes/../libc/include/complex.yaml
[221/2494] Building CXX object libc/src/string/CMakeFiles/libc.src.string.strcoll_l.dir/strcoll_l.cpp.obj
[222/2494] Building CXX object libc/src/stdlib/CMakeFiles/libc.src.stdlib.labs.dir/labs.cpp.obj
[223/2494] Generating header wchar.h from /var/lib/buildbot/fuchsia-x86_64-linux/llvm-project/runtimes/../libc/include/wchar.yaml
[224/2494] Building CXX object libc/src/string/CMakeFiles/libc.src.string.strncpy.dir/strncpy.cpp.obj
[225/2494] Generating header inttypes.h from /var/lib/buildbot/fuchsia-x86_64-linux/llvm-project/runtimes/../libc/include/inttypes.yaml
[226/2494] Generating header strings.h from /var/lib/buildbot/fuchsia-x86_64-linux/llvm-project/runtimes/../libc/include/strings.yaml
[227/2494] Building CXX object libc/src/stdlib/CMakeFiles/libc.src.stdlib.abs.dir/abs.cpp.obj
[228/2494] Building CXX object libc/src/stdio/baremetal/CMakeFiles/libc.src.stdio.baremetal.putchar.dir/putchar.cpp.obj
[229/2494] Building CXX object libc/startup/baremetal/CMakeFiles/libc.startup.baremetal.init.dir/init.cpp.obj
Step 6 (build) failure: build (failure)
...
[193/2494] Copying CXX header __type_traits/alignment_of.h
[194/2494] Copying CXX header __type_traits/can_extract_key.h
[195/2494] Copying CXX header __type_traits/common_reference.h
[196/2494] Generating header assert.h from /var/lib/buildbot/fuchsia-x86_64-linux/llvm-project/runtimes/../libc/include/assert.yaml
[197/2494] Generating header errno.h from /var/lib/buildbot/fuchsia-x86_64-linux/llvm-project/runtimes/../libc/include/errno.yaml
[198/2494] Generating header features.h from /var/lib/buildbot/fuchsia-x86_64-linux/llvm-project/runtimes/../libc/include/features.yaml
[199/2494] Generating header limits.h from /var/lib/buildbot/fuchsia-x86_64-linux/llvm-project/runtimes/../libc/include/limits.yaml
[200/2494] Generating header stdint.h from /var/lib/buildbot/fuchsia-x86_64-linux/llvm-project/runtimes/../libc/include/stdint.yaml
[201/2494] Generating header float.h from /var/lib/buildbot/fuchsia-x86_64-linux/llvm-project/runtimes/../libc/include/float.yaml
[202/2494] Building CXX object libc/src/stdlib/CMakeFiles/libc.src.stdlib.a64l.dir/a64l.cpp.obj
FAILED: libc/src/stdlib/CMakeFiles/libc.src.stdlib.a64l.dir/a64l.cpp.obj 
/var/lib/buildbot/fuchsia-x86_64-linux/build/llvm-build-_n9qsms1/./bin/clang++ --target=armv7em-none-eabi -DLIBC_NAMESPACE=__llvm_libc_21_0_0_git -I/var/lib/buildbot/fuchsia-x86_64-linux/llvm-project/libc -isystem /var/lib/buildbot/fuchsia-x86_64-linux/build/llvm-build-_n9qsms1/include/armv7em-unknown-none-eabi --target=armv7em-none-eabi -Wno-atomic-alignment "-Dvfprintf(stream, format, vlist)=vprintf(format, vlist)" "-Dfprintf(stream, format, ...)=printf(format)" -D_LIBCPP_PRINT=1 -mthumb -fPIC -fno-semantic-interposition -fvisibility-inlines-hidden -Werror=date-time -Werror=unguarded-availability-new -Wall -Wextra -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wmissing-field-initializers -Wimplicit-fallthrough -Wcovered-switch-default -Wno-noexcept-type -Wnon-virtual-dtor -Wdelete-non-virtual-dtor -Wsuggest-override -Wstring-conversion -Wmisleading-indentation -Wctad-maybe-unsupported -ffunction-sections -fdata-sections -ffile-prefix-map=/var/lib/buildbot/fuchsia-x86_64-linux/build/llvm-build-_n9qsms1/runtimes/runtimes-armv7em-none-eabi-bins=../../../../llvm-project -ffile-prefix-map=/var/lib/buildbot/fuchsia-x86_64-linux/llvm-project/= -no-canonical-prefixes -Os -DNDEBUG --target=armv7em-none-eabi -DLIBC_QSORT_IMPL=LIBC_QSORT_HEAP_SORT -DLIBC_TYPES_TIME_T_IS_32_BIT -DLIBC_ADD_NULL_CHECKS "-DLIBC_MATH=(LIBC_MATH_SKIP_ACCURATE_PASS | LIBC_MATH_SMALL_TABLES)" -fpie -ffreestanding -DLIBC_FULL_BUILD -nostdlibinc -ffixed-point -fno-builtin -fno-exceptions -fno-lax-vector-conversions -fno-unwind-tables -fno-asynchronous-unwind-tables -fno-rtti -ftrivial-auto-var-init=pattern -fno-omit-frame-pointer -Wall -Wextra -Werror -Wconversion -Wno-sign-conversion -Wdeprecated -Wno-c99-extensions -Wno-gnu-imaginary-constant -Wno-pedantic -Wimplicit-fallthrough -Wwrite-strings -Wextra-semi -Wnewline-eof -Wnonportable-system-include-path -Wstrict-prototypes -Wthread-safety -Wglobal-constructors -DLIBC_COPT_PUBLIC_PACKAGING -MD -MT libc/src/stdlib/CMakeFiles/libc.src.stdlib.a64l.dir/a64l.cpp.obj -MF libc/src/stdlib/CMakeFiles/libc.src.stdlib.a64l.dir/a64l.cpp.obj.d -o libc/src/stdlib/CMakeFiles/libc.src.stdlib.a64l.dir/a64l.cpp.obj -c /var/lib/buildbot/fuchsia-x86_64-linux/llvm-project/libc/src/stdlib/a64l.cpp
/var/lib/buildbot/fuchsia-x86_64-linux/llvm-project/libc/src/stdlib/a64l.cpp:22:18: error: unknown type name 'int32_t'
   22 | constexpr static int32_t b64_char_to_int(char ch) {
      |                  ^
/var/lib/buildbot/fuchsia-x86_64-linux/llvm-project/libc/src/stdlib/a64l.cpp:47:3: error: unknown type name 'int32_t'
   47 |   int32_t result = 0;
      |   ^
/var/lib/buildbot/fuchsia-x86_64-linux/llvm-project/libc/src/stdlib/a64l.cpp:50:5: error: unknown type name 'int32_t'
   50 |     int32_t cur_val = b64_char_to_int(s[i]);
      |     ^
3 errors generated.
[203/2494] Generating header setjmp.h from /var/lib/buildbot/fuchsia-x86_64-linux/llvm-project/runtimes/../libc/include/setjmp.yaml
[204/2494] Building CXX object libc/src/stdlib/baremetal/CMakeFiles/libc.src.stdlib.baremetal.abort.dir/abort.cpp.obj
[205/2494] Building CXX object libc/src/string/CMakeFiles/libc.src.string.strcmp.dir/strcmp.cpp.obj
[206/2494] Building CXX object libc/src/string/CMakeFiles/libc.src.string.memccpy.dir/memccpy.cpp.obj
[207/2494] Building CXX object libc/src/string/CMakeFiles/libc.src.string.strcoll.dir/strcoll.cpp.obj
[208/2494] Generating header stdckdint.h from /var/lib/buildbot/fuchsia-x86_64-linux/llvm-project/runtimes/../libc/include/stdckdint.yaml
[209/2494] Copying CXX header __algorithm/ranges_copy_if.h
[210/2494] Copying CXX header __algorithm/ranges_copy.h
[211/2494] Building CXX object libc/src/string/CMakeFiles/libc.src.string.memmem.dir/memmem.cpp.obj
[212/2494] Building CXX object libc/src/string/CMakeFiles/libc.src.string.memrchr.dir/memrchr.cpp.obj
[213/2494] Copying CXX header __algorithm/ranges_copy_backward.h
[214/2494] Building CXX object libc/src/math/generic/CMakeFiles/libc.src.math.generic.inv_trigf_utils.dir/inv_trigf_utils.cpp.obj
[215/2494] Building CXX object libc/startup/baremetal/CMakeFiles/libc.startup.baremetal.fini.dir/fini.cpp.obj
[216/2494] Copying CXX header __algorithm/shift_left.h
[217/2494] Copying CXX header __algorithm/ranges_find_if_not.h
[218/2494] Copying CXX header __bit/bit_floor.h
[219/2494] Copying CXX header __algorithm/make_projected.h
[220/2494] Generating header complex.h from /var/lib/buildbot/fuchsia-x86_64-linux/llvm-project/runtimes/../libc/include/complex.yaml
[221/2494] Building CXX object libc/src/string/CMakeFiles/libc.src.string.strcoll_l.dir/strcoll_l.cpp.obj
[222/2494] Building CXX object libc/src/stdlib/CMakeFiles/libc.src.stdlib.labs.dir/labs.cpp.obj
[223/2494] Generating header wchar.h from /var/lib/buildbot/fuchsia-x86_64-linux/llvm-project/runtimes/../libc/include/wchar.yaml
[224/2494] Building CXX object libc/src/string/CMakeFiles/libc.src.string.strncpy.dir/strncpy.cpp.obj
[225/2494] Generating header inttypes.h from /var/lib/buildbot/fuchsia-x86_64-linux/llvm-project/runtimes/../libc/include/inttypes.yaml
[226/2494] Generating header strings.h from /var/lib/buildbot/fuchsia-x86_64-linux/llvm-project/runtimes/../libc/include/strings.yaml
[227/2494] Building CXX object libc/src/stdlib/CMakeFiles/libc.src.stdlib.abs.dir/abs.cpp.obj
[228/2494] Building CXX object libc/src/stdio/baremetal/CMakeFiles/libc.src.stdio.baremetal.putchar.dir/putchar.cpp.obj
[229/2494] Building CXX object libc/startup/baremetal/CMakeFiles/libc.startup.baremetal.init.dir/init.cpp.obj

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:bytecode Issues for the clang bytecode constexpr interpreter clang:frontend Language frontend issues, e.g. anything involving "Sema" clang Clang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants