2

I have the following problem when analyzing if-conditions with my plugin. When I analyze code like

if ((a && b) || c)

Frama-C creates code like this:

if (a) {
    if (b){
        goto _LOR;
    }
    else{
        goto _LAND;
    }
}
else{
    _LAND: ;
    if (c) {
        _LOR: //....

For my analysis, I want to get the control-flow without the conditions split up, so that one statement remains. I want this, because by splitting up the conditional, the reaching of _LOR is dependent on the or-part only.

Example: creating the CFG as in the viewcfg plugin of the developer guide leads to this:

CFG

a=(a+b)+c can be reached in the then and the else-path of if a, which I cancel out in my plugin in the block-statement (so that after a "simple" if, the statement is not dependent on the condition anymore).

Is there a possibility to block the splitting of the if, by a command-line argument or something like that?

byako
  • 3,372
  • 2
  • 21
  • 36
Thomas Böhm
  • 1,456
  • 1
  • 15
  • 27
  • 1
    As a workaround, you can observe that the statement depend on `if c` (since it is only in one of its branches) and `if c` depend on `if b` and `if a`. So you can conclude that the statement depend on the three conditions. – Anne Jun 03 '16 at 08:12
  • @Anne is of course perfectly right: there is an indirect dependency between the `_LOR` and `a` and `b`, by transitivity. In fact, this kind of dependencies is already handled by the `From` plugin of Frama-C. – byako Jun 06 '16 at 11:29
  • @byako yes, it totally makes sense to push all dependencies down the graph, looking at the above example, it would totally work (I would get `a&&b or !a&&c or a&&!b&&c`. But the problem is, that I want the smallest amount of conditions that a statement is dependent of. (and-concatenated). Therefore, I would have to cancel it out at blocks, where 2 or more paths merge. For example in if-else-trees with single conditions. With the way of @Anne, i would get the full dependencies, and no knowledge of what/when to cancel out. I hope it is clear what I mean, otherwise I could add an example. – Thomas Böhm Jun 06 '16 at 12:15
  • With the or's, I would have to make the cross-product of all possible if-combinations, which could be pretty huge in lager programs. Since your answer seems to work for me, I will do some further tests and see, if it causes any problems to use the unsupported version. – Thomas Böhm Jun 06 '16 at 12:19

1 Answers1

3

An undocumented and unsupported solution exists. Before compiling Frama-C, in function initCIL of cil.ml, change

theMachine.useLogicalOperators <- false (* do not use lazy LAND and LOR *);

into

theMachine.useLogicalOperators <- true;

The normalization will use logical || and && operators instead of gotos.

Please note that this is unsupported for a good reason. The Frama-C plugins packaged with the kernel expect an AST in which those operators are not used, so they will probably crash or do something unsound on your program. Use at your own risk!

byako
  • 3,372
  • 2
  • 21
  • 36