tldr;>如何在clang-tidy中隐藏系统标题中的警告?
我有以下最小的示例源文件,它会在系统标题中触发一个铿锵的警告:
#include <future>
int main() {
std::promise<int> p;
p.set_value(3);
}
在Ubuntu 17.04上使用clang-tidy 4.0.0使用libstdc ++ 7.0.1调用它:
$ clang-tidy main.cpp -extra-arg=-std=c++14
产量
Running without flags.
1 warning generated.
/usr/lib/gcc/x86_64-linux-gnu/7.0.1/../../../../include/c++/7.0.1/mutex:693:5: warning: Address of stack memory associated with local variable '__callable' is still referred to by the global variable '__once_callable' upon returning to the caller. This will be a dangling reference [clang-analyzer-core.StackAddressEscape]
}
^
/home/user/main.cpp:5:3: note: Calling 'promise::set_value'
p.set_value(3);
^
/usr/lib/gcc/x86_64-linux-gnu/7.0.1/../../../../include/c++/7.0.1/future:1094:9: note: Calling '_State_baseV2::_M_set_result'
{ _M_future->_M_set_result(_State::__setter(this, std::move(__r))); }
^
/usr/lib/gcc/x86_64-linux-gnu/7.0.1/../../../../include/c++/7.0.1/future:401:2: note: Calling 'call_once'
call_once(_M_once, &_State_baseV2::_M_do_set, this,
^
/usr/lib/gcc/x86_64-linux-gnu/7.0.1/../../../../include/c++/7.0.1/mutex:691:11: note: Assuming '__e' is 0
if (__e)
^
/usr/lib/gcc/x86_64-linux-gnu/7.0.1/../../../../include/c++/7.0.1/mutex:691:7: note: Taking false branch
if (__e)
^
/usr/lib/gcc/x86_64-linux-gnu/7.0.1/../../../../include/c++/7.0.1/mutex:693:5: note: Address of stack memory associated with local variable '__callable' is still referred to by the global variable '__once_callable' upon returning to the caller. This will be a dangling reference
}
我想在系统标头中隐藏警告。我尝试了以下方法:
$ clang-tidy -extra-arg=-std=c++14 main.cpp -header-filter=$(realpath .) -system-headers=0
但警告仍显示。
答案 0 :(得分:4)
我最初得出的结论是这是不可能的,但是我有一个非常接近的黑客。
编译时,我使用CMAKE_EXPORT_COMPILE_COMMANDS = ON生成一个compile_commands.json文件,该文件显示了每个编译的cpp文件传递给编译器的命令。运行clang-tidy
时,我给它提供-p选项,使其指向包含该文件的目录。
此文件中的典型条目如下所示:
{
"directory": "/project/build/package1",
"command": "/usr/bin/clang++-9 -I/opt/thirdparty/include -isystem /usr/include . . . /project/src/package1/src/foo.cpp",
"file": "/project/src/package1/src/foo.cpp"
},
如果我重新编写此文件,以使-I/opt/thirdparty/include
成为-isystem /opt/thirdparty/include
,则/ opt / third-party / include中以前有问题的标头将被忽略,因为clang-tidy会将其视为系统标头。 / p>
我使用sed
重写文件
# Trick clang-tidy into thinking anything in /opt/thirdparty/include is a system header
sed -i 's|-I/opt/thirdparty/include|-isystem /opt/thirdparty/include|g' build/compile_commands.json
# Run clang-tidy using the run-clang-tidy python wrapper
run-clang-tidy.py -p build -header-filter .* $(find src -iname "*.cpp")
答案 1 :(得分:3)
我也遇到了这个问题,并且花了一些时间试图解决这个问题,但我找不到在铿锵声中禁用此类警告的方法。
从阅读this discussion on the LLVM issue tracker regarding a similar issue开始,我得到的印象是问题是从clang-tidy的角度来看,警告实际上位于main.cpp
,因为set_value
的调用来自那里
我的解决方法是在clang-tidy中禁用静态分析检查,并使用scan-build utility运行clang的静态分析,这似乎可以避免这些问题。例如,使用您的main.cpp
:
$ scan-build-3.9 clang++ -std=c++14 main.cpp
scan-build: Using '/usr/lib/llvm-3.9/bin/clang' for static analysis
In file included from main.cpp:1:
In file included from /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0/future:39:
/usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0/mutex:621:11: warning: Address of stack memory associated with local variable '__callable' is still referred to by the global variable '__once_callable' upon returning to the caller. This will be a dangling reference
if (__e)
^~~
1 warning generated.
scan-build: Removing directory '/tmp/scan-build-2017-12-02-112018-13035-1' because it contains no reports.
scan-build: No bugs found.
分析器在系统头中发现相同的错误,但它足够聪明,不能将其包含在最终报告中。 (“没有发现错误”)
如果您对样式指南类型警告感兴趣,例如modernize-*
或readability-*
,您仍然需要单独运行clang-tidy。