[cfe-dev] [StaticAnalyzer] Question about IPA function call inlining

Péter Szécsi via cfe-dev cfe-dev at lists.llvm.org
Sun Jun 25 05:51:43 PDT 2017


Hello Haowei,

You described most of the behaviors right but not exactly.


> When I run clang static analyzer on this piece of code with scan-build,
> the function "func_with_loop()" will not be inlined by ExprEngine.
>
> The func_with_loop() function will be inlined for sure. That is what your
example has just proven by producing the line:


> testmxchannel.c:204:3func_with_loop  Should inline: Direct inlined
>

So it will be inlined. Lets considering the next important line in the
output:


> Block Count exceeded maxBlockVisitOnPath 4Dump SRC
> ...
> testmxchannel.c:204:3func_with_loop  InlinedFailedState is not null
>  Should not inline
>
>
It seems that the ExprEngine did try to inline the function
> "func_with_loop", but the total block count of this function exceeded
> "maxBlockVisitOnPath", which by default is 4. The inline process was rolled
> back and this function is evaluated by "conservativeEvalCall".
>

Yeah. that is what happens BUT! only on the *PATH* where the
maxBlockVisitOnPath exceeded. So the other paths will be simulated but this
path will be rolled back before the point where the analyzer inline the
function and mark the function not to be inlined again
(*NewNodeState->set<ReplayWithoutInlining>(const_cast<Stmt
*>(CE)*). So simulating again that path will trigger the defaultEvalCall on
the same function call which was just rolled back and marked so the
analyzer won't inline it. That is what is checked by the
*getInlineFailedState()
*and that is the reason why the 2. output says it should not be inlined
*. *

In my understanding, by default, when clang static analyzer evaluate a loop
> that the total times of the loop cannot determined, the loop will be
> evaluated for 4 times and an additional ExplodedNode will be created with
> the loop condition evaluated to false. But why in this code example it
> causes the function inline to be rolled back instead of creating an
> additional node that evaluate the loop conditions to false?
>
> Not exactly. The ExplodedGraph will be forked every time when the loop
condition is evaluated. So there will be 5 different paths int
ExplodedGraph while simulating a loop like this:
- when the condition is false
- when the condition is false after the 1. step
- when the condition is false after the 2. step
- when the condition is false after the 3. step
- when the condition is true every time - but this will be the path where
the maxBlockVisitOnPath exceeds and then the above mentioned things happen.

Why is it important to replay the analysis without inlining this function
which contains a loop?
The most problematic case is when the bound is known so the analyzer won't
create new branches for paths where the condition can be false if it knows
it can't be. For example if you try out a code like this:

void func_with_loop(int loop_times) {
  for (int i = 0; i < loop_times; i++) {
    //Do nothing
  }
}

void call_loop() {
  func_with_loop(12);
  ... //the most complex body you can just imagine
}

In this case (without the replaying-without-inlining feature) the analysis
of this call_loop function would be ended while analyzing the inlined
func_with_loop() function and exceeding the maxBlockVisitOnPath. Which is
not something you would like to see so the state is going to be rolled back
and the other parts of the function will be analyzed but without knowing
what the func_with_loop() function did (so yes, with more unknown value).


> Another question I have is that is it possible in checkPreCall() callback
> of a checker to determine if the function call will not be inlined by
> ExprEngine?
>
> I would be surprised if you can check that in checkPreCall() but maybe
somebody else (probably NoQ) knows a way to check this.  (in
checkPostCall() you can do this for sure by checking the wasInlined flag of
the CheckerContext.)

I hope I could help at least a little bit.

Cheers,
Peter
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20170625/da59badc/attachment.html>


More information about the cfe-dev mailing list