ch1bo / flycheck-clang-tidy

Flycheck syntax checker using clang-tidy

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

'-config=' can not correctly parse .clang-tidy file created by '-dump-config' (note: run via docker exec ...)

xwl opened this issue · comments

It looks like -config is expecting YAML format, but clang-tidy -dump-config generates some other format:

$ clang-tidy -dump-config - --
  ---
  Checks:          '-*,some-check'
  WarningsAsErrors: ''
  HeaderFilterRegex: ''

clang-tidy will report some YAML error:

LLVM ERROR: CommonOptionsParser: failed to parse command-line arguments. [CommonOptionsParser]: clang-tidy: 
Unknown command line argument '---'.  Try: 'clang-tidy --help'
clang-tidy: Did you mean '-h'?

I could work around it by passing empty string to -config option, i would also have to change the checker definition to use 'source-inplace' instead of 'source', such that clang-tidy can look up the config file from the parent directories.

To summary, i have two suggestions:

  1. change 'source' to 'source-inplace'
  2. make "-config=" default to "" unless flycheck-clang-tidy is set ?

I can't reproduce this with clang-tidy 10.0.1. Which version are you using? I'd like to avoid using source-inplace if possible, because it clutters the project dir.

I've added your 2nd suggestion. If flycheck-clang-tidy is nil, clang-tidy will be run with empty -config=.

Unknown command line argument '---'.

Sounds like the clang-tidy command line parser does not like the - -- you passed when dumping the config?

'- --' seems irrelevant, the generated file wil be the same.

@tastytea I'm using the same version. Try M-x flycheck-compile and select this checker. Actually I'm a bit surprised, that flycheck-buffer can still report error despite the failure shown in flycheck-compile.

Below are the detail steps to reproduce.

I start the emacs with -q:

  1. test file

     int main(){
         abc = 1;
     }
    
  2. generate the clang-tidy file use the -dump-config:

     bash-4.4# clang-tidy -dump-config > .clang-tidy
     bash-4.4# head .clang-tidy
     ---
     Checks:          'clang-diagnostic-*,clang-analyzer-*'
     WarningsAsErrors: ''
     HeaderFilterRegex: ''
     AnalyzeTemporaryDtors: false
     FormatStyle:     none
     CheckOptions:
     - key:             cert-dcl16-c.NewSuffixes
         value:           'L;LL;LU;LLU'
     - key:             cert-oop54-cpp.WarnOnlyIfThisHasSuspiciousField
     bash-4.4# clang-tidy --version
     LLVM (http://llvm.org/):
     LLVM version 10.0.1
    
  3. M-x flycheck-compile will show:

     -*- mode: compilation; default-directory: "~/tmp/" -*-
     Compilation started at Mon Nov 16 10:05:19
    
     //bin/clang-tidy -p build -extra-arg\=-I/Users/path/tmp/ -config\=---'
     'Checks\:\ \ \ \ \ \ \ \ \ \ \'clang-diagnostic-\*\,clang-analyzer-\*\''
     'WarningsAsErrors\:\ \'\''
     'HeaderFilterRegex\:\ \'\''
     'AnalyzeTemporaryDtors\:\ false'
     'FormatStyle\:\ \ \ \ \ none'
     'CheckOptions\:'
     '\ \ -\ key\:\ \ \ \ \ \ \ \ \ \ \ \ \ cert-dcl16-c.NewSuffixes'
     '\ \ \ \ value\:\ \ \ \ \ \ \ \ \ \ \ \'L\;LL\;LU\;LLU\''
     [snip]
     '...'
     ''
     ' /Users/path/tmp/foo.cpp
     YAML:1:1: error: not a mapping
     ---
     ^~~
     Error: invalid configuration specified.
     Invalid argument
    
     Compilation exited abnormally with code 1 at Mon Nov 16 10:05:26
    

Hm.. with my default config dumped into a .clang-tidy your reproduction steps yield a correct run of clang-tidy:

-*- mode: compilation; default-directory: "/tmp/foo/" -*-
Compilation started at Mon Nov 16 11:46:27

/usr/bin/clang-tidy -p build -extra-arg\=-I/tmp/foo/ -config\=---'
'Checks\:\ \ \ \ \ \ \ \ \ \ \'clang-diagnostic-\*\,clang-analyzer-\*\''
'WarningsAsErrors\:\ \'\''
'HeaderFilterRegex\:\ \'\''
'AnalyzeTemporaryDtors\:\ false'
'FormatStyle\:\ \ \ \ \ none'
'User\:\ \ \ \ \ \ \ \ \ \ \ \ ch1bo'
'CheckOptions\:'
'\ \ -\ key\:\ \ \ \ \ \ \ \ \ \ \ \ \ cert-dcl16-c.NewSuffixes'
'\ \ \ \ value\:\ \ \ \ \ \ \ \ \ \ \ \'L\;LL\;LU\;LLU\''
'\ \ -\ key\:\ \ \ \ \ \ \ \ \ \ \ \ \ cert-oop54-cpp.WarnOnlyIfThisHasSuspiciousField'
'\ \ \ \ value\:\ \ \ \ \ \ \ \ \ \ \ \'0\''
'\ \ -\ key\:\ \ \ \ \ \ \ \ \ \ \ \ \ cppcoreguidelines-explicit-virtual-functions.IgnoreDestructors'
'\ \ \ \ value\:\ \ \ \ \ \ \ \ \ \ \ \'1\''
'\ \ -\ key\:\ \ \ \ \ \ \ \ \ \ \ \ \ cppcoreguidelines-non-private-member-variables-in-classes.IgnoreClassesWithAllMemberVariablesBeingPublic'
'\ \ \ \ value\:\ \ \ \ \ \ \ \ \ \ \ \'1\''
'\ \ -\ key\:\ \ \ \ \ \ \ \ \ \ \ \ \ google-readability-braces-around-statements.ShortStatementLines'
'\ \ \ \ value\:\ \ \ \ \ \ \ \ \ \ \ \'1\''
'\ \ -\ key\:\ \ \ \ \ \ \ \ \ \ \ \ \ google-readability-function-size.StatementThreshold'
'\ \ \ \ value\:\ \ \ \ \ \ \ \ \ \ \ \'800\''
'\ \ -\ key\:\ \ \ \ \ \ \ \ \ \ \ \ \ google-readability-namespace-comments.ShortNamespaceLines'
'\ \ \ \ value\:\ \ \ \ \ \ \ \ \ \ \ \'10\''
'\ \ -\ key\:\ \ \ \ \ \ \ \ \ \ \ \ \ google-readability-namespace-comments.SpacesBeforeComments'
'\ \ \ \ value\:\ \ \ \ \ \ \ \ \ \ \ \'2\''
'\ \ -\ key\:\ \ \ \ \ \ \ \ \ \ \ \ \ modernize-loop-convert.MaxCopySize'
'\ \ \ \ value\:\ \ \ \ \ \ \ \ \ \ \ \'16\''
'\ \ -\ key\:\ \ \ \ \ \ \ \ \ \ \ \ \ modernize-loop-convert.MinConfidence'
'\ \ \ \ value\:\ \ \ \ \ \ \ \ \ \ \ reasonable'
'\ \ -\ key\:\ \ \ \ \ \ \ \ \ \ \ \ \ modernize-loop-convert.NamingStyle'
'\ \ \ \ value\:\ \ \ \ \ \ \ \ \ \ \ CamelCase'
'\ \ -\ key\:\ \ \ \ \ \ \ \ \ \ \ \ \ modernize-pass-by-value.IncludeStyle'
'\ \ \ \ value\:\ \ \ \ \ \ \ \ \ \ \ llvm'
'\ \ -\ key\:\ \ \ \ \ \ \ \ \ \ \ \ \ modernize-replace-auto-ptr.IncludeStyle'
'\ \ \ \ value\:\ \ \ \ \ \ \ \ \ \ \ llvm'
'\ \ -\ key\:\ \ \ \ \ \ \ \ \ \ \ \ \ modernize-use-nullptr.NullMacros'
'\ \ \ \ value\:\ \ \ \ \ \ \ \ \ \ \ \'NULL\''
'...'
''
' /tmp/foo/main.c
Error while trying to load a compilation database:
Could not auto-detect compilation database from directory "build"
No compilation database found in /tmp/foo/build or any parent directory
fixed-compilation-database: Error while opening fixed database: No such file or directory
json-compilation-database: Error while opening JSON database: No such file or directory
Running without flags.
1 error generated.
Error while processing /tmp/foo/main.c.
/tmp/foo/main.c:1:14: error: use of undeclared identifier 'abc' [clang-diagnostic-error]
int main() { abc = 1; }
             ^
Found compiler error(s).

Also other tests with a minimal config, e.g.

---
Checks:          '-clang-analyzer-cplusplus.NewDelete'
...

And two canonical examples from clang-tidy:

void testDivisionByZero() {
  int x = 1;
  int y = x % 0; // warn
}

void f(int *p);

void testUseAfterFree(int *p) {
  delete p;
  f(p); // warn: use after free
}

I was able to verify that this config is correctly used according to the flycheck-clang-tidy variable. In detail I did assert that the division by zero is still warned, but the use after free (NewDelete) is not. Note that by default all builtin checks are on and in particular the "core" checks cannot be turned off when other checks are still in use.

Can you try with a simpler config again? After all your error indicates problems when parsing the string given to -config.

I'm getting the same output as ch1bo. My init file is:

; Bootstrap straight (I omit that here for brevity)

(straight-use-package 'flycheck-clang-tidy)
(require 'flycheck-clang-tidy)

Edit:
init.el
.clang-tidy
flycheck-compile.log

Interesting.. I forgot to mention, i run the clang-tidy via docker. Maybe the arguments are not properly quoted by docker command line. I will try to find out more.

I could confirm that indeed the issue only happens when docker is in the middle.
And I can fix it by change:

(eval (concat "-config=" (flycheck-clang-tidy-get-config)))

to:

(eval (concat "-config=" (shell-quote-argument (flycheck-clang-tidy-get-config))))

But it will break the clang-tidy that is run directly on the host.. Not sure how to deal with this nicely. Maybe I just have to advice flycheck-clang-tidy-get-config?

The bigger question might be why clang-tidy doesn't support a config file argument..

I could confirm that indeed the issue only happens when docker is in the middle.

It seems that docker (or a shell in between) is un-escaping the command before it reaches clang-tidy? Can you prevent that?

Maybe I just have to advice flycheck-clang-tidy-get-config?

Yeah, I think that is the best solution.

i don't know how to do that on bash command line easily, with such large input from -config. I'd rather mess with elisp :)
I will go with the 'advice'.

Thanks for the help!

I could confirm that indeed the issue only happens when docker is in the middle.
And I can fix it by change:

(eval (concat "-config=" (flycheck-clang-tidy-get-config)))

to:

(eval (concat "-config=" (shell-quote-argument (flycheck-clang-tidy-get-config))))

But it will break the clang-tidy that is run directly on the host.. Not sure how to deal with this nicely. Maybe I just have to advice flycheck-clang-tidy-get-config?

The bigger question might be why clang-tidy doesn't support a config file argument..

-config=$(eval - cat ./.clang-tidy)