3

I am trying to use clang-tidy in my CMake (3.17.1) project however it crashes on the Catch2 test library header. Setting the Catch2 as a system header does not seem to help. The command invoked for clang-tidy contains the path to Catch2 as a system include directory yet the diagnostics is still printed for it. When trying to isolate it I have discovered that this does not actually work with clang-tidy:

clang-tidy src.cpp -- -Isystem/Path/to/header

It results in the header not being found at all. What I have learned somewhere (cannot find it now) was to make it actually two --extra-arg parameters of the clang-tidy instead:

clang-tidy --extra-arg=-Isystem --extra-arg=/Path/to/header src.cpp

This however does not work everywhere. On Windows I was able to make it work but on Linux it never worked in any form (together, separate, after --). How does one use the -isystem headers with clang-tidy on Linux? It is very confusing and inconsistent. Furthermore how to do it with CMake?

I have this:

cmake_minimum_required(VERSION 3.10)
set(CMAKE_CXX_CLANG_TIDY clang-tidy)

add_library(Catch2 STATIC Catch2/Catch2.cpp Catch2/include/Catch2/catch.hpp)
target_include_directories(Catch2 SYSTEM PUBLIC Catch2/include)

add_executable(SomeTest SomeTest/test.cpp)
target_link_libraries(Catch2)

The generated command line is rather convoluted (wrapping is mine for readability):

cmake 
-E __run_co_compile 
--tidy="clang-tidy-10;--extra-arg-before=--driver-mode=g++"
--source=../Sometest/test.cpp
-- 
/usr/bin/clang++-10
-isystem ../Catch2/include 
-g
-std=gnu++17
-MD
-MT CMakeFiles/SomeTest.dir/projects/SomeTest/test.cpp.o 
-MF CMakeFiles/SomeTest.dir/projects/SomeTest/FileTest.cpp.o.d 
-o CMakeFiles/SomeTest.dir/projects/SomeTest/test.cpp.o 
-c 
../projects/SomeTest/test.cpp

In the output there are warnings from the Catch2 so the system in the include is just ignored seemingly. I have tried to force the --extra-arg via the CMAKE_CXX_CLANG_TIDY property:

set(CMAKE_CXX_CLANG_TIDY clang-tidy --extra-arg=-isystem --extra-arg=../Catch2/include)

but that does not seem to do the trick either.

Resurrection
  • 3,916
  • 2
  • 34
  • 56
  • Out of curiosity, do you have better luck if you tell `clang-tidy` to use a compilation database? CMake can generate those automatically for you, and `clang-tidy` will leverage the exact same flags you'd use to build. – Stephen Newell Apr 13 '20 at 21:24
  • @StephenNewell I have enabled the compilation database in CMake and used it with clang-tidy manually (e.g. `clang-tidy ../SomeTest/test.cpp`) from the directory where the compilation commands json is. It was picked up fine and it does include the same `-isystem` header. Interestingly it does find the header fine this time but still ignores the `system` as it prints the warnings for the header regardless. – Resurrection Apr 14 '20 at 05:50
  • @StephenNewell As it turns out the problem is not universal but seem specific to Catch2 header (and possibly similar uses of macros). The `-isystem` mostly works when I try to simulate it and even for Catch2 for the most part. However some warnings still bleed through it no matter what (unfortunately from `REQUIRE` macro). I have submitted a bug to LLVM: https://bugs.llvm.org/show_bug.cgi?id=45528 – Resurrection Apr 14 '20 at 10:24

1 Answers1

2

I am following your repro as posted on LLVM bugtracker.

You are doing everything correctly: that is, marking Catch2 as system include with SYSTEM. clang-tidy is also behaving correctly: it only checks your source file test.cpp and doesn't fully check catch.hpp, only the macro expansion.

The problem is the outdated version of Catch2. hicpp-vararg warning has been silenced as of Catch2 2.12.2, so you need to update to at least that version. Moreover, apparently the core issue that hicpp-vararg reported upon has been fixed and this change is expected to be present in clang-tidy 11 release.

Ave Milia
  • 599
  • 4
  • 12