This is an archive of the discontinued LLVM Phabricator instance.

[analyzer] Adjust the reported variable name in retain count checker
ClosedPublic

Authored by vsavchenko on Apr 20 2021, 3:57 AM.

Details

Summary

When reporting leaks, we try to attach the leaking object to some
variable, so it's easier to understand. Before the patch, we always
tried to use the first variable to store the object in question.
This can get very confusing for the user, if that variable doesn't
contain that object at the moment of the actual leak. In many cases,
the warning is dismissed as false positive and it is effectively a
false positive when we fail to properly explain the warning to the
user.

This patch addresses the bigest issue in cases like this. Now we
check if the variable still contains the leaking symbolic object.
If not, we look for the last variable to actually hold it and use
that variable instead.

Diff Detail

Event Timeline

vsavchenko created this revision.Apr 20 2021, 3:57 AM
vsavchenko requested review of this revision.Apr 20 2021, 3:57 AM
Herald added a project: Restricted Project. · View Herald TranscriptApr 20 2021, 3:57 AM
Herald added a subscriber: cfe-commits. · View Herald Transcript

Update comments

NoQ added a comment.Apr 21 2021, 12:28 AM

This is a major improvement. MallocChecker will have to catch up on that. Hopefully through increased code re-use.

clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
651

I feel semi-irrational urge to add comments whenever NRVO is employed.

967–968

Given that the current state doesn't satisfy the requirement on line 945, this can happen for two reasons:

  1. The symbol was there when the variable died so we simply tracked it back to the last moment of time the variable was alive.
  2. The symbol was there but was overwritten later (and then the variable may have also, but haven't necessarily, died).

Case 2 is bad because we're back in business for reporting the wrong variable; it's still more rare than before the patch but i think the problem remains. Something like this should probably demonstrate it:

void foo() {
  Object *Original = allocate(...);
  Original = allocate();
  Original->release();
}

A potential solution may be to add a check in getAllVarBindingsForSymbol that the first node in which we find our symbol corresponds to a *PurgeDeadSymbols program point. It's a straightforward way to find out whether we're in case 1 or in case 2.

clang/test/Analysis/Inputs/expected-plists/retain-release-path-notes.m.plist
5993

This patch seems to add 3 entirely new warnings here. Why do they suddenly start showing up? Are they good?

vsavchenko added inline comments.Apr 22 2021, 12:50 AM
clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
651

I know, and I lacked trust in compilers that all of them will do it, but I think things like this should not be commented. It's not part of main the logic and it looks natural, so we can not explain why we did it this way in particular.

967–968

In this situation, we will report on line Original = allocate();, which should probably be a good enough indicator of what analyzer tries to say.
In your example, we have a choice of either not report variable name at all or report Original

clang/test/Analysis/Inputs/expected-plists/retain-release-path-notes.m.plist
5993

Because I added 3 more test cases? 😅

NoQ added inline comments.Apr 25 2021, 11:24 PM
clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
967–968

I had a look and it looks like all of our UIs are acting up quite a bit on this example. The user ends up completely convinced that it's the current value of Original that's getting leaked, not the original value.

Let's at least add a test and/or a comment? This definitely isn't a regression and the patch is still really good.

clang/test/Analysis/Inputs/expected-plists/retain-release-path-notes.m.plist
5993

Uh-oh ok fair enough :D

Add test for the case when there are no good alternatives

vsavchenko marked an inline comment as done.Apr 26 2021, 11:14 AM
NoQ accepted this revision.Apr 26 2021, 8:31 PM

Great, thanks!~

This revision is now accepted and ready to land.Apr 26 2021, 8:31 PM
This revision was landed with ongoing or failed builds.Apr 28 2021, 8:38 AM
This revision was automatically updated to reflect the committed changes.