Warnings on implicit conversion loses integer precision
Submitted by Georg Drenkhahn
Assigned to Gael Guennebaud @ggael
Link to original bugzilla bug (#877)
Version: 3.3 (current stable)
Description
Clang 3.4 reports a lot of "implicit conversion" warnings when compiling the tests (e.g. http://manao.inria.fr/CDash/viewBuildError.php?type=1&buildid=14193). Many of those are due to conversions of index types mapping to int or long.
I have fixed these type issues by changing index types to match the index types of the accessed objects wherever possible. If this was not possible I converted the implicit conversion into an explicit one and adding internal asserts to be able to catch real overflows on conversion.
Here are short descriptions of the problems and my solution proposals:
eigen/unsupported/test/../../Eigen/src/SparseCore/SparseDenseProduct.h:141:58: warning: implicit conversion loses integer precision: 'Index' (aka 'long') to
'typename TransposeImpl<Block<DynamicSparseMatrix<float, 0, int>, -1, -1, false>, Sparse>::Index' (aka 'int') [-Wshorten-64-to-32]
typename Traits::_RhsNested::InnerIterator it(rhs, outer);
~~ ^~~~~
In SparseDenseOuterProduct if Index type of the Lhs is narrower than Index of Rhs, then coeff access on Rhs shows this warning. I saw no possibility to promote the Index type. outer must be converted explicitly in SparseDenseProduct.h.
--
eigen/unsupported/test/NonLinearOptimization.cpp:249:23: warning: implicit conversion loses integer precision: 'Index' (aka 'long') to 'const int'
[-Wshorten-64-to-32]
const int n = x.size();
Fixed by using VectorXd::Index instead of int in NonLinearOptimization.cpp.
--
eigen/Eigen/src/Core/DenseCoeffsBase.h:499:60: warning: implicit conversion loses integer precision: 'Index' (aka 'long') to 'Index' (aka 'int')
[-Wshorten-64-to-32]
derived().coeffRef(row, col) = other.derived().coeff(row, col);
~~~~~ ^~~
In class DenseCoeffsBase the methods copyPacket(), copyCoeff() might access the other objects with an wider Index type. Fixed this with explicit conversions.
--
eigen/Eigen/src/SparseCore/SparseMatrix.h:1076:23: warning: implicit conversion loses integer precision: 'Index' (aka 'long') to 'Index' (aka 'int')
[-Wshorten-64-to-32]
SparseMatrix dest(other.rows(),other.cols());
~~~~ ^~~~~~~~~~~~
In operator= of SparseMatrix the Index type of the source may be narrower than those of the destination matrix. Solved by explicit conversion.
--
eigen/Eigen/src/Core/AssignEvaluator.h:426:112: warning: implicit conversion loses integer precision: 'Index' (aka 'long') to 'int' [-Wshorten-64-to-32]
copy_using_evaluator_innervec_InnerUnrolling<Kernel, 0, DstXprType::InnerSizeAtCompileTime>::run(kernel, outer);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^~~~~
The run method takes an hard coded int as index. Solved by using Index type of Kernel for the function argument.
--
eigen/Eigen/src/Core/CoreEvaluators.h:580:19: warning: implicit conversion loses integer precision: 'Index' (aka 'long') to 'int' [-Wshorten-64-to-32]
m_rowStride(map.rowStride()),
~^~~~~~~~~~~~~~~
Class members where hard coded ints. Solved by converting to members of type Index.
--
eigen/Eigen/src/Core/Diagonal.h:161:14: warning: implicit conversion loses integer precision: 'long' to 'int' [-Wshorten-64-to-32]
return m_index.value();
~~~~~~ ^~~~~~~~~~~~~~~
Diagonal::index() returned hard coded int type. Solved by converting return type to Index.
Also added obviously forgotten inline keyword to member function.
--
eigen/Eigen/src/IterativeLinearSolvers/IncompleteLUT.h:34:13: warning: implicit conversion loses integer precision: 'Index' (aka 'long') to 'int'
[-Wshorten-64-to-32]
Index n = row.size(); /* length of the vector */
~ ^~~~~~~~~~
Function template QuickSplit receives Index typename from function argument. If this is an int it may not match to the Index type of the Vector function argument. Solved by removing the independent Index template parameter and using Index of vector type instead.
--
eigen/Eigen/src/SparseLU/SparseLU_SupernodalMatrix.h:236:15: warning: implicit conversion loses integer precision: 'Index' (aka 'long') to 'Index' (aka 'int')
[-Wshorten-64-to-32]
Index n = X.rows();
~ ^~~~~~~~
In MappedSuperNodalMatrix<Scalar,Index>::solveInPlace() the Index of the destination matrix may be wider than the class Index type. Solved by explicit conversion.
--
eigen/Eigen/src/SparseLU/SparseLU.h:690:15: warning: implicit conversion loses integer precision: 'Index' (aka 'long') to 'Index' (aka 'int')
[-Wshorten-64-to-32]
Index n = X.rows();
~ ^~~~~~~~
Same as for MappedSuperNodalMatrix.
--
eigen/Eigen/src/SparseLU/SparseLU_panel_bmod.h:209:54: warning: implicit conversion loses integer precision: 'long' to 'int' [-Wshorten-64-to-32]
if(segsize==1) LU_kernel_bmod<1>::run(segsize, dense_col, tempv, glu.lusup, luptr, lda, nrow, glu.lsub, lptr, no_zeros);
~~~~~~~~~~~~~~ ^~~~~~~
Hard coded int types used in method arguments. Solved by using Index type arguments.
--
eigen/Eigen/src/misc/SparseSolve.h:39:38: warning: implicit conversion loses integer precision: 'Index' (aka 'long') to 'Index' (aka 'int') [-Wshorten-64-to-32]
inline Index rows() const { return m_dec.cols(); }
~~~~~~ ^~~~~~~~~~~~
Class sparse_solve_retval_base defined Index as Index of Lhs. Fixed by using promoted Index of Lhs and Rhs.
--
eigen/Eigen/src/SparseQR/SparseQR.h:595:38: warning: implicit conversion loses integer precision: 'Index' (aka 'long') to 'Index' (aka 'int')
[-Wshorten-64-to-32]
inline Index cols() const { return m_other.cols(); }
~~~~~~ ^~~~~~~~~~~~~~
The Index type of class SparseQR_QProduct may not correspond to those of member m_other. Fixed by explicit conversion.
--
eigen/unsupported/test/../../Eigen/src/Core/ReturnByValue.h:63:58: warning: implicit conversion loses integer precision: 'Index' (aka 'long') to 'Index'
(aka 'int') [-Wshorten-64-to-32]
EIGEN_DEVICE_FUNC inline Index rows() const { return static_cast<const Derived*>(this)->rows(); }
~~~~~~ ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The ReturnType of KroneckerProductSparse was defined with Index=int. Fixed by defining it to be equal to promoted index of Rhs::Index and Lhs::Index.
--
eigen/unsupported/Eigen/src/KroneckerProduct/KroneckerTensorProduct.h:154:28: warning: implicit conversion loses integer precision: 'Index' (aka 'long') to
'Index' (aka 'int') [-Wshorten-64-to-32]
dst.resize(this->rows(), this->cols());
Mixing of Rhs::Index and Lhs:Index in various loop variables.
--
eigen/unsupported/Eigen/src/LevenbergMarquardt/LMqrsolv.h:35:15: warning: implicit conversion loses integer precision: 'Index' (aka 'long') to 'int'
[-Wshorten-64-to-32]
Index n = s.cols();
~ ^~~~~~~~
Mixing of types of permutation matrix index and other matrix index in template function void lmqrsolv().
Fixed compiler warning on implicit integer conversion by separating index type for matrix and permutation matric which may not be equal.
--
I have prepared pull request #83 with the fixes for the default branch:
https://bitbucket.org/eigen/eigen/pull-request/83
All changesets are independent from each other as they fix different warnings. Please have a look at it.
### Depends on
#572
### Blocking
#558