Fix dangling reference in IndexedView with expression indices

libeigen/eigen!2335

Closes #1943
This commit is contained in:
Pavel Guzenfeld
2026-03-29 16:39:13 +00:00
committed by Rasmus Munk Larsen
parent 624ab58e8d
commit b7f6aed1b9
2 changed files with 74 additions and 0 deletions

View File

@@ -125,6 +125,15 @@ struct SymbolicExpressionEvaluator<FixedInt<N>, SizeAtCompileTime, void> {
// Handling of generic indices (e.g. array)
//--------------------------------------------------------------------------------
// Detect Eigen expression types that are not plain objects (Matrix/Array).
// These types may hold internal references to temporaries and must be evaluated before storing.
template <typename T, typename = void>
struct is_eigen_index_expression : std::false_type {};
template <typename T>
struct is_eigen_index_expression<T, std::enable_if_t<!std::is_same<T, typename T::PlainObject>::value>>
: std::true_type {};
// Potentially wrap indices in a type that is better-suited for IndexedView evaluation.
template <typename Indices, int NestedSizeAtCompileTime, typename EnableIf = void>
struct IndexedViewHelperIndicesWrapper {
@@ -132,6 +141,15 @@ struct IndexedViewHelperIndicesWrapper {
static const type& CreateIndexSequence(const Indices& indices, Index /*nested_size*/) { return indices; }
};
// Specialization for Eigen expression types (Reshaped, Block, CwiseOp, etc.) used as indices.
// These may hold dangling references to temporaries if not evaluated.
template <typename Indices, int NestedSizeAtCompileTime>
struct IndexedViewHelperIndicesWrapper<Indices, NestedSizeAtCompileTime,
std::enable_if_t<is_eigen_index_expression<Indices>::value>> {
using type = typename Indices::PlainObject;
static type CreateIndexSequence(const Indices& indices, Index /*nested_size*/) { return indices.eval(); }
};
// Extract compile-time and runtime first, size, increments.
template <typename Indices, typename EnableIf = void>
struct IndexedViewHelper {