Page MenuHomePhabricator

[analyzer] Consider array subscripts to be interesting lvalues
ClosedPublic

Authored by vsavchenko on Apr 22 2020, 7:30 AM.

Details

Summary

Static analyzer has a mechanism of clearing redundant nodes when
analysis hits a certain threshold with a number of nodes in exploded
graph (default is 1000). It is similar to GC and aims removing nodes
not useful for analysis. Unfortunately nodes corresponding to array
subscript expressions (that actively participate in data propagation)
get removed during the cleanup. This might prevent the analyzer from
generating useful notes about where it thinks the data came from.

This fix is pretty much consistent with the way analysis works
already. Lvalue "interestingness" stands for the analyzer's
possibility of tracking values through them.

rdar://problem/53280338

Diff Detail

Event Timeline

vsavchenko created this revision.Apr 22 2020, 7:30 AM
martong added inline comments.Apr 22 2020, 9:17 AM
clang/test/Analysis/PR53280338.cpp
1 ↗(On Diff #259283)

AFAIK rdar is not accessible outside Apple. So, for the rest of the open source developers any rdar info is totally useless. Thus, could you please copy the relevant parts of the bug description from there into the test file? Would be even better if we could just mention the rdar link in the test file and the filename itself was better explaining the nature of the bug.

vsavchenko marked an inline comment as done.Apr 22 2020, 10:58 AM
vsavchenko added inline comments.
clang/test/Analysis/PR53280338.cpp
1 ↗(On Diff #259283)

It is a fair point, I'll make it more clear what exactly we are testing here.

Add more clarity on what we test

vsavchenko marked an inline comment as done.Apr 22 2020, 11:15 AM

How come rGe20b388e2f923bfc98f63a13fea9fc19aeaec425 doesn't solve this? Or, rather, how come it even worked if this patch is needed? Is the index being a global variable the issue? The change looks great, but I'm a bit confused.

vsavchenko added a comment.EditedApr 22 2020, 12:43 PM

How come rGe20b388e2f923bfc98f63a13fea9fc19aeaec425 doesn't solve this? Or, rather, how come it even worked if this patch is needed? Is the index being a global variable the issue? The change looks great, but I'm a bit confused.

Hey, thanks! So, I've tried to cover it in the comment and in the commit message.

In this test, both do while and the global index help to reproduce the erroneous behaviour. Usually, the analyzer tracks through array subscript expressions and it adds notes like expected in the test ("Assuming pointer value is null"). But in the test snippet, it was not adding those. The main reason is not in trackExpressionValue, it works fine! trackExpressionValue starts with finding an exploded node, where the lvalue is defined, and such node was not found. A little bit of digging later I found out that the node collector (aka garbage collector) threw those nodes away (check ExplodedGraph::shouldCollect and ExplodedGraph::reclaimRecentlyAllocatedNodes)! Because of the do while loop and the global index, the number of exploded nodes is pretty large. This fact causes GC to kick in and remove the nodes that we need for trackExpressionValue to work. Interesting nodes are on the other hand not deleted and this what helped with the problem.

I hope this clears it a bit!

Szelethus accepted this revision.Apr 22 2020, 1:22 PM

Everything's clear! Nice detective work!

This revision is now accepted and ready to land.Apr 22 2020, 1:22 PM
NoQ accepted this revision.Apr 23 2020, 6:56 AM

Yup. Yet another epic bug!

clang/test/Analysis/CheckThatArraySubsciptNodeIsNotCollected.cpp
19–20

I'm still curious why index being global actually matters here. Like, how does it increase the number of nodes in the graph?

vsavchenko marked an inline comment as done.Apr 23 2020, 7:02 AM
vsavchenko added inline comments.
clang/test/Analysis/CheckThatArraySubsciptNodeIsNotCollected.cpp
19–20

It does not simply increase the number of nodes, it increases it by thousands!

This revision was automatically updated to reflect the committed changes.