Skip to content

Conversation

@tbaederr
Copy link
Contributor

We can't access the RecordLayout of an invalid decl, so return failure if that happens.

Fixes #167076

@tbaederr tbaederr marked this pull request as ready for review November 27, 2025 10:29
@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 Nov 27, 2025
@llvmbot
Copy link
Member

llvmbot commented Nov 27, 2025

@llvm/pr-subscribers-clang

Author: Timm Baeder (tbaederr)

Changes

We can't access the RecordLayout of an invalid decl, so return failure if that happens.

Fixes #167076


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

3 Files Affected:

  • (modified) clang/lib/AST/ByteCode/Interp.cpp (+6-2)
  • (modified) clang/lib/AST/ByteCode/Pointer.cpp (+5-2)
  • (modified) clang/lib/AST/ByteCode/Pointer.h (+2-1)
diff --git a/clang/lib/AST/ByteCode/Interp.cpp b/clang/lib/AST/ByteCode/Interp.cpp
index c3210d7119b40..80ef656dc6285 100644
--- a/clang/lib/AST/ByteCode/Interp.cpp
+++ b/clang/lib/AST/ByteCode/Interp.cpp
@@ -1435,8 +1435,12 @@ static bool getField(InterpState &S, CodePtr OpPC, const Pointer &Ptr,
     return false;
 
   if (Ptr.isIntegralPointer()) {
-    S.Stk.push<Pointer>(Ptr.asIntPointer().atOffset(S.getASTContext(), Off));
-    return true;
+    if (std::optional<IntPointer> IntPtr =
+            Ptr.asIntPointer().atOffset(S.getASTContext(), Off)) {
+      S.Stk.push<Pointer>(std::move(*IntPtr));
+      return true;
+    }
+    return false;
   }
 
   if (!Ptr.isBlockPointer()) {
diff --git a/clang/lib/AST/ByteCode/Pointer.cpp b/clang/lib/AST/ByteCode/Pointer.cpp
index 25719bd6f0f91..00e74db5655d6 100644
--- a/clang/lib/AST/ByteCode/Pointer.cpp
+++ b/clang/lib/AST/ByteCode/Pointer.cpp
@@ -895,8 +895,8 @@ std::optional<APValue> Pointer::toRValue(const Context &Ctx,
   return Result;
 }
 
-IntPointer IntPointer::atOffset(const ASTContext &ASTCtx,
-                                unsigned Offset) const {
+std::optional<IntPointer> IntPointer::atOffset(const ASTContext &ASTCtx,
+                                               unsigned Offset) const {
   if (!this->Desc)
     return *this;
   const Record *R = this->Desc->ElemRecord;
@@ -914,6 +914,9 @@ IntPointer IntPointer::atOffset(const ASTContext &ASTCtx,
     return *this;
 
   const FieldDecl *FD = F->Decl;
+  if (FD->getParent()->isInvalidDecl())
+    return std::nullopt;
+
   const ASTRecordLayout &Layout = ASTCtx.getASTRecordLayout(FD->getParent());
   unsigned FieldIndex = FD->getFieldIndex();
   uint64_t FieldOffset =
diff --git a/clang/lib/AST/ByteCode/Pointer.h b/clang/lib/AST/ByteCode/Pointer.h
index 57c8e45609027..0978090ba8b19 100644
--- a/clang/lib/AST/ByteCode/Pointer.h
+++ b/clang/lib/AST/ByteCode/Pointer.h
@@ -47,7 +47,8 @@ struct IntPointer {
   const Descriptor *Desc;
   uint64_t Value;
 
-  IntPointer atOffset(const ASTContext &ASTCtx, unsigned Offset) const;
+  std::optional<IntPointer> atOffset(const ASTContext &ASTCtx,
+                                     unsigned Offset) const;
   IntPointer baseCast(const ASTContext &ASTCtx, unsigned BaseOffset) const;
 };
 

We can't access the RecordLayout of an invalid decl, so return failure
if that happens.
@tbaederr tbaederr force-pushed the intptr-atoffset-invalid-record branch from 273dd33 to 5ef01c0 Compare November 27, 2025 10:31
@tbaederr tbaederr merged commit bd95a74 into llvm:main Nov 27, 2025
10 checks passed
@llvm-ci
Copy link
Collaborator

llvm-ci commented Nov 27, 2025

LLVM Buildbot has detected a new failure on builder clang-armv8-quick running on linaro-clang-armv8-quick while building clang at step 5 "ninja check 1".

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

Here is the relevant piece of the build log for the reference
Step 5 (ninja check 1) failure: stage 1 checked (failure)
******************** TEST 'Clang :: AST/ByteCode/invalid.cpp' FAILED ********************
Exit Code: 1

Command Output (stdout):
--
# RUN: at line 1
/home/tcwg-buildbot/worker/clang-armv8-quick/stage1/bin/clang -cc1 -internal-isystem /home/tcwg-buildbot/worker/clang-armv8-quick/stage1/lib/clang/22/include -nostdsysteminc -fcxx-exceptions -std=c++20 -fexperimental-new-constant-interpreter -verify=expected,both /home/tcwg-buildbot/worker/clang-armv8-quick/llvm/clang/test/AST/ByteCode/invalid.cpp
# executed command: /home/tcwg-buildbot/worker/clang-armv8-quick/stage1/bin/clang -cc1 -internal-isystem /home/tcwg-buildbot/worker/clang-armv8-quick/stage1/lib/clang/22/include -nostdsysteminc -fcxx-exceptions -std=c++20 -fexperimental-new-constant-interpreter -verify=expected,both /home/tcwg-buildbot/worker/clang-armv8-quick/llvm/clang/test/AST/ByteCode/invalid.cpp
# .---command stderr------------
# | error: diagnostics with 'error' severity expected but not seen: 
# |   File /home/tcwg-buildbot/worker/clang-armv8-quick/llvm/clang/test/AST/ByteCode/invalid.cpp Line 121 'both-error': array is too large
# | 1 error generated.
# `-----------------------------
# error: command failed with exit status: 1

--

********************


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.

[clang][bytecode] assertion failure when computing offset of struct member after huge array

3 participants