diff --git a/Eigen/src/Core/Block.h b/Eigen/src/Core/Block.h index d0b95d50b..5932a9093 100644 --- a/Eigen/src/Core/Block.h +++ b/Eigen/src/Core/Block.h @@ -334,6 +334,17 @@ class BlockImpl_dense enum { XprTypeIsRowMajor = (int(traits::Flags)&RowMajorBit) != 0 }; + + /** \internal Returns base+offset (unless base is null, in which case returns null). + * Adding an offset to nullptr is undefined behavior, so we must avoid it. + */ + template + EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR EIGEN_ALWAYS_INLINE + static Scalar* add_to_nullable_pointer(Scalar* base, Index offset) + { + return base != NULL ? base+offset : NULL; + } + public: typedef MapBase Base; @@ -344,8 +355,9 @@ class BlockImpl_dense */ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE BlockImpl_dense(XprType& xpr, Index i) - : Base(xpr.data() + i * ( ((BlockRows==1) && (BlockCols==XprType::ColsAtCompileTime) && (!XprTypeIsRowMajor)) - || ((BlockRows==XprType::RowsAtCompileTime) && (BlockCols==1) && ( XprTypeIsRowMajor)) ? xpr.innerStride() : xpr.outerStride()), + : Base(add_to_nullable_pointer(xpr.data(), + i * ( ((BlockRows==1) && (BlockCols==XprType::ColsAtCompileTime) && (!XprTypeIsRowMajor)) + || ((BlockRows==XprType::RowsAtCompileTime) && (BlockCols==1) && ( XprTypeIsRowMajor)) ? xpr.innerStride() : xpr.outerStride())), BlockRows==1 ? 1 : xpr.rows(), BlockCols==1 ? 1 : xpr.cols()), m_xpr(xpr), @@ -359,7 +371,8 @@ class BlockImpl_dense */ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE BlockImpl_dense(XprType& xpr, Index startRow, Index startCol) - : Base(xpr.data()+xpr.innerStride()*(XprTypeIsRowMajor?startCol:startRow) + xpr.outerStride()*(XprTypeIsRowMajor?startRow:startCol)), + : Base(add_to_nullable_pointer(xpr.data(), + xpr.innerStride()*(XprTypeIsRowMajor?startCol:startRow) + xpr.outerStride()*(XprTypeIsRowMajor?startRow:startCol))), m_xpr(xpr), m_startRow(startRow), m_startCol(startCol) { init(); @@ -371,7 +384,9 @@ class BlockImpl_dense BlockImpl_dense(XprType& xpr, Index startRow, Index startCol, Index blockRows, Index blockCols) - : Base(xpr.data()+xpr.innerStride()*(XprTypeIsRowMajor?startCol:startRow) + xpr.outerStride()*(XprTypeIsRowMajor?startRow:startCol), blockRows, blockCols), + : Base(add_to_nullable_pointer(xpr.data(), + xpr.innerStride()*(XprTypeIsRowMajor?startCol:startRow) + xpr.outerStride()*(XprTypeIsRowMajor?startRow:startCol)), + blockRows, blockCols), m_xpr(xpr), m_startRow(startRow), m_startCol(startCol) { init(); diff --git a/Eigen/src/Core/StlIterators.h b/Eigen/src/Core/StlIterators.h index 09041db1d..5db3f605b 100644 --- a/Eigen/src/Core/StlIterators.h +++ b/Eigen/src/Core/StlIterators.h @@ -196,6 +196,7 @@ public: pointer_based_stl_iterator() EIGEN_NO_THROW : m_ptr(0) {} pointer_based_stl_iterator(XprType& xpr, Index index) EIGEN_NO_THROW : m_incr(xpr.innerStride()) { + eigen_assert(xpr.data() != NULL || index == 0 || m_incr.value() == 0); m_ptr = xpr.data() + index * m_incr.value(); }