From e80b5ad4d9c96813215810c1fad12a27495f4db9 Mon Sep 17 00:00:00 2001 From: Allan Blanchard <allan.blanchard@cea.fr> Date: Tue, 1 Sep 2020 09:10:43 +0200 Subject: [PATCH] Adds ACSL importer --- _fc-plugins/acsl-importer.md | 159 +++++++++++++++++++++++++++++++++++ 1 file changed, 159 insertions(+) create mode 100644 _fc-plugins/acsl-importer.md diff --git a/_fc-plugins/acsl-importer.md b/_fc-plugins/acsl-importer.md new file mode 100644 index 00000000..785bf447 --- /dev/null +++ b/_fc-plugins/acsl-importer.md @@ -0,0 +1,159 @@ +--- +layout: plugin +title: ACSL Importer +description: Import ACSL specifications from extern files +key: specifications +distrib_mode: proprietary +--- + +## Overview + +This plug-in adds to Frama-C support for out of C source files ACSL specification. Therefore +it is useful only to people that intend to write ACSL specifications and do not want to write +them inside comments of the C source files. + +In addition, the plug-in allows to enter ACSL annotations directly via the Graphical User +Interface. + +## Usage + +All options of the plug-in are prefixed by `-acsl-`. + +The main options are: + +- `-acsl-importer-help`: + lists all options specific to the plug-in +- `-acsl-import <filename list>`: + analyzes the content of files listed in its arguments and inserts the correctly typed + specifications in the abstract syntax tree of Frama-C for further processing. +- `-acsl-Idir <dirname list>`: + specifies the list of directories where the relative file names mentioned in include + directives are searched. +- `-acsl-keep-unsed-symbols`: + configures Frama-C kernel such that unused C symbols aren't removed before the import. +- `-acsl-parse-only`: + parses the ACSL files without typing nor imports. +- `-acsl-typing-only`: + parses and types the ACSL files without imports. +- `-acsl-version`: + pretty prints a text containing the version ID of the plugin. + + +The plug-in can be used as follows. From a C file: + +```c +int f ( int i ); +int g ( int j ); +void job ( int *t , int A) { + for ( int i = 0; i < 50; i ++) t[i] = f (i ); + for ( int j = A; j < 100; j ++) t[j ] = g(j ); +} +``` + +and a specification file: + +``` +function f: + contract: + ensures P(phi(C(\result))); + assigns \nothing ; + +function g: + contract: assigns \nothing ; + +function job: + at 1: assert 50 <= A <= 100; + at loop 1: + loop invariant 0 <= i <= 50; + loop invariant \forall integer k; 0 <= k < i == > P(t[k]); + loop assigns i,t[0..49]; + at loop body 1: + contract: + ensures i == \old(i); + at loop stmt 1: + contract: + requires i==0; + ensures i==50; + at loop 2: + loop invariant A <= j <= 100; + loop assigns j,t[A ..99]; + at return: + assert \forall integer k; 0 <= k < 50 == > P(t[k]); + at call f: + contract: + ensures P(phi(C(t[i]))); +``` + +The following command line: + +``` +frama -c -acsl-import demo.acsl demo.c -print -no-unicode +``` + +generates the following output: + +``` +# frama-c -acsl-import demo.acsl demo.c -print -no-unicode +[kernel] Parsing demo.c (with preprocessing) +[acsl-importer] Success for demo.acsl +[acsl-importer] Done: 1 file. +[kernel] Parsing demo.c (with preprocessing) +[acsl-importer] Success for demo.acsl +[acsl-importer] Done: 1 file. +/* Generated by Frama-C */ +/*@ +axiomatic A { + type event = B | C(integer); + predicate P(integer x) ; + logic integer phi(event e) ; + } + */ +/*@ ensures P(phi(C(\result))); + assigns \nothing; */ +int f(int i); + +/*@ assigns \nothing; */ +int g(int j); + +void job(int *t, int A) { + /*@ assert 50 <= A <= 100; */ + { + int i = 0; + /*@ requires i == 0; + ensures i == 50; */ + /*@ loop invariant 0 <= i <= 50; + loop invariant \forall integer k; 0 <= k < i ==> P(*(t + k)); + loop assigns i, *(t + (0 .. 49)); + */ + while (i < 50) { + /*@ ensures i == \old(i); */ + { + /*@ ensures P(phi(C(*(t + i)))); */ + *(t + i) = f(i); + } + i ++; + } + } + { + int j = A; + /*@ loop invariant A <= j <= 100; + loop assigns j, *(t + (A .. 99)); */ + while (j < 100) { + { + *(t + j) = g(j); + } + j ++; + } + } + /*@ assert \forall integer k; 0 <= k < 50 ==> P(*(t + k)); */ + return; +} + +int T[100]; +void main(void) { + job(T,50); + return; +} +``` + +## Contact \ No newline at end of file -- GitLab