https://github.com/tbaederr created https://github.com/llvm/llvm-project/pull/155157
We need to use the base offset in both cases. Also, add additional assertions to make sure we don't miss this case again. Fixes #155132 >From c466589f26780f35a317a6743ea675e89ea73764 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= <[email protected]> Date: Sun, 24 Aug 2025 12:25:34 +0200 Subject: [PATCH] [clang][bytecode] Fix incorrect offset in elem() We need to use the base offset in both cases. Also, add additional assertions to make sure we don't miss this case again. Fixes #155132 --- clang/lib/AST/ByteCode/EvaluationResult.cpp | 4 ++-- clang/lib/AST/ByteCode/Pointer.h | 17 +++++++++++------ clang/test/AST/ByteCode/invalid.cpp | 8 ++++++++ 3 files changed, 21 insertions(+), 8 deletions(-) diff --git a/clang/lib/AST/ByteCode/EvaluationResult.cpp b/clang/lib/AST/ByteCode/EvaluationResult.cpp index b11531f4296a2..5110e243d167c 100644 --- a/clang/lib/AST/ByteCode/EvaluationResult.cpp +++ b/clang/lib/AST/ByteCode/EvaluationResult.cpp @@ -178,8 +178,8 @@ bool EvaluationResult::checkFullyInitialized(InterpState &S, static void collectBlocks(const Pointer &Ptr, llvm::SetVector<const Block *> &Blocks) { auto isUsefulPtr = [](const Pointer &P) -> bool { - return P.isLive() && !P.isZero() && !P.isDummy() && P.isDereferencable() && - !P.isUnknownSizeArray() && !P.isOnePastEnd(); + return P.isLive() && P.isBlockPointer() && !P.isZero() && !P.isDummy() && + P.isDereferencable() && !P.isUnknownSizeArray() && !P.isOnePastEnd(); }; if (!isUsefulPtr(Ptr)) diff --git a/clang/lib/AST/ByteCode/Pointer.h b/clang/lib/AST/ByteCode/Pointer.h index 0ce54ab0a17df..825a92b4424cb 100644 --- a/clang/lib/AST/ByteCode/Pointer.h +++ b/clang/lib/AST/ByteCode/Pointer.h @@ -696,15 +696,20 @@ class Pointer { assert(asBlockPointer().Pointee); assert(isDereferencable()); assert(getFieldDesc()->isPrimitiveArray()); + assert(I < getFieldDesc()->getNumElems()); unsigned ElemByteOffset = I * getFieldDesc()->getElemSize(); - if (isArrayRoot()) - return *reinterpret_cast<T *>(asBlockPointer().Pointee->rawData() + - asBlockPointer().Base + sizeof(InitMapPtr) + - ElemByteOffset); + if (isArrayRoot()) { + unsigned ReadOffset = BS.Base + sizeof(InitMapPtr) + ElemByteOffset; + assert(ReadOffset + sizeof(T) <= + BS.Pointee->getDescriptor()->getAllocSize()); + return *reinterpret_cast<T *>(BS.Pointee->rawData() + ReadOffset); + } - return *reinterpret_cast<T *>(asBlockPointer().Pointee->rawData() + Offset + - ElemByteOffset); + unsigned ReadOffset = BS.Base + ElemByteOffset; + assert(ReadOffset + sizeof(T) <= + BS.Pointee->getDescriptor()->getAllocSize()); + return *reinterpret_cast<T *>(BS.Pointee->rawData() + ReadOffset); } /// Whether this block can be read from at all. This is only true for diff --git a/clang/test/AST/ByteCode/invalid.cpp b/clang/test/AST/ByteCode/invalid.cpp index 2a6c2d13e8467..affb40eada870 100644 --- a/clang/test/AST/ByteCode/invalid.cpp +++ b/clang/test/AST/ByteCode/invalid.cpp @@ -58,3 +58,11 @@ namespace Casts { /// Just make sure this doesn't crash. float PR9558 = reinterpret_cast<const float&>("asd"); } + + +/// This used to crash in collectBlock(). +struct S { +}; +S s; +S *sp[2] = {&s, &s}; +S *&spp = sp[1]; _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
