CodeNewbie Community 🌱

DeveloperTom404
DeveloperTom404

Posted on

Seamless static analysis integration and overcoming false positives

This article explores how the baseline approach streamlines static analyzer integration and discusses effective strategies for handling false positives.

1272_baseline/image1.png

Introducing the analyzer into a project with the baseline approach

A common challenge when introducing a static analyzer into an existing project is that this process rarely occurs at the "groundwork stage." That's why the analyzer floods users with warnings for the legacy code after the first run. For large codebases, warnings can quickly become overwhelming:

1272_baseline/image2.png

Now, imagine tackling all these warnings straight away—fixing errors and annotating each one. Not only would this consume significant time, but it might also drive developers crazy!

So, what's the solution?

A key point is that static analyzers require configuration before use. PVS-Studio, for example, offers over 1500 diagnostic rules across four languages. Naturally, not all diagnostic rules will suit your needs.

Let's take MISRA standards for C/C++ as an example. Our analyzer supports these standards with specific diagnostic rules. MISRA prioritizes safety and security, flagging even minor code issues—a necessity born from automotive software development but now critical in any high-stakes domain. If your code doesn't adhere to MISRA, its diagnostic rules will only add noise to your reports.

Note. If you are interested in MISRA standards, don't hesitate to explore our MISRA support page for details.

With the basics covered, let's address the core topic. Frenetically annotating and fixing every warning straight away isn't practical. Static analysis isn't introduced in a vacuum: the existing project code likely functions reliably.

Instead, we can treat the project state at integration time as a baseline and suppress all current warnings. This doesn't mean we shelve them: we're just putting them aside as technical debt to gradually fix them later. New post-integration warnings now become our immediate priority.

PVS-Studio static analyzer provides a suppression mode for such cases when the analyzer saves suppressed messages in so-called suppress files. This mode doesn't require altering source code—ideal for mass suppression. The analyzer records each warning's signature (including source context), preventing unnoticed reappearances in future reports.

How to suppress analyzer warnings? In the PVS-Studio's Visual Studio plugin, a dedicated button in the report viewer suppresses all warnings at once:

1272_baseline/image3.png

After clicking, PVS-Studio writes all warnings to the project's primary suppress file, removing them from the report view.

We can also suppress individual warnings via a dropdown menu:

1272_baseline/image4.png

This functionality exists across all PVS-Studio IDE plugins: IntelliJ IDEA, CLion, Rider, Visual Studio, VS Code, and Qt Creator.

In Visual Studio, the Suppress Messages menu tracks suppressed warnings:

1272_baseline/image5.png

Note. Learn how to suppress warnings in IDE plugins and other integrations in the documentation section.

Suppressing false positives

False positives are another common case for suppression. Keep in mind that static analyzers rely on a probabilistic approach. Therefore, the analyzer can be wrong, too.

Note. Sometimes, excluding specific files is wiser than fighting false positives. The analyzer may issue various warnings, for example, for auto-generated files. By removing them, we will make the report much less noisy.

To suppress a false positive in PVS-Studio, use special comments. Suppose the analyzer issues a warning for this snippet:

size_t n = 100;
for (unsigned i = 0;
     i < n;          // here we get V104
     i++)
{
    // ...
}
Enter fullscreen mode Exit fullscreen mode

If we're confident this warning is erroneous and it should be removed from the report, add a comment with a diagnostic rule number:

size_t n = 100;
for (unsigned i = 0;
     i < n; //-V104
     i++)
{
    // ...
}
Enter fullscreen mode Exit fullscreen mode

Suppressing multiple diagnostic rules on one line is equally straightforward:

struct Small { int *pointer; };
struct Big { int *array[20]; };
int Add(const Small &a, Big b) //-V835 //-V813
{
  return *a.pointer + *b.array[10];
}
Enter fullscreen mode Exit fullscreen mode

Optionally, we can add a hash code to the False Alarm mark. If we change the line with this hash code, the analyzer warnings won't be marked as false positive, as the hash code of the changed line will be different.

To enable this function, add the following flag to the.pvsconfig configuration file:

//V_ENABLE_FALSE_ALARMS_WITH_HASH
Enter fullscreen mode Exit fullscreen mode

In the code, the mark with the hash code looks as follows:

//-V817 //-VH"3652460326"
Enter fullscreen mode Exit fullscreen mode

Note. See this documentation section to find out more about this mode and advanced diagnostic configuration.

Suppressing macro-related warnings is trickier. The analyzer is triggered wherever the macro is used—where its body is substituted into the code.

#define TEST_MACRO \
  int a = 0;       \
  size_t b = 0;    \
  b = a; 

void func1()
{
  TEST_MACRO // V1001 triggers here
}

void func2()
{
  TEST_MACRO // V1001 also triggers here 
}
Enter fullscreen mode Exit fullscreen mode

In this case, we can use a special markup to inform the analyzer that all instances of this macro should be treated as a false positive:

//-V:TEST_MACRO:1001

#define TEST_MACRO \
  int a = 0;       \
  size_t b = 0;    \
  b = a; 

void func1()
{
  TEST_MACRO
}

void func2()
{
  TEST_MACRO
}
Enter fullscreen mode Exit fullscreen mode

We can also simply remove these warnings. To do this, we can leave the following comment:

//-V::1001:TEST_MACRO
....
Enter fullscreen mode Exit fullscreen mode

As in the previous example, we can specify several diagnostic rules for macros at once:

//-V:TEST_MACRO:1001, 105, 201
Enter fullscreen mode Exit fullscreen mode

Manually adding comments isn't always convenient. PVS-Studio IDE plugins simplify this: click Mark selected messages as False Alarms in the context menu.

1272_baseline/image6.png

After this, the false positive comment inserts automatically:

1272_baseline/image7.png

To revisit warnings marked as false positive, enable the DisplayFalseAlarms option to include them in the analyzer report.

All PVS-Studio IDE plugins support mass suppression and false positive markup.

Note. Read more about these and other methods of dealing with false positives in this documentation section.

Don't hesitate to report false positives to our support team! Analyzer quality matters to us, so we actively fix valid cases. Contact us via the website feedback form.

Disabling diagnostic rules for a code snippet

In some cases, we need to disable diagnostic rules for a code block—not for the entire project. PVS-Studio for C/C++ supports #pragma directives for this:

  • #pragma pvs(push) saves current diagnostic rule's enable/disable settings;
  • #pragma pvs(disable: XXXX, YYYY, ...) disables listed diagnostic rules;
  • #pragma pvs(enable: XXXX, YYYY, ...) enables listed diagnostic rules;
  • #pragma pvs(pop) restores previous settings.

Look at the example:

void func(int* p1, int* p2)
{
  if (!p1 || !p2)
    return;

#pragma pvs(push)
#pragma pvs(disable: 547)
  if (p1) // V547 will not be issued
    do_something();
#pragma pvs(pop)

  if (p2) // V547 Expression 'p2' is always true.
    do_other();
}
Enter fullscreen mode Exit fullscreen mode

To prevent warnings about unknown #pragma, pass the flag to the compiler:

  • GCC/Clang: -Wno-unknown-pragmas
  • MSVC: -wd4068

Conclusion

We've explored how to integrate static analysis into legacy projects seamlessly using the baseline approach—ignoring legacy warnings to focus on new ones. We've also discussed that the analyzer is not perfect and can issue false positive warnings, but PVS-Studio provides convenient ways both for mass and individual warning suppression.

If uncertain about adopting static analysis, you're welcome to test PVS-Studio on your code with a free license. Thanks for reading! And let me end this post by rewording a proverb: "Trying once beats hearing or reading a hundred times."

Top comments (0)