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

>From 5ef01c0ea26bf2f71cd92ef7a3514556d1b8d06c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= <[email protected]>
Date: Thu, 27 Nov 2025 11:28:25 +0100
Subject: [PATCH] [clang][bytecode] Check for invalid record decls in
 IntPointer::atOffset

We can't access the RecordLayout of an invalid decl, so return failure
if that happens.
---
 clang/lib/AST/ByteCode/Interp.cpp   |  8 ++++++--
 clang/lib/AST/ByteCode/Pointer.cpp  |  7 +++++--
 clang/lib/AST/ByteCode/Pointer.h    |  3 ++-
 clang/test/AST/ByteCode/invalid.cpp | 12 ++++++++++++
 4 files changed, 25 insertions(+), 5 deletions(-)

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;
 };
 
diff --git a/clang/test/AST/ByteCode/invalid.cpp 
b/clang/test/AST/ByteCode/invalid.cpp
index 6b49cc44d64df..2851bea0a9020 100644
--- a/clang/test/AST/ByteCode/invalid.cpp
+++ b/clang/test/AST/ByteCode/invalid.cpp
@@ -111,3 +111,15 @@ namespace InvalidBitCast {
   struct s myx;
   int *myy = ((struct s *)&myx.a)->b;
 }
+
+namespace InvalidIntPtrRecord {
+  typedef __SIZE_TYPE__ Size_t;
+
+#define bufsize ((1LL << (8 * sizeof(Size_t) - 2)) - 256)
+
+  struct S {
+    short buf[bufsize]; // both-error {{array is too large}}
+    int a;
+  };
+  Size_t foo() { return (Size_t)(&((struct S *)0)->a); }
+}

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to