Author: Timm Baeder Date: 2026-10-30T12:56:48+01:00 New Revision: 3950f2b61b82cf1d75c4b6c6d76cc72eda793167
URL: https://github.com/llvm/llvm-project/commit/3950f2b61b82cf1d75c4b6c6d76cc72eda793167 DIFF: https://github.com/llvm/llvm-project/commit/3950f2b61b82cf1d75c4b6c6d76cc72eda793167.diff LOG: [clang][bytecode] Fix bitcast from nullptr_t to array (#237165) First, we need to make sure that initialize() on an arrayroot pointer does not initialize the first element of the array; second, it is possible for such an array to not have an associated FieldDecl, as is the case in the materialized temporary array in the attached reproducer. Added: Modified: clang/lib/AST/ByteCode/Compiler.cpp clang/lib/AST/ByteCode/EvaluationResult.cpp clang/lib/AST/ByteCode/Pointer.cpp clang/lib/AST/ByteCode/Pointer.h clang/test/AST/ByteCode/builtin-bit-cast.cpp Removed: ################################################################################ diff --git a/clang/lib/AST/ByteCode/Compiler.cpp b/clang/lib/AST/ByteCode/Compiler.cpp index 079c24344f21a..71f761f58aed2 100644 --- a/clang/lib/AST/ByteCode/Compiler.cpp +++ b/clang/lib/AST/ByteCode/Compiler.cpp @@ -1310,7 +1310,9 @@ bool Compiler<Emitter>::VisitImaginaryLiteral(const ImaginaryLiteral *E) { return false; if (!this->emitInitElem(SubExprT, 0, SubExpr)) return false; - return this->visitArrayElemInit(1, SubExpr, SubExprT); + if (!this->visitArrayElemInit(1, SubExpr, SubExprT)) + return false; + return this->emitFinishInit(E); } template <class Emitter> @@ -1884,7 +1886,7 @@ bool Compiler<Emitter>::VisitComplexBinOp(const BinaryOperator *E) { return this->emitPopPtr(E); } } - return true; + return this->emitFinishInit(E); } template <class Emitter> diff --git a/clang/lib/AST/ByteCode/EvaluationResult.cpp b/clang/lib/AST/ByteCode/EvaluationResult.cpp index 70f64568483fd..d6dbd8c80f32f 100644 --- a/clang/lib/AST/ByteCode/EvaluationResult.cpp +++ b/clang/lib/AST/ByteCode/EvaluationResult.cpp @@ -62,7 +62,8 @@ static bool CheckArrayInitialized(InterpState &S, SourceLocation Loc, if (BaseDesc->isPrimitiveArray()) { if (BasePtr.allElementsInitialized()) return true; - DiagnoseUninitializedSubobject(S, Loc, BasePtr.getField()); + if (const FieldDecl *F = BasePtr.getField()) + DiagnoseUninitializedSubobject(S, Loc, F); return false; } const Descriptor *ElemDesc = BaseDesc->ElemDesc; diff --git a/clang/lib/AST/ByteCode/Pointer.cpp b/clang/lib/AST/ByteCode/Pointer.cpp index 3890f2ed2f91d..35ffa4e68373a 100644 --- a/clang/lib/AST/ByteCode/Pointer.cpp +++ b/clang/lib/AST/ByteCode/Pointer.cpp @@ -814,7 +814,7 @@ void PtrView::initialize() const { const Descriptor *Desc = getFieldDesc(); assert(Desc); - if (Desc->isPrimitiveArray()) { + if (Offset != Base && Desc->isPrimitiveArray()) { if (Desc->getNumElems() != 0) initializeElement(getIndex()); return; diff --git a/clang/lib/AST/ByteCode/Pointer.h b/clang/lib/AST/ByteCode/Pointer.h index 0fc540cdd8858..8cedb529b73a0 100644 --- a/clang/lib/AST/ByteCode/Pointer.h +++ b/clang/lib/AST/ByteCode/Pointer.h @@ -315,7 +315,7 @@ struct PtrView { assert(Pointee && "Cannot check if null pointer was initialized"); const Descriptor *Desc = getFieldDesc(); assert(Desc); - if (Desc->isPrimitiveArray()) + if (Offset != Base && Desc->isPrimitiveArray()) return isElementInitialized(getIndex()); if (Base == 0) diff --git a/clang/test/AST/ByteCode/builtin-bit-cast.cpp b/clang/test/AST/ByteCode/builtin-bit-cast.cpp index 2aaf84f9130c7..8588b4217a4d9 100644 --- a/clang/test/AST/ByteCode/builtin-bit-cast.cpp +++ b/clang/test/AST/ByteCode/builtin-bit-cast.cpp @@ -616,3 +616,11 @@ namespace StringInDoBitCast { static_assert(foo<b32>(0x42), ""); // both-error {{not an integral constant expression}} \ // both-note {{in call to}} } + +namespace nullptrToArray { + typedef decltype(__builtin_bit_cast(unsigned char[sizeof(nullptr)], nullptr)) footype; + static_assert(__builtin_bit_cast(footype, nullptr) == nullptr); // both-error {{failed due to requirement}} + static_assert(__builtin_bit_cast(footype, nullptr)[0] == 0); // both-error {{not an integral constant expression}} \ + // both-note {{read of uninitialized object}} \ + // both-note {{temporary created here}} +} _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
