Author: Timm Baeder Date: 2025-11-27T13:06:15+01:00 New Revision: bd95a74a2c548867c004ec991defe276f9cbbf40
URL: https://github.com/llvm/llvm-project/commit/bd95a74a2c548867c004ec991defe276f9cbbf40 DIFF: https://github.com/llvm/llvm-project/commit/bd95a74a2c548867c004ec991defe276f9cbbf40.diff LOG: [clang][bytecode] Check for invalid record decls in IntPointer::atOffset (#169786) We can't access the RecordLayout of an invalid decl, so return failure if that happens. Fixes https://github.com/llvm/llvm-project/issues/167076 Added: Modified: clang/lib/AST/ByteCode/Interp.cpp clang/lib/AST/ByteCode/Pointer.cpp clang/lib/AST/ByteCode/Pointer.h clang/test/AST/ByteCode/invalid.cpp Removed: ################################################################################ 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
