[cfe-dev] Question on static analyzer callback: checkBranchCondition()

illiop via cfe-dev cfe-dev at lists.llvm.org
Tue Nov 20 01:20:34 PST 2018


Got your idea.
 
Another 2 questions:
(1) if the condition expr is a littlt complex: A&&B&&C, or (A && B) || funciont(i) , If I want to find the whole expr's value,
     I should konw what kind of the whole binary operator is('...&&...&&...',     '...&&...||...') and which part it is now called back('A', 'B', 'C', 'function(i)')
     it's not convenient (maybe I should do some bookkeeping by myself ? ) to do that.  Am I right ?  
(2)
If the codes are:
if( A && B ){}
while( A && B){}
do...while( A && B){}
for(...; A && B; ...){}
Is there any Quick way to find which controll statement(IfStmt, WhileStmt, DoStmt, ForStmt) the condition expr blongs to ?
Now my method is:
 
void ControllStmtCondChecker::checkBranchCondition(const Stmt* cond, CheckerContext& ctx) const
{
    const ParentMap& Parents = ctx.getLocationContext()->getParentMap();
    const Stmt* parent  = Parents.getParent(cond);
   while(parent)
  {
      if( isa<IfStmt>(parent) ){ ...... break; }
      else if( isa<WhileStmt>(parent) ){ ...... break; }
      ...
 
     else 
    {
         cond = parent;
         parent = Parents.getParent(cond);
    }
 
// here we get the controller statement 'parent'  and its whole condition expr 'cond'
 
}
 
Thanks a lot !



At 2018-11-20 15:02:46, "Artem Dergachev" <noqnoqneo at gmail.com> wrote:
>(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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20181120/d49d2e8e/attachment.html>


More information about the cfe-dev mailing list