clang-tidy:如何压制警告?

问题描述 投票:9回答:4

我最近开始尝试使用llvm的clang-tidy工具。现在我试图压制来自第三方库代码的错误警告。为此,我想使用命令行选项

-header-filter=<string>-line-filter=<string>

但到目前为止没有成功。所以对于时间有限的人,我会在开头提出这个问题,然后再解释我已经尝试过的问题。

Question

我需要为clang-tidy工具提供什么选项来抑制来自某个行和文件的警告?

如果这是不可能的

什么选项可以抑制外部头文件的警告?


What I did so far

我对clang-tidy的原始调用看起来像这样

clang-tidy-3.8 -checks=-*,clang-analyzer-*,-clang-analyzer-alpha* -p Generated/LinuxMakeClangNoPCH Sources/CodeAssistant/ModuleListsFileManipulator_fixtures.cpp

我要压制的产生警告的第一行看起来像这样

.../gmock/gmock-spec-builders.h:1272:5: warning: Use of memory after it is freed [clang-analyzer-cplusplus.NewDelete]
    return function_mocker_->AddNewExpectation(

gmock人告诉我这是假阳性所以我想压制它。首先,我尝试使用-line-filter=<string>选项。文件说:

  -line-filter=<string>      - List of files with line ranges to filter the
                               warnings. Can be used together with
                               -header-filter. The format of the list is a JSON
                               array of objects:
                                 [
                                   {"name":"file1.cpp","lines":[[1,3],[5,7]]},
                                   {"name":"file2.h"}
                                 ]

我假设过滤掉了给定行中的警告。但是文档没有说明它们是否被过滤掉了。在一些摆弄之后我创建了一个包含内容的.json文件

[
  {"name":"gmock-spec-builders.h","lines":[[1272,1272]]}
]

并将命令行修改为

clang-tidy-3.8 -checks=-*,clang-analyzer-*,-clang-analyzer-alpha* -p Generated/LinuxMakeClangNoPCH -line-filter="$(< Sources/CodeAssistant/CodeAssistant_ClangTidySuppressions.json)" Sources/CodeAssistant/ModuleListsFileManipulator_fixtures.cpp

它将文件的内容写入参数。这会抑制警告,但不仅是此警告,而是来自ModuleListsFileManipulator_fixtures.cpp文件的所有警告。我尝试了更多的东西,但我无法使它工作。

所以我尝试了-header-filter=<string>选项。这里的文档指出,必须提供一个正则表达式,该表达式匹配应显示诊断的所有头文件。好吧,我想,让我们使用一个regualar表达式来匹配与分析的.cpp文件在同一文件夹中的所有内容。我可以忍受这一点,虽然它可能会删除因使用外部标头错误导致的警告。

在这里,我不确定正则表达式是否必须匹配完整(绝对)文件名或只是文件名的一部分。我试过了

-header-filter=.*\/CodeAssistant\/.*.h

它匹配CodeAssistant文件夹中的所有绝对头文件名,但它没有抑制gmock-spec-builders.h文件中的警告。

因此,我希望单独抑制每个警告,以便我可以确定每个警告是否是真正的问题,但如果这是不可能的,我也可以抑制来自整个外部标题的警告。

感谢您的时间。

suppress-warnings clang-static-analyzer clang-tidy
4个回答
2
投票

我通过将// NOLINT添加到gmock-spec-builders.h的第1790行来解决了这个问题

这是差异:

--- gmock-spec-builders.orig.h  2016-09-17 09:46:48.527313088 +0200
+++ gmock-spec-builders.h       2016-09-17 09:46:58.958353697 +0200
@@ -1787,7 +1787,7 @@
 #define ON_CALL(obj, call) GMOCK_ON_CALL_IMPL_(obj, call)

 #define GMOCK_EXPECT_CALL_IMPL_(obj, call) \
-    ((obj).gmock_##call).InternalExpectedAt(__FILE__, __LINE__, #obj, #call)
+    ((obj).gmock_##call).InternalExpectedAt(__FILE__, __LINE__, #obj, #call) // NOLINT
 #define EXPECT_CALL(obj, call) GMOCK_EXPECT_CALL_IMPL_(obj, call)

 #endif  // GMOCK_INCLUDE_GMOCK_GMOCK_SPEC_BUILDERS_H_

对于这个补丁的上游(我在代码中看到其他NOLINT)或者发布一个关于整齐的人的错误报告会很好。


4
投票

我发现了另一种非侵入性(不向第三方库添加// NOLINT)抑制警告的方法。例如,当前版本的Google Test未通过某些cppcoreguidelines-*检查。以下代码允许您验证当前差异,排除包含gtest宏的行:

git diff -U3 | sed '
    s/^+\( *TEST(\)/ \1/;
    s/^+\( *EXPECT_[A-Z]*(\)/ \1/;
    s/^+\( *ASSERT_[A-Z]*(\)/ \1/;
' | recountdiff | interdiff -U0 /dev/null /dev/stdin | clang-tidy-diff.py -p1 -path build

它假设之前生成了文件build/compile_commands.json,并且您的环境中可以使用clang-tidy-diff.py。来自recountdiffinterdiffpatchutils是操纵补丁的标准工具。

该脚本的工作原理如下:

  1. git diff -U3生成一个包含3个上下文行的补丁。
  2. sed ...从不需要的行中删除前缀+,即将它们转换为上下文。
  3. recountdiff纠正块头中的偏移量(在第一个范围内)。
  4. interdiff -U0 /dev/null /dev/stdin只是从补丁中删除所有上下文行。结果,它分裂了最初的帅哥。
  5. clang-tidy-diff.py只读取块头的第二个范围,并通过clang-tidy选项将它们传递给-line-filter

UPD:为interdiff提供足够数量的上下文行非常重要,否则可能会在结果中产生一些瑕疵。参见man interdiff的引文:

为获得最佳结果,差异必须至少有三行上下文。

特别是,我发现git diff -U0 | ... | interdiff在分割块之后会产生一些伪文字$!otj


1
投票

我还遇到了原始补丁没有覆盖的其他一些案例。在尝试修复此问题时,我还遇到了clang-tidy(https://llvm.org/bugs/show_bug.cgi?id=30565)中的分段错误。目前我还没有成功地压制所有错误。

如果/当我找到它时,我会在这里提供更新的答案:)


0
投票

我无法用命令行选项实现我想要的,所以我将在cpp文件中使用// NOLINT注释,这是由接受的答案提出的。

我也会尝试将修复程序推送到googletest。

我发现-line-filter选项中的行被过滤了。但是给出具体的行并不是我问题的真正解决方案。我宁愿需要像Valgrind中实现的抑制机制。

© www.soinside.com 2019 - 2024. All rights reserved.