From bb1de9dbdede6669c2c86c028a9deff637e3d1f6 Mon Sep 17 00:00:00 2001 From: Antonio Sanchez Date: Thu, 10 Dec 2020 14:05:38 -0800 Subject: Fix Ref Stride checks. The existing `Ref` class failed to consider cases where the Ref's `Stride` setting *could* match the underlying referred object's stride, but **didn't** at runtime. This led to trying to set invalid stride values, causing runtime failures in some cases, and garbage due to mismatched strides in others. Here we add the missing runtime checks. This involves computing the strides necessary to align with the referred object's storage, and verifying we can actually set those strides at runtime. In the `const` case, if it *may* be possible to refer to the original storage at compile-time but fails at runtime, then we defer to the `construct(...)` method that makes a copy. Added more tests to check these cases. Fixes #2093. --- test/ref.cpp | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) (limited to 'test/ref.cpp') diff --git a/test/ref.cpp b/test/ref.cpp index c0b6ffdcf..ebfc70d3d 100644 --- a/test/ref.cpp +++ b/test/ref.cpp @@ -141,6 +141,69 @@ template void ref_vector(const VectorType& m) VERIFY_IS_APPROX(mat1, mat2); } +template +void ref_vector_fixed_sizes() +{ + typedef Matrix RowMajorMatrixType; + typedef Matrix ColMajorMatrixType; + typedef Matrix RowVectorType; + typedef Matrix ColVectorType; + typedef Matrix RowVectorTransposeType; + typedef Matrix ColVectorTransposeType; + typedef Stride DynamicStride; + + RowMajorMatrixType mr = RowMajorMatrixType::Random(); + ColMajorMatrixType mc = ColMajorMatrixType::Random(); + + Index i = internal::random(0,Rows-1); + Index j = internal::random(0,Cols-1); + + // Reference ith row. + Ref mr_ri = mr.row(i); + VERIFY_IS_EQUAL(mr_ri, mr.row(i)); + Ref mc_ri = mc.row(i); + VERIFY_IS_EQUAL(mc_ri, mc.row(i)); + + // Reference jth col. + Ref mr_cj = mr.col(j); + VERIFY_IS_EQUAL(mr_cj, mr.col(j)); + Ref mc_cj = mc.col(j); + VERIFY_IS_EQUAL(mc_cj, mc.col(j)); + + // Reference the transpose of row i. + Ref mr_rit = mr.row(i); + VERIFY_IS_EQUAL(mr_rit, mr.row(i).transpose()); + Ref mc_rit = mc.row(i); + VERIFY_IS_EQUAL(mc_rit, mc.row(i).transpose()); + + // Reference the transpose of col j. + Ref mr_cjt = mr.col(j); + VERIFY_IS_EQUAL(mr_cjt, mr.col(j).transpose()); + Ref mc_cjt = mc.col(j); + VERIFY_IS_EQUAL(mc_cjt, mc.col(j).transpose()); + + // Const references without strides. + Ref cmr_ri = mr.row(i); + VERIFY_IS_EQUAL(cmr_ri, mr.row(i)); + Ref cmc_ri = mc.row(i); + VERIFY_IS_EQUAL(cmc_ri, mc.row(i)); + + Ref cmr_cj = mr.col(j); + VERIFY_IS_EQUAL(cmr_cj, mr.col(j)); + Ref cmc_cj = mc.col(j); + VERIFY_IS_EQUAL(cmc_cj, mc.col(j)); + + Ref cmr_rit = mr.row(i); + VERIFY_IS_EQUAL(cmr_rit, mr.row(i).transpose()); + Ref cmc_rit = mc.row(i); + VERIFY_IS_EQUAL(cmc_rit, mc.row(i).transpose()); + + Ref cmr_cjt = mr.col(j); + VERIFY_IS_EQUAL(cmr_cjt, mr.col(j).transpose()); + Ref cmc_cjt = mc.col(j); + VERIFY_IS_EQUAL(cmc_cjt, mc.col(j).transpose()); +} + template void check_const_correctness(const PlainObjectType&) { // verify that ref-to-const don't have LvalueBit @@ -287,6 +350,9 @@ EIGEN_DECLARE_TEST(ref) CALL_SUBTEST_4( ref_matrix(Matrix,10,15>()) ); CALL_SUBTEST_5( ref_matrix(MatrixXi(internal::random(1,10),internal::random(1,10))) ); CALL_SUBTEST_6( call_ref() ); + + CALL_SUBTEST_8( (ref_vector_fixed_sizes()) ); + CALL_SUBTEST_8( (ref_vector_fixed_sizes()) ); } CALL_SUBTEST_7( test_ref_overloads() ); -- cgit v1.2.3