I want to use user assertion of value analysis plugin of Frama-C (Neon version), however I have some problem to come up with the suitable model of assume
statement, which is very useful for me to apply particular constraints, for example, here is my test code:
#include "/usr/local/share/frama-c/builtin.h"
int main(void)
{
int selection = Frama_C_interval(0,10);
int a;
assume(selection > 5);
if (selection > 5)
{
a = 2;
}
else
{
a = 1;
}
//@ assert a == 2;
return 0;
}
I want that the value of selection
will be greater than 5 after this assume
statement so that the assertion will be valid.
My initial attempt was to write this function
void assume(int a){ while(!a); return;}
, but it was unsuccessful.
Please help me, thanks.
The easiest way to constrain selection
would be to use an assert
(which of course won't be proved by Value). If you want to distinguish between the assert
that are in fact hypotheses you make from the assert
that you want to verify, you can use ACSL's naming mechanism, such as
//@ assert assumption: selection > 5;
and verify that the only assert
that are unknown are the ones named assumption
.
Using an assume
function cannot work as such, because it will only reduce the possible value of the a
parameter to be non-zero. Value is not able to infer the relation between the value of a
in assume
and the value of selection
in main
. However, it is possible to help it a little bit. First, -slevel
allows to propagate several abstract state in parallel. Second, an assert
given in an disjunctive will force Value to split its state (if the -slevel
is big enough to do so). Thus, with the following code
#include "builtin.h"
void assume(int a) { while(!a); return; }
int main(void)
{
int selection = Frama_C_interval(0,10);
int a;
/*@ assert selection > 5 || selection <= 5; */
assume(selection > 5);
if (selection > 5)
{
a = 2;
}
else
{
a = 1;
}
//@ assert a == 2;
return 0;
}
and the following command line:
frama-c -cpp-extra-args="-I$(frama-c -print-share-path)" -val -slevel 2
After the first assert
(which obviously valid), Frama-C will propagate separately two states: one in which selection > 5
and one in which selection <= 5
. In the first case, assume
is called with 1
as argument, thus returns immediately, and the then
branch of the if
is taken, so that the second assert
is valid. In the second state, assume
is called with 0
, and never returns. Thus for all cases where control reaches the second assert
, it is valid.
Note that you really need to add the first assert
inside the body of main
, and to copy in ACSL the argument you pass to assume
. Otherwise, the state split won't occur (more precisely, you will split on a
, not on selection
).