[cfe-dev] Question on static analyzer callback: checkBranchCondition()
Artem Dergachev via cfe-dev
cfe-dev at lists.llvm.org
Mon Nov 19 23:02:46 PST 2018
(whoops, re-added the mailing list)
Due to the short circuit nature of logical binary operators, the value
of the expression `x && y` is equal to the value of `y` as long as `y`
gets evaluated at all, and to `false` otherwise. You can see which
branch is evaluated in the callback for `x` by figuring out if `x`
evaluates to `false`, and in this case you already know that the value
of `x && y` would be false. You can see which branch is evaluated in the
callback for `y` - it is definitely the branch on which `y` is
evaluated. In this callback the value of `x && y` can be computed as `y`.
P.S. If you are trying to prove that some expressions in the code are
always false or always true, you won't be able to do it that way,
because all computations within checker callbacks are based on the
assumptions that allowed the program to reach the respective point in a
certain state, and may be incorrect on other paths to the same program
point in which the state of the program is different or different
assumptions have been made. For example, in code
if (a < 10) {
}
if (a < 10) {
}
you would "prove" that the second branch condition is both "always true"
(i.e., assuming you take the true branch on the first if(), the
condition is definitely true on the second if) and "always false" (i.e.,
assuming you take the false branch on the first if(), the condition is
definitely false on the second if).
Static Analyzer's path-sensitive engine is only useful for problems that
consist in finding execution paths with special properties
("may"-problems), not for proving that paths with certain properties do
not exist ("must"-problems). The only on-by-default "must"-checker in
the Static Analyzer is the DeadStores checker (assigned value is
discarded or overwritten before use on all paths after the assignment),
and it works by exploring the CFG manually and doesn't rely on the
Static Analyzer's path-sensitive engine.
On 11/19/18 7:56 PM, illiop via cfe-dev wrote:
> Hello,
> Thanks in advance for any help!
> If I have the following code:
> void function()
> {
> int a = 1;
> if ( ( a<10 ) && ( a > 20 ) ) // always false
> {
> }
> }
> How can I evaluate the whole condition expression '( a<10 ) && ( a >
> 20 ) ' ?
> When I write code like:
> class MyChecker : public Checker< check::BranchCOndition >
> {
> public:
> void checkBranchCondition(const Stmt* cond, CheckerContext& ctx) const;
> }
> I found that checkBranchCondition() only be called back 2 times, once
> for 'a<10' , once for 'a > 20 '. And it's done. No further call back.
> But my goal is to get the 'value' for the whole '( a<10 ) && ( a > 20
> ) '.
> I tried the following in vain:
> 1. in checkBranchCondition(), find the 'father' node(it is '( a<10 )
> && ( a > 20 ) ' ), and evaluate its 'sval', but the sval is
> invalid/undifined
> 2. Use check::PostStmt<CompoundStmt> call back. It does NOT called
> back at all
> 3. Use check::PostStmt<Stmt> call back, and try to find the 'father'
> by : if(isa<IfStmt>(stmt)), useless.
> 4. Use check::PostStmt<BinaryOperator>, but it still only called back
> 2 times: once for 'a<10' , once for 'a > 20 '
> I am a fresh man in the static analyzer, please help, thanks!
> illiop
>
>
>
>
> _______________________________________________
> cfe-dev mailing list
> cfe-dev at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
More information about the cfe-dev
mailing list