I am trying to add tests to Iterator Modeling where std::advance(), std::prev() and std::next() are used. These latter two use the former one, which in some implementations uses __advance(). In real scenarios it happens that std::prev() or next() or std::advance() called by them or __advance() called by that one is not inlined. I would like to test these scenarios explicitly. My idea is to limit the inline stack by using -analyzer-inline-max-stack-depth, but any value I use the result is the same: everything is inlined, even __advance(). Do I misunderstand this flag, or it does not work at all?



We already have such tests and they're working as expected.

I think your problem must be that some functions are inlined regardless of that limit, eg. the ones with trivial (linear) CFG. If that's the case, you'll also have to figure out why aren't they inlined in the real world for the same reason.


Yes, I saw such tests. My functions are trivial (linear) indeed, but they have basically the same implementation in the real headers as well, and in many cases std::prev(Something.end()) becomes Something.end() causing false positives. When I started investigating this problem, it turned out that in some cases std::prev() is not inlined at all, in some other cases std::prev() is inlined but std::advance() called by it is not and there were cases when both were inlined but __advance() called by std::advance() was not. I just saw the exploded graph. When I implemented modeling of these functions for the non-inlined case the false positives were gone.

I have no idea why some of these functions in some cases were not inlined. Maybe budget ran out? How to test it explicitly?



I usually debug why something's inlined or not by step-by-step-debugging ExprEngine::defaultEvalCall().

As usual, you can make conditional breakpoints with condition`Pred->Id == ...` assuming you've already located the offending node in the ExplodedGraph dump or via debug prints.