0

I run clang-tidy on a folder and it shows

Use -header-filter=.* to display errors from all non-system headers. Use -system-headers to display errors from system headers as well.
Found compiler error(s).

But it did not show additional message on the details of the error. Btw, log file is also not produced. What could be the way to inspect the error?

kstn
  • 537
  • 4
  • 14
  • Is the file compilable? Have you followed clang-tidy advice: Use `-header-filter=.*` to display errors from all non-system headers? – 273K Aug 28 '23 at 15:15

1 Answers1

0

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.

Scott McPeak
  • 8,803
  • 2
  • 40
  • 79