4

I want to remove/ignore a clang warning for a block of code and found multiple examples of how to use pragamas for this. For example if the warning is unused-variable you can disable it by using:

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

int a;

#pragma clang diagnostic pop

However the problem is that I do not get a warning in the output when building the repository, I only get to know which clang check it is that gives the warning... And I can not find any other questions or documentations where this is the case. This is what my output looks:

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

I have tried hundreds of different combinations of how to ignore this but nothing works (using // NOLINT is not a viable option). Among the things that i have tried, here are some:

#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

Note, "fixing" the code is also not an option since it is third party code.

pablo285
  • 2,460
  • 4
  • 14
  • 38
JakobVinkas
  • 1,003
  • 7
  • 23
  • As a side note, this is a dangerous warning to disable even for a single variable, are you sure about it? – Afshin Jun 24 '21 at 13:19
  • @Afshin it sure it... but it is not my code and I have no intention to change it... I have also never had an issue and looking through the source code it seems as though the warning could never take place anyway. I'm new to clang but it seems to not always be fully logical in regards to what events actually could happen. – JakobVinkas Jun 24 '21 at 13:23
  • what is your build system?CMake? – Afshin Jun 24 '21 at 13:41
  • @Afshin I am using CMake and Ninja – JakobVinkas Jun 28 '21 at 05:58

3 Answers3

3

As mentioned in the comments the #pragma clang diagnostic approach can only be used to suppress compiler warnings. The warnings you refer to are coming from clang-static-analyzer which is now a part of clang-tidy.

The only two options to disable a specific clang-tidy check via code are the //NOLINT and //NOLINTNEXTLINE macros.

As you mentioned the code in question is third-party I will assume that you are not interested in analyzing it at all. Since you are using CMake this is easily done via .clang-tidy files. You can place a .clang-tidy file in the root directory of your project and list/configure the desired checks there like this:

Checks: '-*,cppcoreguidelines-*'

(this would enable all Cpp Core Guidelines checks).

Then in the directory where your third-party code is placed you can disable clang-tidy analysis via a .clang-tidy file placed in that directory. As .clang-tidy files cannot be empty or specify no checks, you can do this by "misconfiguring" a check like this:

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

For more details on this approach see this answer.

Alternatively you can use the .clang-tidy file in the third-party directory to disable only some checks.

pablo285
  • 2,460
  • 4
  • 14
  • 38
2

According to this, for Clang Static Analyzer you have to use:

#ifndef __clang_analyzer__
// code
#endif
0x5453
  • 12,753
  • 1
  • 32
  • 61
  • 1
    That seems to "remove" the code completely, I now get warning from other checks ([clang-analyzer-deadcode.DeadStores]) claiming that the code just above the block of code now has unused variables. Is this what is should do or have I implemented it wrong? – JakobVinkas Jun 24 '21 at 13:20
0

Best approach that comes to my mind is a little dependent to your build system. Let's assume that you have a sample code like this:

Main file:

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

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

This creates the clang tidy warning in the mentioned line. Now what You can do? Separate your code into 2 files:

File A:

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

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

Main file:

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

And now disable cland-tidy for File A. This is a sample, But I guess you understand my general idea. You cannot disable clang-tidy because it is in another library and you cannot touch that code for several reasons. //NOLINT does not work on function too. So just create a wrapper in a single file for using that library and disable clang-tidy in that wrapper file for whole file.

Afshin
  • 8,839
  • 1
  • 18
  • 53
  • So there is no way to use the #pragma method to remove the type of warning that I get? I would very much prefer to not change to much of the structure and the #pragma seemed as the perfect solution but I do not understand when to use it since I never get any warning as those presented in the #pragma examples..... – JakobVinkas Jun 28 '21 at 06:02
  • @JakobVinkas I think you misunderstand something. The warning that you get comes from `clang-tidy`, not `clang` (I didn't get your warning until I enabled `clang-tidy`). On the other hand, `#pragma clang diagnostic` disables warning for `clang`, not `clang-tidy`. The only way to disable `clang-tidy` warnings are `//NOLINT` comments, so you cannot use `#pragma` for it. – Afshin Jun 28 '21 at 06:24
  • So the code refactoring and file ignoring is the only viable when the warning comes from a function call to a third party code base? – JakobVinkas Jun 28 '21 at 06:26
  • @JakobVinkas This is the only way that comes into my mind. To be more specific, I have not tested it myself, but theoretically it should work. You can test it on a small example(like mine first) before applying on whole project. Another way is disabling clang-tidy for whole project or the file that uses library. But you may miss other clang-tidy warnings if you do so. But if it is already enabled right now, you probably want it :D – Afshin Jun 28 '21 at 06:29
  • How do I disable only a single file from the check? As you can tell I am new to the clang-tidy ;) I have a cmake file with `set(CLANG_TIDY_ARGS --checks=clang-analyzer-cplusplus.*)` but it is a rather large project and I can not find where to select which files should be checked... – JakobVinkas Jun 28 '21 at 06:37
  • @JakobVinkas disabling for a single file in cmake may be a little hacky approach. but the line the you send me from cmake seems to be a custom way to run clang-tidy. You need to check whole cmake to see how they integrate it. – Afshin Jun 28 '21 at 06:50