From 4155267c45b3e5260cfd0203804d55257f8a81cf Mon Sep 17 00:00:00 2001 From: "KOKO\\Mimi" Date: Sun, 9 Aug 2026 11:47:58 +0900 Subject: [PATCH] feat(linear-static-3d-euler-beam): step 9 - dense-math-adapters-review-fix --- ...tatic-3d-euler-beam-implementation-report.md | 17 +++++++++++++++++ src/fesa/math/matrix.cpp | 11 ++++++++++- tests/unit/math/matrix_test.cpp | 5 +++++ 3 files changed, 32 insertions(+), 1 deletion(-) diff --git a/docs/implementation-plans/linear-static-3d-euler-beam-implementation-report.md b/docs/implementation-plans/linear-static-3d-euler-beam-implementation-report.md index 5b978e7..8b249ac 100644 --- a/docs/implementation-plans/linear-static-3d-euler-beam-implementation-report.md +++ b/docs/implementation-plans/linear-static-3d-euler-beam-implementation-report.md @@ -127,3 +127,20 @@ - handoff: backend-free `fesa::Vector` and `fesa::Matrix` public APIs, with owning dense storage and checked BLAS operations, are available to Step 10 and later DOF/element/assembly tasks. + +### Review Fix Round 1 — matrix-storage-size-overflow + +- regression_test: `tests/unit/math/matrix_test.cpp` now constructs + `Matrix{SIZE_MAX / 2 + 1, 2}` and requires `std::length_error`. +- RED: `cmake --build .harness/build --config Debug --target fesa_tests` exited 0; + `ctest --test-dir .harness/build -C Debug -R DenseMath --output-on-failure` + exited 8 with 1/2 failures because the wraparound constructor threw nothing. +- fix: `Matrix` computes its storage size through a checked helper before vector + construction and rejects exactly `columns != 0 && rows > SIZE_MAX / columns`. +- GREEN: the same targeted build and DenseMath CTest commands exited 0; 2/2 passed. +- VERIFY: approved MSVC x64 configure and full Debug build exited 0; targeted + DenseMath passed 2/2, discovery found 7 tests, and the full suite passed 7/7. + The public-header MKL scan had zero matches, `git diff --check` exited 0, and + `git diff --exit-code -- reference/` exited 0. +- scope: the deferred empty-dot review minor was not changed, reference artifacts + remain untouched, and phase Step 9 status/timestamps were not modified. diff --git a/src/fesa/math/matrix.cpp b/src/fesa/math/matrix.cpp index c5fd90d..f4d7b2e 100644 --- a/src/fesa/math/matrix.cpp +++ b/src/fesa/math/matrix.cpp @@ -9,6 +9,15 @@ namespace fesa { namespace { +std::size_t checkedStorageSize(const std::size_t rows, const std::size_t columns) { + // Reject shape multiplication overflow before logical dimensions and storage diverge. + if (columns != 0 && + rows > (std::numeric_limits::max)() / columns) { + throw std::length_error{"Dense matrix dimensions exceed the storage size range."}; + } + return rows * columns; +} + MKL_INT toMklSize(const std::size_t size) { if (size > static_cast((std::numeric_limits::max)())) { throw std::length_error{"Dense matrix dimension exceeds the MKL integer range."}; @@ -30,7 +39,7 @@ Matrix::Matrix( const std::size_t rows, const std::size_t columns, const double value) - : rows_(rows), columns_(columns), values_(rows * columns, value) {} + : rows_(rows), columns_(columns), values_(checkedStorageSize(rows, columns), value) {} Matrix::Matrix(const Matrix& other) : rows_(other.rows_), columns_(other.columns_), values_(other.values_.size()) { diff --git a/tests/unit/math/matrix_test.cpp b/tests/unit/math/matrix_test.cpp index 11866dc..65bde0e 100644 --- a/tests/unit/math/matrix_test.cpp +++ b/tests/unit/math/matrix_test.cpp @@ -2,6 +2,7 @@ #include +#include #include #include @@ -9,6 +10,10 @@ namespace fesa { namespace { TEST(DenseMath, RowMajorMatrixMatchesKnownGemvGemm) { + const std::size_t wraparoundRows = + (std::numeric_limits::max)() / 2U + 1U; + EXPECT_THROW(static_cast(Matrix{wraparoundRows, 2}), std::length_error); + Matrix zeroRows{0, 3}; Vector threeValues{3, 2.0}; const Vector zeroRowProduct = zeroRows.multiply(threeValues);