'-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:
- change 'source' to 'source-inplace'
- 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:
-
test file
int main(){ abc = 1; }
-
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
-
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)
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)