I'm using CMake for my project and I wanted to introduce clang-tidy checks to the project.
I'm using for this purpose CMAKE_CXX_CLANG_TIDY and .clang-tidy file for checks setup.
I wanted to use warnings-as-errors to have reliable way in CI to check whether commit introduces some new violations. Unfortunately I have some problems with enabling checks due to 3rd-party libraries.
PLEASE LOOK AT EDIT2!
For example I use Eigen which is header-only library. Due to this fact I get some warnings in my code eg. "a_file.cpp"
/snap/cmake/301/bin/cmake -E __run_co_compile --tidy="clang-tidy;--extra-arg-before=--driver-mode=g++" --source=../../a_file.cpp -- /usr/bin/clang++ -DEIGEN_MPL2_ONLY -DEIGEN_STACK_ALLOCATION_LIMIT=16384 -I../../SomePath -I../../SomePath2 -isystem ../../path_to/include/Eigen -m64 -stdlib=libc++ -g -fPIC -std=c++11 -MD -MT a_file.cpp.o -MF a_file.cpp.o.d -o a_file.cpp.o -c a_file.cpp
../../path_to/include/Eigen/Eigen/src/Core/Swap.h:89:36: error: Assigned value is garbage or undefined [clang-analyzer-core.uninitialized.Assign,-warnings-as-errors]
a_file.cpp:279:5: note: Loop condition is true. Entering loop body
for( unsigned int i = 0; i < 100; ++i )
^
a_file.cpp:282:13: note: Calling move assignment operator for 'Matrix<float, 3, 1, 0, 3, 1>'
some_name = Vector3f( GetRandom( fDummy ),GetRandom( fDummy ), GetRandom( fDummy ) );
I'm a bit out of ideas how to ignore this kind of problems as header-filter doesn't seem to resolve this issue - for other checks [bugprone-xxx] I have similar issues. What are my options besides adding //NO-LINT everywhere?
Edit: added a bit of context to error.
EDIT2:
As I still struggle with correct handling for clang-tidy I've prepared a repository to show the example problem.
https://github.com/MaciejPatro/test_clang_tidy
This is a minimal repository with 2 header files, and one cpp files that uses doctest. I use two checks there: clang-analyzer-cplusplus*,google-readability-todo - first one demonstrating the problem with doctest inclusion and second one because it's the simplest one to create a "bug".
some_header.h
void else_after_return() {
// TODO wrong hpp some
}
other_header.h
void wrong_function() {
// TODO wrong hpp other
}
my_test.cpp
#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN
#include <doctest/doctest.h>
#include <some_header.h>
#include <other_header.h>
TEST_CASE("a test")
{
// TODO wrong cpp
else_after_return();
wrong_function();
CHECK(5 != 7);
}
There are 3 tests that give these results:
Ignore header files (no --header-filter specified).
I can see:
/home/pmac/projects/test_clang_tidy/source/tests/my_test.cpp:9:3: warning: missing username/bug in TODO [google-readability-todo]
Which is expected
Allow all header files ( --header-filter=.* )
I can see:
/home/pmac/projects/test_clang_tidy/source/include/other_header.h:5:3: warning: missing username/bug in TODO [google-readability-todo]
/home/pmac/projects/test_clang_tidy/source/include/some_header.h:5:3: warning: missing username/bug in TODO [google-readability-todo]
/home/pmac/projects/test_clang_tidy/source/tests/my_test.cpp:9:3: warning: missing username/bug in TODO [google-readability-todo]
Which makes sense for me
Only header files with "some in name" (--header-filter=.some.)
/home/pmac/projects/test_clang_tidy/source/include/some_header.h:5:3: warning: missing username/bug in TODO [google-readability-todo]
/home/pmac/projects/test_clang_tidy/source/tests/my_test.cpp:9:3: warning: missing username/bug in TODO [google-readability-todo]
Everything seems fine
Next 3 tests add the second check clang-analyzer-cplusplus which is visible in doctest. Now regardless of the settings provided to clang-tidy I get additionally a warning from doctest MACRO DOCTEST_DO_BINARY_EXPRESSION_COMPARISON which is expanded from CHECK:
/home/pmac/.conan/data/doctest/2.4.6/_/_/package/5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9/include/doctest/doctest.h:1239:9: warning: Potential leak of memory pointed to by field 'ptr' [clang-analyzer-cplusplus.NewDeleteLeaks]
I want the warning from doctest being filtered out - unfortunately none of settings (--header-filter, nor including it as system header -isystem) allows me to ignore it.
Here is the full command line how the my_test.cpp is compiled (to confirm that doctest header is included with -isystem)
/home/pmac/.local/lib/python3.8/site-packages/cmake/data/bin/cmake -E __run_co_compile --tidy="clang-tidy-12;-checks=-*,clang-analyzer-cplusplus*,google-readability-todo;--header-filter=.*some.*;--extra-arg-before=--driver-mode=g++" --source=../source/tests/my_test.cpp -- /usr/bin/c++ -I../source/include -isystem /home/pmac/.conan/data/doctest/2.4.6/_/_/package/5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9/include -g -std=gnu++2a -MD -MT source/CMakeFiles/test_clang_tidy_tests.dir/tests/my_test.cpp.o -MF source/CMakeFiles/test_clang_tidy_tests.dir/tests/my_test.cpp.o.d -o source/CMakeFiles/test_clang_tidy_tests.dir/tests/my_test.cpp.o -c ../source/tests/my_test.cpp
Is there any other way to filter out the warning generated by MACROs included from a 3rd party library? I don't want to remove checks in my tests because of 3rdparty library.
To change "Tests" in repository comment/uncomment lines in https://github.com/MaciejPatro/test_clang_tidy/blob/master/CMakeLists.txt
set(CMAKE_CXX_CLANG_TIDY "clang-tidy-12;-checks=-*,google-readability-todo")
#set(CMAKE_CXX_CLANG_TIDY "clang-tidy-12;-checks=-*,google-readability-todo;--header-filter=.*")
#set(CMAKE_CXX_CLANG_TIDY "clang-tidy-12;-checks=-*,google-readability-todo;--header-filter=.*some.*")
# Something works wrong here!
#set(CMAKE_CXX_CLANG_TIDY "clang-tidy-12;-checks=-*,clang-analyzer-cplusplus*,google-readability-todo)
#set(CMAKE_CXX_CLANG_TIDY "clang-tidy-12;-checks=-*,clang-analyzer-cplusplus*,google-readability-todo;--header-filter=.*")
#set(CMAKE_CXX_CLANG_TIDY "clang-tidy-12;-checks=-*,clang-analyzer-cplusplus*,google-readability-todo;--header-filter=.*some.*")
The error you have posted does not look spurious. The problem likely isn't with the 3rd-party library, but with your usage of it. You have not supplied enough code to give a fully correct answer as it's not clear what fDummy and GetRandom are. If fDummy is being moved into GetRandom, you have a real error here.
The comments have already listed the ways to ignore errors contained within header files: using -isystem (in CMake, imported targets use this by default, otherwise you can manually apply SYSTEM to target_include_directories).
GetRandom and fDummy code can you add it in here?
It is not clear with what you have written.
Also, include directories handle all these warnings in CMAKE.
(yes i meant inclusion as system headers. )
.clang-tidy
...
HeaderFilterRegex: '.*'
...
or
clang-tidy ... --header-filter='.*' ...
From clang-tidy output when analyzing a lot of code:
Suppressed ... warnings (... in non-user code).
Use -header-filter=.* to display errors from all non-system headers. Use -system-headers to display errors from system headers as well.
Related
I was trying to include the GMP library, which was simply the code below(I did nothing else):
#include <gmpxx.h>
However, when I tried to compile the code, the following error from g++ compiler occured:
myCode.cpp:3:10: fatal error: gmpxx.h: No such file or directory
#include <gmpxx.h>
^~~~~~~~~~~~~~~~~~~~~~
I have tried everything I searched online, putting the GMP lib here and there, adding INFINITE includepaths in c_cpp_properties.json, still, it keeps showing the message, although, I can find the file through "Go to Definition" option.
Is there any known solution to this?
It's not enough to configure VS Code includes, you need to pass those options to the compiler as well.
You don't mention your platform at all, so I'm going to use an example from my personal machine, a Macbook Pro with the fmt library.
When compiling with the fmt library, I have to provide three more options to the compiler.
-I/usr/local/include // Tells the compiler where to look for extra includes
-L/usr/local/lib // Tells the compiler where to look for extra libraries
-lfmt // fmt-specific command to use fmt library
So the full command ends up looking like this:
g++ -Wall -std=c++17 -I/user/local/include -L/usr/local/lib -lfmt main.cpp
I need all three options because fmt is installed in a non-standard location that the compiler doesn't check by default. According to the documentation, you can get away with just -lgmp and -lgmpxx if you installed the library in a standard location (happens by default with *nix and a package manager, I imagine).
If you use build tasks in VS Code, this can be set up and automated for you.
I am using clang-tidy as a "linter" tool in development. I started to integrate 3rd party software into my code and when I include their header files using:
-I/path/to/include
tons of errors are generated, I haven't even #include the headers yet.
error: too many errors emitted, stopping now [clang-diagnostic-error]
...
/path/to/include/wchar.h:81:1: error: unknown type name 'wint_t' [clang-diagnostic-error]
wint_t fgetwc(FILE *__stream);
^
/path/to/include/wchar.h:81:15: error: unknown type name 'FILE' [clang-diagnostic-error]
wint_t fgetwc(FILE *__stream);
^
...
I compile my program using:
/usr/bin/clang-tidy-4.0 /path/to/main.cpp -checks=-*,cppcoreguidelines* -- -lang-c++ -I/path/to/include -std=gnu++11 -Wall -Werror -O0 -g -D<define variables>
It seems that these "clang-diagnostic-errors" do not stop compilation, as it continues to compile and runs fine. Is there a flag to turn this error off/suppress it? I do not want to see it since I did not write these header files.
If I get rid of the argument -I/path/to/include everything compiles fine with no errors.
There is no way to ignore clang-diagnostic-error since it's basically a compiler error.
For clang-tidy to work the analyzed code needs to be compile-able by the clang backend to generate an AST(Abstract syntax tree).
The problem is you are including headers that cannot be compiled by clang (I'm guessing windows headers intended for MSVC).
I'm not sure if this would not break something later, so just at your own risk. I managed to "solve" this (because it was just a matter of having an error on the Problems list) on VSCode:
"C_Cpp.codeAnalysis.clangTidy.args": [
"--extra-arg=-ferror-limit=1"
]
This makes clang-tidy tell the compiler to throw just one error and give up. So clang-tidy will parse whatever is left.
I know was for VSCode, but the argument can be used in other IDEs.
I'm trying to compile a CPP application (an open source project) in the latest cygwin64 environment using g++ 6.4.0 and I get the following error:
error: 'posix_memalign' was not declared in this scope
now posix_memlign can be found in stdlib.h if you compile the most simple CPP "hello world" application there wouldn't be a problem calling posix_memlign.
The make file of the project report the following setup for the compilation
g++ -DHAVE_CONFIG_H -I. -Wall -Wnon-virtual-dtor -I. -I./include -g -O3 -std=c++0x -g -O3 -std=c++0x -MT lib/rectangular_binary_matrix.lo -MD -MP -MF lib/.deps/rectangular_binary_matrix.Tpo -c lib/rectangular_binary_matrix.cc -DDLL_EXPORT -DPIC -o lib/.libs/rectangular_binary_matrix.o
so it doesn't look like it override the default include path. Any ideas?
p.s.
I was able to build the code on Linux (Redhat) without a problem.
posix_memalign is not part of the C Standard Library or the C++ Standard
library and the cygwin GCC compilers do not provide it, although other
compilers may do so, including GCC compilers from other builders.
You might consider using instead the C Standard function aligned_alloc, if you feel comfortable to edit your project source. It is provided in <cstdlib> for C++ compilation in cygwin g++ 6.4.0
Later
I do see the function in C:\cygwin64\usr\include\stdlib.h...
The fact that you can find the function declaration in the header file
does not mean that the compiler can see it after preprocessing. The same
source header may be used by many builders, exposing different
declarations to the compiler depending on the builder's settings of implementor
macros. In this case, the declaration is concealed from your compiler by
the fact that __POSIX_VISIBLE >= 200112 is false. Identifiers beginning __ are reserved for implementors.
See the explanation of this macro
and note the comment:
* The following private macros are used throughout the headers to control
* which symbols should be exposed. They are for internal use only, as
* indicated by the leading double underscore, and must never be used outside
* of these headers.
[SOLUTION FOUND]
Hello (I'm posting this on 2 threads regarding the same problem).
I'm here because I had the "POSIX_VISIBLE >= 200112" and the "posix_memalign was not declared in this scope" issue, which was halting the compilation of a program.
I'm not a programmer and tried various fixes on my own for a couple hours. Then finally Googled & came upon this site. The solutions here did not work for me, but I'll describe what did work:
The "posix_memalign" text was in a "stdlib.h" file that was being included into the code. The first problem was that in my "cygwin" directory, I have 25 instances of "stdlib.h"! Which one of those was being included?! I'm all new to this, but I finally found that
echo | gcc -E -Wp,-v -
might at least give an idea of which directory the files were being "included" from. This narrowed down the number of "stdlib.h" files to 4. Out of 4 such files, only one had the "posix_memalign" text. I tried changing the filename of that stdlib.h to see if it would cause an error--and confirm that it was the stdlib.h in question. However, this didn't effect the program. So I searched for a "stdlib.h" file in the next directory higher. THAT "stdlib.h" file also had the "POSIX" text in it. So when I changed THAT stdlib.h filename, the program DID error out. So that was the stdlib.h to deal with.
I saw that the "POSIX_VISIBLE >= 200112" instruction effected only the ONE line of code with "posix_memalign" in it. (In other words, the "POSIX_VISIBLE" instruction was not being used for the whole file.) I considered "commenting" it out, or deleting it. But then non-programmer me got the ingenious idea to simply change the ">=" to a "<". So I now had "POSIX_VISIBLE < 200112". I saved the file, ran the "configure" and "make" routine again, and boom, all was well. Program compiled properly.
Moral of the story, if you can determine the file (containing the POSIX statement and the posix_memalign) which is being accessed by your code, you may be able to solve your problem by just changing that one POSIX_VISIBLE operator as I did. (And you may want to switch that operator back after your compiling is done, in case that stdlib.h library file needs to be used by other programs in the future.)
I am on Ubuntu 16.04, GCC 5.4.
According to here one can disable warnings from external headers by treating them as system headers. However, when I am using VTK I came across a warning that I am unable to disable. Below is the minimum code to reproduce it
#include "vtkVersion.h"
int main(){
return 0;
}
Compile it with g++ main.cpp -isystem /usr/include/vtk-5.10/ return warning message
In file included from /usr/include/c++/5/backward/strstream:50:0,
from /usr/include/vtk-5.10/vtkIOStream.h:108,
from /usr/include/vtk-5.10/vtkSystemIncludes.h:40,
from /usr/include/vtk-5.10/vtkIndent.h:24,
from /usr/include/vtk-5.10/vtkObjectBase.h:43,
from /usr/include/vtk-5.10/vtkObject.h:41,
from /usr/include/vtk-5.10/vtkVersion.h:29,
from Example.cpp:3:
/usr/include/c++/5/backward/backward_warning.h:32:2: warning: #warning This file includes at least one deprecated or antiquated header which may be removed without further notice at a future date. Please use a non-deprecated interface with equivalent functionality instead. For a listing of replacement headers and interfaces, consult the file backward_warning.h. To disable this warning use -Wno-deprecated. [-Wcpp]
#warning \
^
If VTK is not installed you can simply install it with sudo apt-get install libvtk5-dev
Why does the warnings appeared? In my code I have very strict compiler flags and I treat warnings as errors. However, not all external libraries are coded with such strict compiler flags, I am able to get away with including the external headers with the -isystem flag but VTK is giving me problems. My ugly workaround is adding -Wno-deprecated in my own compiler flags to get pass it but obviously this is not the right way to do it. What's the best way to solve this?
For both Clang and GCC, the -isystem flag adds a "system" include path, which causes the compiler not to emit warnings related to code found in those headers.
However, running clang-check on my code, I see the following warning:
In file included from <myfile>.cpp:1:
In file included from <Qt-path>/gcc_64/include/QtCore/QCoreApplication:1:
In file included from <Qt-path>/gcc_64/include/QtCore/qcoreapplication.h:40:
<Qt-path>/gcc_64/include/QtCore/qobject.h:235:16: warning: Potential memory leak
return connectImpl(sender, reinterpret_cast<void **>(&signal),
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1 warning generated.
...so it would appear that clang-check does not treat -isystem include paths differently from -I include paths. Am I misusing the tool or misinterpreting the output (i.e., is this actually a potential error in my code)? Is there another way to explicitly ignore errors from Qt headers when running clang-check?
This is because you also have to include the "QtCore" directory via-"isystem", in addition to just the base Qt include directory. This is because Clang finds a more specific include (QT -Is the modules as well) and uses that. See the Clang Manual for -isystem information on how the includes work.
Effectively you want to do the following:
contains(QT,"core") {
QMAKE_CXXFLAGS *= $$join(QMAKE_INCDIR_QT, " -isystem", "-isystem", "/QtCore")
}
And repeat this for all standard Qt modules (Designer, Gui, Help, Network, etc).
I had this problem and arrived at this question via search engine. So for anybody else like me; the answer is to use the -extra-arg twice!
For example
./MyTool -extra-arg="-isystem" -extra-arg="my/system/include/path" myfile.cpp
And you don't get all those warnings.