Hi,
I noticed a strange behavior of function call inlining when I was debugging my checker.
For a very simple code example:
void func_with_loop(int loop_times) {
for (int i = 0; i < loop_times; i++) {
//Do nothing
}
}
void call_loop(int tag) {
func_with_loop(tag);
}
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.
To demo this behavior, here is my patch to the clang to print if the function call is inlined: https://gist.github.com/zeroomega/bbe2cfa298a912a1b5b37fa4b9cd76b5 . The output of clang after this patch is:
testmxchannel.c:204:3func_with_loop Should inline: Direct inlined
Block Count exceeded maxBlockVisitOnPath 4Dump SRC
[B1]
1: i
2: [B1.1]++
Preds (1): B2
Succs (1): B2
Dump Dst:
[B2]
1: i
2: [B2.1] (ImplicitCastExpr, LValueToRValue, int)
3: loop_times
4: [B2.3] (ImplicitCastExpr, LValueToRValue, int)
5: [B2.2] < [B2.4]
T: for (…; [B2.5]; …)
Preds (2): B1 B3
Succs (2): B1 B0
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”. I manually increased the value of “maxBlockVisitOnPath” but “func_with_loop” was still not inlined.
Is it an intended behavior of clang static analyzer or is it a bug? 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?
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?
Thanks for any help,
Haowei