https://github.com/Nemi26 updated https://github.com/llvm/llvm-project/pull/233008
>From 15354d3c0ef6aa92ec350211317f3a0fce2a3a6e Mon Sep 17 00:00:00 2001 From: Nemi26 <[email protected]> Date: Sat, 17 Oct 2026 05:14:19 +0200 Subject: [PATCH] [clang] Zero-initialize matrix types from empty init lists in constant evaluation Both constant evaluators assumed that a matrix initializer list holds one initializer per element, which only holds for HLSL. Outside HLSL, `m{}` is the only initializer list a matrix accepts, and evaluating it crashed, for example when constant-initializing a namespace-scope `m3 x{};` or in a constexpr function in C++23. Value-initialize the matrix to zero for an empty initializer list, in ExprConstant and in the bytecode interpreter. The bytecode interpreter now also value-initializes a matrix for `m3()`, as ExprConstant does. Fixes #232999 Co-Authored-By: Claude Opus 5.5 <[email protected]> --- clang/docs/ReleaseNotes.md | 2 ++ clang/lib/AST/ByteCode/Compiler.cpp | 14 +++++++++--- clang/lib/AST/ExprConstant.cpp | 19 ++++++++++++++++ clang/test/SemaCXX/matrix-type-constexpr.cpp | 23 ++++++++++++++++++++ 4 files changed, 55 insertions(+), 3 deletions(-) create mode 100644 clang/test/SemaCXX/matrix-type-constexpr.cpp diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md index 7d3f0eb702553d..a90ff6ad8b6e68 100644 --- a/clang/docs/ReleaseNotes.md +++ b/clang/docs/ReleaseNotes.md @@ -1076,6 +1076,8 @@ features cannot lower the translation-unit ABI level; Objective-C `@implementation` that was ended by a nested `@interface`, `@protocol` or `@implementation` before its `@end`. (#GH209503) - Fixed use-after-free with annotate attribute on a C++ class method with a this-adjusting thunk. +- Fixed a crash when the constant evaluator initialized a `matrix_type` + variable with an empty initializer list, such as `m{}`. (#GH232999) ### OpenACC Specific Changes diff --git a/clang/lib/AST/ByteCode/Compiler.cpp b/clang/lib/AST/ByteCode/Compiler.cpp index 40b36b4e715a10..aa7da18d1da64b 100644 --- a/clang/lib/AST/ByteCode/Compiler.cpp +++ b/clang/lib/AST/ByteCode/Compiler.cpp @@ -2661,7 +2661,7 @@ bool Compiler<Emitter>::visitInitList(ArrayRef<const Expr *> Inits, if (const auto *MT = QT->getAs<ConstantMatrixType>()) { unsigned NumElems = MT->getNumElementsFlattened(); - assert(Inits.size() == NumElems); + assert(Inits.empty() || Inits.size() == NumElems); QualType ElemQT = MT->getElementType(); PrimType ElemT = classifyPrim(ElemQT); @@ -2670,8 +2670,12 @@ bool Compiler<Emitter>::visitInitList(ArrayRef<const Expr *> Inits, // the matrix APValue convention and therefore no index remapping is // required. for (unsigned I = 0; I != NumElems; ++I) { - if (!this->visit(Inits[I])) + if (Inits.empty()) { + if (!this->visitZeroInitializer(ElemT, ElemQT, E)) + return false; + } else if (!this->visit(Inits[I])) { return false; + } if (!this->emitInitElem(ElemT, I, E)) return false; } @@ -4202,7 +4206,8 @@ bool Compiler<Emitter>::VisitCXXScalarValueInitExpr( if (OptPrimType T = classify(Ty)) return this->visitZeroInitializer(*T, Ty, E); - if (Ty->isAnyComplexType() || Ty->isVectorType()) { + if (Ty->isAnyComplexType() || Ty->isVectorType() || + Ty->isConstantMatrixType()) { if (!Initializing) { UnsignedOrNone LocalIndex = allocateLocal(E); if (!LocalIndex) @@ -4216,6 +4221,9 @@ bool Compiler<Emitter>::VisitCXXScalarValueInitExpr( if (const auto *CT = Ty->getAs<ComplexType>()) { NumElems = 2; ElemQT = CT->getElementType(); + } else if (const auto *MT = Ty->getAs<ConstantMatrixType>()) { + NumElems = MT->getNumElementsFlattened(); + ElemQT = MT->getElementType(); } else { const auto *VT = Ty->castAs<VectorType>(); NumElems = VT->getNumElements(); diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index 6d390032e2c717..55e9473c69bde5 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -15582,6 +15582,8 @@ class MatrixExprEvaluator : public ExprEvaluatorBase<MatrixExprEvaluator> { return true; } + bool ZeroInitialization(const Expr *E); + bool VisitCastExpr(const CastExpr *E); bool VisitInitListExpr(const InitListExpr *E); }; @@ -15593,6 +15595,20 @@ static bool EvaluateMatrix(const Expr *E, APValue &Result, EvalInfo &Info) { return MatrixExprEvaluator(Info, Result).Visit(E); } +bool MatrixExprEvaluator::ZeroInitialization(const Expr *E) { + const auto *MT = E->getType()->castAs<ConstantMatrixType>(); + QualType EltTy = MT->getElementType(); + APValue ZeroElement; + if (EltTy->isIntegerType()) + ZeroElement = APValue(Info.Ctx.MakeIntValue(0, EltTy)); + else + ZeroElement = + APValue(APFloat::getZero(Info.Ctx.getFloatTypeSemantics(EltTy))); + + SmallVector<APValue, 16> Elements(MT->getNumElementsFlattened(), ZeroElement); + return Success(Elements, E); +} + bool MatrixExprEvaluator::VisitCastExpr(const CastExpr *E) { const auto *MT = E->getType()->castAs<ConstantMatrixType>(); unsigned NumRows = MT->getNumRows(); @@ -15641,6 +15657,9 @@ bool MatrixExprEvaluator::VisitInitListExpr(const InitListExpr *E) { const auto *MT = E->getType()->castAs<ConstantMatrixType>(); QualType EltTy = MT->getElementType(); + if (E->getNumInits() == 0) + return ZeroInitialization(E); + assert(E->getNumInits() == MT->getNumElementsFlattened() && "Expected number of elements in initializer list to match the number " "of matrix elements"); diff --git a/clang/test/SemaCXX/matrix-type-constexpr.cpp b/clang/test/SemaCXX/matrix-type-constexpr.cpp new file mode 100644 index 00000000000000..180cebe5e929b0 --- /dev/null +++ b/clang/test/SemaCXX/matrix-type-constexpr.cpp @@ -0,0 +1,23 @@ +// RUN: %clang_cc1 -fsyntax-only -fenable-matrix -std=c++11 -verify %s +// RUN: %clang_cc1 -fsyntax-only -fenable-matrix -std=c++11 -verify %s -fexperimental-new-constant-interpreter +// RUN: %clang_cc1 -fsyntax-only -fenable-matrix -std=c++23 -verify %s +// RUN: %clang_cc1 -fsyntax-only -fenable-matrix -std=c++23 -verify %s -fexperimental-new-constant-interpreter +// expected-no-diagnostics + +// GH232999 + +typedef float fx3x3_t __attribute__((matrix_type(3, 3))); +typedef int ix2x4_t __attribute__((matrix_type(2, 4))); + +fx3x3_t GlobalFloat{}; +ix2x4_t GlobalInt{}; + +#if __cplusplus >= 202302L +constexpr bool f() { + fx3x3_t M{}; + ix2x4_t N{}; + fx3x3_t O = fx3x3_t(); + return true; +} +static_assert(f()); +#endif _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
