To get a trial key
fill out the form below
Team License (standard version)
Enterprise License (extended version)
* By clicking this button you agree to our Privacy Policy statement

** This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.
Request our prices
New License
License Renewal
--Select currency--
USD
EUR
GBP
RUB
* By clicking this button you agree to our Privacy Policy statement

** This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.
Message submitted.

Your message has been sent. We will email you at


If you haven't received our response, please do the following:
check your Spam/Junk folder and click the "Not Spam" button for our message.
This way, you won't miss messages from our team in the future.

>
>
>
Why PVS-Studio Doesn't Offer Automatic …

Why PVS-Studio Doesn't Offer Automatic Fixes

Nov. 19, 2020
Author:

Static analyzer PVS-Studio can detect bugs in pretty complex and intricate parts of code, and coming up with appropriate fixes for such bugs may be a tough task even for human developers. That's exactly the reason why we should avoid offering any options for automatic fixing at all. Here are a couple of examples.

0776_Autoreplace/image1.png

Those who are only getting started with PVS-Studio sometimes wonder why it doesn't offer to fix bugs automatically. Interestingly, the regular users don't ask this question. As you gain experience working with the analyzer, it becomes clear that automatic replacement can't be applied to most bugs. At least not until we have full-fledged artificial intelligence :).

Such replacement would be possible if PVS-Studio analyzed coding style. But that's not what it is designed to do. It doesn't offer formatting or naming edits. It doesn't offer (at least as of this writing :) automatic replacement of all NULLs with nullptrs in C++ code. Good as it is, such an edit has little to do with search and elimination of bugs.

Instead, PVS-Studio's job is to detect bugs and potential vulnerabilities. In many cases, fixing them requires a creative approach and changing the program's behavior. Only the human developer can decide upon the appropriate way of fixing a given bug.

The most likely suggestion you'd get from the analyzer when it detects a defect is to simplify the code to make the anomaly go away, but that wouldn't be enough to eliminate the defect itself. Yet figuring out what exactly the code is intended to do and coming up with a sensible and useful fix is too difficult a job.

As an example, here's a bug discussed in my article "February 31".

static const int kDaysInMonth[13] = {
  0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
};

bool ValidateDateTime(const DateTime& time) {
  if (time.year < 1 || time.year > 9999 ||
      time.month < 1 || time.month > 12 ||
      time.day < 1 || time.day > 31 ||
      time.hour < 0 || time.hour > 23 ||
      time.minute < 0 || time.minute > 59 ||
      time.second < 0 || time.second > 59) {
    return false;
  }
  if (time.month == 2 && IsLeapYear(time.year)) {
    return time.month <= kDaysInMonth[time.month] + 1;
  } else {
    return time.month <= kDaysInMonth[time.month];
  }
}

The analyzer realizes that both checks evaluate to true. But it doesn't know why. It knows nothing about days, months, and other entities. And you'd have a very hard time trying to teach those things to it. The only thing you can possibly teach it to do is to offer to simplify the function:

bool ValidateDateTime(const DateTime& time) {
  if (time.year < 1 || time.year > 9999 ||
      time.month < 1 || time.month > 12 ||
      time.day < 1 || time.day > 31 ||
      time.hour < 0 || time.hour > 23 ||
      time.minute < 0 || time.minute > 59 ||
      time.second < 0 || time.second > 59) {
    return false;
  }
  if (time.month == 2 && IsLeapYear(time.year)) {
    return true;
  } else {
    return true;
  }
}

Well, why stop at that? Let's have the analyzer apply the following fix:

bool ValidateDateTime(const DateTime& time) {
  if (time.year < 1 || time.year > 9999 ||
      time.month < 1 || time.month > 12 ||
      time.day < 1 || time.day > 31 ||
      time.hour < 0 || time.hour > 23 ||
      time.minute < 0 || time.minute > 59 ||
      time.second < 0 || time.second > 59) {
    return false;
  }
  return true;
}

It's funny but it misses the point ;). The analyzer has removed the portion of code that's considered redundant from the viewpoint of the C++ language. Yet only the human developer can determine whether the code is indeed redundant (which is very often the case) or contains a typo and month must be replaced with day.

You may say that I'm dramatizing things and that automatic replacement is a viable option. No, it's not. Even we humans make mistakes trying to figure such issues out – how can we expect better judgement from an inanimate computer program? Here's an interesting example of a manual careless fix that actually doesn't fix anything. If the human fails, the machine will surely fail too.

In August of this pandemic year, I posted an article covering the issues found in the PMDK library. Among other defects, I discussed one bug that compromised overflow protection:

static DWORD
get_rel_wait(const struct timespec *abstime)
{
  struct __timeb64 t;
  _ftime64_s(&t);
  time_t now_ms = t.time * 1000 + t.millitm;
  time_t ms = (time_t)(abstime->tv_sec * 1000 +
    abstime->tv_nsec / 1000000);

  DWORD rel_wait = (DWORD)(ms - now_ms);

  return rel_wait < 0 ? 0 : rel_wait;
}

Since the rel_wait variable is unsigned, the subsequent check rel_wait < 0 is pointless. PVS-Studio's diagnostic message: V547 [CWE-570] Expression 'rel_wait < 0' is always false. Unsigned type value is never < 0. os_thread_windows.c 359

The article inspired somebody to do mass fixing of the bugs it mentioned: Fix various issues reported by PVS-Studio analysis.

What fix do you think they suggested? Quite a plain one: core: simplify windows timer implementation.

0776_Autoreplace/image2.png

But it only simplifies the code, not fixes it! Somebody else noticed this and opened a discussion: ISSUE: os_thread_windows.c - get_rel_wait() will block if abstime is in the past.

As you can see, even humans make mistakes when trying to come up with a fix. Machines are just hopeless in that respect.

Actually, when you come to think of it, the wish for bugs to get fixed automatically is quite an odd one. Every fix demands care and close inspection of the code. Besides, a warning may turn out to be a false positive, in which case it must not be touched at all. Code analysis and bug fixing don't tolerate haste. A better strategy is to run analysis regularly and fix freshly introduced bugs.

Popular related articles
PVS-Studio for Java

Date: 01.17.2019

Author: Andrey Karpov

In the seventh version of the PVS-Studio static analyzer, we added support of the Java language. It's time for a brief story of how we've started making support of the Java language, how far we've co…
The Last Line Effect

Date: 05.31.2014

Author: Andrey Karpov

I have studied many errors caused by the use of the Copy-Paste method, and can assure you that programmers most often tend to make mistakes in the last fragment of a homogeneous code block. I have ne…
The way static analyzers fight against false positives, and why they do it

Date: 03.20.2017

Author: Andrey Karpov

In my previous article I wrote that I don't like the approach of evaluating the efficiency of static analyzers with the help of synthetic tests. In that article, I give the example of a code fragment…
The Ultimate Question of Programming, Refactoring, and Everything

Date: 04.14.2016

Author: Andrey Karpov

Yes, you've guessed correctly - the answer is "42". In this article you will find 42 recommendations about coding in C++ that can help a programmer avoid a lot of errors, save time and effort. The au…
The Evil within the Comparison Functions

Date: 05.19.2017

Author: Andrey Karpov

Perhaps, readers remember my article titled "Last line effect". It describes a pattern I've once noticed: in most cases programmers make an error in the last line of similar text blocks. Now I want t…
How PVS-Studio Proved to Be More Attentive Than Three and a Half Programmers

Date: 10.22.2018

Author: Andrey Karpov

Just like other static analyzers, PVS-Studio often produces false positives. What you are about to read is a short story where I'll tell you how PVS-Studio proved, just one more time, to be more atte…
Free PVS-Studio for those who develops open source projects

Date: 12.22.2018

Author: Andrey Karpov

On the New 2019 year's eve, a PVS-Studio team decided to make a nice gift for all contributors of open-source projects hosted on GitHub, GitLab or Bitbucket. They are given free usage of PVS-Studio s…
Characteristics of PVS-Studio Analyzer by the Example of EFL Core Libraries, 10-15% of False Positives

Date: 07.31.2017

Author: Andrey Karpov

After I wrote quite a big article about the analysis of the Tizen OS code, I received a large number of questions concerning the percentage of false positives and the density of errors (how many erro…
PVS-Studio ROI

Date: 01.30.2019

Author: Andrey Karpov

Occasionally, we're asked a question, what monetary value the company will receive from using PVS-Studio. We decided to draw up a response in the form of an article and provide tables, which will sho…
Technologies used in the PVS-Studio code analyzer for finding bugs and potential vulnerabilities

Date: 11.21.2018

Author: Andrey Karpov

A brief description of technologies used in the PVS-Studio tool, which let us effectively detect a large number of error patterns and potential vulnerabilities. The article describes the implementati…

Comments (0)

Next comments

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.
This website uses cookies and other technology to provide you a more personalized experience. By continuing the view of our web-pages you accept the terms of using these files. If you don't want your personal data to be processed, please, leave this site.
Learn More →
Accept