Message: "Use -header-filter=..."
The message:
Use -header-filter=.* to display errors from all non-system headers. Use -system-headers to display errors from system headers as well.
means that there were some findings that were not shown because they
were in a file that is not the primary source file and that did not
match the header filter setting.
The message is produced at
ClangTidyMain.cpp:290:
if (Stats.ErrorsIgnoredNonUserCode)
llvm::errs() << "Use -header-filter=.* to display errors from all "
"non-system headers. Use -system-headers to display "
"errors from system headers as well.\n";
The ErrorsIgnoredNonUserCode
counter is incremented at
ClangTidyDiagnosticConsumer.cpp:309:
} else if (!LastErrorRelatesToUserCode) {
++Context.Stats.ErrorsIgnoredNonUserCode;
Errors.pop_back(); // <------- discards the finding
The LastErrorRelatesToUserCode
flag is initially false
, but can be
set to true
at
ClangTidyDiagnosticConsumer.cpp:547:
LastErrorRelatesToUserCode = LastErrorRelatesToUserCode ||
Sources.isInMainFile(Location) ||
getHeaderFilter()->match(FileName);
So, if clang-tidy
wanted to report something, but chose not to because
of its location, the "Use -header-filter=..." message is printed.
Option: -header-filter
If you want to see the findings that were suppressed, then follow the
instructions in the message and add:
-header-filter=.*
to the clang-tidy
command line.
Although, I would suggest putting quotes around the .*
part in order
to ensure that the shell does not expand it:
-header-filter='.*'
(It usually works without quotes because there will usually not be any
files in the current directory that match it as a glob expression.)
The documentation for this
flag says:
--header-filter=<string> - Regular expression matching the names of the
headers to output diagnostics from. Diagnostics
from the main file of each translation unit are
always displayed.
Can be used together with -line-filter.
This option overrides the 'HeaderFilterRegex'
option in .clang-tidy file, if any.
Note that the message talks about -header-filter
(one leading hyphen)
and the documentation talks about --header-filter
(two leading
hyphens). Both options have the same effect.
Also, be aware that many of the checks enabled by default with
clang-tidy
do not need the -header-filter
flag to report issues in
functions defined in header files because they also report a call site
in the primary source file. (And if there is no call site in the
primary source file, they do not report at all, even with
-header-filter=.*
.)
Option: -system-headers
Even with -header-filter='.*'
, the "Use -header-filter=..." message
can be produced if there is a finding in a "system" header, such as one
found via the -isystem
search path option. In that case, you have to
also pass -system-headers
or --system-headers
:
--system-headers - Display the errors from system headers.
This option overrides the 'SystemHeaders' option
in .clang-tidy file, if any.
Example of header filtering
I'll demonstrate these options using these files:
// psf.cc
#include <sys-header.h>
#include "header.h"
struct PSFClass { PSFClass(int); };
// header.h
struct HeaderClass { HeaderClass(int); };
// mysys/sys-header.h
struct SysHeaderClass { SysHeaderClass(int); };
Running clang-tidy
(version 16.0.0) with the
google-explicit-constructor
check, but only default header filters:
$ clang-tidy -checks='-*,google-explicit-constructor' psf.cc -- -isystem mysys
3 warnings generated.
<path>/psf.cc:4:19: warning: single-argument constructors must be marked explicit to avoid unintentional implicit conversions [google-explicit-constructor]
struct PSFClass { PSFClass(int); };
^
explicit
Suppressed 2 warnings (2 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.
Adding -header-filter=.*
:
$ clang-tidy -header-filter='.*' -checks='-*,google-explicit-constructor' psf.cc -- -isystem mysys
3 warnings generated.
<path>/header.h:2:22: warning: single-argument constructors must be marked explicit to avoid unintentional implicit conversions [google-explicit-constructor]
struct HeaderClass { HeaderClass(int); };
^
explicit
<path>/psf.cc:4:19: warning: single-argument constructors must be marked explicit to avoid unintentional implicit conversions [google-explicit-constructor]
struct PSFClass { PSFClass(int); };
^
explicit
Suppressed 1 warnings (1 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.
Adding -system-headers
:
$ clang-tidy -header-filter='.*' -system-headers -checks='-*,google-explicit-constructor' psf.cc -- -isystem mysys
3 warnings generated.
<path>/header.h:2:22: warning: single-argument constructors must be marked explicit to avoid unintentional implicit conversions [google-explicit-constructor]
struct HeaderClass { HeaderClass(int); };
^
explicit
<path>/psf.cc:4:19: warning: single-argument constructors must be marked explicit to avoid unintentional implicit conversions [google-explicit-constructor]
struct PSFClass { PSFClass(int); };
^
explicit
mysys/sys-header.h:2:25: warning: single-argument constructors must be marked explicit to avoid unintentional implicit conversions [google-explicit-constructor]
struct SysHeaderClass { SysHeaderClass(int); };
^
Anomaly: on the final finding, clang-tidy
does not print the word
explicit
below the caret (^
). I don't know why.
Message: "Found compiler error(s)."
Independent of the above, clang-tidy
will print:
Found compiler error(s).
if the parser encountered errors in the code before reaching the stage
of running the clang-tidy
checks. These errors would be reported by
clang
itself as well.
If you see this message, then clang-tidy
is not able to fully
understand the code, so fixing these messages should be the first
priority. Basically, work on getting clang
to compile the code
cleanly first, then consider using clang-tidy
.