4

Clang-tidy reports warnings with a simple code involving Eigen. My questions are:

  1. Are they really false-positive warnings?
  2. How can I suppress them? They cannot be suppressed completely by adding // NOLINT(clang-analyzer-core.NullDereference,clang-analyzer-core.uninitialized.UndefReturn) to L6.

Environment:

  • Eigen version 3.3.7 (installed via vcpkg)
  • CMake version 3.10.2
  • Ninja version 1.8.2
  • Clang version 6.0.0-1ubuntu2

main.cpp

#include <Eigen/SparseCore>

int main() {
  Eigen::SparseMatrix<int> m(1, 1);

  m.coeffRef(0, 0)++;

  return 0;
}

CMakeLists.txt

cmake_minimum_required(VERSION 3.5)

project(eigen-test CXX)

set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

add_executable(eigen-test main.cpp)
target_compile_options(eigen-test PRIVATE -Wall -Wextra)
target_include_directories(eigen-test PRIVATE $ENV{HOME}/vcpkg/installed/x64-linux/include)

Command-lines and outputs

$ mkdir build && cd build
$ CXX=clang++ cmake .. -GNinja
-- The CXX compiler identification is Clang 6.0.0
-- Check for working CXX compiler: /usr/bin/clang++
-- Check for working CXX compiler: /usr/bin/clang++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: /home/foo/eigen-test/build
$ clang-tidy ../main.cpp
2 warnings generated.
/home/foo/vcpkg/installed/x64-linux/include/Eigen/src/SparseCore/CompressedStorage.h:121:80: warning: Returning null reference [clang-analyzer-core.uninitialized.UndefReturn]
    inline StorageIndex& index(Index i) { eigen_internal_assert(m_indices!=0); return m_indices[i]; }
                                                                               ^
/home/foo/eigen-test/main.cpp:4:28: note: Calling constructor for 'SparseMatrix'
  Eigen::SparseMatrix<int> m(1, 1);
                           ^
/home/foo/vcpkg/installed/x64-linux/include/Eigen/src/SparseCore/SparseMatrix.h:667:12: note: Calling default constructor for 'CompressedStorage'
    inline SparseMatrix(Index rows, Index cols)
           ^
/home/foo/vcpkg/installed/x64-linux/include/Eigen/src/SparseCore/CompressedStorage.h:36:22: note: Null pointer value stored to 'm.m_data.m_indices'
      : m_values(0), m_indices(0), m_size(0), m_allocatedSize(0)
                     ^
/home/foo/vcpkg/installed/x64-linux/include/Eigen/src/SparseCore/SparseMatrix.h:667:12: note: Returning from default constructor for 'CompressedStorage'
    inline SparseMatrix(Index rows, Index cols)
           ^
/home/foo/eigen-test/main.cpp:4:28: note: Returning from constructor for 'SparseMatrix'
  Eigen::SparseMatrix<int> m(1, 1);
                           ^
/home/foo/eigen-test/main.cpp:6:3: note: Calling 'SparseMatrix::coeffRef'
  m.coeffRef(0, 0)++;
  ^
/home/foo/vcpkg/installed/x64-linux/include/Eigen/src/SparseCore/SparseMatrix.h:210:27: note: '?' condition is false
      const Index outer = IsRowMajor ? row : col;
                          ^
/home/foo/vcpkg/installed/x64-linux/include/Eigen/src/SparseCore/SparseMatrix.h:211:27: note: '?' condition is false
      const Index inner = IsRowMajor ? col : row;
                          ^
/home/foo/vcpkg/installed/x64-linux/include/Eigen/src/SparseCore/SparseMatrix.h:214:19: note: '?' condition is false
      Index end = m_innerNonZeros ? m_outerIndex[outer] + m_innerNonZeros[outer] : m_outerIndex[outer+1];
                  ^
/home/foo/vcpkg/installed/x64-linux/include/Eigen/src/SparseCore/SparseMatrix.h:216:7: note: Taking false branch
      if(end<=start)
      ^
/home/foo/vcpkg/installed/x64-linux/include/Eigen/src/SparseCore/SparseMatrix.h:219:10: note: Left side of '&&' is true
      if((p<end) && (m_data.index(p)==inner))
         ^
/home/foo/vcpkg/installed/x64-linux/include/Eigen/src/SparseCore/SparseMatrix.h:219:22: note: Calling 'CompressedStorage::index'
      if((p<end) && (m_data.index(p)==inner))
                     ^
/home/foo/vcpkg/installed/x64-linux/include/Eigen/src/SparseCore/CompressedStorage.h:121:80: note: Returning null reference
    inline StorageIndex& index(Index i) { eigen_internal_assert(m_indices!=0); return m_indices[i]; }
                                                                               ^
/home/foo/vcpkg/installed/x64-linux/include/Eigen/src/SparseCore/CompressedStorage.h:136:13: warning: Array access (via field 'm_indices') results in a null pointer dereference [clang-analyzer-core.NullDereference]
        if (m_indices[mid]<key)
            ^
/home/foo/eigen-test/main.cpp:4:28: note: Calling constructor for 'SparseMatrix'
  Eigen::SparseMatrix<int> m(1, 1);
                           ^
/home/foo/vcpkg/installed/x64-linux/include/Eigen/src/SparseCore/SparseMatrix.h:667:12: note: Calling default constructor for 'CompressedStorage'
    inline SparseMatrix(Index rows, Index cols)
           ^
/home/foo/vcpkg/installed/x64-linux/include/Eigen/src/SparseCore/CompressedStorage.h:36:22: note: Null pointer value stored to 'm.m_data.m_indices'
      : m_values(0), m_indices(0), m_size(0), m_allocatedSize(0)
                     ^
/home/foo/vcpkg/installed/x64-linux/include/Eigen/src/SparseCore/SparseMatrix.h:667:12: note: Returning from default constructor for 'CompressedStorage'
    inline SparseMatrix(Index rows, Index cols)
           ^
/home/foo/eigen-test/main.cpp:4:28: note: Returning from constructor for 'SparseMatrix'
  Eigen::SparseMatrix<int> m(1, 1);
                           ^
/home/foo/eigen-test/main.cpp:6:3: note: Calling 'SparseMatrix::coeffRef'
  m.coeffRef(0, 0)++;
  ^
/home/foo/vcpkg/installed/x64-linux/include/Eigen/src/SparseCore/SparseMatrix.h:210:27: note: '?' condition is false
      const Index outer = IsRowMajor ? row : col;
                          ^
/home/foo/vcpkg/installed/x64-linux/include/Eigen/src/SparseCore/SparseMatrix.h:211:27: note: '?' condition is false
      const Index inner = IsRowMajor ? col : row;
                          ^
/home/foo/vcpkg/installed/x64-linux/include/Eigen/src/SparseCore/SparseMatrix.h:214:19: note: '?' condition is false
      Index end = m_innerNonZeros ? m_outerIndex[outer] + m_innerNonZeros[outer] : m_outerIndex[outer+1];
                  ^
/home/foo/vcpkg/installed/x64-linux/include/Eigen/src/SparseCore/SparseMatrix.h:216:7: note: Taking false branch
      if(end<=start)
      ^
/home/foo/vcpkg/installed/x64-linux/include/Eigen/src/SparseCore/SparseMatrix.h:218:23: note: Calling 'CompressedStorage::searchLowerIndex'
      const Index p = m_data.searchLowerIndex(start,end-1,StorageIndex(inner));
                      ^
/home/foo/vcpkg/installed/x64-linux/include/Eigen/src/SparseCore/CompressedStorage.h:133:7: note: Loop condition is true.  Entering loop body
      while(end>start)
      ^
/home/foo/vcpkg/installed/x64-linux/include/Eigen/src/SparseCore/CompressedStorage.h:136:13: note: Array access (via field 'm_indices') results in a null pointer dereference
        if (m_indices[mid]<key)
            ^
Jiro
  • 83
  • 5
  • 1
    Looks like a false warning to me. If `m_indices` is null then `(end<=start)` must be true (unless someone manually modified internals of the structure). No idea how to convince clang-tidy that this can't happen. – chtz Sep 17 '19 at 14:19

0 Answers0