Page MenuHomePhabricator

[Analyzer] Iterator Checkers - Check and simulate `std::advance`, `std::prev` and `std::next`
Needs ReviewPublic

Authored by baloghadamsoftware on Jun 5 2019, 2:27 AM.

Details

Reviewers
NoQ
Szelethus
Summary

In case of invoking std::advance, std::prev and std::next range errors should be reported in the invoker and not inside the STL implementation code. Another problem is if the analyzer budget runs out just at the point these functions are invoked. This results in strange behavior such as std::prev(v.end()) equals v.end(). To prevent this simulate these functions if they were not inlined.

Diff Detail

Event Timeline

This patch definitely reduces the number of false positives, but may not be enough. The problem is that std::advance() may call another function that does the actual incremention or decremention, in the gcc implementation it is __advance(). If the std::advance() is inlined but __advance() not then we still get false positive. The obvious way would be to simulate __advance() as well but it is an implementation dependent internal function and may be totally different for other implementations. Another idea is that instead of querying the CheckerContext whether advance() was inlined we go up the exploded graph and find its "precall" state and compare the values of the first parameter related to the second one in the two states. This is a bit more complex and more expensive but this for me this seems to be the correct solution.

Again, this a place where a debugging functionality would be awesome to precisely observe the change being made. I also noticed that IteratorChecker and related classes don't have any dump methods, maybe that is worth investing into as well?