From 78942df284a4a00c59a6edcc187684cdbc333fb9 Mon Sep 17 00:00:00 2001 From: Nicolas Pauss Date: Sun, 25 Sep 2022 02:02:43 +0200 Subject: cc: use '-x c*-header' for header files for C and C++ linters. (#4318) When linting an header file in C or C++, `-x c-header` or `-x c++-header` should be used instead of `-x c` or `-x c++`. Using `-x c` or `-x c++` for headers files can lead to unused variables and functions marked as static inlined as seen in #4096. Using `-x c-header` or `-x c++-header` solve these issues. The list of file extensions that are considered as header files can be configured with the variables `g:ale_c_cc_header_exts` and `g:ale_cpp_cc_header_exts`. --- ale_linters/c/cc.vim | 5 ++++- ale_linters/cpp/cc.vim | 5 ++++- autoload/ale/c.vim | 11 +++++++++++ doc/ale-c.txt | 11 +++++++++++ doc/ale-cpp.txt | 11 +++++++++++ test/linter/test_c_cc.vader | 16 ++++++++++++++++ test/linter/test_cpp_cc.vader | 16 ++++++++++++++++ 7 files changed, 73 insertions(+), 2 deletions(-) diff --git a/ale_linters/c/cc.vim b/ale_linters/c/cc.vim index 5655fbf7..d0215041 100644 --- a/ale_linters/c/cc.vim +++ b/ale_linters/c/cc.vim @@ -3,6 +3,7 @@ call ale#Set('c_cc_executable', '') call ale#Set('c_cc_options', '-std=c11 -Wall') +call ale#Set('c_cc_header_exts', ['h']) function! ale_linters#c#cc#GetExecutable(buffer) abort let l:executable = ale#Var(a:buffer, 'c_cc_executable') @@ -22,6 +23,8 @@ endfunction function! ale_linters#c#cc#GetCommand(buffer, output) abort let l:cflags = ale#c#GetCFlags(a:buffer, a:output) let l:ale_flags = ale#Var(a:buffer, 'c_cc_options') + let l:header_exts = ale#Var(a:buffer, 'c_cc_header_exts') + let l:lang_flag = ale#c#GetLanguageFlag(a:buffer, l:header_exts, 'c') if l:cflags =~# '-std=' let l:ale_flags = substitute( @@ -36,7 +39,7 @@ function! ale_linters#c#cc#GetCommand(buffer, output) abort " " `-o /dev/null` or `-o null` is needed to catch all errors, " -fsyntax-only doesn't catch everything. - return '%e -S -x c' + return '%e -S -x ' . l:lang_flag \ . ' -o ' . g:ale#util#nul_file \ . ' -iquote %s:h' \ . ale#Pad(l:cflags) diff --git a/ale_linters/cpp/cc.vim b/ale_linters/cpp/cc.vim index ffb8f068..f8021531 100644 --- a/ale_linters/cpp/cc.vim +++ b/ale_linters/cpp/cc.vim @@ -3,6 +3,7 @@ call ale#Set('cpp_cc_executable', '') call ale#Set('cpp_cc_options', '-std=c++14 -Wall') +call ale#Set('cpp_cc_header_exts', ['h', 'hpp']) function! ale_linters#cpp#cc#GetExecutable(buffer) abort let l:executable = ale#Var(a:buffer, 'cpp_cc_executable') @@ -22,6 +23,8 @@ endfunction function! ale_linters#cpp#cc#GetCommand(buffer, output) abort let l:cflags = ale#c#GetCFlags(a:buffer, a:output) let l:ale_flags = ale#Var(a:buffer, 'cpp_cc_options') + let l:header_exts = ale#Var(a:buffer, 'cpp_cc_header_exts') + let l:lang_flag = ale#c#GetLanguageFlag(a:buffer, l:header_exts, 'c++') if l:cflags =~# '-std=' let l:ale_flags = substitute( @@ -36,7 +39,7 @@ function! ale_linters#cpp#cc#GetCommand(buffer, output) abort " " `-o /dev/null` or `-o null` is needed to catch all errors, " -fsyntax-only doesn't catch everything. - return '%e -S -x c++' + return '%e -S -x ' . l:lang_flag \ . ' -o ' . g:ale#util#nul_file \ . ' -iquote %s:h' \ . ale#Pad(l:cflags) diff --git a/autoload/ale/c.vim b/autoload/ale/c.vim index e729aec8..4a9b80fb 100644 --- a/autoload/ale/c.vim +++ b/autoload/ale/c.vim @@ -585,3 +585,14 @@ function! ale#c#IncludeOptions(include_paths) abort return join(l:option_list) endfunction + +" Get the language flag depending on if the file is a header or not. +function! ale#c#GetLanguageFlag(buffer, header_exts, linter_lang) abort + let l:buf_ext = expand('#' . a:buffer . ':e') + + if index(a:header_exts, l:buf_ext) >= 0 + return a:linter_lang . '-header' + endif + + return a:linter_lang +endfunction diff --git a/doc/ale-c.txt b/doc/ale-c.txt index bd8c4937..c71a81de 100644 --- a/doc/ale-c.txt +++ b/doc/ale-c.txt @@ -136,6 +136,17 @@ g:ale_c_cc_options *g:ale_c_cc_options* This variable can be change to modify flags given to the C compiler. +g:ale_c_cc_header_exts *g:ale_c_cc_header_exts* + *b:ale_c_cc_header_exts* + Type: |List| + Default: `['h']` + + This variable can be change to modify the list of extensions of the files + considered as header files. + + ALE will use `'-x c-header'` instead of `'-x c'` for header files. + + =============================================================================== ccls *ale-c-ccls* diff --git a/doc/ale-cpp.txt b/doc/ale-cpp.txt index 1f079205..a09bc021 100644 --- a/doc/ale-cpp.txt +++ b/doc/ale-cpp.txt @@ -65,6 +65,17 @@ g:ale_cpp_cc_options *g:ale_cpp_cc_options* This variable can be change to modify flags given to the C++ compiler. +g:ale_cpp_cc_header_exts *g:ale_cpp_cc_header_exts* + *b:ale_cpp_cc_header_exts* + Type: |List| + Default: `['h', 'hpp']` + + This variable can be change to modify the list of extensions of the files + considered as header files. + + ALE will use `'-x c++-header'` instead of `'-x c++'` for header files. + + =============================================================================== ccls *ale-cpp-ccls* diff --git a/test/linter/test_c_cc.vader b/test/linter/test_c_cc.vader index c8c2de7d..953aa238 100644 --- a/test/linter/test_c_cc.vader +++ b/test/linter/test_c_cc.vader @@ -53,3 +53,19 @@ Execute(The -std flag should be replaced by parsed C flags): let g:get_cflags_return_value = '-std=c99' AssertLinter 'gcc', ale#Escape('gcc') . b:command_tail + +Execute(The header files should use -x c-header): + let b:command_tail = substitute(b:command_tail, '-x c', '-x c-header', '') + + call ale#test#SetFilename('../test-files/c/makefile_project/subdir/test.h') + + AssertLinter 'gcc', ale#Escape('gcc') . b:command_tail + +Execute(The header file extensions should be configurable): + let b:command_tail = substitute(b:command_tail, '-x c', '-x c-header', '') + + call ale#assert#SetUpLinterTest('c', 'cc') + let b:ale_c_cc_header_exts = ['json'] + call ale#test#SetFilename('../test-files/c/json_project/build/compile_commands.json') + + AssertLinter 'gcc', ale#Escape('gcc') . b:command_tail diff --git a/test/linter/test_cpp_cc.vader b/test/linter/test_cpp_cc.vader index dec3a07c..44fe4521 100644 --- a/test/linter/test_cpp_cc.vader +++ b/test/linter/test_cpp_cc.vader @@ -53,3 +53,19 @@ Execute(The -std flag should be replaced by parsed C flags): let g:get_cflags_return_value = '-std=c++11' AssertLinter 'gcc', ale#Escape('gcc') . b:command_tail + +Execute(The header files should use -x c++-header): + let b:command_tail = substitute(b:command_tail, '-x c++', '-x c++-header', '') + + call ale#test#SetFilename('../test-files/c/hpp_file_project/test.hpp') + + AssertLinter 'gcc', ale#Escape('gcc') . b:command_tail + +Execute(The header file extensions should be configurable): + let b:command_tail = substitute(b:command_tail, '-x c++', '-x c++-header', '') + + call ale#assert#SetUpLinterTest('cpp', 'cc') + let b:ale_cpp_cc_header_exts = ['json'] + call ale#test#SetFilename('../test-files/c/json_project/build/compile_commands.json') + + AssertLinter 'gcc', ale#Escape('gcc') . b:command_tail -- cgit v1.2.3