能否针对特定代码分支抑制clang-tidy相关告警?
问题背景
我使用LLVM 12.0.0版本,某依赖库中存在一段仅用于单元测试的特殊代码分支——正常业务场景下该分支永远不会被执行。当项目引入该库并通过clang-tidy做静态代码分析时,工具会基于这段不可达代码报告潜在错误。
示例代码如下:
#include <iostream> // 库代码部分 class Test { public: int number; }; Test instance; const Test& getMemory(bool fork) { if (fork) { return instance; } else { // PROBLEM SOURCE! // 此分支仅用于测试,永远不会执行,希望抑制所有与此行相关的clang-tidy告警 return *(new Test); } } // 项目业务代码 int test(bool fork) { // PROBLEM WARNING! // clang-tidy在此处报告与上述不可达分支相关的错误 Test myInstance = getMemory(fork); myInstance.number = 123; std::cout << "Number is " << myInstance.number << std::endl; return 0; }
当前困境:在PROBLEM SOURCE处添加// NOLINTNEXTLINE无法解决问题,clang-tidy仍会在PROBLEM WARNING位置报告错误。我不想在项目代码中添加抑制语句(避免污染业务代码),也不想完全禁用该库的clang-tidy告警(库的其他部分可能存在有价值的问题提示)。请问能否选择性抑制与该特定不可达分支相关的所有告警——不是抑制分支内部代码的告警,而是抑制由该分支引发的其他位置的告警?
解决方案
1. 在库代码中标记分支不可达(推荐)
直接在库的测试专用分支中添加__builtin_unreachable(),告诉编译器和clang-tidy该分支永远不会被执行,工具会忽略此分支的代码分析,自然不会在项目代码中触发相关告警。
修改后的库代码:
const Test& getMemory(bool fork) { if (fork) { return instance; } else { __builtin_unreachable(); // 明确标记此分支不可达 return *(new Test); } }
这种方式无需修改项目代码,也不会影响库其他代码的clang-tidy检查。
2. 通过clang-tidy配置文件做精准抑制(无法修改库代码时使用)
如果无法修改依赖库的代码,可以在项目的.clang-tidy配置文件中,针对触发告警的具体规则,添加对该库函数的豁免。
例如,若clang-tidy报告的是cppcoreguidelines-owning-memory规则的错误,可在配置中添加:
CheckOptions: - key: cppcoreguidelines-owning-memory.IgnoreReturnsFromFunctions value: 'getMemory'
此方法需要明确知道触发告警的规则名称,可通过clang-tidy的输出信息获取。
3. 给库函数添加返回值属性
给getMemory函数添加[[clang::returns_nonnull]]属性,明确标记函数返回的引用始终有效,也能让clang-tidy忽略基于不可达分支的错误推断:
[[clang::returns_nonnull]] const Test& getMemory(bool fork) { // 原函数代码 }
内容的提问来源于stack exchange,提问作者Benjamin Bihler

