This is an archive of the discontinued LLVM Phabricator instance.

[analyzer][NFC] Split the no state change logic and bug report suppression into two visitors
Needs ReviewPublic

Authored by spaits on Mar 1 2023, 7:20 AM.

Details

Summary

As discussed in my previous patch (D142354) the analyzer can understand std::variant and std::any through regular inlining. However warnings coming from these classes were suppressed by NoStateChangeFuncVisitor, more specificly by an instance of NoStoreFuncVisitor. The reason behind that is that we suppress bug reports when a system header function was supposed to initialize its parameter but failed to (as you can read about it in a comment block visible in this patch).

Now the problem is that these bug report were suppressed, but they had nothing to do with uninitialized values. In a follow up patch I intend to fix that and see how this suppression logic works as it was meant to be, but my initial testing shows that they no longer falsely suppress reports like this:

std::variant<int, std::string> v = 0;
int i = std::get<int>(v);
10/i; // FIXME: This should warn for division by zero!

In this patch I only separated these two functionalities because I don't think this suppression should be implemented in a NoStateChangeVisitor but in it's own.

Diff Detail

Event Timeline

spaits created this revision.Mar 1 2023, 7:20 AM
Herald added a project: Restricted Project. · View Herald TranscriptMar 1 2023, 7:20 AM
spaits requested review of this revision.Mar 1 2023, 7:20 AM
Herald added a project: Restricted Project. · View Herald TranscriptMar 1 2023, 7:20 AM
Herald added a subscriber: cfe-commits. · View Herald Transcript

We worked on this together, so I waited a bit for others to have a say in this, but this design seems like a no brainer to me. Please fix those comments, otherwise LGTM.

Also, while the patch is LGTM (moving code around is okay), the comment says "system headers having a chance to initialize the value but failing to do so", but do we ever check anywhere whether the function actually had the chance to change the value (passed by reference/pointer)?

clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
454–455

Since we don't check within this visitor whether the value is uninitialized, these comments are no longer up-to-date (and were not before your patch either).

What we are really doing here is flat out suppressing the report if it contains an inlined standard library function. What also needs to be said is that this visitor is as dumb as it comes -- its really down to the caller (or, more specifically, the one who registers this visitor) to make sure that this heuristic should be employed.

For example, if the bug report is about an uninitialized value that was passed to a system header function as a pointer/reference, this visitor could suppress the warning on the grounds that the system header likely would have initialized this value, but in some obscure cases the function could fail and not initialize the value, which could theoretically occur but practice it yields only (or mostly) false positives.

454–455

Here as well, drop the bit about uninitializedness, unless you talk about it in the context of an example.

spaits updated this revision to Diff 504062.Mar 10 2023, 2:15 AM

As @Szelethus has mentioned in his reply I tried to improve on the comment. I hope now it describes correctly what the new visitor is good for.

Szelethus added inline comments.Mar 13 2023, 3:30 AM
clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
449

We also lost this, unfortunately, and this is kind of the point where we check whether the std function has anything to do with the uninitialized value (its been passed as parameter or something).

Please investigate whether losing this has any effect (and it very likely does).

Do you plan to selectively enable warnings coming from the STL to catch misuses of certain STL types?

I think we should probably discuss this direction first. It is, in general, a fragile approach. Users might use Clang with GCC's, LLVM's, or MSVC's standard library. Today, we do not have the means to ensure that these checks continue to work as expected on all STL implementations over time. Also, those warning reports might be leaky in a sense the reported path might contain implementations details from the STL that is hard to interpret.

I am afraid, if we want to provide a good user experience, we might be doomed to manually simulate the behavior of STL classes.

What do you think?

spaits added a comment.EditedMar 16 2023, 8:56 AM

Do you plan to selectively enable warnings coming from the STL to catch misuses of certain STL types?

No. At first when we have found out that the Static Analyzer can reason about std::variant but it suppresses the diagnostics (D142354#4079643), we were suspecting a too strong heuristic somewhere, that invalidates even true positives. Since the Static Analyzer was able to reason about std::variant by itself we we did not want to write a checker to do the same thing. So the plan was to find the point where the suppression happen and change on the heuristics so it can let thru every kind of true positive about STL types/functions. But as it turns out, it is kind of impossible to do that without letting a lot of false positives to not be suppressed.

While it seems like it may be very difficult to unsuppress all the reports from std::variant, it still made sense to fine-tune some of these suppression.

Also, those warning reports might be leaky in a sense the reported path might contain implementations details from the STL that is hard to interpret.

We have tested the new heuristics and the new reports did not contain implementation details form STL. Obviously the test do not cover every possibility so there might be some leaking but we haven't seen it yet.

I am afraid, if we want to provide a good user experience, we might be doomed to manually simulate the behavior of STL classes.

That might be the best approach to prevent the mentioned implementation dependency. Plus it would probably make it easier to write my BSc thesis if I have created a brand new checker.

On another note, it might be interesting to see how the checker approach and the force-inlining analyses compare (even if one of those approaches turn out to be a dead end).