使用 #pragma 删除基于 clang 检查的 clang 警告

Using #pragma to remove clang warnings based on clang check

我想 remove/ignore 对代码块发出 clang 警告,并找到了多个关于如何为此使用 pragamas 的示例。例如,如果警告是 unused-variable,您可以使用以下方法禁用它:

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-variable"

int a;

#pragma clang diagnostic pop

但是问题是我在构建存储库时没有在输出中收到警告,我只知道发出警告的是哪个 clang 检查...而且我找不到任何其他问题或在这种情况下的文档。这是我的输出结果:

warning: Use of memory after it is freed [clang-analyzer-cplusplus.NewDelete]

我已经尝试了数百种不同的组合来忽略它,但没有任何效果(使用 // NOLINT 不是一个可行的选择)。在我尝试过的事情中,这里有一些:

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Winline-new-delete"
#pragma clang diagnostic ignored "-Wmost"
#pragma clang diagnostic ignored "-Weverything"
#pragma clang diagnostic ignored "clang-analyzer-cplusplus.NewDelete"
#pragma clang diagnostic ignored "-Wclang-analyzer-cplusplus.NewDelete"
#pragma clang diagnostic ignored "-clang-analyzer-cplusplus.NewDelete"
#pragma clang diagnostic ignored "-W-NewDelete"
#pragma clang diagnostic ignored "-W-new-delete"

// code

#pragma clang diagnostic pop

请注意,“修复”代码也不是一个选项,因为它是第三方代码。

根据 this,对于 Clang 静态分析器,您必须使用:

#ifndef __clang_analyzer__
// code
#endif

我想到的最佳方法有点依赖于您的构建系统。假设您有这样的示例代码:

主文件:

int main()
{
    // ...
    int *a = new int;
    *a = 10;
    delete a;

    if (::rand() < 10) {
        std::cout  << *a; //<-- clang tidy warning here
    }
    //...
}

这会在上述行中创建 clang tidy 警告。现在你能做什么?将您的代码分成 2 个文件:

文件A:

void foo() {
    int *a = new int;
    *a = 10;
    delete a;

    if (::rand() < 10) {
        std::cout  << *a; //<-- clang tidy warning here
    }
}

主文件:

int main()
{
    // ...
    foo();
    //...
}

现在为 文件 A 禁用 cland-tidy。这是一个示例,但我想您了解我的总体思路。您不能禁用 clang-tidy,因为它在另一个库中,并且出于多种原因您不能触摸该代码。 //NOLINT 也不适用于函数。因此,只需在单个文件中创建一个包装器以使用该库,并在该包装器文件中为整个文件禁用 clang-tidy

如评论中所述,#pragma clang diagnostic 方法只能用于抑制 compiler 警告。您提到的警告来自 clang-static-analyzer 现在是 clang-tidy.

的一部分

通过代码禁用特定 clang-tidy 检查的唯一两个选项是 //NOLINT//NOLINTNEXTLINE 宏。

正如您提到的,有问题的代码是第三方的,我假设您根本没有兴趣分析它。由于您使用的是 CMake,因此可以通过 .clang-tidy 文件轻松完成。您可以在项目的根目录中放置一个 .clang-tidy 文件,然后 list/configure 在那里进行所需的检查,如下所示:

Checks: '-*,cppcoreguidelines-*'

(这将启用所有 Cpp 核心指南检查)。

然后在放置第三方代码的目录中,您可以通过放置在该目录中的 .clang-tidy 文件禁用 clang-tidy 分析。由于 .clang-tidy 文件不能为空或不指定检查,您可以通过“错误配置”这样的检查来做到这一点:

Checks: '-*,misc-definitions-in-headers'
CheckOptions:
  - { key: HeaderFileExtensions,          value: "x" }

有关此方法的更多详细信息,请参阅

或者,您可以使用第三方目录中的 .clang-tidy 文件来仅禁用某些检查。