From 011c162603ae7a74075483764cedef102b0cbf6b Mon Sep 17 00:00:00 2001 From: Virgile Prevosto <virgile.prevosto@m4x.org> Date: Fri, 13 Mar 2020 18:55:22 +0100 Subject: [PATCH 001/218] [typing] only scalar types can be casted to _Bool --- src/kernel_internals/typing/cabs2cil.ml | 18 +++++++++++------- .../syntax/oracle/wrong-assignment.res.oracle | 4 ++++ tests/syntax/wrong-assignment.i | 8 ++++++++ 3 files changed, 23 insertions(+), 7 deletions(-) create mode 100644 tests/syntax/oracle/wrong-assignment.res.oracle create mode 100644 tests/syntax/wrong-assignment.i diff --git a/src/kernel_internals/typing/cabs2cil.ml b/src/kernel_internals/typing/cabs2cil.ml index 481fde16c7e..3d7d49a0bc6 100644 --- a/src/kernel_internals/typing/cabs2cil.ml +++ b/src/kernel_internals/typing/cabs2cil.ml @@ -1349,15 +1349,19 @@ let makeCastT ~(e: exp) ~(oldt: typ) ~(newt: typ) = let makeCast ~(e: exp) ~(newt: typ) = makeCastT e (typeOf e) newt -(* A cast that is used for conditional expressions. Pointers are Ok. - Abort if invalid *) -let checkBool (ot : typ) (_ : exp) = - match unrollType ot with +let is_scalar_type t = + match unrollType t with | TInt _ | TPtr _ | TEnum _ - | TFloat _ -> () - | _ -> Kernel.fatal ~current:true "castToBool %a" Cil_printer.pp_typ ot + | TFloat _ -> true + | _ -> false + +(* A cast that is used for conditional expressions. Pointers are Ok. + Abort if invalid *) +let checkBool (ot : typ) (_ : exp) = + if not (is_scalar_type ot) then + Kernel.fatal ~current:true "castToBool %a" Cil_printer.pp_typ ot (* Evaluate constants to CTrue (non-zero) or CFalse (zero) *) let rec isConstTrueFalse c: [ `CTrue | `CFalse ] = @@ -2829,7 +2833,7 @@ let rec castTo ?context ?(fromsource=false) match ot', nt' with | TNamed _, _ | _, TNamed _ -> Kernel.fatal ~current:true "unrollType failed in castTo" - | _, TInt(IBool,_) -> + | t, TInt(IBool,_) when is_scalar_type t -> if is_boolean_result e then result else nt, diff --git a/tests/syntax/oracle/wrong-assignment.res.oracle b/tests/syntax/oracle/wrong-assignment.res.oracle new file mode 100644 index 00000000000..aba1a2ecee9 --- /dev/null +++ b/tests/syntax/oracle/wrong-assignment.res.oracle @@ -0,0 +1,4 @@ +[kernel] Parsing tests/syntax/wrong-assignment.i (no preprocessing) +[kernel] tests/syntax/wrong-assignment.i:7: Failure: castTo ebool -> _Bool +[kernel] User Error: stopping on file "tests/syntax/wrong-assignment.i" that has errors. +[kernel] Frama-C aborted: invalid user input. diff --git a/tests/syntax/wrong-assignment.i b/tests/syntax/wrong-assignment.i new file mode 100644 index 00000000000..da2a59b86ae --- /dev/null +++ b/tests/syntax/wrong-assignment.i @@ -0,0 +1,8 @@ +typedef struct { _Bool a; } ebool; + +ebool b, c; + +void d() { + // this assignment should be rejected + c.a = b; +} -- GitLab From 81fbce4e4496a7de0b15345227d64d4df6d49480 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Loi=CC=88c=20Correnson?= <loic.correnson@cea.fr> Date: Mon, 23 Mar 2020 16:35:23 +0100 Subject: [PATCH 002/218] [wp] test exhibiting the scope problem --- src/plugins/wp/tests/wp_bts/issue_837.c | 15 +++++ .../tests/wp_bts/oracle/issue_837.res.oracle | 66 +++++++++++++++++++ .../wp_bts/oracle_qualif/issue_837.res.oracle | 23 +++++++ 3 files changed, 104 insertions(+) create mode 100644 src/plugins/wp/tests/wp_bts/issue_837.c create mode 100644 src/plugins/wp/tests/wp_bts/oracle/issue_837.res.oracle create mode 100644 src/plugins/wp/tests/wp_bts/oracle_qualif/issue_837.res.oracle diff --git a/src/plugins/wp/tests/wp_bts/issue_837.c b/src/plugins/wp/tests/wp_bts/issue_837.c new file mode 100644 index 00000000000..c266ff99736 --- /dev/null +++ b/src/plugins/wp/tests/wp_bts/issue_837.c @@ -0,0 +1,15 @@ +#define TEST(x) ( x ? 1 : 0 ) + +//@ assigns \nothing; +void foo(int a, int b) +{ + if (a && TEST(b)) ; else if (TEST(b)) + {} // BUG: the assigns is not proved by WP +} + +//@ assigns \nothing; +void bar(int a, int b) +{ + if (a && TEST(b)) ; else if (TEST(b)) + ; // OK: the assigns is correctly proved by WP +} diff --git a/src/plugins/wp/tests/wp_bts/oracle/issue_837.res.oracle b/src/plugins/wp/tests/wp_bts/oracle/issue_837.res.oracle new file mode 100644 index 00000000000..2c7f2a6b78d --- /dev/null +++ b/src/plugins/wp/tests/wp_bts/oracle/issue_837.res.oracle @@ -0,0 +1,66 @@ +# frama-c -wp [...] +[kernel] Parsing tests/wp_bts/issue_837.c (with preprocessing) +[wp] Running WP plugin... +[wp] Loading driver 'share/wp.driver' +[wp] Warning: Missing RTE guards +------------------------------------------------------------ + Function bar +------------------------------------------------------------ + +Goal Assigns nothing in 'bar' (1/5): +Effect at line 13 +Prove: true. + +------------------------------------------------------------ + +Goal Assigns nothing in 'bar' (2/5): +Effect at line 13 +Prove: true. + +------------------------------------------------------------ + +Goal Assigns nothing in 'bar' (3/5): +Effect at line 13 +Prove: true. + +------------------------------------------------------------ + +Goal Assigns nothing in 'bar' (4/5): +Effect at line 13 +Prove: true. + +------------------------------------------------------------ + +Goal Assigns nothing in 'bar' (5/5): +Effect at line 13 +Prove: true. + +------------------------------------------------------------ +------------------------------------------------------------ + Function foo +------------------------------------------------------------ + +Goal Assigns nothing in 'foo' (1/4): +Effect at line 6 +Prove: true. + +------------------------------------------------------------ + +Goal Assigns nothing in 'foo' (2/4): +Effect at line 6 +Prove: true. + +------------------------------------------------------------ + +Goal Assigns nothing in 'foo' (3/4): +Effect at line 6 +Prove: true. + +------------------------------------------------------------ + +Goal Assigns nothing in 'foo' (4/4): +Effect at line 6 +Assume { Type: is_sint32(a). (* Residual *) When: a != 0. } +Prove: (ta_tmp_0=false). + +------------------------------------------------------------ diff --git a/src/plugins/wp/tests/wp_bts/oracle_qualif/issue_837.res.oracle b/src/plugins/wp/tests/wp_bts/oracle_qualif/issue_837.res.oracle new file mode 100644 index 00000000000..a619021a1b9 --- /dev/null +++ b/src/plugins/wp/tests/wp_bts/oracle_qualif/issue_837.res.oracle @@ -0,0 +1,23 @@ +# frama-c -wp [...] +[kernel] Parsing tests/wp_bts/issue_837.c (with preprocessing) +[wp] Running WP plugin... +[wp] Loading driver 'share/wp.driver' +[wp] Warning: Missing RTE guards +[wp] 9 goals scheduled +[wp] [Qed] Goal typed_bar_assigns_part1 : Valid +[wp] [Qed] Goal typed_bar_assigns_part2 : Valid +[wp] [Qed] Goal typed_bar_assigns_part3 : Valid +[wp] [Qed] Goal typed_bar_assigns_part4 : Valid +[wp] [Qed] Goal typed_bar_assigns_part5 : Valid +[wp] [Qed] Goal typed_foo_assigns_part1 : Valid +[wp] [Qed] Goal typed_foo_assigns_part2 : Valid +[wp] [Qed] Goal typed_foo_assigns_part3 : Valid +[wp] [Alt-Ergo] Goal typed_foo_assigns_part4 : Unsuccess +[wp] Proved goals: 8 / 9 + Qed: 8 + Alt-Ergo: 0 (unsuccess: 1) +------------------------------------------------------------ + Functions WP Alt-Ergo Total Success + foo 3 - 4 75.0% + bar 5 - 5 100% +------------------------------------------------------------ -- GitLab From 16c650851439d48b362a4e9cb249b766bce09173 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Loi=CC=88c=20Correnson?= <loic.correnson@cea.fr> Date: Mon, 23 Mar 2020 17:06:07 +0100 Subject: [PATCH 003/218] [wp] fix open/close blocks --- src/plugins/wp/calculus.ml | 9 ++-- src/plugins/wp/cil2cfg.ml | 54 +++++++++---------- src/plugins/wp/cil2cfg.mli | 4 +- .../tests/wp_bts/oracle/issue_837.res.oracle | 3 +- .../wp_bts/oracle_qualif/issue_837.res.oracle | 9 ++-- 5 files changed, 38 insertions(+), 41 deletions(-) diff --git a/src/plugins/wp/calculus.ml b/src/plugins/wp/calculus.ml index 1ff49f9195b..01e99eacd7f 100644 --- a/src/plugins/wp/calculus.ml +++ b/src/plugins/wp/calculus.ml @@ -605,11 +605,10 @@ module Cfg (W : Mcfg.S) = struct wp_scope wenv formals Mcfg.SC_Function_after_POST obj *) in - let res = - let blks = Cil2cfg.blocks_closed_by_edge cfg e in - let free_locals res b = wp_scope wenv b.blocals Mcfg.SC_Block_out res in - List.fold_left free_locals res blks - in + let Cil2cfg.{ b_closed ; b_opened } = Cil2cfg.block_scope_for_edge cfg e in + let do_block sc res b = wp_scope wenv b.blocals sc res in + let res = List.fold_left (do_block Mcfg.SC_Block_in) res b_opened in + let res = List.fold_left (do_block Mcfg.SC_Block_out) res b_closed in debug "[compute_edge] before %a done@." Cil2cfg.pp_node v; Cil.CurrentLoc.set old_loc; res diff --git a/src/plugins/wp/cil2cfg.ml b/src/plugins/wp/cil2cfg.ml index b995b8212a4..8a8402eb871 100644 --- a/src/plugins/wp/cil2cfg.ml +++ b/src/plugins/wp/cil2cfg.ml @@ -626,36 +626,34 @@ let get_post_label cfg v = | None -> None | Some s -> Some (Clabels.stmt s) -let blocks_closed_by_edge cfg e = +type block_scope = { b_opened : block list ; b_closed : block list } + +let no_scope = { b_opened = [] ; b_closed = [] } + +let block_scope s s' = + try + { + b_opened = Kernel_function.blocks_opened_by_edge s s' ; + b_closed = Kernel_function.blocks_closed_by_edge s s' ; + } + with Not_found | Invalid_argument _ -> + debug "[blocks_closed_by_edge] not found sid:%d -> sid:%d@." s.sid s'.sid; + no_scope + +let block_scope_for_edge cfg e = debug "[blocks_closed_by_edge] for %a...@." pp_edge e; let v_before = edge_src e in - let blocks = match node_type v_before with - | Vstmt s | Vtest (true, s, _) | Vloop (_, s) | Vswitch (s,_) -> - ignore (Ast.get ()); (* Since CIL Cfg computation is required and - Ast.get () have to do this well. *) - begin match s.succs with - | [s'] -> (try Kernel_function.blocks_closed_by_edge s s' - with Not_found as e -> debug "[blocks_closed_by_edge] not found sid:%d -> sid:%d@." - s.sid s'.sid; - raise e) - | [] | _ :: _ -> - let s' = get_edge_next_stmt cfg e in - match s' with - | None -> [] - | Some s' -> - debug - "[blocks_closed_by_edge] found sid:%d -> sid:%d@." - s.sid s'.sid; - try Kernel_function.blocks_closed_by_edge s s' - with Invalid_argument _ -> [] - end - | _ -> (* TODO ? *) [] - in - let v_after = edge_dst e in - let blocks = match node_type v_after with - | VblkOut (Bfct, b) -> b::blocks - | _ -> blocks - in blocks + match node_type v_before with + | Vstmt s | Vtest (true, s, _) | Vloop (_, s) | Vswitch (s,_) -> + begin match s.succs with + | [s'] -> block_scope s s' + | [] | _ :: _ -> + let s' = get_edge_next_stmt cfg e in + match s' with + | None -> no_scope + | Some s' -> block_scope s s' + end + | _ -> (* TODO ? *) no_scope let has_exit cfg = try diff --git a/src/plugins/wp/cil2cfg.mli b/src/plugins/wp/cil2cfg.mli index f0c16fe47c0..5df3e524af0 100644 --- a/src/plugins/wp/cil2cfg.mli +++ b/src/plugins/wp/cil2cfg.mli @@ -107,7 +107,9 @@ val get_switch_edges : t -> node -> (exp list * edge) list * edge but gives the edge to VcallOut first and the edge to Vexit second. *) val get_call_out_edges : t -> node -> edge * edge -val blocks_closed_by_edge : t -> edge -> block list +type block_scope = { b_opened : block list ; b_closed : block list } + +val block_scope_for_edge : t -> edge -> block_scope val is_back_edge : edge -> bool diff --git a/src/plugins/wp/tests/wp_bts/oracle/issue_837.res.oracle b/src/plugins/wp/tests/wp_bts/oracle/issue_837.res.oracle index 2c7f2a6b78d..d1e95f07802 100644 --- a/src/plugins/wp/tests/wp_bts/oracle/issue_837.res.oracle +++ b/src/plugins/wp/tests/wp_bts/oracle/issue_837.res.oracle @@ -60,7 +60,6 @@ Prove: true. Goal Assigns nothing in 'foo' (4/4): Effect at line 6 -Assume { Type: is_sint32(a). (* Residual *) When: a != 0. } -Prove: (ta_tmp_0=false). +Prove: true. ------------------------------------------------------------ diff --git a/src/plugins/wp/tests/wp_bts/oracle_qualif/issue_837.res.oracle b/src/plugins/wp/tests/wp_bts/oracle_qualif/issue_837.res.oracle index a619021a1b9..1e55e4e4da4 100644 --- a/src/plugins/wp/tests/wp_bts/oracle_qualif/issue_837.res.oracle +++ b/src/plugins/wp/tests/wp_bts/oracle_qualif/issue_837.res.oracle @@ -12,12 +12,11 @@ [wp] [Qed] Goal typed_foo_assigns_part1 : Valid [wp] [Qed] Goal typed_foo_assigns_part2 : Valid [wp] [Qed] Goal typed_foo_assigns_part3 : Valid -[wp] [Alt-Ergo] Goal typed_foo_assigns_part4 : Unsuccess -[wp] Proved goals: 8 / 9 - Qed: 8 - Alt-Ergo: 0 (unsuccess: 1) +[wp] [Qed] Goal typed_foo_assigns_part4 : Valid +[wp] Proved goals: 9 / 9 + Qed: 9 ------------------------------------------------------------ Functions WP Alt-Ergo Total Success - foo 3 - 4 75.0% + foo 4 - 4 100% bar 5 - 5 100% ------------------------------------------------------------ -- GitLab From 3f344200588c4971e655178ddfb924dc22b26b4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Loi=CC=88c=20Correnson?= <loic.correnson@cea.fr> Date: Mon, 23 Mar 2020 18:04:38 +0100 Subject: [PATCH 004/218] [wp] optimise block in/out --- src/plugins/wp/calculus.ml | 5 +- .../wp/tests/wp_plugin/oracle_qualif/f.dot | 134 ++++++++---------- .../oracle_qualif/f_default_for_stmt_2.dot | 132 ++++++++--------- .../wp/tests/wp_plugin/oracle_qualif/g.dot | 82 +++++------ 4 files changed, 157 insertions(+), 196 deletions(-) diff --git a/src/plugins/wp/calculus.ml b/src/plugins/wp/calculus.ml index 01e99eacd7f..dec7620bbed 100644 --- a/src/plugins/wp/calculus.ml +++ b/src/plugins/wp/calculus.ml @@ -494,8 +494,9 @@ module Cfg (W : Mcfg.S) = struct | Mcfg.SC_Function_frame -> "function frame" | Mcfg.SC_Function_out -> "function out" ) (Pretty_utils.pp_list ~sep:", " Printer.pp_varinfo) vars; - W.scope wenv vars scope obj - + match scope with + | Mcfg.(SC_Block_in | SC_Block_out) when vars = [] -> obj + | _ -> W.scope wenv vars scope obj (** @return the WP stored for edge [e]. Compute it if it is not already * there and store it. Also handle the Acut annotations. *) diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/f.dot b/src/plugins/wp/tests/wp_plugin/oracle_qualif/f.dot index 9b4f1de3952..077cfed3a2e 100644 --- a/src/plugins/wp/tests/wp_plugin/oracle_qualif/f.dot +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/f.dot @@ -2,89 +2,73 @@ digraph f { rankdir = TB ; node [ style = filled, shape = box ] ; N000 [ color = red, shape = circle, label = "*" ] ; - N074 [ color=red , label="Prove f_ensures" ] ; - N074 -> N000 [ style=dotted ] ; - N075 [ color=red , label="Prove f_ensures_2" ] ; - N075 -> N074 [ style=dotted ] ; - N076 [ label="" , shape=circle ] ; + N056 [ color=red , label="Prove f_ensures" ] ; + N056 -> N000 [ style=dotted ] ; + N057 [ color=red , label="Prove f_ensures_2" ] ; + N057 -> N056 [ style=dotted ] ; + N058 [ label="" , shape=circle ] ; + N058 -> N057 ; + N058 -> N056 ; + N059 [ color=lightblue , label="F-out { a b }" ] ; + N059 -> N058 ; + N060 [ label="Label wp:post" ] ; + N060 -> N059 ; + N061 [ color=lightblue , label="B-out { __retres }" ] ; + N061 -> N060 ; + N062 [ color=orange , label="Return __retres" ] ; + N062 -> N061 ; + N063 [ label="Label wp:sid27 (Stmt s27)" ] ; + N063 -> N062 ; + N064 [ label="Label wp:sid26 (Stmt s26)" ] ; + N064 -> N063 ; + N065 [ color=green , label="Assume f_assert" ] ; + N065 -> N064 ; + N066 [ color=red , label="Prove f_assert" ] ; + N066 -> N065 [ style=dotted ] ; + N067 [ label="" , shape=circle ] ; + N067 -> N066 ; + N067 -> N065 ; + N068 [ label="Label wp:sid25 (Stmt s25)" ] ; + N068 -> N067 ; + N069 [ color=orange , label="__retres := a + b" ] ; + N069 -> N068 ; + N070 [ label="Label wp:sid6 (Stmt s6)" ] ; + N070 -> N069 ; + N071 [ label="Label wp:sid24 (Stmt s24)" ] ; + N071 -> N070 ; + N072 [ color=orange , label="Return __retres" ] ; + N072 -> N061 ; + N073 [ label="Label wp:sid27 (Stmt s27)" ] ; + N073 -> N072 ; + N074 [ color=orange , label="__retres := -1" ] ; + N074 -> N073 ; + N075 [ label="Label wp:sid8 (Stmt s8)" ] ; + N075 -> N074 ; + N076 [ color=green , label="Assume f_ensures_3" ] ; N076 -> N075 ; - N076 -> N074 ; - N077 [ color=lightblue , label="F-out { a b }" ] ; + N077 [ color=orange , label="Havoc f_assigns: +assigns __retres;" ] ; N077 -> N076 ; - N078 [ label="Label wp:post" ] ; - N078 -> N077 ; - N079 [ color=lightblue , label="B-out { __retres }" ] ; + N078 [ color=cyan , label="If a > 0" ] ; + N078 -> N071 ; + N078 -> N000 [ style=dotted ]; + N079 [ label="Label wp:sid4 (Stmt s4)" ] ; N079 -> N078 ; - N080 [ color=orange , label="Return __retres" ] ; + N080 [ label="" , shape=circle ] ; + N080 -> N077 ; N080 -> N079 ; - N081 [ color=lightblue , label="B-out { }" ] ; + N081 [ label="Label wp:sid2 (Stmt s2)" ] ; N081 -> N080 ; - N082 [ color=lightblue , label="B-out { }" ] ; + N082 [ color=lightblue , label="B-in { __retres }" ] ; N082 -> N081 ; - N083 [ color=lightblue , label="B-out { }" ] ; + N083 [ color=lightblue , label="F-frame { a b }" ] ; N083 -> N082 ; - N084 [ label="Label wp:sid27 (Stmt s27)" ] ; + N084 [ label="Label wp:pre" ] ; N084 -> N083 ; - N085 [ label="Label wp:sid26 (Stmt s26)" ] ; + N085 [ color=lightblue , label="F-in { a b }" ] ; N085 -> N084 ; - N086 [ color=green , label="Assume f_assert" ] ; + N086 [ color=lightblue , label="Global { }" ] ; N086 -> N085 ; - N087 [ color=red , label="Prove f_assert" ] ; - N087 -> N086 [ style=dotted ] ; - N088 [ label="" , shape=circle ] ; - N088 -> N087 ; - N088 -> N086 ; - N089 [ label="Label wp:sid25 (Stmt s25)" ] ; - N089 -> N088 ; - N090 [ color=orange , label="__retres := a + b" ] ; - N090 -> N089 ; - N091 [ label="Label wp:sid6 (Stmt s6)" ] ; - N091 -> N090 ; - N092 [ color=lightblue , label="B-in { }" ] ; - N092 -> N091 ; - N093 [ label="Label wp:sid24 (Stmt s24)" ] ; - N093 -> N092 ; - N094 [ color=lightblue , label="B-in { }" ] ; - N094 -> N093 ; - N095 [ color=orange , label="Return __retres" ] ; - N095 -> N079 ; - N096 [ label="Label wp:sid27 (Stmt s27)" ] ; - N096 -> N095 ; - N097 [ color=orange , label="__retres := -1" ] ; - N097 -> N096 ; - N098 [ label="Label wp:sid8 (Stmt s8)" ] ; - N098 -> N097 ; - N099 [ color=green , label="Assume f_ensures_3" ] ; - N099 -> N098 ; - N100 [ color=orange , label="Havoc f_assigns: -assigns __retres;" ] ; - N100 -> N099 ; - N101 [ color=lightblue , label="B-in { }" ] ; - N101 -> N000 [ style=dotted ]; - N102 [ color=lightblue , label="B-out { }" ] ; - N102 -> N101 ; - N103 [ color=cyan , label="If a > 0" ] ; - N103 -> N094 ; - N103 -> N102 ; - N104 [ label="Label wp:sid4 (Stmt s4)" ] ; - N104 -> N103 ; - N105 [ color=lightblue , label="B-in { }" ] ; - N105 -> N104 ; - N106 [ label="" , shape=circle ] ; - N106 -> N100 ; - N106 -> N105 ; - N107 [ label="Label wp:sid2 (Stmt s2)" ] ; - N107 -> N106 ; - N108 [ color=lightblue , label="B-in { __retres }" ] ; - N108 -> N107 ; - N109 [ color=lightblue , label="F-frame { a b }" ] ; - N109 -> N108 ; - N110 [ label="Label wp:pre" ] ; - N110 -> N109 ; - N111 [ color=lightblue , label="F-in { a b }" ] ; - N111 -> N110 ; - N112 [ color=lightblue , label="Global { }" ] ; - N112 -> N111 ; - N113 [ color=cyan , label="Function f" ] ; - N113 -> N112 ; + N087 [ color=cyan , label="Function f" ] ; + N087 -> N086 ; } diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/f_default_for_stmt_2.dot b/src/plugins/wp/tests/wp_plugin/oracle_qualif/f_default_for_stmt_2.dot index e5347d619f1..be3a8a3a5db 100644 --- a/src/plugins/wp/tests/wp_plugin/oracle_qualif/f_default_for_stmt_2.dot +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/f_default_for_stmt_2.dot @@ -2,80 +2,64 @@ digraph f { rankdir = TB ; node [ style = filled, shape = box ] ; N000 [ color = red, shape = circle, label = "*" ] ; - N114 [ color=lightblue , label="F-out { a b }" ] ; - N114 -> N000 [ style=dotted ]; - N115 [ label="Label wp:post" ] ; + N088 [ color=lightblue , label="F-out { a b }" ] ; + N088 -> N000 [ style=dotted ]; + N089 [ label="Label wp:post" ] ; + N089 -> N088 ; + N090 [ color=lightblue , label="B-out { __retres }" ] ; + N090 -> N089 ; + N091 [ color=orange , label="Return __retres" ] ; + N091 -> N090 ; + N092 [ label="Label wp:sid27 (Stmt s27)" ] ; + N092 -> N091 ; + N093 [ label="Label wp:sid26 (Stmt s26)" ] ; + N093 -> N092 ; + N094 [ color=green , label="Assume f_assert" ] ; + N094 -> N093 ; + N095 [ label="Label wp:sid25 (Stmt s25)" ] ; + N095 -> N094 ; + N096 [ color=orange , label="__retres := a + b" ] ; + N096 -> N095 ; + N097 [ label="Label wp:sid6 (Stmt s6)" ] ; + N097 -> N096 ; + N098 [ label="Label wp:sid24 (Stmt s24)" ] ; + N098 -> N097 ; + N099 [ color=orange , label="Return __retres" ] ; + N099 -> N090 ; + N100 [ label="Label wp:sid27 (Stmt s27)" ] ; + N100 -> N099 ; + N101 [ color=orange , label="__retres := -1" ] ; + N101 -> N100 ; + N102 [ label="Label wp:sid8 (Stmt s8)" ] ; + N102 -> N101 ; + N103 [ color=green , label="Assume f_ensures_3" ] ; + N103 -> N102 ; + N104 [ color=red , label="Assigns f_assigns" ] ; + N105 [ label="" , shape=circle ] ; + N105 -> N104 ; + N105 -> N103 ; + N106 [ color=red , label="Prove f_ensures_3" ] ; + N106 -> N105 [ style=dotted ] ; + N107 [ label="" , shape=circle ] ; + N107 -> N106 ; + N107 -> N105 ; + N108 [ color=cyan , label="If a > 0" ] ; + N108 -> N098 ; + N108 -> N107 ; + N109 [ label="Label wp:sid4 (Stmt s4)" ] ; + N109 -> N108 ; + N110 [ label="Label wp:sid2 (Stmt s2)" ] ; + N110 -> N109 ; + N111 [ color=lightblue , label="B-in { __retres }" ] ; + N111 -> N110 ; + N112 [ color=lightblue , label="F-frame { a b }" ] ; + N112 -> N111 ; + N113 [ label="Label wp:pre" ] ; + N113 -> N112 ; + N114 [ color=lightblue , label="F-in { a b }" ] ; + N114 -> N113 ; + N115 [ color=lightblue , label="Global { }" ] ; N115 -> N114 ; - N116 [ color=lightblue , label="B-out { __retres }" ] ; + N116 [ color=cyan , label="Function f" ] ; N116 -> N115 ; - N117 [ color=orange , label="Return __retres" ] ; - N117 -> N116 ; - N118 [ color=lightblue , label="B-out { }" ] ; - N118 -> N117 ; - N119 [ color=lightblue , label="B-out { }" ] ; - N119 -> N118 ; - N120 [ color=lightblue , label="B-out { }" ] ; - N120 -> N119 ; - N121 [ label="Label wp:sid27 (Stmt s27)" ] ; - N121 -> N120 ; - N122 [ label="Label wp:sid26 (Stmt s26)" ] ; - N122 -> N121 ; - N123 [ color=green , label="Assume f_assert" ] ; - N123 -> N122 ; - N124 [ label="Label wp:sid25 (Stmt s25)" ] ; - N124 -> N123 ; - N125 [ color=orange , label="__retres := a + b" ] ; - N125 -> N124 ; - N126 [ label="Label wp:sid6 (Stmt s6)" ] ; - N126 -> N125 ; - N127 [ color=lightblue , label="B-in { }" ] ; - N127 -> N126 ; - N128 [ label="Label wp:sid24 (Stmt s24)" ] ; - N128 -> N127 ; - N129 [ color=lightblue , label="B-in { }" ] ; - N129 -> N128 ; - N130 [ color=orange , label="Return __retres" ] ; - N130 -> N116 ; - N131 [ label="Label wp:sid27 (Stmt s27)" ] ; - N131 -> N130 ; - N132 [ color=orange , label="__retres := -1" ] ; - N132 -> N131 ; - N133 [ label="Label wp:sid8 (Stmt s8)" ] ; - N133 -> N132 ; - N134 [ color=green , label="Assume f_ensures_3" ] ; - N134 -> N133 ; - N135 [ color=red , label="Assigns f_assigns" ] ; - N136 [ label="" , shape=circle ] ; - N136 -> N135 ; - N136 -> N134 ; - N137 [ color=red , label="Prove f_ensures_3" ] ; - N137 -> N136 [ style=dotted ] ; - N138 [ label="" , shape=circle ] ; - N138 -> N137 ; - N138 -> N136 ; - N139 [ color=lightblue , label="B-in { }" ] ; - N139 -> N138 ; - N140 [ color=lightblue , label="B-out { }" ] ; - N140 -> N139 ; - N141 [ color=cyan , label="If a > 0" ] ; - N141 -> N129 ; - N141 -> N140 ; - N142 [ label="Label wp:sid4 (Stmt s4)" ] ; - N142 -> N141 ; - N143 [ color=lightblue , label="B-in { }" ] ; - N143 -> N142 ; - N144 [ label="Label wp:sid2 (Stmt s2)" ] ; - N144 -> N143 ; - N145 [ color=lightblue , label="B-in { __retres }" ] ; - N145 -> N144 ; - N146 [ color=lightblue , label="F-frame { a b }" ] ; - N146 -> N145 ; - N147 [ label="Label wp:pre" ] ; - N147 -> N146 ; - N148 [ color=lightblue , label="F-in { a b }" ] ; - N148 -> N147 ; - N149 [ color=lightblue , label="Global { }" ] ; - N149 -> N148 ; - N150 [ color=cyan , label="Function f" ] ; - N150 -> N149 ; } diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/g.dot b/src/plugins/wp/tests/wp_plugin/oracle_qualif/g.dot index 5cdbeab8327..4fffdb8fb16 100644 --- a/src/plugins/wp/tests/wp_plugin/oracle_qualif/g.dot +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/g.dot @@ -2,55 +2,47 @@ digraph g { rankdir = TB ; node [ style = filled, shape = box ] ; N000 [ color = red, shape = circle, label = "*" ] ; - N049 [ color=red , label="Prove g_ensures_2" ] ; - N049 -> N000 [ style=dotted ] ; - N050 [ color=lightblue , label="F-out { a b }" ] ; + N035 [ color=red , label="Prove g_ensures_2" ] ; + N035 -> N000 [ style=dotted ] ; + N036 [ color=lightblue , label="F-out { a b }" ] ; + N036 -> N035 ; + N037 [ label="Label wp:post" ] ; + N037 -> N036 ; + N038 [ color=lightblue , label="B-out { __retres }" ] ; + N038 -> N037 ; + N039 [ color=orange , label="Return __retres" ] ; + N039 -> N038 ; + N040 [ label="Label wp:sid32 (Stmt s32)" ] ; + N040 -> N039 ; + N041 [ label="Label wp:sid31 (Stmt s31)" ] ; + N041 -> N040 ; + N042 [ color=green , label="Assume g_assert" ] ; + N042 -> N041 ; + N043 [ color=red , label="Prove g_assert" ] ; + N043 -> N042 [ style=dotted ] ; + N044 [ label="" , shape=circle ] ; + N044 -> N043 ; + N044 -> N042 ; + N045 [ label="Label wp:sid30 (Stmt s30)" ] ; + N045 -> N044 ; + N046 [ color=orange , label="__retres := a + b" ] ; + N046 -> N045 ; + N047 [ label="Label wp:sid13 (Stmt s13)" ] ; + N047 -> N046 ; + N048 [ label="Label wp:sid29 (Stmt s29)" ] ; + N048 -> N047 ; + N049 [ label="Label wp:sid11 (Stmt s11)" ] ; + N049 -> N048 ; + N050 [ color=lightblue , label="B-in { __retres }" ] ; N050 -> N049 ; - N051 [ label="Label wp:post" ] ; + N051 [ color=lightblue , label="F-frame { a b }" ] ; N051 -> N050 ; - N052 [ color=lightblue , label="B-out { __retres }" ] ; + N052 [ label="Label wp:pre" ] ; N052 -> N051 ; - N053 [ color=orange , label="Return __retres" ] ; + N053 [ color=lightblue , label="F-in { a b }" ] ; N053 -> N052 ; - N054 [ color=lightblue , label="B-out { }" ] ; + N054 [ color=lightblue , label="Global { }" ] ; N054 -> N053 ; - N055 [ color=lightblue , label="B-out { }" ] ; + N055 [ color=cyan , label="Function g" ] ; N055 -> N054 ; - N056 [ label="Label wp:sid32 (Stmt s32)" ] ; - N056 -> N055 ; - N057 [ label="Label wp:sid31 (Stmt s31)" ] ; - N057 -> N056 ; - N058 [ color=green , label="Assume g_assert" ] ; - N058 -> N057 ; - N059 [ color=red , label="Prove g_assert" ] ; - N059 -> N058 [ style=dotted ] ; - N060 [ label="" , shape=circle ] ; - N060 -> N059 ; - N060 -> N058 ; - N061 [ label="Label wp:sid30 (Stmt s30)" ] ; - N061 -> N060 ; - N062 [ color=orange , label="__retres := a + b" ] ; - N062 -> N061 ; - N063 [ label="Label wp:sid13 (Stmt s13)" ] ; - N063 -> N062 ; - N064 [ color=lightblue , label="B-in { }" ] ; - N064 -> N063 ; - N065 [ label="Label wp:sid29 (Stmt s29)" ] ; - N065 -> N064 ; - N066 [ color=lightblue , label="B-in { }" ] ; - N066 -> N065 ; - N067 [ label="Label wp:sid11 (Stmt s11)" ] ; - N067 -> N066 ; - N068 [ color=lightblue , label="B-in { __retres }" ] ; - N068 -> N067 ; - N069 [ color=lightblue , label="F-frame { a b }" ] ; - N069 -> N068 ; - N070 [ label="Label wp:pre" ] ; - N070 -> N069 ; - N071 [ color=lightblue , label="F-in { a b }" ] ; - N071 -> N070 ; - N072 [ color=lightblue , label="Global { }" ] ; - N072 -> N071 ; - N073 [ color=cyan , label="Function g" ] ; - N073 -> N072 ; } -- GitLab From 8b39f0cdccbd0cce39c4ac703e519fcccf932e00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Loi=CC=88c=20Correnson?= <loic.correnson@cea.fr> Date: Mon, 23 Mar 2020 18:10:52 +0100 Subject: [PATCH 005/218] [wp] fix scope of function body --- src/plugins/wp/calculus.ml | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/plugins/wp/calculus.ml b/src/plugins/wp/calculus.ml index dec7620bbed..272f255fe7f 100644 --- a/src/plugins/wp/calculus.ml +++ b/src/plugins/wp/calculus.ml @@ -565,13 +565,17 @@ module Cfg (W : Mcfg.S) = struct | Cil2cfg.VblkIn (Cil2cfg.Bfct, b) -> let obj = get_only_succ env cfg v in let obj = wp_scope wenv b.blocals Mcfg.SC_Block_in obj in - wp_scope wenv formals Mcfg.SC_Function_frame obj + let obj = wp_scope wenv formals Mcfg.SC_Function_frame obj in + obj + | Cil2cfg.VblkOut (Cil2cfg.Bfct, b) -> + let obj = get_only_succ env cfg v in + let obj = wp_scope wenv b.blocals Mcfg.SC_Block_out obj in + obj + | Cil2cfg.VblkOut _ -> + get_only_succ env cfg v | Cil2cfg.VblkIn (_, b) -> let obj = get_only_succ env cfg v in wp_scope wenv b.blocals Mcfg.SC_Block_in obj - | Cil2cfg.VblkOut (_, _b) -> - let obj = get_only_succ env cfg v in - obj (* cf. blocks_closed_by_edge below *) | Cil2cfg.Vstmt s -> let obj = get_only_succ env cfg v in wp_stmt wenv s obj -- GitLab From 36104e935eb38f231ae36415797d610b1f80b89f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Loi=CC=88c=20Correnson?= <loic.correnson@cea.fr> Date: Mon, 23 Mar 2020 18:29:40 +0100 Subject: [PATCH 006/218] [wp] fix duplicated block in --- src/plugins/wp/calculus.ml | 5 +---- src/plugins/wp/cil2cfg.ml | 6 +++++- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/plugins/wp/calculus.ml b/src/plugins/wp/calculus.ml index 272f255fe7f..2f3c5e7e07f 100644 --- a/src/plugins/wp/calculus.ml +++ b/src/plugins/wp/calculus.ml @@ -571,11 +571,8 @@ module Cfg (W : Mcfg.S) = struct let obj = get_only_succ env cfg v in let obj = wp_scope wenv b.blocals Mcfg.SC_Block_out obj in obj - | Cil2cfg.VblkOut _ -> + | Cil2cfg.VblkOut _ | Cil2cfg.VblkIn _ -> get_only_succ env cfg v - | Cil2cfg.VblkIn (_, b) -> - let obj = get_only_succ env cfg v in - wp_scope wenv b.blocals Mcfg.SC_Block_in obj | Cil2cfg.Vstmt s -> let obj = get_only_succ env cfg v in wp_stmt wenv s obj diff --git a/src/plugins/wp/cil2cfg.ml b/src/plugins/wp/cil2cfg.ml index 8a8402eb871..0afef00829b 100644 --- a/src/plugins/wp/cil2cfg.ml +++ b/src/plugins/wp/cil2cfg.ml @@ -653,7 +653,11 @@ let block_scope_for_edge cfg e = | None -> no_scope | Some s' -> block_scope s s' end - | _ -> (* TODO ? *) no_scope + | VblkIn(Bstmt _,b) -> { b_opened=[b] ; b_closed=[] } + | Vcall _ + | VblkIn _ | VblkOut _ | Vtest(false,_,_) + | VfctIn | VfctOut | Vstart | Vend | Vexit | Vloop2 _ -> + no_scope let has_exit cfg = try -- GitLab From 22f9d23b5acc3fc379a346a4a4b68c96dc3cc7b5 Mon Sep 17 00:00:00 2001 From: Virgile Prevosto <virgile.prevosto@m4x.org> Date: Mon, 23 Mar 2020 18:30:16 +0100 Subject: [PATCH 007/218] [printer] print_sid is for Cil_printer as well as for Printer. --- src/kernel_services/ast_printing/cil_printer.ml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/kernel_services/ast_printing/cil_printer.ml b/src/kernel_services/ast_printing/cil_printer.ml index f1b5ab00c66..2b8c620ea6b 100644 --- a/src/kernel_services/ast_printing/cil_printer.ml +++ b/src/kernel_services/ast_printing/cil_printer.ml @@ -1180,6 +1180,9 @@ class cil_printer () = object (self) method annotated_stmt (next: stmt) fmt (s: stmt) = pp_open_hvbox fmt 0; + if Kernel.is_debug_key_enabled Kernel.dkey_print_sid then begin + Format.fprintf fmt "/* sid:%d */@\n" s.sid; + end; (* print the statement. *) if Cil.is_skip s.skind && not s.ghost && s.sattr = [] then begin if verbose || s.labels <> [] then begin -- GitLab From bfeb8c16321488ac18207d996d255b367e5e7ce7 Mon Sep 17 00:00:00 2001 From: Virgile Prevosto <virgile.prevosto@m4x.org> Date: Mon, 23 Mar 2020 13:50:28 +0100 Subject: [PATCH 008/218] [typing] avoid removing a block if previous stmt is a statement contract or any code annotation that is specifying what the whole next statement is doing --- src/kernel_internals/typing/cabs2cil.ml | 159 +++++++++--------- src/kernel_services/ast_queries/file.ml | 26 +-- .../ast_queries/logic_utils.ml | 21 +++ .../ast_queries/logic_utils.mli | 9 + tests/spec/oracle/stmt_contract.res.oracle | 2 + tests/spec/stmt_contract.i | 3 + 6 files changed, 120 insertions(+), 100 deletions(-) diff --git a/src/kernel_internals/typing/cabs2cil.ml b/src/kernel_internals/typing/cabs2cil.ml index 48b894205ee..42b88e95e86 100644 --- a/src/kernel_internals/typing/cabs2cil.ml +++ b/src/kernel_internals/typing/cabs2cil.ml @@ -2100,82 +2100,89 @@ struct Cil_printer.pp_stmt s l; with Found -> () - class cleanUnspecified = object(self) - inherit nopCilVisitor - val unspecified_stack = Stack.create () - - val mutable replace_table = [] - - (* we start in a deterministic block. *) - initializer Stack.push false unspecified_stack - - method private push: 'a.bool->'a->'a visitAction = - fun flag x -> - Stack.push flag unspecified_stack; - ChangeDoChildrenPost - (x,fun x -> ignore(Stack.pop unspecified_stack); x) - - - method! vblock b = - b.bstmts <- - List.rev - (List.fold_left( - fun res s -> - match s.skind with - | Block b when - (not (Stack.top unspecified_stack)) && - b.battrs = [] && b.blocals = [] && - s.labels = [] - -> List.rev_append b.bstmts res - | _ -> s ::res) - [] b.bstmts); - DoChildren - - method! vstmt s = - let ghost = s.ghost in - let change_label_stmt s s' = - List.iter - (function - | Label (x,_,_) -> H.replace labelStmt x s' - | Case _ | Default _ -> replace_table <- (s, s') :: replace_table - ) s.labels; - s'.labels <- s.labels @ s'.labels - in - match s.skind with - | UnspecifiedSequence [s',_,_,_,_] -> - change_label_stmt s s'; - ChangeDoChildrenPost(s', fun x -> x) - | UnspecifiedSequence [] -> - let s' = mkEmptyStmt ~ghost ~valid_sid ~loc:(cabslu "_useq") () in - change_label_stmt s s'; - ChangeTo s'; - | UnspecifiedSequence _ -> self#push true s - | Block { battrs = []; blocals = []; bstmts = [s']} -> - change_label_stmt s s'; - ChangeDoChildrenPost (s', fun x -> x) - | Block _ | If _ | Loop _ - | TryFinally _ | TryExcept _ | Throw _ | TryCatch _ -> - self#push false s - | Switch _ -> - let change_cases stmt = - match stmt.skind with - | Switch(e,body,cases,loc) -> - let newcases = - List.map - (fun s -> - try List.assq s replace_table - with Not_found -> s) - cases - in - stmt.skind <- Switch(e,body,newcases,loc); - ignore (Stack.pop unspecified_stack); - stmt - | _ -> assert false - in Stack.push false unspecified_stack; - ChangeDoChildrenPost(s,change_cases) - | Instr _ | Return _ | Goto _ | Break _ - | Continue _ -> DoChildren - end + class cleanUnspecified = + let is_annot_next_stmt = function + | [] -> false + | { skind = Instr (Code_annot (c,_)) } :: _ -> + Logic_utils.is_annot_next_stmt c + | _ -> false + in + object(self) + inherit nopCilVisitor + val unspecified_stack = Stack.create () + + val mutable replace_table = [] + + (* we start in a deterministic block. *) + initializer Stack.push false unspecified_stack + + method private push: 'a.bool->'a->'a visitAction = + fun flag x -> + Stack.push flag unspecified_stack; + ChangeDoChildrenPost + (x,fun x -> ignore(Stack.pop unspecified_stack); x) + + + method! vblock b = + b.bstmts <- + List.rev + (List.fold_left( + fun res s -> + match s.skind with + | Block b when + (not (Stack.top unspecified_stack)) && + b.battrs = [] && b.blocals = [] && + s.labels = [] && not (is_annot_next_stmt res) + -> List.rev_append b.bstmts res + | _ -> s ::res) + [] b.bstmts); + DoChildren + + method! vstmt s = + let ghost = s.ghost in + let change_label_stmt s s' = + List.iter + (function + | Label (x,_,_) -> H.replace labelStmt x s' + | Case _ | Default _ -> replace_table <- (s, s') :: replace_table + ) s.labels; + s'.labels <- s.labels @ s'.labels + in + match s.skind with + | UnspecifiedSequence [s',_,_,_,_] -> + change_label_stmt s s'; + ChangeDoChildrenPost(s', fun x -> x) + | UnspecifiedSequence [] -> + let s' = mkEmptyStmt ~ghost ~valid_sid ~loc:(cabslu "_useq") () in + change_label_stmt s s'; + ChangeTo s'; + | UnspecifiedSequence _ -> self#push true s + | Block { battrs = []; blocals = []; bstmts = [s']} -> + change_label_stmt s s'; + ChangeDoChildrenPost (s', fun x -> x) + | Block _ | If _ | Loop _ + | TryFinally _ | TryExcept _ | Throw _ | TryCatch _ -> + self#push false s + | Switch _ -> + let change_cases stmt = + match stmt.skind with + | Switch(e,body,cases,loc) -> + let newcases = + List.map + (fun s -> + try List.assq s replace_table + with Not_found -> s) + cases + in + stmt.skind <- Switch(e,body,newcases,loc); + ignore (Stack.pop unspecified_stack); + stmt + | _ -> assert false + in Stack.push false unspecified_stack; + ChangeDoChildrenPost(s,change_cases) + | Instr _ | Return _ | Goto _ | Break _ + | Continue _ -> DoChildren + end let mkFunctionBody ~ghost (c: chunk) : block = if c.cases <> [] then diff --git a/src/kernel_services/ast_queries/file.ml b/src/kernel_services/ast_queries/file.ml index 49e7e958ce5..a1635dcd9df 100644 --- a/src/kernel_services/ast_queries/file.ml +++ b/src/kernel_services/ast_queries/file.ml @@ -730,28 +730,6 @@ let synchronize_source_annot has_new_stmt kf = | Some block, Some stmt_father when block == stmt_father -> true | _, _ -> false in - let is_annot_next annot = - match annot.annot_content with - | AStmtSpec _ | APragma (Slice_pragma SPstmt | Impact_pragma IPstmt) - -> true - | AExtended(_,is_loop,{ext_name}) -> - let warn_not_a_code_annot () = - Kernel.( - warning ~wkey:wkey_acsl_extension - "%s is not a code annotation extension" name) - in - (match Logic_env.extension_category ext_name with - | exception Not_found -> warn_not_a_code_annot () ; false - | Ext_code_annot (Ext_here | Ext_next_loop)-> false - | Ext_code_annot Ext_next_stmt-> true - | Ext_code_annot Ext_next_both-> not is_loop - | Ext_contract | Ext_global -> warn_not_a_code_annot () ; false) - | AAssert _ | AInvariant _ | AVariant _ - | AAssigns _ | AAllocation _ - | APragma (Slice_pragma (SPctrl | SPexpr _)) - | APragma (Impact_pragma (IPexpr _)) - | APragma (Loop_pragma _) -> false - in let synchronize_user_annot a = add_annotation kf st a in let synchronize_previous_user_annots () = if !user_annots_for_next_stmt <> [] then begin @@ -759,7 +737,7 @@ let synchronize_source_annot has_new_stmt kf = let my_annots = !user_annots_for_next_stmt in let post_action st = let treat_annot (has_annot,st) (st_ann, annot) = - if is_annot_next annot then begin + if Logic_utils.is_annot_next_stmt annot then begin if has_annot || st.labels <> [] || st_ann.labels <> [] then begin st_ann.skind <- (Block (Cil.mkBlockNonScoping [st])); @@ -822,7 +800,7 @@ let synchronize_source_annot has_new_stmt kf = (* Code annotation isn't considered as a real stmt. So, previous annotations should be relative to the next stmt. Only this [annot] may be synchronised to that stmt *) - if is_annot_next annot then + if Logic_utils.is_annot_next_stmt annot then (* Annotation relative to the effect of next statement *) add_user_annot_for_next_stmt st annot else diff --git a/src/kernel_services/ast_queries/logic_utils.ml b/src/kernel_services/ast_queries/logic_utils.ml index bbc4329de6a..41237fee587 100644 --- a/src/kernel_services/ast_queries/logic_utils.ml +++ b/src/kernel_services/ast_queries/logic_utils.ml @@ -573,6 +573,27 @@ let is_trivially_true p = Ptrue -> true | _ -> false +let is_annot_next_stmt c = + match c.annot_content with + | AStmtSpec _ | APragma (Slice_pragma SPstmt | Impact_pragma IPstmt) -> true + | AExtended(_,is_loop,{ext_name}) -> + let warn_not_a_code_annot () = + Kernel.( + warning ~wkey:wkey_acsl_extension + "%s is not a code annotation extension" ext_name) + in + (match Logic_env.extension_category ext_name with + | exception Not_found -> warn_not_a_code_annot () ; false + | Ext_code_annot (Ext_here | Ext_next_loop)-> false + | Ext_code_annot Ext_next_stmt-> true + | Ext_code_annot Ext_next_both-> not is_loop + | Ext_contract | Ext_global -> warn_not_a_code_annot () ; false) + | AAssert _ | AInvariant _ | AVariant _ + | AAssigns _ | AAllocation _ + | APragma (Slice_pragma (SPctrl | SPexpr _)) + | APragma (Impact_pragma (IPexpr _)) + | APragma (Loop_pragma _) -> false + let rec add_attribute_glob_annot a g = match g with | Dfun_or_pred ({ l_var_info },_) | Dinvariant({ l_var_info }, _) diff --git a/src/kernel_services/ast_queries/logic_utils.mli b/src/kernel_services/ast_queries/logic_utils.mli index c19683aac4b..b3a51cdf016 100644 --- a/src/kernel_services/ast_queries/logic_utils.mli +++ b/src/kernel_services/ast_queries/logic_utils.mli @@ -250,6 +250,15 @@ val is_trivially_true: predicate -> bool @since Nitrogen-20111001 *) val is_trivially_false: predicate -> bool +(** {2 Code annotations} *) + +(** Does the annotation apply to the next statement (e.g. a statement + contract). Also false for loop-related annotations. + + @since Frama-C+dev +*) +val is_annot_next_stmt: code_annotation -> bool + (** {2 Global annotations} *) (** add an attribute to a global annotation diff --git a/tests/spec/oracle/stmt_contract.res.oracle b/tests/spec/oracle/stmt_contract.res.oracle index c60dcabab0a..f8723d8fb48 100644 --- a/tests/spec/oracle/stmt_contract.res.oracle +++ b/tests/spec/oracle/stmt_contract.res.oracle @@ -38,6 +38,8 @@ int main(int c) /*@ requires before_label: \true; */ label: /*@ requires after_label: \true; */ y = 8; + /*@ ensures x ≡ 0 ∨ x ≡ 7; */ + if (c >= 3) x = 0; else x = 7; /*@ requires x ≡ 7; */ /*@ ensures x ≡ 7; */ { diff --git a/tests/spec/stmt_contract.i b/tests/spec/stmt_contract.i index ccac6381fcc..80e9690322a 100644 --- a/tests/spec/stmt_contract.i +++ b/tests/spec/stmt_contract.i @@ -32,6 +32,9 @@ int main(int c) { //@ requires after_label: \true; y=8; + /*@ ensures x == 0 || x == 7; */ + x = (c >= 3) ? 0 : 7; + /*@ requires x == 7; */ /*@ ensures x == 7; */ return 0; -- GitLab From d54c7753bd7fae0b1ed47126e4f2a5f473a6d9f5 Mon Sep 17 00:00:00 2001 From: Lionel Blatter <Lionel.BLATTER@cea.fr> Date: Tue, 24 Mar 2020 15:41:14 +0100 Subject: [PATCH 009/218] Add autocomplete for -kernel-msg-key, -wp-msg-key, -kernel-warn-key and -wp-prover --- share/autocomplete_frama-c | 100 ++++++++++++++++++++++++++++++++----- 1 file changed, 87 insertions(+), 13 deletions(-) diff --git a/share/autocomplete_frama-c b/share/autocomplete_frama-c index 4ddb075dae7..86fbd0ab6c1 100644 --- a/share/autocomplete_frama-c +++ b/share/autocomplete_frama-c @@ -31,6 +31,9 @@ # If you want to enable Frama-C completion only for your account, append # this file to ~/.bash_completion. # +# For a less verbose completition for options with comma-separated values, +# put "set show-all-if-ambiguous on" in your "~/.inputrc". +# # Assuming frama-c is in your PATH, # you can also put the following line into your .bashrc: # @@ -38,39 +41,110 @@ # # ----------------------------------------------------------------------------- +# Remove the colon from the list of completion word break characters +COMP_WORDBREAKS=${COMP_WORDBREAKS//:} + _frama-c () { local cur local basic_options local sub_options + local advance_options COMPREPLY=() # Array variable storing the possible completions. local sub_comp_line="${COMP_LINE[@]:0:(${COMP_POINT})}" local sub_comp_set=( $sub_comp_line ) - if [[ ${sub_comp_line: -1} == ' ' ]] ; then + compopt +o default + + if [[ ${sub_comp_line: -1} == ' ' ]] + then cur="" else cur="${sub_comp_set[@]: -1}" fi - # Generate the completion matches and load them into $COMPREPLY array. - case "$cur" in - -*-*) - sub_option="$(frama-c -autocomplete | grep -E -o " $cur[^*]+" |sort |uniq)"; - COMPREPLY=( $( compgen -W "${sub_option}" -- $cur ) );; - - -*) - basic_options="$(frama-c -autocomplete | grep -E -o " \-[^-]+-?" |sort |uniq)" - COMPREPLY=( $( compgen -W "${basic_options}" -- $cur ) );; - esac + + # Generate the completion matches for -wp-msg-key and load them into $COMPREPLY array. + # Generate the completion matches for -kernel-msg-key and load them into $COMPREPLY array. + if [[ "${COMP_WORDS[COMP_CWORD -1]}" == "-wp-msg-key" ]] || [[ "${COMP_WORDS[COMP_CWORD -1]}" == "-kernel-msg-key" ]] + then + # https://github.com/scop/bash-completion/issues/240 + local prefix=; [[ $cur == *,* ]] && prefix="${cur%,*}," + advance_options="$(frama-c ${COMP_WORDS[COMP_CWORD -1]} help | grep -E -o " [^*]+" |sort |uniq)" + + # Solution from: https://github.com/scop/bash-completion/commit/021058b38ad7279c33ffbaa36d73041d607385ba + # But, if show-all-if-ambiguous is set to off completion for options with comma-separated values loses its prefix: + # https://github.com/scop/bash-completion/issues/240. + # So we have two ways for completion, depending on the value of show-all-if-ambiguous + local ambigous="$(bind -v | grep show-all-if-ambiguous)" + ambigous="${ambigous##* }" + if [[ "$ambigous" == "on" ]] + then + COMPREPLY=( $( compgen -W "${advance_options}" -- "${cur##*,}" ) ) + [[ ${#COMPREPLY[@]} -eq 1 ]] && COMPREPLY=( ${COMPREPLY/#/$prefix} ) + else + COMPREPLY=( $( compgen -P "$prefix" -W "${advance_options}" -- "${cur##*,}" ) ) + fi + + + # Generate the completion matches for -wp-prover and load them into $COMPREPLY array. + elif [[ "${COMP_WORDS[COMP_CWORD -1]}" == "-wp-prover" ]] + then + local prefix=; [[ $cur == *,* ]] && prefix="${cur%,*}," + # The current output of -wp-detect is not suitable for an easy grep using regular expressions, + # so the possible completions are not added to $COMPREPLY. + advance_options="none scritp tip alt-ergo altgr-ergo coq native:alt-ergo native:coq native:coqide" + local ambigous="$(bind -v | grep show-all-if-ambiguous)" + ambigous="${ambigous##* }" + if [[ "$ambigous" == "on" ]] + then + COMPREPLY=( $( compgen -W "${advance_options}" -- "${cur##*,}" ) ) + [[ ${#COMPREPLY[@]} -eq 1 ]] && COMPREPLY=( ${COMPREPLY/#/$prefix} ) + else + COMPREPLY=( $( compgen -P "$prefix" -W "${advance_options}" -- "${cur##*,}" ) ) + fi + + + # Generate the completion matches for -kernel-warn-key and load them into $COMPREPLY array. + elif [[ "${COMP_WORDS[COMP_CWORD -1]}" == "-kernel-warn-key" ]] + then + local prefix=; [[ $cur == *,* ]] && prefix="${cur%,*}," + advance_options="$(frama-c -kernel-warn-key help | grep -E -o " [^*]+[^:] ")" + + local ambigous="$(bind -v | grep show-all-if-ambiguous)" + ambigous="${ambigous##* }" + if [[ "$ambigous" == "on" ]] + then + COMPREPLY=( $( compgen -W "${advance_options}" -- "${cur##*,}" ) ) + [[ ${#COMPREPLY[@]} -eq 1 ]] && COMPREPLY=( ${COMPREPLY/#/$prefix} ) + else + COMPREPLY=( $( compgen -P "$prefix" -W "${advance_options}" -- "${cur##*,}" ) ) + fi + + + # Generate the completion matches for -* and load them into $COMPREPLY array. + else + case "$cur" in + -*-*) + sub_option="$(frama-c -autocomplete | grep -E -o " $cur[^*]+" |sort |uniq)"; + COMPREPLY=( $( compgen -W "${sub_option}" -- $cur ) );; + + -*) + basic_options="$(frama-c -autocomplete | grep -E -o " \-[^-]+-?" |sort |uniq)" + COMPREPLY=( $( compgen -W "${basic_options}" -- $cur ) );; + *) + compopt -o default + COMPREPLY=();; + esac + fi return 0 } -complete -o nospace -f -F _frama-c filename frama-c -complete -o nospace -f -F _frama-c filename frama-c-gui +complete -o nospace -F _frama-c frama-c +complete -o nospace -F _frama-c frama-c-gui # Local Variables: # mode: sh -- GitLab From e80dbe06203fdfa887358f4406ad762e8d7acc44 Mon Sep 17 00:00:00 2001 From: Allan Blanchard <allan.blanchard@cea.fr> Date: Wed, 25 Mar 2020 09:54:42 +0100 Subject: [PATCH 010/218] [Instantiate] Do not fail on function pointers --- src/plugins/instantiate/Makefile.in | 2 +- src/plugins/instantiate/tests/plugin/function_pointers.i | 6 ++++++ .../tests/plugin/oracle/function_pointers.res.oracle | 1 + src/plugins/instantiate/transform.ml | 3 ++- 4 files changed, 10 insertions(+), 2 deletions(-) create mode 100644 src/plugins/instantiate/tests/plugin/function_pointers.i create mode 100644 src/plugins/instantiate/tests/plugin/oracle/function_pointers.res.oracle diff --git a/src/plugins/instantiate/Makefile.in b/src/plugins/instantiate/Makefile.in index d316b8c7c15..843525c882d 100644 --- a/src/plugins/instantiate/Makefile.in +++ b/src/plugins/instantiate/Makefile.in @@ -62,7 +62,7 @@ PLUGIN_CMO := \ PLUGIN_DISTRIBUTED := $(PLUGIN_ENABLE) PLUGIN_DISTRIB_EXTERNAL:= Makefile.in configure.ac configure #PLUGIN_NO_DEFAULT_TEST := no -PLUGIN_TESTS_DIRS := string stdlib options api +PLUGIN_TESTS_DIRS := string stdlib options api plugin ################ # Generic part # diff --git a/src/plugins/instantiate/tests/plugin/function_pointers.i b/src/plugins/instantiate/tests/plugin/function_pointers.i new file mode 100644 index 00000000000..8f27dd1ab18 --- /dev/null +++ b/src/plugins/instantiate/tests/plugin/function_pointers.i @@ -0,0 +1,6 @@ +/* run.config + OPT: -instantiate +*/ +void foo(void (* bar)()){ + (*bar)(); +} \ No newline at end of file diff --git a/src/plugins/instantiate/tests/plugin/oracle/function_pointers.res.oracle b/src/plugins/instantiate/tests/plugin/oracle/function_pointers.res.oracle new file mode 100644 index 00000000000..bcf3d3f77fa --- /dev/null +++ b/src/plugins/instantiate/tests/plugin/oracle/function_pointers.res.oracle @@ -0,0 +1 @@ +[kernel] Parsing tests/plugin/function_pointers.i (no preprocessing) diff --git a/src/plugins/instantiate/transform.ml b/src/plugins/instantiate/transform.ml index 6324749d9de..7ef4a276a17 100644 --- a/src/plugins/instantiate/transform.ml +++ b/src/plugins/instantiate/transform.ml @@ -104,7 +104,8 @@ class transformer = object(self) | Not_found -> (fct, args) method! vinst = function - | Call(_) | Local_init(_, ConsInit(_, _, Plain_func), _) -> + | Call(_, { enode = Lval((Var _), NoOffset)} , _, _) + | Local_init(_, ConsInit(_ , _, Plain_func), _) -> let change = function | [ Call(r, ({ enode = Lval((Var f), NoOffset) } as e), args, loc) ] -> let f, args = self#replace_call (r, f, args) in -- GitLab From cdba1f48ede4afca87cee449bca566e625a96fac Mon Sep 17 00:00:00 2001 From: Allan Blanchard <allan.blanchard@cea.fr> Date: Wed, 25 Mar 2020 17:48:39 +0100 Subject: [PATCH 011/218] [Instantiate] Memset: take of nested typedefs --- src/plugins/instantiate/string/memset.ml | 2 +- .../tests/string/memset_nested_typedef.c | 9 +++ .../oracle/memset_nested_typedef.res.oracle | 75 +++++++++++++++++++ 3 files changed, 85 insertions(+), 1 deletion(-) create mode 100644 src/plugins/instantiate/tests/string/memset_nested_typedef.c create mode 100644 src/plugins/instantiate/tests/string/oracle/memset_nested_typedef.res.oracle diff --git a/src/plugins/instantiate/string/memset.ml b/src/plugins/instantiate/string/memset.ml index f1935a41528..7c2bc6ce40c 100644 --- a/src/plugins/instantiate/string/memset.ml +++ b/src/plugins/instantiate/string/memset.ml @@ -63,7 +63,7 @@ let pset_len_bytes_to_value ?loc ptr value bytes_len = let pset_len_bytes_to_zero ?loc ptr bytes_len = let eq_value ?loc t = - let value = match t.term_type with + let value = match Logic_utils.unroll_type t.term_type with | Ctype(TPtr(_)) -> term Tnull t.term_type | Ctype(TFloat(_)) -> treal ?loc 0. | Ctype(TInt(_)) -> tinteger ?loc 0 diff --git a/src/plugins/instantiate/tests/string/memset_nested_typedef.c b/src/plugins/instantiate/tests/string/memset_nested_typedef.c new file mode 100644 index 00000000000..2e01be12e5c --- /dev/null +++ b/src/plugins/instantiate/tests/string/memset_nested_typedef.c @@ -0,0 +1,9 @@ +#include <string.h> + +typedef unsigned t; +struct X { t s_addr; }; + +void test() { + struct X x; + memset(&x, 0, sizeof(x)); +} diff --git a/src/plugins/instantiate/tests/string/oracle/memset_nested_typedef.res.oracle b/src/plugins/instantiate/tests/string/oracle/memset_nested_typedef.res.oracle new file mode 100644 index 00000000000..27287ebadeb --- /dev/null +++ b/src/plugins/instantiate/tests/string/oracle/memset_nested_typedef.res.oracle @@ -0,0 +1,75 @@ +[kernel] Parsing tests/string/memset_nested_typedef.c (with preprocessing) +/* Generated by Frama-C */ +#include "stddef.h" +#include "string.h" +#include "strings.h" +typedef unsigned int t; +struct X { + t s_addr ; +}; +/*@ requires aligned_end: len % 4 ≡ 0; + requires + valid_dest: \let __fc_len = len / 4; \valid(ptr + (0 .. __fc_len - 1)); + ensures + set_content: + \let __fc_len = len / 4; + ∀ ℤ j0; 0 ≤ j0 < __fc_len ⇒ (ptr + j0)->s_addr ≡ 0; + ensures result: \result ≡ ptr; + assigns *(ptr + (0 .. len / 4 - 1)), \result; + assigns *(ptr + (0 .. len / 4 - 1)) \from \nothing; + assigns \result \from ptr; + */ +struct X *memset_st_X_0(struct X *ptr, size_t len) +{ + struct X *__retres; + __retres = (struct X *)memset((void *)ptr,0,len); + return __retres; +} + +void test(void) +{ + struct X x; + memset_st_X_0(& x,sizeof(x)); + return; +} + + +[kernel] Parsing tests/string/result/memset_nested_typedef.c (with preprocessing) +[kernel] Parsing tests/string/memset_nested_typedef.c (with preprocessing) +[kernel] tests/string/memset_nested_typedef.c:6: Warning: + dropping duplicate def'n of func test at tests/string/memset_nested_typedef.c:6 in favor of that at tests/string/result/memset_nested_typedef.c:28 +/* Generated by Frama-C */ +#include "stddef.h" +#include "string.h" +#include "strings.h" +typedef unsigned int t; +struct X { + t s_addr ; +}; +/*@ requires aligned_end: len % 4 ≡ 0; + requires + valid_dest: \let __fc_len = len / 4; \valid(ptr + (0 .. __fc_len - 1)); + ensures + set_content: + \let __fc_len = \old(len) / 4; + ∀ ℤ j0; 0 ≤ j0 < __fc_len ⇒ (\old(ptr) + j0)->s_addr ≡ 0; + ensures result: \result ≡ \old(ptr); + assigns *(ptr + (0 .. len / 4 - 1)), \result; + assigns *(ptr + (0 .. len / 4 - 1)) \from \nothing; + assigns \result \from ptr; + */ +struct X *memset_st_X_0(struct X *ptr, size_t len) +{ + struct X *__retres; + __retres = (struct X *)memset((void *)ptr,0,len); + return __retres; +} + +void test(void) +{ + struct X x; + memset_st_X_0(& x,sizeof(x)); + return; +} + + -- GitLab From 6520856e1f6e425da1bd2b144ecc968993ff2bcb Mon Sep 17 00:00:00 2001 From: Allan Blanchard <allan.blanchard@cea.fr> Date: Wed, 25 Mar 2020 18:05:46 +0100 Subject: [PATCH 012/218] [Instantiate] Ignore nested unions in memset --- src/plugins/instantiate/string/memset.ml | 16 ++++--- .../tests/string/memset_nested_union.c | 11 +++++ .../oracle/memset_nested_union.res.oracle | 45 +++++++++++++++++++ 3 files changed, 67 insertions(+), 5 deletions(-) create mode 100644 src/plugins/instantiate/tests/string/memset_nested_union.c create mode 100644 src/plugins/instantiate/tests/string/oracle/memset_nested_union.res.oracle diff --git a/src/plugins/instantiate/string/memset.ml b/src/plugins/instantiate/string/memset.ml index 7c2bc6ce40c..d597bd3a452 100644 --- a/src/plugins/instantiate/string/memset.ml +++ b/src/plugins/instantiate/string/memset.ml @@ -183,13 +183,19 @@ let memset_value e = | Const(CInt64(ni, _, _)) when Integer.equal ni ff -> Some 255 | _ -> None -let is_union_type = function - | TComp({ cstruct = false }, _, _) -> true +let rec contains_union_type t = + match Cil.unrollType t with + | TComp({ cstruct = false }, _, _) -> + true + | TComp({ cfields = fields }, _, _) -> + List.exists contains_union_type (List.map (fun f -> f.ftype) fields) + | TArray(t, _, _, _) -> + contains_union_type t | _ -> false let well_typed_call _ret = function | [ ptr ; _ ; _ ] when any_char_composed_type (type_from_arg ptr) -> true - | [ ptr ; _ ; _ ] when is_union_type (type_from_arg ptr) -> false + | [ ptr ; _ ; _ ] when contains_union_type (type_from_arg ptr) -> false | [ ptr ; _ ; _ ] when Cil.isVoidType (type_from_arg ptr) -> false | [ _ ; value ; _ ] -> begin match memset_value value with @@ -201,7 +207,7 @@ let well_typed_call _ret = function let key_from_call _ret = function | [ ptr ; _ ; _ ] when any_char_composed_type (type_from_arg ptr) -> (type_from_arg ptr), None - | [ ptr ; value ; _ ] when not (is_union_type (type_from_arg ptr)) -> + | [ ptr ; value ; _ ] when not (contains_union_type (type_from_arg ptr)) -> (type_from_arg ptr), (memset_value value) | _ -> failwith "Call to Memset.key_from_call on an ill-typed call" @@ -226,7 +232,7 @@ let generate_prototype = function let name = function_name ^ "_" ^ (string_of_typ t) in let fun_type = char_prototype t in name, fun_type - | t, Some x when not (is_union_type t) && (x = 0 || x = 255) -> + | t, Some x when not (contains_union_type t) && (x = 0 || x = 255) -> let ext = if x = 0 then "_0" else if x = 255 then "_FF" else assert false in let name = function_name ^ "_" ^ (string_of_typ t) ^ ext in let fun_type = non_char_prototype t in diff --git a/src/plugins/instantiate/tests/string/memset_nested_union.c b/src/plugins/instantiate/tests/string/memset_nested_union.c new file mode 100644 index 00000000000..ea236b94e15 --- /dev/null +++ b/src/plugins/instantiate/tests/string/memset_nested_union.c @@ -0,0 +1,11 @@ +#include <string.h> + +union U { + int x ; + unsigned y ; +}; +struct X { union U u ; }; +void test() { + struct X x; + memset(&x, 0, sizeof(x)); +} diff --git a/src/plugins/instantiate/tests/string/oracle/memset_nested_union.res.oracle b/src/plugins/instantiate/tests/string/oracle/memset_nested_union.res.oracle new file mode 100644 index 00000000000..99b6125cfd4 --- /dev/null +++ b/src/plugins/instantiate/tests/string/oracle/memset_nested_union.res.oracle @@ -0,0 +1,45 @@ +[kernel] Parsing tests/string/memset_nested_union.c (with preprocessing) +[instantiate] tests/string/memset_nested_union.c:10: Warning: + Ignore call: not well typed +/* Generated by Frama-C */ +#include "stddef.h" +#include "string.h" +#include "strings.h" +union U { + int x ; + unsigned int y ; +}; +struct X { + union U u ; +}; +void test(void) +{ + struct X x; + memset((void *)(& x),0,sizeof(x)); + return; +} + + +[kernel] Parsing tests/string/result/memset_nested_union.c (with preprocessing) +[kernel] Parsing tests/string/memset_nested_union.c (with preprocessing) +[kernel] tests/string/memset_nested_union.c:8: Warning: + dropping duplicate def'n of func test at tests/string/memset_nested_union.c:8 in favor of that at tests/string/result/memset_nested_union.c:12 +/* Generated by Frama-C */ +#include "stddef.h" +#include "string.h" +#include "strings.h" +union U { + int x ; + unsigned int y ; +}; +struct X { + union U u ; +}; +void test(void) +{ + struct X x; + memset((void *)(& x),0,sizeof(x)); + return; +} + + -- GitLab From a465676c71fb6fd008e6dff2f41c025c69dc25f3 Mon Sep 17 00:00:00 2001 From: Allan Blanchard <allan.blanchard@cea.fr> Date: Wed, 25 Mar 2020 18:23:06 +0100 Subject: [PATCH 013/218] [Instantiate] Ignore incomplete types in string functions --- src/plugins/instantiate/string/memcmp.ml | 3 +- src/plugins/instantiate/string/memcpy.ml | 3 +- src/plugins/instantiate/string/memmove.ml | 3 +- src/plugins/instantiate/string/memset.ml | 1 + src/plugins/instantiate/tests/string/memcmp.c | 5 +++ src/plugins/instantiate/tests/string/memcpy.c | 6 +++ .../instantiate/tests/string/memmove.c | 6 +++ .../instantiate/tests/string/memset_value.c | 5 +++ .../tests/string/oracle/memcmp.res.oracle | 31 +++++++++++--- .../tests/string/oracle/memcpy.res.oracle | 34 +++++++++++++--- .../tests/string/oracle/memmove.res.oracle | 34 +++++++++++++--- .../string/oracle/memset_value.res.oracle | 40 ++++++++++++++----- 12 files changed, 141 insertions(+), 30 deletions(-) diff --git a/src/plugins/instantiate/string/memcmp.ml b/src/plugins/instantiate/string/memcmp.ml index 813ab06065f..e493cbb3939 100644 --- a/src/plugins/instantiate/string/memcmp.ml +++ b/src/plugins/instantiate/string/memcmp.ml @@ -97,7 +97,8 @@ let well_typed_call _ret = function | [ s1 ; s2 ; len ] -> (Cil.isIntegralType (Cil.typeOf len)) && (Cil_datatype.Typ.equal (type_from_arg s1) (type_from_arg s2)) && - (not (Cil.isVoidType (type_from_arg s1))) + (not (Cil.isVoidType (type_from_arg s1))) && + (Cil.isCompleteType (type_from_arg s1)) | _ -> false let key_from_call _ret = function diff --git a/src/plugins/instantiate/string/memcpy.ml b/src/plugins/instantiate/string/memcpy.ml index 6be6f6664ba..02d06b3d5ea 100644 --- a/src/plugins/instantiate/string/memcpy.ml +++ b/src/plugins/instantiate/string/memcpy.ml @@ -103,7 +103,8 @@ let well_typed_call _ret = function | [ dest ; src ; len ] -> (Cil.isIntegralType (Cil.typeOf len)) && (Cil_datatype.Typ.equal (type_from_arg dest) (type_from_arg src)) && - (not (Cil.isVoidType (type_from_arg dest))) + (not (Cil.isVoidType (type_from_arg dest))) && + (Cil.isCompleteType (type_from_arg dest)) | _ -> false let key_from_call _ret = function diff --git a/src/plugins/instantiate/string/memmove.ml b/src/plugins/instantiate/string/memmove.ml index 97c3dcb1c57..75aef926971 100644 --- a/src/plugins/instantiate/string/memmove.ml +++ b/src/plugins/instantiate/string/memmove.ml @@ -97,7 +97,8 @@ let well_typed_call _ret = function | [ dest ; src ; len ] -> (Cil.isIntegralType (Cil.typeOf len)) && (Cil_datatype.Typ.equal (type_from_arg dest) (type_from_arg src)) && - (not (Cil.isVoidType (type_from_arg dest))) + (not (Cil.isVoidType (type_from_arg dest))) && + (Cil.isCompleteType (type_from_arg dest)) | _ -> false let key_from_call _ret = function diff --git a/src/plugins/instantiate/string/memset.ml b/src/plugins/instantiate/string/memset.ml index d597bd3a452..79c0fd60bbe 100644 --- a/src/plugins/instantiate/string/memset.ml +++ b/src/plugins/instantiate/string/memset.ml @@ -197,6 +197,7 @@ let well_typed_call _ret = function | [ ptr ; _ ; _ ] when any_char_composed_type (type_from_arg ptr) -> true | [ ptr ; _ ; _ ] when contains_union_type (type_from_arg ptr) -> false | [ ptr ; _ ; _ ] when Cil.isVoidType (type_from_arg ptr) -> false + | [ ptr ; _ ; _ ] when not (Cil.isCompleteType (type_from_arg ptr)) -> false | [ _ ; value ; _ ] -> begin match memset_value value with | None -> false diff --git a/src/plugins/instantiate/tests/string/memcmp.c b/src/plugins/instantiate/tests/string/memcmp.c index 004f004f222..404692f9eb1 100644 --- a/src/plugins/instantiate/tests/string/memcmp.c +++ b/src/plugins/instantiate/tests/string/memcmp.c @@ -29,4 +29,9 @@ int nested(int (*s1)[10], int (*s2)[10], int n){ int with_void(void *s1, void *s2, int n){ return memcmp(s1, s2, 10) ; +} + +struct incomplete ; +int with_incomplete(struct incomplete* s1, struct incomplete* s2, int n){ + return memcmp(s1, s2, n); } \ No newline at end of file diff --git a/src/plugins/instantiate/tests/string/memcpy.c b/src/plugins/instantiate/tests/string/memcpy.c index 4f245bbbd06..f2c6c03d864 100644 --- a/src/plugins/instantiate/tests/string/memcpy.c +++ b/src/plugins/instantiate/tests/string/memcpy.c @@ -36,3 +36,9 @@ void with_void(void *src, void *dest, int n){ void *res = memcpy(dest, src, n); memcpy(src, res, n); } + +struct incomplete ; +void with_incomplete(struct incomplete* src, struct incomplete* dest, int n){ + struct incomplete* res = memcpy(dest, src, n); + memcpy(src, res, n); +} \ No newline at end of file diff --git a/src/plugins/instantiate/tests/string/memmove.c b/src/plugins/instantiate/tests/string/memmove.c index 9fca890b0e1..a40698297fd 100644 --- a/src/plugins/instantiate/tests/string/memmove.c +++ b/src/plugins/instantiate/tests/string/memmove.c @@ -36,3 +36,9 @@ void with_void(void *src, void *dest, int n){ void *res = memmove(dest, src, n); memmove(src, res, n); } + +struct incomplete ; +void with_incomplete(struct incomplete *src, struct incomplete *dest, int n){ + struct incomplete *res = memmove(dest, src, n); + memmove(src, res, n); +} diff --git a/src/plugins/instantiate/tests/string/memset_value.c b/src/plugins/instantiate/tests/string/memset_value.c index 25f04a59ff0..432b8ed6a6d 100644 --- a/src/plugins/instantiate/tests/string/memset_value.c +++ b/src/plugins/instantiate/tests/string/memset_value.c @@ -51,3 +51,8 @@ void with_void(void* dest, int value){ void* res = memset(dest, value, 10); memset(res, value, 10); } + +void with_incomplete(struct incomplete* dest, int value){ + struct incomplete * res = memset(dest, value, 10); + memset(res, value, 10); +} \ No newline at end of file diff --git a/src/plugins/instantiate/tests/string/oracle/memcmp.res.oracle b/src/plugins/instantiate/tests/string/oracle/memcmp.res.oracle index 9a3d0e63811..9d73f30f20f 100644 --- a/src/plugins/instantiate/tests/string/oracle/memcmp.res.oracle +++ b/src/plugins/instantiate/tests/string/oracle/memcmp.res.oracle @@ -1,5 +1,6 @@ [kernel] Parsing tests/string/memcmp.c (with preprocessing) [instantiate] tests/string/memcmp.c:31: Warning: Ignore call: not well typed +[instantiate] tests/string/memcmp.c:36: Warning: Ignore call: not well typed /* Generated by Frama-C */ #include "stddef.h" #include "string.h" @@ -9,6 +10,7 @@ struct X { int y ; }; typedef int named; +struct incomplete; /*@ requires aligned_end: len % 4 ≡ 0; requires valid_read_s1: @@ -150,21 +152,30 @@ int with_void(void *s1, void *s2, int n) return tmp; } +int with_incomplete(struct incomplete *s1, struct incomplete *s2, int n) +{ + int tmp; + tmp = memcmp((void const *)s1,(void const *)s2,(unsigned int)n); + return tmp; +} + [kernel] Parsing tests/string/result/memcmp.c (with preprocessing) [kernel] Parsing tests/string/memcmp.c (with preprocessing) [kernel] tests/string/memcmp.c:10: Warning: - def'n of func integer at tests/string/memcmp.c:10 (sum 1085) conflicts with the one at tests/string/result/memcmp.c:34 (sum 1972); keeping the one at tests/string/result/memcmp.c:34. + def'n of func integer at tests/string/memcmp.c:10 (sum 1085) conflicts with the one at tests/string/result/memcmp.c:35 (sum 1972); keeping the one at tests/string/result/memcmp.c:35. [kernel] tests/string/memcmp.c:14: Warning: - def'n of func with_named at tests/string/memcmp.c:14 (sum 1085) conflicts with the one at tests/string/result/memcmp.c:41 (sum 1972); keeping the one at tests/string/result/memcmp.c:41. + def'n of func with_named at tests/string/memcmp.c:14 (sum 1085) conflicts with the one at tests/string/result/memcmp.c:42 (sum 1972); keeping the one at tests/string/result/memcmp.c:42. [kernel] tests/string/memcmp.c:18: Warning: - def'n of func structure at tests/string/memcmp.c:18 (sum 1085) conflicts with the one at tests/string/result/memcmp.c:72 (sum 1972); keeping the one at tests/string/result/memcmp.c:72. + def'n of func structure at tests/string/memcmp.c:18 (sum 1085) conflicts with the one at tests/string/result/memcmp.c:73 (sum 1972); keeping the one at tests/string/result/memcmp.c:73. [kernel] tests/string/memcmp.c:22: Warning: - def'n of func pointers at tests/string/memcmp.c:22 (sum 1085) conflicts with the one at tests/string/result/memcmp.c:103 (sum 1972); keeping the one at tests/string/result/memcmp.c:103. + def'n of func pointers at tests/string/memcmp.c:22 (sum 1085) conflicts with the one at tests/string/result/memcmp.c:104 (sum 1972); keeping the one at tests/string/result/memcmp.c:104. [kernel] tests/string/memcmp.c:26: Warning: - def'n of func nested at tests/string/memcmp.c:26 (sum 1087) conflicts with the one at tests/string/result/memcmp.c:137 (sum 1974); keeping the one at tests/string/result/memcmp.c:137. + def'n of func nested at tests/string/memcmp.c:26 (sum 1087) conflicts with the one at tests/string/result/memcmp.c:138 (sum 1974); keeping the one at tests/string/result/memcmp.c:138. [kernel] tests/string/memcmp.c:30: Warning: - def'n of func with_void at tests/string/memcmp.c:30 (sum 1087) conflicts with the one at tests/string/result/memcmp.c:144 (sum 1974); keeping the one at tests/string/result/memcmp.c:144. + def'n of func with_void at tests/string/memcmp.c:30 (sum 1087) conflicts with the one at tests/string/result/memcmp.c:145 (sum 1974); keeping the one at tests/string/result/memcmp.c:145. +[kernel] tests/string/memcmp.c:35: Warning: + def'n of func with_incomplete at tests/string/memcmp.c:35 (sum 1087) conflicts with the one at tests/string/result/memcmp.c:152 (sum 1974); keeping the one at tests/string/result/memcmp.c:152. /* Generated by Frama-C */ #include "stddef.h" #include "string.h" @@ -174,6 +185,7 @@ struct X { int y ; }; typedef int named; +struct incomplete; /*@ requires aligned_end: len % 4 ≡ 0; requires valid_read_s1: @@ -324,4 +336,11 @@ int with_void(void *s1, void *s2, int n) return tmp; } +int with_incomplete(struct incomplete *s1, struct incomplete *s2, int n) +{ + int tmp; + tmp = memcmp((void const *)s1,(void const *)s2,(unsigned int)n); + return tmp; +} + diff --git a/src/plugins/instantiate/tests/string/oracle/memcpy.res.oracle b/src/plugins/instantiate/tests/string/oracle/memcpy.res.oracle index 63bd23cf23c..a9bc6101a25 100644 --- a/src/plugins/instantiate/tests/string/oracle/memcpy.res.oracle +++ b/src/plugins/instantiate/tests/string/oracle/memcpy.res.oracle @@ -1,6 +1,8 @@ [kernel] Parsing tests/string/memcpy.c (with preprocessing) [instantiate] tests/string/memcpy.c:36: Warning: Ignore call: not well typed [instantiate] tests/string/memcpy.c:37: Warning: Ignore call: not well typed +[instantiate] tests/string/memcpy.c:42: Warning: Ignore call: not well typed +[instantiate] tests/string/memcpy.c:43: Warning: Ignore call: not well typed /* Generated by Frama-C */ #include "stddef.h" #include "string.h" @@ -10,6 +12,7 @@ struct X { int y ; }; typedef int named; +struct incomplete; /*@ requires aligned_end: len % 4 ≡ 0; requires valid_dest: \let __fc_len = len / 4; \valid(dest + (0 .. __fc_len - 1)); @@ -162,21 +165,31 @@ void with_void(void *src, void *dest, int n) return; } +void with_incomplete(struct incomplete *src, struct incomplete *dest, int n) +{ + struct incomplete *res = + memcpy((void *)dest,(void const *)src,(unsigned int)n); + memcpy((void *)src,(void const *)res,(unsigned int)n); + return; +} + [kernel] Parsing tests/string/result/memcpy.c (with preprocessing) [kernel] Parsing tests/string/memcpy.c (with preprocessing) [kernel] tests/string/memcpy.c:10: Warning: - dropping duplicate def'n of func integer at tests/string/memcpy.c:10 in favor of that at tests/string/result/memcpy.c:36 + dropping duplicate def'n of func integer at tests/string/memcpy.c:10 in favor of that at tests/string/result/memcpy.c:37 [kernel] tests/string/memcpy.c:15: Warning: - dropping duplicate def'n of func with_named at tests/string/memcpy.c:15 in favor of that at tests/string/result/memcpy.c:43 + dropping duplicate def'n of func with_named at tests/string/memcpy.c:15 in favor of that at tests/string/result/memcpy.c:44 [kernel] tests/string/memcpy.c:20: Warning: - dropping duplicate def'n of func structure at tests/string/memcpy.c:20 in favor of that at tests/string/result/memcpy.c:76 + dropping duplicate def'n of func structure at tests/string/memcpy.c:20 in favor of that at tests/string/result/memcpy.c:77 [kernel] tests/string/memcpy.c:25: Warning: - dropping duplicate def'n of func pointers at tests/string/memcpy.c:25 in favor of that at tests/string/result/memcpy.c:109 + dropping duplicate def'n of func pointers at tests/string/memcpy.c:25 in favor of that at tests/string/result/memcpy.c:110 [kernel] tests/string/memcpy.c:30: Warning: - dropping duplicate def'n of func nested at tests/string/memcpy.c:30 in favor of that at tests/string/result/memcpy.c:147 + dropping duplicate def'n of func nested at tests/string/memcpy.c:30 in favor of that at tests/string/result/memcpy.c:148 [kernel] tests/string/memcpy.c:35: Warning: - dropping duplicate def'n of func with_void at tests/string/memcpy.c:35 in favor of that at tests/string/result/memcpy.c:155 + dropping duplicate def'n of func with_void at tests/string/memcpy.c:35 in favor of that at tests/string/result/memcpy.c:156 +[kernel] tests/string/memcpy.c:41: Warning: + dropping duplicate def'n of func with_incomplete at tests/string/memcpy.c:41 in favor of that at tests/string/result/memcpy.c:163 /* Generated by Frama-C */ #include "stddef.h" #include "string.h" @@ -186,6 +199,7 @@ struct X { int y ; }; typedef int named; +struct incomplete; /*@ requires aligned_end: len % 4 ≡ 0; requires valid_dest: \let __fc_len = len / 4; \valid(dest + (0 .. __fc_len - 1)); @@ -349,4 +363,12 @@ void with_void(void *src, void *dest, int n) return; } +void with_incomplete(struct incomplete *src, struct incomplete *dest, int n) +{ + struct incomplete *res = + memcpy((void *)dest,(void const *)src,(unsigned int)n); + memcpy((void *)src,(void const *)res,(unsigned int)n); + return; +} + diff --git a/src/plugins/instantiate/tests/string/oracle/memmove.res.oracle b/src/plugins/instantiate/tests/string/oracle/memmove.res.oracle index 6023a30c6bf..9d8a290eff8 100644 --- a/src/plugins/instantiate/tests/string/oracle/memmove.res.oracle +++ b/src/plugins/instantiate/tests/string/oracle/memmove.res.oracle @@ -1,6 +1,8 @@ [kernel] Parsing tests/string/memmove.c (with preprocessing) [instantiate] tests/string/memmove.c:36: Warning: Ignore call: not well typed [instantiate] tests/string/memmove.c:37: Warning: Ignore call: not well typed +[instantiate] tests/string/memmove.c:42: Warning: Ignore call: not well typed +[instantiate] tests/string/memmove.c:43: Warning: Ignore call: not well typed /* Generated by Frama-C */ #include "stddef.h" #include "string.h" @@ -10,6 +12,7 @@ struct X { int y ; }; typedef int named; +struct incomplete; /*@ requires aligned_end: len % 4 ≡ 0; requires valid_dest: \let __fc_len = len / 4; \valid(dest + (0 .. __fc_len - 1)); @@ -146,21 +149,31 @@ void with_void(void *src, void *dest, int n) return; } +void with_incomplete(struct incomplete *src, struct incomplete *dest, int n) +{ + struct incomplete *res = + memmove((void *)dest,(void const *)src,(unsigned int)n); + memmove((void *)src,(void const *)res,(unsigned int)n); + return; +} + [kernel] Parsing tests/string/result/memmove.c (with preprocessing) [kernel] Parsing tests/string/memmove.c (with preprocessing) [kernel] tests/string/memmove.c:10: Warning: - dropping duplicate def'n of func integer at tests/string/memmove.c:10 in favor of that at tests/string/result/memmove.c:32 + dropping duplicate def'n of func integer at tests/string/memmove.c:10 in favor of that at tests/string/result/memmove.c:33 [kernel] tests/string/memmove.c:15: Warning: - dropping duplicate def'n of func with_named at tests/string/memmove.c:15 in favor of that at tests/string/result/memmove.c:39 + dropping duplicate def'n of func with_named at tests/string/memmove.c:15 in favor of that at tests/string/result/memmove.c:40 [kernel] tests/string/memmove.c:20: Warning: - dropping duplicate def'n of func structure at tests/string/memmove.c:20 in favor of that at tests/string/result/memmove.c:68 + dropping duplicate def'n of func structure at tests/string/memmove.c:20 in favor of that at tests/string/result/memmove.c:69 [kernel] tests/string/memmove.c:25: Warning: - dropping duplicate def'n of func pointers at tests/string/memmove.c:25 in favor of that at tests/string/result/memmove.c:97 + dropping duplicate def'n of func pointers at tests/string/memmove.c:25 in favor of that at tests/string/result/memmove.c:98 [kernel] tests/string/memmove.c:30: Warning: - dropping duplicate def'n of func nested at tests/string/memmove.c:30 in favor of that at tests/string/result/memmove.c:131 + dropping duplicate def'n of func nested at tests/string/memmove.c:30 in favor of that at tests/string/result/memmove.c:132 [kernel] tests/string/memmove.c:35: Warning: - dropping duplicate def'n of func with_void at tests/string/memmove.c:35 in favor of that at tests/string/result/memmove.c:139 + dropping duplicate def'n of func with_void at tests/string/memmove.c:35 in favor of that at tests/string/result/memmove.c:140 +[kernel] tests/string/memmove.c:41: Warning: + dropping duplicate def'n of func with_incomplete at tests/string/memmove.c:41 in favor of that at tests/string/result/memmove.c:147 /* Generated by Frama-C */ #include "stddef.h" #include "string.h" @@ -170,6 +183,7 @@ struct X { int y ; }; typedef int named; +struct incomplete; /*@ requires aligned_end: len % 4 ≡ 0; requires valid_dest: \let __fc_len = len / 4; \valid(dest + (0 .. __fc_len - 1)); @@ -317,4 +331,12 @@ void with_void(void *src, void *dest, int n) return; } +void with_incomplete(struct incomplete *src, struct incomplete *dest, int n) +{ + struct incomplete *res = + memmove((void *)dest,(void const *)src,(unsigned int)n); + memmove((void *)src,(void const *)res,(unsigned int)n); + return; +} + diff --git a/src/plugins/instantiate/tests/string/oracle/memset_value.res.oracle b/src/plugins/instantiate/tests/string/oracle/memset_value.res.oracle index 26ed27864cc..e0a760dc1f0 100644 --- a/src/plugins/instantiate/tests/string/oracle/memset_value.res.oracle +++ b/src/plugins/instantiate/tests/string/oracle/memset_value.res.oracle @@ -23,6 +23,10 @@ Ignore call: not well typed [instantiate] tests/string/memset_value.c:52: Warning: Ignore call: not well typed +[instantiate] tests/string/memset_value.c:56: Warning: + Ignore call: not well typed +[instantiate] tests/string/memset_value.c:57: Warning: + Ignore call: not well typed /* Generated by Frama-C */ #include "stddef.h" #include "string.h" @@ -32,6 +36,7 @@ struct X { int y ; }; typedef int named; +struct incomplete; /*@ requires in_bounds_value: -128 ≤ value < 128; requires valid_dest: \valid(ptr + (0 .. len - 1)); ensures @@ -151,27 +156,36 @@ void with_void(void *dest, int value) return; } +void with_incomplete(struct incomplete *dest, int value) +{ + struct incomplete *res = memset((void *)dest,value,(unsigned int)10); + memset((void *)res,value,(unsigned int)10); + return; +} + [kernel] Parsing tests/string/result/memset_value.c (with preprocessing) [kernel] Parsing tests/string/memset_value.c (with preprocessing) [kernel] tests/string/memset_value.c:10: Warning: - dropping duplicate def'n of func chars at tests/string/memset_value.c:10 in favor of that at tests/string/result/memset_value.c:26 + dropping duplicate def'n of func chars at tests/string/memset_value.c:10 in favor of that at tests/string/result/memset_value.c:27 [kernel] tests/string/memset_value.c:15: Warning: - dropping duplicate def'n of func uchars at tests/string/memset_value.c:15 in favor of that at tests/string/result/memset_value.c:50 + dropping duplicate def'n of func uchars at tests/string/memset_value.c:15 in favor of that at tests/string/result/memset_value.c:51 [kernel] tests/string/memset_value.c:20: Warning: - dropping duplicate def'n of func nested_chars at tests/string/memset_value.c:20 in favor of that at tests/string/result/memset_value.c:78 + dropping duplicate def'n of func nested_chars at tests/string/memset_value.c:20 in favor of that at tests/string/result/memset_value.c:79 [kernel] tests/string/memset_value.c:25: Warning: - dropping duplicate def'n of func integer at tests/string/memset_value.c:25 in favor of that at tests/string/result/memset_value.c:85 + dropping duplicate def'n of func integer at tests/string/memset_value.c:25 in favor of that at tests/string/result/memset_value.c:86 [kernel] tests/string/memset_value.c:30: Warning: - dropping duplicate def'n of func with_named at tests/string/memset_value.c:30 in favor of that at tests/string/result/memset_value.c:92 + dropping duplicate def'n of func with_named at tests/string/memset_value.c:30 in favor of that at tests/string/result/memset_value.c:93 [kernel] tests/string/memset_value.c:35: Warning: - dropping duplicate def'n of func structure at tests/string/memset_value.c:35 in favor of that at tests/string/result/memset_value.c:99 + dropping duplicate def'n of func structure at tests/string/memset_value.c:35 in favor of that at tests/string/result/memset_value.c:100 [kernel] tests/string/memset_value.c:40: Warning: - dropping duplicate def'n of func pointers at tests/string/memset_value.c:40 in favor of that at tests/string/result/memset_value.c:107 + dropping duplicate def'n of func pointers at tests/string/memset_value.c:40 in favor of that at tests/string/result/memset_value.c:108 [kernel] tests/string/memset_value.c:45: Warning: - dropping duplicate def'n of func nested at tests/string/memset_value.c:45 in favor of that at tests/string/result/memset_value.c:114 + dropping duplicate def'n of func nested at tests/string/memset_value.c:45 in favor of that at tests/string/result/memset_value.c:115 [kernel] tests/string/memset_value.c:50: Warning: - dropping duplicate def'n of func with_void at tests/string/memset_value.c:50 in favor of that at tests/string/result/memset_value.c:122 + dropping duplicate def'n of func with_void at tests/string/memset_value.c:50 in favor of that at tests/string/result/memset_value.c:123 +[kernel] tests/string/memset_value.c:55: Warning: + dropping duplicate def'n of func with_incomplete at tests/string/memset_value.c:55 in favor of that at tests/string/result/memset_value.c:130 /* Generated by Frama-C */ #include "stddef.h" #include "string.h" @@ -181,6 +195,7 @@ struct X { int y ; }; typedef int named; +struct incomplete; /*@ requires in_bounds_value: -128 ≤ value < 128; requires valid_dest: \valid(ptr + (0 .. len - 1)); ensures @@ -305,4 +320,11 @@ void with_void(void *dest, int value) return; } +void with_incomplete(struct incomplete *dest, int value) +{ + struct incomplete *res = memset((void *)dest,value,(unsigned int)10); + memset((void *)res,value,(unsigned int)10); + return; +} + -- GitLab From 5ed93d579371ebc07eec3c4543a1b8d7b3620018 Mon Sep 17 00:00:00 2001 From: Allan Blanchard <allan.blanchard@cea.fr> Date: Wed, 25 Mar 2020 18:30:44 +0100 Subject: [PATCH 014/218] [Instantiate] m/c alloc: refuse incomplete types --- src/plugins/instantiate/stdlib/calloc.ml | 3 +- src/plugins/instantiate/stdlib/malloc.ml | 3 +- src/plugins/instantiate/tests/stdlib/calloc.c | 1 + src/plugins/instantiate/tests/stdlib/free.c | 3 + src/plugins/instantiate/tests/stdlib/malloc.c | 3 + .../tests/stdlib/oracle/calloc.res.oracle | 7 +- .../tests/stdlib/oracle/free.res.oracle | 76 ++++++++++++++++++- .../tests/stdlib/oracle/malloc.res.oracle | 11 ++- 8 files changed, 97 insertions(+), 10 deletions(-) diff --git a/src/plugins/instantiate/stdlib/calloc.ml b/src/plugins/instantiate/stdlib/calloc.ml index 1ea994392c6..e1cc1460c39 100644 --- a/src/plugins/instantiate/stdlib/calloc.ml +++ b/src/plugins/instantiate/stdlib/calloc.ml @@ -133,7 +133,8 @@ let well_typed_call ret args = match ret, args with | Some ret, [ _ ; _ ] -> let t = Cil.typeOfLval ret in - Cil.isPointerType t && not (Cil.isVoidPtrType t) + Cil.isPointerType t && not (Cil.isVoidPtrType t) && + Cil.isCompleteType (Cil.typeOf_pointed t) | _ -> false let key_from_call ret _ = diff --git a/src/plugins/instantiate/stdlib/malloc.ml b/src/plugins/instantiate/stdlib/malloc.ml index a6debf251e1..9cc215a7711 100644 --- a/src/plugins/instantiate/stdlib/malloc.ml +++ b/src/plugins/instantiate/stdlib/malloc.ml @@ -72,7 +72,8 @@ let well_typed_call ret args = match ret, args with | Some ret, [ _ ] -> let t = Cil.typeOfLval ret in - Cil.isPointerType t && not (Cil.isVoidPtrType t) + Cil.isPointerType t && not (Cil.isVoidPtrType t) && + Cil.isCompleteType (Cil.typeOf_pointed t) | _ -> false let key_from_call ret _ = diff --git a/src/plugins/instantiate/tests/stdlib/calloc.c b/src/plugins/instantiate/tests/stdlib/calloc.c index 77be4d292f1..87b1f9338cc 100644 --- a/src/plugins/instantiate/tests/stdlib/calloc.c +++ b/src/plugins/instantiate/tests/stdlib/calloc.c @@ -19,4 +19,5 @@ int main(void){ int (*pa) [10] = calloc(10, sizeof(int[10])) ; struct Flex* f = calloc(1, sizeof(struct Flex) + 3 * sizeof(int)) ; void *v = calloc(10, sizeof(char)); + struct incomplete* inc = calloc(10, 10); } \ No newline at end of file diff --git a/src/plugins/instantiate/tests/stdlib/free.c b/src/plugins/instantiate/tests/stdlib/free.c index 40cab4f547c..e61ed8864c1 100644 --- a/src/plugins/instantiate/tests/stdlib/free.c +++ b/src/plugins/instantiate/tests/stdlib/free.c @@ -11,4 +11,7 @@ void baz(int (*x) [10]){ } void with_void(void * x){ free(x); +} +void with_incomplete(struct incomplete* t){ + free(t); } \ No newline at end of file diff --git a/src/plugins/instantiate/tests/stdlib/malloc.c b/src/plugins/instantiate/tests/stdlib/malloc.c index 0d5aa4ea04a..00a07820a9a 100644 --- a/src/plugins/instantiate/tests/stdlib/malloc.c +++ b/src/plugins/instantiate/tests/stdlib/malloc.c @@ -11,6 +11,8 @@ struct Flex { int f[] ; } ; +struct incomplete ; + int main(void){ int* pi = malloc(sizeof(int) * 10) ; float* pf = malloc(sizeof(float) * 10) ; @@ -19,4 +21,5 @@ int main(void){ int (*pa) [10] = malloc(sizeof(int[10]) * 10) ; struct Flex* f = malloc(sizeof(struct Flex) + 3 * sizeof(int)) ; void *v = malloc(sizeof(char) * 10); + struct incomplete* inc = malloc(10); } \ No newline at end of file diff --git a/src/plugins/instantiate/tests/stdlib/oracle/calloc.res.oracle b/src/plugins/instantiate/tests/stdlib/oracle/calloc.res.oracle index 5fb370ab29a..81cf9b246df 100644 --- a/src/plugins/instantiate/tests/stdlib/oracle/calloc.res.oracle +++ b/src/plugins/instantiate/tests/stdlib/oracle/calloc.res.oracle @@ -1,5 +1,6 @@ [kernel] Parsing tests/stdlib/calloc.c (with preprocessing) [instantiate] tests/stdlib/calloc.c:21: Warning: Ignore call: not well typed +[instantiate] tests/stdlib/calloc.c:22: Warning: Ignore call: not well typed /* Generated by Frama-C */ #include "stdlib.h" struct X { @@ -11,6 +12,7 @@ struct Flex { char c ; int f[] ; }; +struct incomplete; /*@ requires correct_size: 0 ≤ size - 8 ∧ 0 ≡ (size - 8) % 4; requires only_one: num ≡ 1; assigns \result, __fc_heap_status; @@ -263,6 +265,7 @@ int main(void) calloc_st_Flex((unsigned int)1, sizeof(struct Flex) + (unsigned int)3 * sizeof(int)); void *v = calloc((unsigned int)10,sizeof(char)); + struct incomplete *inc = calloc((unsigned int)10,(unsigned int)10); __retres = 0; return __retres; } @@ -271,7 +274,7 @@ int main(void) [kernel] Parsing tests/stdlib/result/calloc.c (with preprocessing) [kernel] Parsing tests/stdlib/calloc.c (with preprocessing) [kernel] tests/stdlib/calloc.c:14: Warning: - def'n of func main at tests/stdlib/calloc.c:14 (sum 6403) conflicts with the one at tests/stdlib/result/calloc.c:252 (sum 8177); keeping the one at tests/stdlib/result/calloc.c:252. + def'n of func main at tests/stdlib/calloc.c:14 (sum 7290) conflicts with the one at tests/stdlib/result/calloc.c:253 (sum 9064); keeping the one at tests/stdlib/result/calloc.c:253. /* Generated by Frama-C */ #include "stdlib.h" struct X { @@ -283,6 +286,7 @@ struct Flex { char c ; int f[] ; }; +struct incomplete; /*@ requires correct_size: 0 ≤ size - 8 ∧ 0 ≡ (size - 8) % 4; requires only_one: num ≡ 1; assigns \result, __fc_heap_status; @@ -539,6 +543,7 @@ int main(void) calloc_st_Flex((unsigned int)1, sizeof(struct Flex) + (unsigned int)3 * sizeof(int)); void *v = calloc((unsigned int)10,sizeof(char)); + struct incomplete *inc = calloc((unsigned int)10,(unsigned int)10); __retres = 0; return __retres; } diff --git a/src/plugins/instantiate/tests/stdlib/oracle/free.res.oracle b/src/plugins/instantiate/tests/stdlib/oracle/free.res.oracle index 1e764fcd7c6..11f5ef65b0e 100644 --- a/src/plugins/instantiate/tests/stdlib/oracle/free.res.oracle +++ b/src/plugins/instantiate/tests/stdlib/oracle/free.res.oracle @@ -2,6 +2,7 @@ [instantiate] tests/stdlib/free.c:13: Warning: Ignore call: not well typed /* Generated by Frama-C */ #include "stdlib.h" +struct incomplete; /*@ requires freeable: ptr ≡ \null ∨ \freeable(ptr); assigns __fc_heap_status; assigns __fc_heap_status \from __fc_heap_status, ptr; @@ -104,19 +105,54 @@ void with_void(void *x) return; } +/*@ requires freeable: ptr ≡ \null ∨ \freeable(ptr); + assigns __fc_heap_status; + assigns __fc_heap_status \from __fc_heap_status, ptr; + frees ptr; + + behavior allocation: + assumes ptr ≢ \null; + ensures freed: \allocable(ptr); + assigns __fc_heap_status; + assigns __fc_heap_status \from __fc_heap_status, ptr; + frees ptr; + + behavior no_allocation: + assumes ptr ≡ \null; + assigns \nothing; + allocates \nothing; + + complete behaviors no_allocation, allocation; + disjoint behaviors no_allocation, allocation; + */ +void free_st_incomplete(struct incomplete *ptr) +{ + free((void *)ptr); + return; +} + +void with_incomplete(struct incomplete *t) +{ + free_st_incomplete(t); + return; +} + [kernel] Parsing tests/stdlib/result/free.c (with preprocessing) [kernel] Parsing tests/stdlib/free.c (with preprocessing) [kernel] tests/stdlib/free.c:3: Warning: - dropping duplicate def'n of func foo at tests/stdlib/free.c:3 in favor of that at tests/stdlib/result/free.c:29 + dropping duplicate def'n of func foo at tests/stdlib/free.c:3 in favor of that at tests/stdlib/result/free.c:30 [kernel] tests/stdlib/free.c:6: Warning: - dropping duplicate def'n of func bar at tests/stdlib/free.c:6 in favor of that at tests/stdlib/result/free.c:61 + dropping duplicate def'n of func bar at tests/stdlib/free.c:6 in favor of that at tests/stdlib/result/free.c:62 [kernel] tests/stdlib/free.c:9: Warning: - dropping duplicate def'n of func baz at tests/stdlib/free.c:9 in favor of that at tests/stdlib/result/free.c:93 + dropping duplicate def'n of func baz at tests/stdlib/free.c:9 in favor of that at tests/stdlib/result/free.c:94 [kernel] tests/stdlib/free.c:12: Warning: - dropping duplicate def'n of func with_void at tests/stdlib/free.c:12 in favor of that at tests/stdlib/result/free.c:99 + dropping duplicate def'n of func with_void at tests/stdlib/free.c:12 in favor of that at tests/stdlib/result/free.c:100 +[kernel] tests/stdlib/free.c:15: Warning: + dropping duplicate def'n of func with_incomplete at tests/stdlib/free.c:15 in favor of that at tests/stdlib/result/free.c:132 /* Generated by Frama-C */ #include "stdlib.h" +struct incomplete; /*@ requires freeable: ptr ≡ \null ∨ \freeable(ptr); assigns __fc_heap_status; assigns __fc_heap_status \from __fc_heap_status, ptr; @@ -219,4 +255,36 @@ void with_void(void *x) return; } +/*@ requires freeable: ptr ≡ \null ∨ \freeable(ptr); + assigns __fc_heap_status; + assigns __fc_heap_status \from __fc_heap_status, ptr; + frees ptr; + + behavior allocation: + assumes ptr ≢ \null; + ensures freed: \allocable(\old(ptr)); + assigns __fc_heap_status; + assigns __fc_heap_status \from __fc_heap_status, ptr; + frees ptr; + + behavior no_allocation: + assumes ptr ≡ \null; + assigns \nothing; + allocates \nothing; + + complete behaviors no_allocation, allocation; + disjoint behaviors no_allocation, allocation; + */ +void free_st_incomplete(struct incomplete *ptr) +{ + free((void *)ptr); + return; +} + +void with_incomplete(struct incomplete *t) +{ + free_st_incomplete(t); + return; +} + diff --git a/src/plugins/instantiate/tests/stdlib/oracle/malloc.res.oracle b/src/plugins/instantiate/tests/stdlib/oracle/malloc.res.oracle index feb0c41909d..485abcec7f4 100644 --- a/src/plugins/instantiate/tests/stdlib/oracle/malloc.res.oracle +++ b/src/plugins/instantiate/tests/stdlib/oracle/malloc.res.oracle @@ -1,5 +1,6 @@ [kernel] Parsing tests/stdlib/malloc.c (with preprocessing) -[instantiate] tests/stdlib/malloc.c:21: Warning: Ignore call: not well typed +[instantiate] tests/stdlib/malloc.c:23: Warning: Ignore call: not well typed +[instantiate] tests/stdlib/malloc.c:24: Warning: Ignore call: not well typed /* Generated by Frama-C */ #include "stdlib.h" struct X { @@ -11,6 +12,7 @@ struct Flex { char c ; int f[] ; }; +struct incomplete; /*@ requires correct_size: 0 ≤ size - 8 ∧ 0 ≡ (size - 8) % 4; assigns \result, __fc_heap_status; assigns \result \from __fc_heap_status, size; @@ -208,6 +210,7 @@ int main(void) struct Flex *f = malloc_st_Flex(sizeof(struct Flex) + (unsigned int)3 * sizeof(int)); void *v = malloc(sizeof(char) * (unsigned int)10); + struct incomplete *inc = malloc((unsigned int)10); __retres = 0; return __retres; } @@ -215,8 +218,8 @@ int main(void) [kernel] Parsing tests/stdlib/result/malloc.c (with preprocessing) [kernel] Parsing tests/stdlib/malloc.c (with preprocessing) -[kernel] tests/stdlib/malloc.c:14: Warning: - def'n of func main at tests/stdlib/malloc.c:14 (sum 6403) conflicts with the one at tests/stdlib/result/malloc.c:198 (sum 8177); keeping the one at tests/stdlib/result/malloc.c:198. +[kernel] tests/stdlib/malloc.c:16: Warning: + def'n of func main at tests/stdlib/malloc.c:16 (sum 7290) conflicts with the one at tests/stdlib/result/malloc.c:199 (sum 9064); keeping the one at tests/stdlib/result/malloc.c:199. /* Generated by Frama-C */ #include "stdlib.h" struct X { @@ -228,6 +231,7 @@ struct Flex { char c ; int f[] ; }; +struct incomplete; /*@ requires correct_size: 0 ≤ size - 8 ∧ 0 ≡ (size - 8) % 4; assigns \result, __fc_heap_status; assigns \result \from __fc_heap_status, size; @@ -425,6 +429,7 @@ int main(void) struct Flex *f = malloc_st_Flex(sizeof(struct Flex) + (unsigned int)3 * sizeof(int)); void *v = malloc(sizeof(char) * (unsigned int)10); + struct incomplete *inc = malloc((unsigned int)10); __retres = 0; return __retres; } -- GitLab From a5ed19d03f7dd29c2e67910254afd2afc8cfc429 Mon Sep 17 00:00:00 2001 From: Allan Blanchard <allan.blanchard@cea.fr> Date: Thu, 26 Mar 2020 10:53:55 +0100 Subject: [PATCH 015/218] [wp] Adds missing 'round' functions to Cfloat MLW --- src/plugins/wp/share/why3/frama_c_wp/cfloat.mlw | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/plugins/wp/share/why3/frama_c_wp/cfloat.mlw b/src/plugins/wp/share/why3/frama_c_wp/cfloat.mlw index aaedd4489ef..3cfc3d7f07f 100644 --- a/src/plugins/wp/share/why3/frama_c_wp/cfloat.mlw +++ b/src/plugins/wp/share/why3/frama_c_wp/cfloat.mlw @@ -76,6 +76,19 @@ theory Cfloat axiom to_f64_minus_infinity: forall x. x <. -. F64.max_real -> is_negative_infinite_f64 (to_f64 x) axiom to_f64_plus_infinity: forall x. x >. F64.max_real -> is_positive_infinite_f64 (to_f64 x) + (* Note: This is OK as we have in Why3 ieee_float: + + axiom Round_idempotent : + forall m1 m2:mode, x:real. round m1 (round m2 x) = round m2 x + + So we can round RNE (to_f32/64 behavior) after any rounding. + *) + function round_float (m: Rounding.mode) (r: real) : f32 = + to_f32 (F32.round m r) + + function round_double (m: Rounding.mode) (r: real) : f64 = + to_f64 (F64.round m r) + (* Take care of +0/-0 *) axiom is_zero_to_f32_zero: F32.is_zero (to_f32 0.0) axiom is_zero_to_f64_zero: F64.is_zero (to_f64 0.0) -- GitLab From 5f00774bc1b1d226a426cfb2a8f6358018dd407c Mon Sep 17 00:00:00 2001 From: Allan Blanchard <allan.blanchard@cea.fr> Date: Thu, 26 Mar 2020 10:54:27 +0100 Subject: [PATCH 016/218] [wp] Updates float drivers to match Cfloat MLW --- src/plugins/wp/share/wp.driver | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/plugins/wp/share/wp.driver b/src/plugins/wp/share/wp.driver index a45458db4a8..2fb2f16fed1 100644 --- a/src/plugins/wp/share/wp.driver +++ b/src/plugins/wp/share/wp.driver @@ -96,12 +96,12 @@ coq.file += "coqwp:real/Abs.v"; coq.file += "coqwp/Cfloat.v"; why3.import += "frama_c_wp.cfloat.Cfloat"; altergo.file += "ergo/Cfloat.mlw"; -type "rounding_mode" = "rounding_mode"; -ctor "\\Up"() = "Up"; -ctor "\\Down"() = "Down"; -ctor "\\ToZero"() = "ToZero"; -ctor "\\NearestAway"() = "NearestTiesToAway"; -ctor "\\NearestEven"() = "NearestTiesToEven"; +type "rounding_mode" = "Rounding.mode"; +ctor "\\Up"() = "Rounding.RTP"; +ctor "\\Down"() = "Rounding.RTN"; +ctor "\\ToZero"() = "Rounding.RTZ"; +ctor "\\NearestAway"() = "Rounding.RNA"; +ctor "\\NearestEven"() = "Rounding.RNE"; predicate "\\is_finite"(float32) = "is_finite_f32"; predicate "\\is_finite"(float64) = "is_finite_f64"; predicate "\\is_NaN"(float32) = "is_NaN_f32"; @@ -112,8 +112,8 @@ predicate "\\is_plus_infinity"(float32) = "is_positive_infinite_f32"; predicate "\\is_plus_infinity"(float64) = "is_positive_infinite_f64"; predicate "\\is_minus_infinity"(float32) = "is_negative_infinite_f32"; predicate "\\is_minus_infinity"(float64) = "is_negative_infinite_f64"; -logic bool "\\round_float"(rounding_mode,real) = "round_float"; -logic bool "\\round_double"(rounding_mode,real) = "round_double"; +logic float32 "\\round_float"(rounding_mode,real) = "round_float"; +logic float64 "\\round_double"(rounding_mode,real) = "round_double"; library vset: type set = "set"; -- GitLab From b24dc837727215cfe146bec7581d1e55212ea6bc Mon Sep 17 00:00:00 2001 From: Allan Blanchard <allan.blanchard@cea.fr> Date: Thu, 26 Mar 2020 10:55:31 +0100 Subject: [PATCH 017/218] [wp] New test to check float drivers bindings --- src/plugins/wp/tests/wp_plugin/float_driver.i | 39 + .../wp_plugin/oracle/float_driver.res.oracle | 708 ++++++++++++++++++ 2 files changed, 747 insertions(+) create mode 100644 src/plugins/wp/tests/wp_plugin/float_driver.i create mode 100644 src/plugins/wp/tests/wp_plugin/oracle/float_driver.res.oracle diff --git a/src/plugins/wp/tests/wp_plugin/float_driver.i b/src/plugins/wp/tests/wp_plugin/float_driver.i new file mode 100644 index 00000000000..da87cc93b36 --- /dev/null +++ b/src/plugins/wp/tests/wp_plugin/float_driver.i @@ -0,0 +1,39 @@ +/* run.config + OPT:-wp -wp-gen -wp-prover why3 -wp-msg-key="print-generated" +*/ +/* run.config_qualif + DONTRUN: +*/ + +/*@ + ensures DBL_RNE: \eq_double(\result,\round_double(\NearestEven, x)); + ensures DBL_RNA: \eq_double(\result,\round_double(\NearestAway, x)); + ensures DBL_RTZ: \eq_double(\result,\round_double(\ToZero, x)); + ensures DBL_RTP: \eq_double(\result,\round_double(\Up, x)); + ensures DBL_RTN: \eq_double(\result,\round_double(\Down, x)); + ensures DBL_FIN: \is_finite(\result); + ensures DBL_INF: \is_infinite(\result); + ensures DBL_NAN: \is_NaN(\result); + ensures DBL_PINF: \is_plus_infinity(\result); + ensures DBL_MINF: \is_minus_infinity(\result); +*/ +double for_double(double x) { + return x+1.0; +} + +/*@ + ensures FLT_RNE: \eq_float(\result,\round_float(\NearestEven, x)); + ensures FLT_RNA: \eq_float(\result,\round_float(\NearestAway, x)); + ensures FLT_RTZ: \eq_float(\result,\round_float(\ToZero, x)); + ensures FLT_RTP: \eq_float(\result,\round_float(\Up, x)); + ensures FLT_RTN: \eq_float(\result,\round_float(\Down, x)); + ensures FLT_FIN: \is_finite(\result); + ensures FLT_INF: \is_infinite(\result); + ensures FLT_NAN: \is_NaN(\result); + ensures FLT_PINF: \is_plus_infinity(\result); + ensures FLT_MINF: \is_minus_infinity(\result); +*/ +float for_float(float x) { + return x+1.0f; +} + diff --git a/src/plugins/wp/tests/wp_plugin/oracle/float_driver.res.oracle b/src/plugins/wp/tests/wp_plugin/oracle/float_driver.res.oracle new file mode 100644 index 00000000000..a0099411079 --- /dev/null +++ b/src/plugins/wp/tests/wp_plugin/oracle/float_driver.res.oracle @@ -0,0 +1,708 @@ +# frama-c -wp [...] +[kernel] Parsing tests/wp_plugin/float_driver.i (no preprocessing) +[wp] Running WP plugin... +[wp] Loading driver 'share/wp.driver' +[wp] Warning: Missing RTE guards +[wp] 20 goals scheduled +[wp:print-generated] + theory WP + (* use why3.BuiltIn.BuiltIn *) + + (* use bool.Bool *) + + (* use int.Int *) + + (* use int.ComputerDivision *) + + (* use real.RealInfix *) + + (* use frama_c_wp.qed.Qed *) + + (* use map.Map *) + + (* use real.Abs *) + + (* use frama_c_wp.cmath.Cmath *) + + (* use real.Square *) + + (* use frama_c_wp.cmath.Square1 *) + + (* use frama_c_wp.cfloat.Cfloat *) + + goal wp_goal : + forall f:t. + eq_f64 (add_f64 f (0x1.0000000000000p0:t)) (round_double RTP (of_f64 f)) + end +[wp:print-generated] + theory WP1 + (* use why3.BuiltIn.BuiltIn *) + + (* use bool.Bool *) + + (* use int.Int *) + + (* use int.ComputerDivision *) + + (* use real.RealInfix *) + + (* use frama_c_wp.qed.Qed *) + + (* use map.Map *) + + (* use real.Abs *) + + (* use frama_c_wp.cmath.Cmath *) + + (* use real.Square *) + + (* use frama_c_wp.cmath.Square1 *) + + (* use frama_c_wp.cfloat.Cfloat *) + + goal wp_goal : + forall f:t. + eq_f64 (add_f64 f (0x1.0000000000000p0:t)) (round_double RTZ (of_f64 f)) + end +[wp:print-generated] + theory WP2 + (* use why3.BuiltIn.BuiltIn *) + + (* use bool.Bool *) + + (* use int.Int *) + + (* use int.ComputerDivision *) + + (* use real.RealInfix *) + + (* use frama_c_wp.qed.Qed *) + + (* use map.Map *) + + (* use real.Abs *) + + (* use frama_c_wp.cmath.Cmath *) + + (* use real.Square *) + + (* use frama_c_wp.cmath.Square1 *) + + (* use frama_c_wp.cfloat.Cfloat *) + + goal wp_goal : + forall f:t. + eq_f64 (add_f64 f (0x1.0000000000000p0:t)) (round_double RNA (of_f64 f)) + end +[wp:print-generated] + theory WP3 + (* use why3.BuiltIn.BuiltIn *) + + (* use bool.Bool *) + + (* use int.Int *) + + (* use int.ComputerDivision *) + + (* use real.RealInfix *) + + (* use frama_c_wp.qed.Qed *) + + (* use map.Map *) + + (* use real.Abs *) + + (* use frama_c_wp.cmath.Cmath *) + + (* use real.Square *) + + (* use frama_c_wp.cmath.Square1 *) + + (* use frama_c_wp.cfloat.Cfloat *) + + goal wp_goal : + forall f:t. + eq_f64 (add_f64 f (0x1.0000000000000p0:t)) (round_double RNE (of_f64 f)) + end +[wp:print-generated] + theory WP4 + (* use why3.BuiltIn.BuiltIn *) + + (* use bool.Bool *) + + (* use int.Int *) + + (* use int.ComputerDivision *) + + (* use real.RealInfix *) + + (* use frama_c_wp.qed.Qed *) + + (* use map.Map *) + + (* use real.Abs *) + + (* use frama_c_wp.cmath.Cmath *) + + (* use real.Square *) + + (* use frama_c_wp.cmath.Square1 *) + + (* use frama_c_wp.cfloat.Cfloat *) + + goal wp_goal : forall f:t. is_NaN_f64 (add_f64 f (0x1.0000000000000p0:t)) + end +[wp:print-generated] + theory WP5 + (* use why3.BuiltIn.BuiltIn *) + + (* use bool.Bool *) + + (* use int.Int *) + + (* use int.ComputerDivision *) + + (* use real.RealInfix *) + + (* use frama_c_wp.qed.Qed *) + + (* use map.Map *) + + (* use real.Abs *) + + (* use frama_c_wp.cmath.Cmath *) + + (* use real.Square *) + + (* use frama_c_wp.cmath.Square1 *) + + (* use frama_c_wp.cfloat.Cfloat *) + + goal wp_goal : + forall f:t. is_infinite_f64 (add_f64 f (0x1.0000000000000p0:t)) + end +[wp:print-generated] + theory WP6 + (* use why3.BuiltIn.BuiltIn *) + + (* use bool.Bool *) + + (* use int.Int *) + + (* use int.ComputerDivision *) + + (* use real.RealInfix *) + + (* use frama_c_wp.qed.Qed *) + + (* use map.Map *) + + (* use real.Abs *) + + (* use frama_c_wp.cmath.Cmath *) + + (* use real.Square *) + + (* use frama_c_wp.cmath.Square1 *) + + (* use frama_c_wp.cfloat.Cfloat *) + + goal wp_goal : + forall f:t. is_finite_f64 (add_f64 f (0x1.0000000000000p0:t)) + end +[wp:print-generated] + theory WP7 + (* use why3.BuiltIn.BuiltIn *) + + (* use bool.Bool *) + + (* use int.Int *) + + (* use int.ComputerDivision *) + + (* use real.RealInfix *) + + (* use frama_c_wp.qed.Qed *) + + (* use map.Map *) + + (* use real.Abs *) + + (* use frama_c_wp.cmath.Cmath *) + + (* use real.Square *) + + (* use frama_c_wp.cmath.Square1 *) + + (* use frama_c_wp.cfloat.Cfloat *) + + goal wp_goal : + forall f:t. + eq_f64 (add_f64 f (0x1.0000000000000p0:t)) (round_double RTN (of_f64 f)) + end +[wp:print-generated] + theory WP8 + (* use why3.BuiltIn.BuiltIn *) + + (* use bool.Bool1 *) + + (* use int.Int1 *) + + (* use int.ComputerDivision1 *) + + (* use real.RealInfix1 *) + + (* use frama_c_wp.qed.Qed1 *) + + (* use map.Map1 *) + + (* use real.Abs1 *) + + (* use frama_c_wp.cmath.Cmath1 *) + + (* use real.Square2 *) + + (* use frama_c_wp.cmath.Square3 *) + + (* use frama_c_wp.cfloat.Cfloat1 *) + + goal wp_goal : + forall f:t1. + eq_f32 (add_f32 f (0x1.0000000000000p0:t1)) + (round_float RNA1 (of_f32 f)) + end +[wp:print-generated] + theory WP9 + (* use why3.BuiltIn.BuiltIn *) + + (* use bool.Bool1 *) + + (* use int.Int1 *) + + (* use int.ComputerDivision1 *) + + (* use real.RealInfix1 *) + + (* use frama_c_wp.qed.Qed1 *) + + (* use map.Map1 *) + + (* use real.Abs1 *) + + (* use frama_c_wp.cmath.Cmath1 *) + + (* use real.Square2 *) + + (* use frama_c_wp.cmath.Square3 *) + + (* use frama_c_wp.cfloat.Cfloat1 *) + + goal wp_goal : + forall f:t1. + eq_f32 (add_f32 f (0x1.0000000000000p0:t1)) + (round_float RNE1 (of_f32 f)) + end +[wp:print-generated] + theory WP10 + (* use why3.BuiltIn.BuiltIn *) + + (* use bool.Bool *) + + (* use int.Int *) + + (* use int.ComputerDivision *) + + (* use real.RealInfix *) + + (* use frama_c_wp.qed.Qed *) + + (* use map.Map *) + + (* use real.Abs *) + + (* use frama_c_wp.cmath.Cmath *) + + (* use real.Square *) + + (* use frama_c_wp.cmath.Square1 *) + + (* use frama_c_wp.cfloat.Cfloat *) + + goal wp_goal : + forall f:t. is_negative_infinite_f64 (add_f64 f (0x1.0000000000000p0:t)) + end +[wp:print-generated] + theory WP11 + (* use why3.BuiltIn.BuiltIn *) + + (* use bool.Bool *) + + (* use int.Int *) + + (* use int.ComputerDivision *) + + (* use real.RealInfix *) + + (* use frama_c_wp.qed.Qed *) + + (* use map.Map *) + + (* use real.Abs *) + + (* use frama_c_wp.cmath.Cmath *) + + (* use real.Square *) + + (* use frama_c_wp.cmath.Square1 *) + + (* use frama_c_wp.cfloat.Cfloat *) + + goal wp_goal : + forall f:t. is_positive_infinite_f64 (add_f64 f (0x1.0000000000000p0:t)) + end +[wp:print-generated] + theory WP12 + (* use why3.BuiltIn.BuiltIn *) + + (* use bool.Bool1 *) + + (* use int.Int1 *) + + (* use int.ComputerDivision1 *) + + (* use real.RealInfix1 *) + + (* use frama_c_wp.qed.Qed1 *) + + (* use map.Map1 *) + + (* use real.Abs1 *) + + (* use frama_c_wp.cmath.Cmath1 *) + + (* use real.Square2 *) + + (* use frama_c_wp.cmath.Square3 *) + + (* use frama_c_wp.cfloat.Cfloat1 *) + + goal wp_goal : + forall f:t1. is_finite_f32 (add_f32 f (0x1.0000000000000p0:t1)) + end +[wp:print-generated] + theory WP13 + (* use why3.BuiltIn.BuiltIn *) + + (* use bool.Bool1 *) + + (* use int.Int1 *) + + (* use int.ComputerDivision1 *) + + (* use real.RealInfix1 *) + + (* use frama_c_wp.qed.Qed1 *) + + (* use map.Map1 *) + + (* use real.Abs1 *) + + (* use frama_c_wp.cmath.Cmath1 *) + + (* use real.Square2 *) + + (* use frama_c_wp.cmath.Square3 *) + + (* use frama_c_wp.cfloat.Cfloat1 *) + + goal wp_goal : + forall f:t1. + eq_f32 (add_f32 f (0x1.0000000000000p0:t1)) + (round_float RTN1 (of_f32 f)) + end +[wp:print-generated] + theory WP14 + (* use why3.BuiltIn.BuiltIn *) + + (* use bool.Bool1 *) + + (* use int.Int1 *) + + (* use int.ComputerDivision1 *) + + (* use real.RealInfix1 *) + + (* use frama_c_wp.qed.Qed1 *) + + (* use map.Map1 *) + + (* use real.Abs1 *) + + (* use frama_c_wp.cmath.Cmath1 *) + + (* use real.Square2 *) + + (* use frama_c_wp.cmath.Square3 *) + + (* use frama_c_wp.cfloat.Cfloat1 *) + + goal wp_goal : + forall f:t1. + eq_f32 (add_f32 f (0x1.0000000000000p0:t1)) + (round_float RTP1 (of_f32 f)) + end +[wp:print-generated] + theory WP15 + (* use why3.BuiltIn.BuiltIn *) + + (* use bool.Bool1 *) + + (* use int.Int1 *) + + (* use int.ComputerDivision1 *) + + (* use real.RealInfix1 *) + + (* use frama_c_wp.qed.Qed1 *) + + (* use map.Map1 *) + + (* use real.Abs1 *) + + (* use frama_c_wp.cmath.Cmath1 *) + + (* use real.Square2 *) + + (* use frama_c_wp.cmath.Square3 *) + + (* use frama_c_wp.cfloat.Cfloat1 *) + + goal wp_goal : + forall f:t1. + eq_f32 (add_f32 f (0x1.0000000000000p0:t1)) + (round_float RTZ1 (of_f32 f)) + end +[wp:print-generated] + theory WP16 + (* use why3.BuiltIn.BuiltIn *) + + (* use bool.Bool1 *) + + (* use int.Int1 *) + + (* use int.ComputerDivision1 *) + + (* use real.RealInfix1 *) + + (* use frama_c_wp.qed.Qed1 *) + + (* use map.Map1 *) + + (* use real.Abs1 *) + + (* use frama_c_wp.cmath.Cmath1 *) + + (* use real.Square2 *) + + (* use frama_c_wp.cmath.Square3 *) + + (* use frama_c_wp.cfloat.Cfloat1 *) + + goal wp_goal : + forall f:t1. + is_negative_infinite_f32 (add_f32 f (0x1.0000000000000p0:t1)) + end +[wp:print-generated] + theory WP17 + (* use why3.BuiltIn.BuiltIn *) + + (* use bool.Bool1 *) + + (* use int.Int1 *) + + (* use int.ComputerDivision1 *) + + (* use real.RealInfix1 *) + + (* use frama_c_wp.qed.Qed1 *) + + (* use map.Map1 *) + + (* use real.Abs1 *) + + (* use frama_c_wp.cmath.Cmath1 *) + + (* use real.Square2 *) + + (* use frama_c_wp.cmath.Square3 *) + + (* use frama_c_wp.cfloat.Cfloat1 *) + + goal wp_goal : + forall f:t1. + is_positive_infinite_f32 (add_f32 f (0x1.0000000000000p0:t1)) + end +[wp:print-generated] + theory WP18 + (* use why3.BuiltIn.BuiltIn *) + + (* use bool.Bool1 *) + + (* use int.Int1 *) + + (* use int.ComputerDivision1 *) + + (* use real.RealInfix1 *) + + (* use frama_c_wp.qed.Qed1 *) + + (* use map.Map1 *) + + (* use real.Abs1 *) + + (* use frama_c_wp.cmath.Cmath1 *) + + (* use real.Square2 *) + + (* use frama_c_wp.cmath.Square3 *) + + (* use frama_c_wp.cfloat.Cfloat1 *) + + goal wp_goal : forall f:t1. is_NaN_f32 (add_f32 f (0x1.0000000000000p0:t1)) + end +[wp:print-generated] + theory WP19 + (* use why3.BuiltIn.BuiltIn *) + + (* use bool.Bool1 *) + + (* use int.Int1 *) + + (* use int.ComputerDivision1 *) + + (* use real.RealInfix1 *) + + (* use frama_c_wp.qed.Qed1 *) + + (* use map.Map1 *) + + (* use real.Abs1 *) + + (* use frama_c_wp.cmath.Cmath1 *) + + (* use real.Square2 *) + + (* use frama_c_wp.cmath.Square3 *) + + (* use frama_c_wp.cfloat.Cfloat1 *) + + goal wp_goal : + forall f:t1. is_infinite_f32 (add_f32 f (0x1.0000000000000p0:t1)) + end +[wp] 20 goals generated +------------------------------------------------------------ + Function for_double +------------------------------------------------------------ + +Goal Post-condition 'DBL_RNE' in 'for_double': +Prove: eq_f64(add_f64(x, to_f64(1.0)), round_double(Rounding.RNE, of_f64(x))). + +------------------------------------------------------------ + +Goal Post-condition 'DBL_RNA' in 'for_double': +Prove: eq_f64(add_f64(x, to_f64(1.0)), round_double(Rounding.RNA, of_f64(x))). + +------------------------------------------------------------ + +Goal Post-condition 'DBL_RTZ' in 'for_double': +Prove: eq_f64(add_f64(x, to_f64(1.0)), round_double(Rounding.RTZ, of_f64(x))). + +------------------------------------------------------------ + +Goal Post-condition 'DBL_RTP' in 'for_double': +Prove: eq_f64(add_f64(x, to_f64(1.0)), round_double(Rounding.RTP, of_f64(x))). + +------------------------------------------------------------ + +Goal Post-condition 'DBL_RTN' in 'for_double': +Prove: eq_f64(add_f64(x, to_f64(1.0)), round_double(Rounding.RTN, of_f64(x))). + +------------------------------------------------------------ + +Goal Post-condition 'DBL_FIN' in 'for_double': +Prove: is_finite_f64(add_f64(x, to_f64(1.0))). + +------------------------------------------------------------ + +Goal Post-condition 'DBL_INF' in 'for_double': +Prove: is_infinite_f64(add_f64(x, to_f64(1.0))). + +------------------------------------------------------------ + +Goal Post-condition 'DBL_NAN' in 'for_double': +Prove: is_NaN_f64(add_f64(x, to_f64(1.0))). + +------------------------------------------------------------ + +Goal Post-condition 'DBL_PINF' in 'for_double': +Prove: is_positive_infinite_f64(add_f64(x, to_f64(1.0))). + +------------------------------------------------------------ + +Goal Post-condition 'DBL_MINF' in 'for_double': +Prove: is_negative_infinite_f64(add_f64(x, to_f64(1.0))). + +------------------------------------------------------------ +------------------------------------------------------------ + Function for_float +------------------------------------------------------------ + +Goal Post-condition 'FLT_RNE' in 'for_float': +Prove: eq_f32(add_f32(x, to_f32(1.0)), round_float(Rounding.RNE, of_f32(x))). + +------------------------------------------------------------ + +Goal Post-condition 'FLT_RNA' in 'for_float': +Prove: eq_f32(add_f32(x, to_f32(1.0)), round_float(Rounding.RNA, of_f32(x))). + +------------------------------------------------------------ + +Goal Post-condition 'FLT_RTZ' in 'for_float': +Prove: eq_f32(add_f32(x, to_f32(1.0)), round_float(Rounding.RTZ, of_f32(x))). + +------------------------------------------------------------ + +Goal Post-condition 'FLT_RTP' in 'for_float': +Prove: eq_f32(add_f32(x, to_f32(1.0)), round_float(Rounding.RTP, of_f32(x))). + +------------------------------------------------------------ + +Goal Post-condition 'FLT_RTN' in 'for_float': +Prove: eq_f32(add_f32(x, to_f32(1.0)), round_float(Rounding.RTN, of_f32(x))). + +------------------------------------------------------------ + +Goal Post-condition 'FLT_FIN' in 'for_float': +Prove: is_finite_f32(add_f32(x, to_f32(1.0))). + +------------------------------------------------------------ + +Goal Post-condition 'FLT_INF' in 'for_float': +Prove: is_infinite_f32(add_f32(x, to_f32(1.0))). + +------------------------------------------------------------ + +Goal Post-condition 'FLT_NAN' in 'for_float': +Prove: is_NaN_f32(add_f32(x, to_f32(1.0))). + +------------------------------------------------------------ + +Goal Post-condition 'FLT_PINF' in 'for_float': +Prove: is_positive_infinite_f32(add_f32(x, to_f32(1.0))). + +------------------------------------------------------------ + +Goal Post-condition 'FLT_MINF' in 'for_float': +Prove: is_negative_infinite_f32(add_f32(x, to_f32(1.0))). + +------------------------------------------------------------ -- GitLab From 8dda36f2b740176af3aab24dbe5343a512fec728 Mon Sep 17 00:00:00 2001 From: Allan Blanchard <allan.blanchard@cea.fr> Date: Thu, 26 Mar 2020 09:41:28 +0100 Subject: [PATCH 018/218] [Instantiate] Better failure messages --- src/plugins/instantiate/Makefile.in | 2 +- src/plugins/instantiate/basic_blocks.ml | 36 +++++++++---------- src/plugins/instantiate/stdlib/basic_alloc.ml | 4 ++- src/plugins/instantiate/stdlib/calloc.ml | 14 ++++---- src/plugins/instantiate/stdlib/free.ml | 6 ++-- src/plugins/instantiate/stdlib/malloc.ml | 6 ++-- src/plugins/instantiate/string/memcmp.ml | 8 +++-- src/plugins/instantiate/string/memcpy.ml | 8 +++-- src/plugins/instantiate/string/memmove.ml | 8 +++-- src/plugins/instantiate/string/memset.ml | 28 +++++++++------ src/plugins/instantiate/transform.ml | 4 ++- 11 files changed, 73 insertions(+), 51 deletions(-) diff --git a/src/plugins/instantiate/Makefile.in b/src/plugins/instantiate/Makefile.in index 843525c882d..144f5c7128e 100644 --- a/src/plugins/instantiate/Makefile.in +++ b/src/plugins/instantiate/Makefile.in @@ -55,7 +55,7 @@ PLUGIN_EXTRA_DIRS:=\ stdlib PLUGIN_CMI := PLUGIN_CMO := \ - basic_blocks options instantiator_builder transform register \ + options basic_blocks instantiator_builder transform register \ $(SRC_STRING) \ $(SRC_STDLIB) diff --git a/src/plugins/instantiate/basic_blocks.ml b/src/plugins/instantiate/basic_blocks.ml index c525eb2cd2b..660db8c83c0 100644 --- a/src/plugins/instantiate/basic_blocks.ml +++ b/src/plugins/instantiate/basic_blocks.ml @@ -73,7 +73,8 @@ let rec string_of_typ_aux = function | TComp (ci, _, _) -> "un_" ^ ci.cname | TArray (t, Some e, _, _) -> "arr" ^ (string_of_exp e) ^ "_" ^ string_of_typ t - | _ -> assert false + | t -> + Options.fatal "unsupported type %a" Cil_printer.pp_typ t and string_of_typ t = string_of_typ_aux (Cil.unrollType t) and string_of_exp e = Format.asprintf "%a" Cil_printer.pp_exp e @@ -111,9 +112,10 @@ let tplus ?loc t1 t2 = let tdivide ?loc t1 t2 = term ?loc (TBinOp(Div, t1, t2)) t1.term_type -let ttype_of_pointed = function +let ttype_of_pointed t = + match Logic_utils.unroll_type t with | Ctype(TPtr(t, _)) | Ctype(TArray(t, _, _, _)) -> Ctype t - | _ -> assert false + | _ -> Options.fatal "ttype_of_pointed on a non pointer type" let tbuffer_range ?loc ptr len = let last = tminus ?loc len (tinteger ?loc 1) in @@ -139,9 +141,9 @@ and tunref_range_unfold ?loc lval typ = let taccess ?loc ptr offset = let get_lval = function | TLval(lval) -> lval - | _ -> assert false + | _ -> Options.fatal "unexpected non-lvalue on call to taccess" in - match ptr.term_type with + match Logic_utils.unroll_type ptr.term_type with | Ctype(TPtr(_)) -> let address = tplus ?loc ptr offset in let lval = TLval(TMem(address), TNoOffset) in @@ -150,19 +152,15 @@ let taccess ?loc ptr offset = let lval = get_lval ptr.term_node in let lval = addTermOffsetLval (TIndex(offset, TNoOffset)) lval in term ?loc (TLval lval) (ttype_of_pointed ptr.term_type) - | _ -> assert false + | _ -> Options.fatal "taccess on a non pointer type" let sizeofpointed = function | Ctype(TPtr(t, _)) | Ctype(TArray(t, _, _, _)) -> Cil.bytesSizeOf t - | _ -> assert false + | _ -> Options.fatal "size_of_pointed on a non pointer type" let sizeof = function | Ctype t -> Cil.bytesSizeOf t - | _ -> assert false - -let unroll_logic_type = function - | Ctype t -> Ctype (Cil.unrollType t) - | t -> t + | _ -> Options.fatal "sizeof on a non C type" let tunref_range_bytes_len ?loc ptr bytes_len = let sizeof = sizeofpointed ptr.term_type in @@ -218,7 +216,7 @@ and pall_elems_eq ?loc depth t1 t2 len = let eq = peq_unfold ?loc (depth+1) t1_acc t2_acc in pforall ?loc ([ind], (pimplies ?loc (bounds, eq))) and peq_unfold ?loc depth t1 t2 = - match unroll_logic_type t1.term_type with + match Logic_utils.unroll_type t1.term_type with | Ctype(TArray(_, Some len, _, _)) -> let len = Logic_utils.expr_to_term ~cast:false len in pall_elems_eq ?loc depth t1 t2 len @@ -234,12 +232,14 @@ and pall_elems_pred ?loc depth t1 len pred = let eq = punfold_pred ?loc depth t1_acc pred in pforall ?loc ([ind], (pimplies ?loc (bounds, eq))) and punfold_pred ?loc ?(dyn_len = None) depth t1 pred = - match unroll_logic_type t1.term_type with + match Logic_utils.unroll_type t1.term_type with | Ctype(TArray(_, opt_len, _, _)) -> - let len = match opt_len, dyn_len with + let len = + match opt_len, dyn_len with | Some len, None -> Logic_utils.expr_to_term ~cast:false len | _ , Some len -> len - | None, None -> assert false + | None, None -> + Options.fatal "Unfolding array: cannot find a length" in pall_elems_pred ?loc (depth+1) t1 len pred | Ctype(TComp(ci, _, _)) -> @@ -253,9 +253,9 @@ and pall_fields_pred ?loc ?(flex_mem_len=None) depth t1 ci pred = punfold_pred ?loc ~dyn_len depth term pred in let rec eqs_fields = function + | [] -> [] | [ x ] -> [ eq flex_mem_len x ] | x :: l -> let x' = eq None x in x' :: (eqs_fields l) - | _ -> assert false in pands (eqs_fields ci.cfields) @@ -263,7 +263,7 @@ let punfold_flexible_struct_pred ?loc the_struct bytes_len pred = let struct_len = tinteger ?loc (sizeof the_struct.term_type) in let ci = match the_struct.term_type with | Ctype(TComp(ci, _, _) as t) when Cil.has_flexible_array_member t -> ci - | _ -> assert false + | _ -> Options.fatal "Unfolding flexible on a non flexible structure" in let flex_type = Ctype (Extlib.last ci.cfields).ftype in let flex_len = tminus bytes_len struct_len in diff --git a/src/plugins/instantiate/stdlib/basic_alloc.ml b/src/plugins/instantiate/stdlib/basic_alloc.ml index 96ab43c06e5..41679ef1d11 100644 --- a/src/plugins/instantiate/stdlib/basic_alloc.ml +++ b/src/plugins/instantiate/stdlib/basic_alloc.ml @@ -25,12 +25,14 @@ open Basic_blocks open Cil_types open Extlib +let unexpected = Options.fatal "Stdlib.Basic_alloc: unexpected: %s" + let valid_size ?loc typ size = let p = match typ with | TComp (ci, _, _) when Cil.has_flexible_array_member typ -> let elem = match (last ci.cfields).ftype with | TArray(t, _ , _, _) -> tinteger ?loc (Cil.bytesSizeOf t) - | _ -> assert false + | _ -> unexpected "non array last field on flexible structure" in let base = tinteger ?loc (Cil.bytesSizeOf typ) in let flex = tminus ?loc size base in diff --git a/src/plugins/instantiate/stdlib/calloc.ml b/src/plugins/instantiate/stdlib/calloc.ml index e1cc1460c39..86eada6103d 100644 --- a/src/plugins/instantiate/stdlib/calloc.ml +++ b/src/plugins/instantiate/stdlib/calloc.ml @@ -27,13 +27,15 @@ open Logic_const let function_name = "calloc" +let unexpected = Options.fatal "Stdlib.Calloc: unexpected: %s" + let pset_len_to_zero ?loc alloc_type num size = let eq_simpl_value ?loc t = - let value = match t.term_type with + let value = match Logic_utils.unroll_type t.term_type with | Ctype(TPtr(_)) -> term Tnull t.term_type | Ctype(TFloat(_)) -> treal ?loc 0. | Ctype(TInt(_)) -> tinteger ?loc 0 - | _ -> assert false + | _ -> unexpected "non atomic type during equality generation" in prel ?loc (Req, t, value) in @@ -62,9 +64,9 @@ let generate_requires ?loc alloc_type num size = let pinitialized_len ?loc alloc_type num size = let result = tresult ?loc (ptr_of alloc_type) in let initialized ?loc t = - let t = match t.term_node, t.term_type with + let t = match t.term_node, Logic_utils.unroll_type t.term_type with | TLval (lv), Ctype t -> taddrof ?loc lv (Ctype (ptr_of t)) - | _ -> assert false + | _ -> unexpected "non lvalue or non c-type during initialized generation" in pinitialized ?loc (here_label, t) in @@ -108,7 +110,7 @@ let make_behavior_no_allocation loc alloc_type num size = let generate_spec alloc_type { svar = vi } loc = let (cnum, csize) = match Cil.getFormalsDecl vi with | [ cnum ; csize ] -> cnum, csize - | _ -> assert false + | _ -> unexpected "ill-formed fundec in specification generation" in let num = tlogic_coerce ~loc (cvar_to_tvar cnum) Linteger in let size = tlogic_coerce ~loc (cvar_to_tvar csize) Linteger in @@ -143,7 +145,7 @@ let key_from_call ret _ = let ret_t = Cil.unrollTypeDeep (Cil.typeOfLval ret) in let ret_t = Cil.type_remove_qualifier_attributes_deep ret_t in Cil.typeOf_pointed ret_t - | None -> assert false + | None -> unexpected "trying to generate a key on an ill-typed call" let retype_args _typ args = args let args_for_original _typ args = args diff --git a/src/plugins/instantiate/stdlib/free.ml b/src/plugins/instantiate/stdlib/free.ml index 7e00ccdb12e..7ef4c509bb2 100644 --- a/src/plugins/instantiate/stdlib/free.ml +++ b/src/plugins/instantiate/stdlib/free.ml @@ -25,6 +25,8 @@ open Basic_alloc open Cil_types open Logic_const +let unexpected = Options.fatal "Stdlib.Free: unexpected: %s" + let function_name = "free" let null_pointer ?loc ptr = @@ -63,7 +65,7 @@ let make_behavior_no_deallocation loc ptr = let generate_spec _typ { svar = vi } loc = let ptr = match Cil.getFormalsDecl vi with | [ ptr ] -> cvar_to_tvar ptr - | _ -> assert false + | _ -> unexpected "ill-formed fundec in specification generation" in let requires = generate_requires loc ptr in let assigns = generate_global_assigns ptr in @@ -95,7 +97,7 @@ let key_from_call _ret args = let ptr_t = Cil.unrollTypeDeep (Cil.typeOf ptr) in let ptr_t = Cil.type_remove_qualifier_attributes_deep ptr_t in Cil.typeOf_pointed ptr_t - | _ -> assert false + | _ -> unexpected "trying to generate a key on an ill-typed call" let retype_args _typ args = List.map Cil.stripCasts args let args_for_original _typ args = args diff --git a/src/plugins/instantiate/stdlib/malloc.ml b/src/plugins/instantiate/stdlib/malloc.ml index 9cc215a7711..16521b530ae 100644 --- a/src/plugins/instantiate/stdlib/malloc.ml +++ b/src/plugins/instantiate/stdlib/malloc.ml @@ -27,6 +27,8 @@ open Logic_const let function_name = "malloc" +let unexpected = Options.fatal "Stdlib.Malloc: unexpected: %s" + let generate_global_assigns loc ptr_type size = let assigns_result = assigns_result ~loc ptr_type [ size ] in let assigns_heap = assigns_heap [ size ] in @@ -49,7 +51,7 @@ let make_behavior_no_allocation loc ptr_type size = let generate_spec alloc_typ { svar = vi } loc = let (csize) = match Cil.getFormalsDecl vi with | [ size ] -> size - | _ -> assert false + | _ -> unexpected "ill-formed fundec in specification generation" in let size = tlogic_coerce ~loc (cvar_to_tvar csize) Linteger in let requires = [ valid_size ~loc alloc_typ size ] in @@ -82,7 +84,7 @@ let key_from_call ret _ = let ret_t = Cil.unrollTypeDeep (Cil.typeOfLval ret) in let ret_t = Cil.type_remove_qualifier_attributes_deep ret_t in Cil.typeOf_pointed ret_t - | None -> assert false + | None -> unexpected "trying to generate a key on an ill-typed call" let retype_args _typ args = args let args_for_original _typ args = args diff --git a/src/plugins/instantiate/string/memcmp.ml b/src/plugins/instantiate/string/memcmp.ml index e493cbb3939..633294db95b 100644 --- a/src/plugins/instantiate/string/memcmp.ml +++ b/src/plugins/instantiate/string/memcmp.ml @@ -26,6 +26,8 @@ open Basic_blocks let function_name = "memcmp" +let unexpected = Options.fatal "String.Memcmp: unexpected: %s" + let generate_requires loc s1 s2 len = List.map new_predicate [ { (pcorrect_len_bytes ~loc s1.term_type len) @@ -63,7 +65,7 @@ let generate_ensures loc s1 s2 len = let generate_spec _t { svar = vi } loc = let (c_s1, c_s2, clen) = match Cil.getFormalsDecl vi with | [ s1 ; s2 ; len ] -> s1, s2, len - | _ -> assert false + | _ -> unexpected "ill-formed fundec in specification generation" in let s1 = cvar_to_tvar c_s1 in let s2 = cvar_to_tvar c_s2 in @@ -103,7 +105,7 @@ let well_typed_call _ret = function let key_from_call _ret = function | [ s1 ; _ ; _ ] -> type_from_arg s1 - | _ -> failwith "Call to Memmove.key_from_call on an ill-typed call" + | _ -> unexpected "trying to generate a key on an ill-typed call" let retype_args override_key = function | [ s1 ; s2 ; len ] -> @@ -114,7 +116,7 @@ let retype_args override_key = function Cil_datatype.Typ.equal (type_from_arg s2) override_key ) ; [ s1 ; s2 ; len ] - | _ -> failwith "Call to Memmove.retype_args on an ill-typed call" + | _ -> unexpected "trying to retype arguments on an ill-typed call" let args_for_original _t args = args diff --git a/src/plugins/instantiate/string/memcpy.ml b/src/plugins/instantiate/string/memcpy.ml index 02d06b3d5ea..d0db608eef1 100644 --- a/src/plugins/instantiate/string/memcpy.ml +++ b/src/plugins/instantiate/string/memcpy.ml @@ -26,6 +26,8 @@ open Basic_blocks let function_name = "memcpy" +let unexpected = Options.fatal "String.Memcpy: unexpected: %s" + let pseparated_memcpy_len_bytes ?loc p1 p2 bytes_len = let generate len = pseparated_memories ?loc p1 len p2 len in plet_len_div_size ?loc p1.term_type bytes_len generate @@ -67,7 +69,7 @@ let generate_ensures loc t dest src len = let generate_spec _t { svar = vi } loc = let (cdest, csrc, clen) = match Cil.getFormalsDecl vi with | [ dest ; src ; len ] -> dest, src, len - | _ -> assert false + | _ -> unexpected "ill-formed fundec in specification generation" in let t = cdest.vtype in let dest = cvar_to_tvar cdest in @@ -109,7 +111,7 @@ let well_typed_call _ret = function let key_from_call _ret = function | [ dest ; _ ; _ ] -> type_from_arg dest - | _ -> failwith "Call to Memcpy.key_from_call on an ill-typed call" + | _ -> unexpected "trying to generate a key on an ill-typed call" let retype_args override_key = function | [ dest ; src ; len ] -> @@ -120,7 +122,7 @@ let retype_args override_key = function Cil_datatype.Typ.equal (type_from_arg src) override_key ) ; [ dest ; src ; len ] - | _ -> failwith "Call to Memcpy.retype_args on an ill-typed call" + | _ -> unexpected "trying to retype arguments on an ill-typed call" let args_for_original _t args = args diff --git a/src/plugins/instantiate/string/memmove.ml b/src/plugins/instantiate/string/memmove.ml index 75aef926971..6481c423a1f 100644 --- a/src/plugins/instantiate/string/memmove.ml +++ b/src/plugins/instantiate/string/memmove.ml @@ -26,6 +26,8 @@ open Basic_blocks let function_name = "memmove" +let unexpected = Options.fatal "String.Memmove: unexpected: %s" + let pmoved_len_bytes ?loc dest src bytes_len = plet_len_div_size ?loc dest.term_type bytes_len (punfold_all_elems_eq ?loc dest src) @@ -61,7 +63,7 @@ let generate_ensures loc t dest src len = let generate_spec _t { svar = vi } loc = let (cdest, csrc, clen) = match Cil.getFormalsDecl vi with | [ dest ; src ; len ] -> dest, src, len - | _ -> assert false + | _ -> unexpected "ill-formed fundec in specification generation" in let t = cdest.vtype in let dest = cvar_to_tvar cdest in @@ -103,7 +105,7 @@ let well_typed_call _ret = function let key_from_call _ret = function | [ dest ; _ ; _ ] -> type_from_arg dest - | _ -> failwith "Call to Memmove.key_from_call on an ill-typed call" + | _ -> unexpected "trying to generate a key on an ill-typed call" let retype_args override_key = function | [ dest ; src ; len ] -> @@ -114,7 +116,7 @@ let retype_args override_key = function Cil_datatype.Typ.equal (type_from_arg src) override_key ) ; [ dest ; src ; len ] - | _ -> failwith "Call to Memmove.retype_args on an ill-typed call" + | _ -> unexpected "trying to retype arguments on an ill-typed call" let args_for_original _t args = args diff --git a/src/plugins/instantiate/string/memset.ml b/src/plugins/instantiate/string/memset.ml index 79c0fd60bbe..393f6ae626b 100644 --- a/src/plugins/instantiate/string/memset.ml +++ b/src/plugins/instantiate/string/memset.ml @@ -27,6 +27,8 @@ open Basic_blocks let function_name = "memset" type key = (typ * int option) +let unexpected = Options.fatal "String.Memset: unexpected: %s" + module With_collection = struct module OptIntInfo = struct let module_name = String.capitalize_ascii "Instantiate.Memset.OptInt.Datatype" @@ -67,7 +69,7 @@ let pset_len_bytes_to_zero ?loc ptr bytes_len = | Ctype(TPtr(_)) -> term Tnull t.term_type | Ctype(TFloat(_)) -> treal ?loc 0. | Ctype(TInt(_)) -> tinteger ?loc 0 - | _ -> assert false + | _ -> unexpected "non atomic type during equality generation" in prel ?loc (Req, t, value) in @@ -82,7 +84,7 @@ let pset_len_bytes_all_bits_to_one ?loc ptr bytes_len = in let find_nan_for_type t = List.find (of_type t) nans in let all_bits_to_one ?loc t = - match t.term_type with + match Logic_utils.unroll_type t.term_type with | Ctype(TFloat(_)) -> papp ?loc ((find_nan_for_type t.term_type), [], [t]) | Ctype(TPtr(_)) -> @@ -97,7 +99,8 @@ let pset_len_bytes_all_bits_to_one ?loc ptr bytes_len = in let value = term ?loc (TConst (Integer (value,None))) Linteger in prel ?loc (Req, t, value) - | _ -> assert false + | _ -> + unexpected "non atomic type during equality generation" in plet_len_div_size ?loc ptr.term_type bytes_len (fun len -> punfold_all_elems_pred ?loc ptr len all_bits_to_one) @@ -110,7 +113,7 @@ let generate_requires loc ptr value len = [ { (pcorrect_len_bytes ~loc ptr.term_type len) with pred_name = ["aligned_end"] } ] | Some value -> - let low, up = match value.term_type with + let low, up = match Logic_utils.unroll_type value.term_type with | Ctype(TInt((IChar|ISChar|IUChar) as kind, _)) -> let bits = bitsSizeOfInt kind in let plus_one = Integer.add (Integer.of_int 1) in @@ -121,7 +124,8 @@ let generate_requires loc ptr value len = in let integer ?loc i = term ?loc (TConst (Integer (i, None))) Linteger in (integer ~loc low), (integer ~loc up) - | _ -> assert false + | _ -> + unexpected "non atomic type during value bounds generation" in [ { (pbounds_incl_excl ~loc low value up) with pred_name = [ "in_bounds_value" ] } ] @@ -149,7 +153,8 @@ let generate_ensures e loc t ptr value len = [ { (pset_len_bytes_to_zero ~loc ptr len) with pred_name } ] | Some 255, None -> [ { (pset_len_bytes_all_bits_to_one ~loc ptr len) with pred_name }] - | _ -> assert false + | _ -> + unexpected "ill-formed key in ensure generation" in List.map (fun p -> Normal, new_predicate p) (content @ [ { (presult_ptr ~loc t ptr) with pred_name = [ "result"] } @@ -159,7 +164,7 @@ let generate_spec (_t, e) { svar = vi } loc = let (cptr, cvalue, clen) = match Cil.getFormalsDecl vi with | [ ptr ; value ; len ] -> ptr, (Some value), len | [ ptr ; len ] -> ptr, None, len - | _ -> assert false + | _ -> unexpected "ill-formed fundec in specification generation" in let t = cptr.vtype in let ptr = cvar_to_tvar cptr in @@ -210,7 +215,7 @@ let key_from_call _ret = function (type_from_arg ptr), None | [ ptr ; value ; _ ] when not (contains_union_type (type_from_arg ptr)) -> (type_from_arg ptr), (memset_value value) - | _ -> failwith "Call to Memset.key_from_call on an ill-typed call" + | _ -> unexpected "trying to generate a key on an ill-typed call" let char_prototype t = assert (any_char_composed_type t) ; @@ -239,7 +244,7 @@ let generate_prototype = function let fun_type = non_char_prototype t in name, fun_type | _, _ -> - failwith "Call to Memset.generate_prototype on an ill-typed call" + unexpected "trying to generate a prototype on an ill-typed call" let retype_args (t, e) args = match e, args with @@ -255,7 +260,7 @@ let retype_args (t, e) args = assert (match memset_value v with Some x when x = fv -> true | _ -> false) ; [ ptr ; n ] | _ -> - failwith "Call to Memset.retype_args on an ill-typed call" + unexpected "trying to retype arguments on an ill-typed call" let args_for_original (_t , e) args = match e with @@ -264,7 +269,8 @@ let args_for_original (_t , e) args = let loc = Cil_datatype.Location.unknown in match args with | [ ptr ; len ] -> [ ptr ; (Cil.integer ~loc n) ; len] - | _ -> assert false + | _ -> + unexpected "wrong number of arguments replacing call" let () = Transform.register (module struct module Hashtbl = With_collection.Hashtbl diff --git a/src/plugins/instantiate/transform.ml b/src/plugins/instantiate/transform.ml index 7ef4a276a17..28f7a1ca811 100644 --- a/src/plugins/instantiate/transform.ml +++ b/src/plugins/instantiate/transform.ml @@ -126,6 +126,7 @@ let compute_call_preconditions_statuses kf = let stmt = Kernel_function.find_first_stmt kf in let _ = Kernel_function.find_all_enclosing_blocks stmt in match stmt.skind with + | Instr (Local_init(_, ConsInit(fct, _, Plain_func), _)) | Instr (Call(_, { enode = Lval ((Var fct), NoOffset) }, _, _)) -> let called_kf = Globals.Functions.get fct in Statuses_by_call.setup_all_preconditions_proxies called_kf ; @@ -133,7 +134,8 @@ let compute_call_preconditions_statuses kf = ~warn_missing:true called_kf stmt in List.iter (fun (_, p) -> validate_property p) reqs ; - | _ -> assert false + | _ -> + Options.fatal "Transformation: unexpected instruction kind on precondition" let compute_postconditions_statuses kf = let posts bhv = -- GitLab From 8c048b588a6dcb8b9e82f233bf792f1892248ff4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Loi=CC=88c=20Correnson?= <loic.correnson@cea.fr> Date: Thu, 26 Mar 2020 13:09:01 +0100 Subject: [PATCH 019/218] [wp] cache updates --- .../cache/08a266d8ed47524ea462446955f56846.json | 2 ++ .../cache/9c4dd961e0443b101eb51979ae15b5c1.json | 2 ++ .../cache/a789e11c15e566b594c893a9d69b77b8.json | 2 ++ .../cache/f95876c31865b8f2909e450d06c08e6c.json | 2 ++ .../cache/6044af008ca0e2c7fcccdd5236af32af.json | 2 ++ .../cache/6094e7c19eba3f50fb8b90f9528226e9.json | 2 ++ .../cache/78b4274586b7b6ac948dbd0f36d4c1e3.json | 1 + .../cache/a7988461f3fa13ce0532e386a9323033.json | 2 ++ .../cache/dbf4a65cfc0e20fdc41c28df5f546971.json | 2 ++ .../cache/f4ca48ef31089fb2cf5facb451a37704.json | 2 ++ .../cache/fa725e97995b55101c0cf42a29c0f813.json | 1 + .../cache/a36ac87b7682612f29171f0561dcd7f5.json | 1 + .../cache/0a905fe4d67333c2edc713c01cc378f7.json | 2 ++ .../cache/e415e5ac31242f42e0ec3f9659d65967.json | 2 ++ .../cache/f23d47414c80f975ea6a853ebf08af80.json | 2 ++ .../equal.0.session/cache/37ca01b8d9af3adaa85337898f17bbcf.json | 2 ++ .../equal.0.session/cache/e693f887cbaf3748fcba8d0e78496a04.json | 2 ++ .../equal.0.session/cache/fb71b4e14680e40fdfe23d5a71f51776.json | 2 ++ .../cache/0d2abb971445d7e4694380d263060055.json | 2 ++ .../cache/1932508452358e4ae474447d8950a0af.json | 2 ++ .../cache/4529c9de8c01d20f9fbbf88ecaf071c5.json | 2 ++ .../cache/61d6a3a8bbf8eb3941c06207e0edcf6a.json | 2 ++ .../cache/62d262414e3d2e705480be1fdf742280.json | 2 ++ .../cache/7d7abc4aed08f6d397d86a95f08df503.json | 2 ++ .../cache/7e1f0d1b2e2f4fcb6f82eead533aaf21.json | 2 ++ .../cache/879774fa75e5c6e3931a522784aef644.json | 2 ++ .../cache/888ea152c7a0297037a8c6283858d6e4.json | 2 ++ .../cache/bbcaecdc16ceacd6d70aa7a3ad1466aa.json | 2 ++ .../cache/d3dbfa3988959e87318bcf002f3c4e47.json | 2 ++ .../cache/d8bb8e21e04ed3c720d63f31187ee652.json | 2 ++ .../cache/ece5499b76e2b762927d44b60311d491.json | 2 ++ .../cache/f983884d24497fe1e604b085bc61d42d.json | 2 ++ .../cache/3eda240a1618c4e2129a56faa362aa41.json | 2 ++ .../cache/566431057d4fc34ebe07842f87363104.json | 2 ++ .../cache/90bad8d1a177f25e5355b292480850a8.json | 2 ++ .../cache/d9555471b99fab97496429da35c60b85.json | 2 ++ .../cache/ed750337872ba241506bb6b5482d452a.json | 2 ++ .../cache/f61afc24017b7e4fa237b53dacd04d71.json | 2 ++ .../cache/fe3b18624cd214c20103e2ccebb30e28.json | 2 ++ .../cache/fed99e0d6926411c893b99634bf52d5c.json | 2 ++ .../cache/f9448d0b7eb7302bfe3607804bc64e21.json | 2 ++ .../logic.0.session/cache/3c6e8a313ea22d4bc1727ce213fa7a32.json | 1 + .../logic.0.session/cache/8ab45c40e1e4b7574dc56ff9ab462b9e.json | 1 + .../logic.0.session/cache/b2dccb583e60d479c0d381f01ce67a42.json | 2 ++ .../logic.0.session/cache/de909dc4b72d103e8cf9096883ab48c9.json | 1 + .../cache/087830674d518a84a70572bcc511f73c.json | 2 ++ .../cache/18a9a7122ae19461824b858ac602249a.json | 2 ++ .../cache/3fa100d08d6ab289efe6867d26dd6261.json | 2 ++ .../cache/bd55350a94ac10760699d752bc1585d3.json | 2 ++ .../cache/f42d568fbe3428bab8f1402c8db924d3.json | 2 ++ .../null.0.session/cache/2112ab864e0651e150b5554b140c0721.json | 2 ++ .../null.0.session/cache/aad81927bc4771f96d0db10c87c31bf1.json | 2 ++ .../cache/47b74acd14f46caf2bab31cb3340e856.json | 1 + .../cache/5bafa9923e7396335d9ee20e2716d4fc.json | 1 + .../cache/df9f51a2a33abbdc1e33b3e88575ee88.json | 1 + .../cache/e6079b75bc05ca97140090d4e0b21c18.json | 1 + .../cache/47b74acd14f46caf2bab31cb3340e856.json | 1 + .../cache/5bafa9923e7396335d9ee20e2716d4fc.json | 1 + .../cache/df9f51a2a33abbdc1e33b3e88575ee88.json | 1 + .../cache/e6079b75bc05ca97140090d4e0b21c18.json | 1 + .../cache/aeba54fcd5bc6c917c8d92eb80efed6d.json | 1 + .../reads.0.session/cache/0cbdd126867b26cc1e3fc3a5b279bb0d.json | 2 ++ .../reads.0.session/cache/cd6211b4ab473cbfa4d355d0a774ef99.json | 2 ++ .../cache/07b7a43b195fb4f33dd51c9d6bd273d4.json | 2 ++ .../cache/22ae78621c875b3d3cafc538d7eb7ff4.json | 2 ++ .../cache/2be784ca088c5e1a38cbb9ef0222a259.json | 2 ++ .../cache/54f4913abf23075ad98087f17fc620ee.json | 2 ++ .../cache/72b24ef7daf0640c07d9fffa1961d184.json | 2 ++ .../cache/8445d12d440f5e77ee1f7f848cc15b68.json | 2 ++ .../cache/8fb3eea396680aa56e7f96b68ebc2245.json | 2 ++ .../cache/b583dc30d2074490b3fe0ec73cde2dba.json | 2 ++ .../cache/ea5ad50dafc3e3b81b14b672b31faf00.json | 2 ++ .../cache/39afa23189acb8a1b45f730656f3293d.json | 1 + .../cache/b020d8fbac2c1f5a2bb5eff45748c8a2.json | 2 ++ .../cache/d9121cbf1bf929d8a33ed73cdc206552.json | 2 ++ .../cache/baf52c3966dd21bbba0c7a9c81245af2.json | 1 + .../cache/e832de44187e0b48e1388bf9d9475713.json | 2 ++ .../cache/75f6139d28d2176c962de1fda927c848.json | 2 ++ .../cache/420e102e36b2fd0c60d608072d4bbb2b.json | 1 + .../cache/e875e59da9e2107108c67c5c5e48fac1.json | 2 ++ .../cache/ffed0f9e761b9b65d16681ee125d45de.json | 1 + .../cache/e875e59da9e2107108c67c5c5e48fac1.json | 2 ++ .../cache/2065ac6b91a5b85360f219bf4cb61e6f.json | 2 ++ .../cache/834bd396ea03675670f1d7506bf20204.json | 2 ++ .../cache/23393517d8e9a6945aaf5f8c70de67fd.json | 2 ++ .../cache/1025ed1b7e69c8126064452d7cfa2035.json | 2 ++ .../cache/9bd0456062678ca3e8613d336cf8a543.json | 2 ++ .../cache/b02c74702da73481b452499d0feb4af7.json | 2 ++ .../find.0.session/cache/10e70a38e2154839eaae1f1af07fdefc.json | 2 ++ .../find.0.session/cache/135f708793f6fbdc42f4f9d1d1a915c3.json | 2 ++ .../find.0.session/cache/196d356f0ee751ff8133066d78d7929c.json | 2 ++ .../find.0.session/cache/19d9f4b1d3439b94533a38f9eb1a9457.json | 2 ++ .../find.0.session/cache/1a1c741b4fc7ec6915e77dfd6219af40.json | 2 ++ .../find.0.session/cache/1cdcca3d343f4d3666de43999a2859ca.json | 2 ++ .../find.0.session/cache/1eca7fb782936ff88f49a91e6dcd344c.json | 2 ++ .../find.0.session/cache/1f176d5e2b1db0d6e22c16c743220569.json | 2 ++ .../find.0.session/cache/2a7b0348cb3cbb4fcbfad39cfd486e74.json | 2 ++ .../find.0.session/cache/3505ecb809a014f95037869b0e9856e2.json | 2 ++ .../find.0.session/cache/3c7a12cba6964122ac5a406e963e0bac.json | 2 ++ .../find.0.session/cache/42a0fc36bd9559b12c9d5c9ca7e6e427.json | 2 ++ .../find.0.session/cache/493aed7b8f27b8c3737d5175c5888710.json | 2 ++ .../find.0.session/cache/5610a35160a9c2fa66735e0a84235057.json | 2 ++ .../find.0.session/cache/5b41f41e7e6bfe1b5f2a7e510adfcc40.json | 2 ++ .../find.0.session/cache/68bff29417d8a9a908b65a5cdcb559a8.json | 2 ++ .../find.0.session/cache/72222d01b03c631765b96be604890d30.json | 2 ++ .../find.0.session/cache/7c34d2375d6a48a8a2126c8574daacfd.json | 2 ++ .../find.0.session/cache/7dd61d8b30a0d3a1046e8cd99ddf1261.json | 2 ++ .../find.0.session/cache/84634dd1a45d865c6efeca0f4ab49056.json | 2 ++ .../find.0.session/cache/8496a6c0c66a6097c0cc03d173f00c85.json | 2 ++ .../find.0.session/cache/91c9d1dc4216af4315c0cc5b197aa492.json | 2 ++ .../find.0.session/cache/a37053af97bb1db4be167ff7423d4db8.json | 2 ++ .../find.0.session/cache/a97aa29b9f62010d94b1cbab03e4674f.json | 2 ++ .../find.0.session/cache/b3f4583c783aed5095d5f9366f0c583b.json | 2 ++ .../find.0.session/cache/bf04376f6c833a40b4eef1681e1b30f1.json | 2 ++ .../find.0.session/cache/e1499a3b76fe2f4b3db4526b4115ff49.json | 2 ++ .../find.0.session/cache/f6df7d034c012e8f2ce7865d478879d5.json | 2 ++ .../cache/09bf4ce202d8fe39b4526829cb133533.json | 2 ++ .../cache/12c217a27c7139d5f30742273bb085d0.json | 2 ++ .../cache/14128ab2ffe87237e86d3203305033e7.json | 2 ++ .../cache/1b66f8317c14095c081f7afd5b594741.json | 2 ++ .../cache/40b6423d8ddcdc8d72f113ee27b56d23.json | 2 ++ .../cache/415e18fe08911875e6c12f7bad3309c4.json | 2 ++ .../cache/7622228a2ace3b4ea6973fb817034fe1.json | 2 ++ .../cache/7841f539527a85329546eb99578ee528.json | 2 ++ .../cache/f546de791b323fbc7cd8207ceb72043b.json | 2 ++ .../cache/0446f6215cc2b5ece0a84642b8a23227.json | 2 ++ .../cache/1ae181b24023bef5693b9686ebcfebc5.json | 2 ++ .../cache/264a621e237c98dca54cad8896fc45f1.json | 2 ++ .../cache/3ce33a0a8dd65193f55247eca68d0add.json | 2 ++ .../cache/5ffb302fc24b5d55cfba13e1b133442e.json | 2 ++ .../cache/646c4849b1b86e71a02ed6b4e22a5e5a.json | 2 ++ .../cache/8328e1c16a7f7be1c88cb684053fd185.json | 2 ++ .../cache/839040132fbcfc4d3618a0fd1ed7c357.json | 2 ++ .../cache/93059dee8bcf5e3a31af3752b3b47c07.json | 2 ++ .../cache/944a7d63361ee9d7e563e26d0a674bee.json | 2 ++ .../cache/a6b4cc7471adb5a2d0e53268d885e407.json | 2 ++ .../cache/d0e0a407fb1103313547ae958851d341.json | 2 ++ .../cache/f2fc829e259a63aa018c8f5cf2ad51c0.json | 2 ++ .../cache/0126fde627766c5e80152d3092ba2aee.json | 2 ++ .../cache/0818d1c09010d257ad8c6815571d99c3.json | 2 ++ .../cache/102640ec6d1d7a8943086db5f48bebc0.json | 2 ++ .../cache/1241313db0937a5391841138a16626ef.json | 2 ++ .../cache/1722ca0d2e1d91ed7b209013be7aea8f.json | 2 ++ .../cache/4b25798e4a62bf641694ca833c687e01.json | 2 ++ .../cache/51a0fccaa9c5a1f25e08d0458ea80328.json | 2 ++ .../cache/55e7e2a928f55171c0e6181cae34c889.json | 2 ++ .../cache/5c661be4ce7386b877644ffa77d309d7.json | 2 ++ .../cache/61afefe4a097e7a7c785f3f4711f0081.json | 2 ++ .../cache/682f9aad475f771ccd7cdc3bf7f9c96a.json | 2 ++ .../cache/6ae4f6e0ab89bc7fc2e2cf55211c6247.json | 2 ++ .../cache/6f4fec2bff531d88deff253886a30de4.json | 2 ++ .../cache/94cad0bd9e2c593f0562adbf518c46e5.json | 2 ++ .../cache/a3d422cc76ed132eeee720e81a464390.json | 2 ++ .../cache/b1283c4ee81ea5f47112cda8ecef4271.json | 2 ++ .../cache/c20b5a7aa139ba61a8805faf4dae831d.json | 2 ++ .../cache/c849712dfd490b5807a8ff59bc39dc34.json | 2 ++ .../cache/d3420889a7d9c7949b2d1f7715ad1591.json | 2 ++ .../cache/d3ecbb7211cf7ee8fa1710e0d6276a98.json | 2 ++ .../cache/e7910d533bc9cd3f26f0a2db15a2628f.json | 2 ++ .../cache/1da20b026e23dace33f59b4fe30cf704.json | 2 ++ .../cache/26477daefc637e3827acaa7cf7867619.json | 2 ++ .../cache/2e634a920437c83054eec1a07f763cd9.json | 2 ++ .../cache/386154e29073d9acf9fbbc284ccff087.json | 2 ++ .../cache/3be45a6c1d0da2f96f8c1e424a7ab67a.json | 2 ++ .../cache/3f218707b6712edd9bd1d69daa728c14.json | 2 ++ .../cache/4dab6dd8ae580689cfd0d1ba4875ec2d.json | 2 ++ .../cache/4dd3ca5f4c88877a589aae7858e95d76.json | 2 ++ .../cache/5502d8c13d4b19675da7ec1d6fde0e81.json | 2 ++ .../cache/57a1707949cda96266d7a170ab0db4ed.json | 2 ++ .../cache/597c3ce8a628b364884f7aae153eb0f7.json | 2 ++ .../cache/69aed695592a136372272f0976cb7cb0.json | 2 ++ .../cache/6d31b5b9261d0201d9d5d613d393fca5.json | 2 ++ .../cache/70261faccb832e91f3b93fc06ab58117.json | 2 ++ .../cache/76671ff5da324cf7df7b1795b2b206e2.json | 2 ++ .../cache/82652d462ec64309a7df17f1c5d545e1.json | 2 ++ .../cache/a7fffe44ad3c1effe6026e43591942ce.json | 2 ++ .../cache/a8a8445ca94c28d23a1a736558e69c8c.json | 2 ++ .../cache/b5e466768f27e36ace65e700da4c6762.json | 2 ++ .../cache/b6b84b8aa7e49ae4e58e874d380e52ec.json | 2 ++ .../cache/c0517fb8e7353916d3a8af59a55cfe96.json | 2 ++ .../cache/f3c1620b867b46248a65cace35447c1f.json | 2 ++ .../cache/f7589a89ccb1575e24730fc330fcf0d0.json | 2 ++ .../cache/0d38200a674100ddfe7feec44eb47f95.json | 2 ++ .../cache/146ba3796f4ee4106a5e8667bd7c3f50.json | 2 ++ .../cache/1c7541e16fa613b0a976bfc393da96ed.json | 2 ++ .../cache/1d98ee567fabc1936f14d72a0a2a19e6.json | 2 ++ .../cache/20c6bfbc4023e7a48004f3a7eb2ad3e5.json | 2 ++ .../cache/34b5e8da6fcfd4368079c11b0279db8f.json | 2 ++ .../cache/45db19c6faa1857dc87eb5a34ce27371.json | 2 ++ .../cache/56a7807ae39f0ecb4e627be901632939.json | 2 ++ .../cache/90300cb727c65d761a7f041a9b946827.json | 2 ++ .../cache/93fc40b2b5154a19653646b42b6c2df6.json | 2 ++ .../cache/951e03065266dffb0914d1775c1ad10c.json | 2 ++ .../cache/b4b46240c49a9f0ef2530dea215e1919.json | 2 ++ .../cache/c5d6eefd823963da7ca16544bc3f3912.json | 2 ++ .../cache/f17c3d079b701186ae67cf3c2a6a0277.json | 2 ++ .../cache/fb2a96c00753836cd4d75f4c8ebfd06f.json | 2 ++ .../cache/059ee2fae3aa0fd30ca23f0159275ef3.json | 2 ++ .../cache/07832109afbac0e38eb5d87932066e08.json | 2 ++ .../cache/088564331bfc8b3af317aacddb4ccbea.json | 2 ++ .../cache/08e74ef80a419837ad146845c97f173b.json | 2 ++ .../cache/0c31169754f2628df2aefb14cc504990.json | 2 ++ .../cache/0ec7f155931ed9e99efae24fd0898491.json | 2 ++ .../cache/0f76081bfd4cb878c7ac624b1e0677ec.json | 2 ++ .../cache/113dabb6f94d8c3225236c434a5d13a7.json | 2 ++ .../cache/178e24799cae3dcec5f3257226b96a20.json | 2 ++ .../cache/1b75b91371009810dc97ffa389bb5531.json | 2 ++ .../cache/1da5cd2893da7c1322294978850c6fd3.json | 2 ++ .../cache/1f482c6de3c7a19cda334e37d01fe177.json | 2 ++ .../cache/2d2277efecc9ac0135f43533fb7fd64e.json | 2 ++ .../cache/2d5464d4e8192a657d37126dca5910da.json | 2 ++ .../cache/2ddd3e6ac842e9117c49c9ddaf740411.json | 2 ++ .../cache/2e3c2cb35cef3cb6057febf0bdf10744.json | 2 ++ .../cache/37377966b3e186a9febaac6df135d3e9.json | 2 ++ .../cache/45124138476e1855a6f35cf90a0f7385.json | 2 ++ .../cache/50c141eec33504c5c1bed095ab2c1934.json | 2 ++ .../cache/5aa93b7609826cef11995c6f79edc54c.json | 2 ++ .../cache/634fb439c79d4b2df9278efe8f97f1a2.json | 2 ++ .../cache/6356a66f92291eedbf596c86247cdf40.json | 2 ++ .../cache/66d43256948fe0b03dc360a4a2654dfb.json | 2 ++ .../cache/69483893c71ff4f7f440dddd3e21f386.json | 2 ++ .../cache/6c00a117f0e575dde2c838780b6a2b5f.json | 2 ++ .../cache/6f907d24a6c6d51475fbbba7851998d4.json | 2 ++ .../cache/737d7d224b95933e11e8630b0d5e1e67.json | 2 ++ .../cache/744202b8726995ad41adcfd26dbd3977.json | 2 ++ .../cache/784037581ab4f838952f762dd078ccd2.json | 2 ++ .../cache/7b20ca91596a368e107ee308c5abb683.json | 2 ++ .../cache/7e28eb621b6c70199ef921ecc2b766f9.json | 2 ++ .../cache/82d303e4f3b78e54f806a99c19a64876.json | 2 ++ .../cache/8421490fd39132bfdfa1fa54817bc682.json | 2 ++ .../cache/85c2351bf7a38814cb9a0a47ea6c2ea7.json | 2 ++ .../cache/865e884b2f3e33610e0aa609d35c6f09.json | 2 ++ .../cache/88bebb3c661a1f33578350b8200b7c25.json | 2 ++ .../cache/8a7b631f75a3073c3262178ccfedd3e7.json | 2 ++ .../cache/8aafa7388f31a7314c199713ca0ae084.json | 2 ++ .../cache/8e942fe174bf1f62bb36a5abab4deb26.json | 2 ++ .../cache/92d2d156fb93ee5c5f2d3f2faa4c4275.json | 2 ++ .../cache/9c97f1cddb0b9fcf61a6d1caddc3e897.json | 2 ++ .../cache/9cab00be1ec378b961d688830f12c8b5.json | 2 ++ .../cache/a2374beb942675808f3c1588a5f13a68.json | 2 ++ .../cache/ae94fd34b628e3925ec2951d2ed0d153.json | 2 ++ .../cache/b0969ad7ecf31664172fda8b609f8917.json | 2 ++ .../cache/b57d3798758c77258d386ffb51fb4324.json | 2 ++ .../cache/bd76bf896c68ddef8cbba6f20100fac8.json | 2 ++ .../cache/be1d9ed1ba49360aaa18b8d4b577c56f.json | 2 ++ .../cache/c57fbc674ee49672402990996b38e761.json | 2 ++ .../cache/ca5e36cff267d97e2595ae3f8187bcdd.json | 2 ++ .../cache/cd48e56312a247d0852ac3ca63754265.json | 2 ++ .../cache/d39b5b1c24cd1c7d131652c2ca1dd878.json | 2 ++ .../cache/d4b82b17f751426ee45e116de56f70bb.json | 2 ++ .../cache/d51e6faa5980c6069ff809306e33fe61.json | 2 ++ .../cache/e8bad62a574dfb263cbb0424c1f994cc.json | 2 ++ .../cache/e997b52aca1d60592f0c918574d95bca.json | 2 ++ .../cache/eec066c7871c347d05d218448003bb42.json | 2 ++ .../cache/fa144aad657dae3418db4f22e288c17e.json | 2 ++ .../byref.0.session/cache/56b7eefc17044e0ff95c99434cf88399.json | 1 + .../cache/852210deac5464ecf4c672c0f6c67fb7.json | 2 ++ .../cache/aa862239bf067f3148dc841ef36e7c1a.json | 2 ++ .../cache/d85b1504de7e92963b9c333e4ba02d6f.json | 2 ++ .../cache/6dd7fce5505a14bc287568321ce0111b.json | 2 ++ .../cache/2eb20108bba00807202ca8ddffbe9321.json | 2 ++ .../cache/84e7fceb770bfa7d815f522cfce14408.json | 2 ++ .../cache/8773bd69d274eceb0acf3767f4ae9575.json | 2 ++ .../cache/8d2421a35a8365649870fd7b2f8a1222.json | 2 ++ .../cache/a514c4e0dbce3a19cb575797578db2ee.json | 2 ++ .../cache/1055ecf60b0251e2ce8a583866b59b5d.json | 2 ++ .../cache/3ad89ca7d6079981ace01e3d25910e63.json | 2 ++ .../cache/5518bc5769e51a2ec423d55457d4323c.json | 2 ++ .../cache/5c4bdf85b0130c246990c9addb9d2556.json | 2 ++ .../cache/aeb63d64f83c4e31d79d7e8e869de07e.json | 1 + .../cache/1aa29de269f2b73adeae713ac86acec7.json | 2 ++ .../cache/762ba8fbb24bdd2a875e3ac97bcdb1a0.json | 2 ++ .../cache/b280eb527d15c1796693db544778a327.json | 1 + .../cache/f55cc495403a5870a0396a5e15c05b4d.json | 2 ++ .../cache/762ba8fbb24bdd2a875e3ac97bcdb1a0.json | 2 ++ .../cache/b280eb527d15c1796693db544778a327.json | 2 ++ .../cache/f55cc495403a5870a0396a5e15c05b4d.json | 2 ++ .../copy.0.session/cache/05e5c5311bfe8997e3278f3e5c22829a.json | 2 ++ .../copy.0.session/cache/074cb03898e8ed122caa93327a7b7a77.json | 2 ++ .../copy.0.session/cache/58369c7fb3048b416fdd3fc5458c5b83.json | 2 ++ .../copy.0.session/cache/65e3ef4a8586c488db122d88f499b0d9.json | 2 ++ .../copy.0.session/cache/9df2b33683d9824243472af4e8d5c5f7.json | 2 ++ .../copy.0.session/cache/d52a4f7a87fca3c71ec617296f285903.json | 2 ++ .../cache/7c61992a1e5557d753841a5f66eef4ae.json | 2 ++ .../cache/dd5c27a7c1200d3431d2c30bf2899942.json | 2 ++ .../cache/e2e624a33e02433818d9a93dc4b967fb.json | 1 + .../cache/f8e79502a4545e9f174c055480b11bad.json | 2 ++ .../flash.0.session/cache/62c8c83348d53abd331942b7638c0e65.json | 1 + .../flash.0.session/cache/ad24c8fdc842200098097f4c5b243a1b.json | 1 + .../flash.0.session/cache/d57a0b96fe98d0e1d1578d06300ae6af.json | 1 + .../flash.0.session/cache/e98f4a09d201fc4ff4b2c17441acaa8d.json | 1 + .../flash.0.session/cache/fb1ff75dc8c936a96751f5ffdde36e50.json | 1 + .../flash.1.session/cache/354efda647c2b52e3acf13bee479341a.json | 2 ++ .../flash.1.session/cache/5a90230e76db08ca4977aaefa5af6afc.json | 2 ++ .../flash.1.session/cache/687c6ba705dc05a8d976db9c98dbc1b7.json | 2 ++ .../flash.1.session/cache/6d33d3e9e0c138689b7b7b81af41c61b.json | 2 ++ .../flash.1.session/cache/d1203dcf4cb1b7eb56cc98aaeee8d670.json | 2 ++ .../cache/7c52f41beefbdb46d7a18dde9bbf2bf8.json | 1 + .../cache/6c499bc384463731f06e46d71bc8ca72.json | 1 + .../frame.0.session/cache/b475650b9898e2e1a3a99a196f007c1d.json | 1 + .../frame.0.session/cache/c226acb64e8c66b0e8ce990e608b7583.json | 1 + .../cache/22137e3a0e8bb8e5c6f558c96a8b0584.json | 1 + .../cache/3aa6fff5b9a5f4e04964329dadd25933.json | 2 ++ .../cache/eb1a359dc7730155217ac94756d7dffa.json | 2 ++ .../cache/25c9ec98fb41e974a3fac1a61d027acc.json | 2 ++ .../cache/42ee58e19309bd5df73821e3cfd04518.json | 2 ++ .../loop.0.session/cache/185d1270b8988dc69c4d7d49e40360fe.json | 2 ++ .../loop.0.session/cache/6094e7c19eba3f50fb8b90f9528226e9.json | 2 ++ .../loop.0.session/cache/67237129e97d7ae8d5ff4b62d632af5c.json | 2 ++ .../loop.0.session/cache/d9a9c67c0ce931a0559a5db9f619abd9.json | 2 ++ .../loop.0.session/cache/ed73ec0948ff5ae6b53fce8a8adada7a.json | 2 ++ .../loop.0.session/cache/fa725e97995b55101c0cf42a29c0f813.json | 1 + .../cache/32e4d5d1ffef8a7dbb1fe8c7d536f845.json | 1 + .../cache/3e0d119a220c45bb16b0d7612fae4738.json | 2 ++ .../cache/725d46c74277558f772438a95d5ffa30.json | 2 ++ .../cache/fff4cb231748d3746212595b0892b5f9.json | 1 + .../cache/46c7ee5a8694d5a20e47282f25e34be5.json | 2 ++ .../cache/8051f3e6d0df90db81f77cee4ad63859.json | 2 ++ .../cache/8091b9c0849f4d1a46e4879e5348fdb0.json | 2 ++ .../cache/8b223534ba1fa0aa7e4ef5bd8ff12d15.json | 2 ++ .../cache/9e537d84dc915243e941b46128dbd193.json | 2 ++ .../rte.0.session/cache/23ff27cd5de1ace498e0001fd798be43.json | 1 + .../rte.0.session/cache/3de2cb0c1d0276cbaa7600ff25e6f29a.json | 1 + .../rte.0.session/cache/56b7eefc17044e0ff95c99434cf88399.json | 1 + .../rte.0.session/cache/f978123c614da8cddf33e186f24f3e67.json | 1 + .../cache/33446f0a42119240b0b63f1a2c0bc6ff.json | 2 ++ .../cache/3480784fd33fa9f4cae3b169a359cc57.json | 2 ++ .../cache/4bc35b1105da43dc265e953cbf96035d.json | 2 ++ .../cache/607e1a10e4ccbf9b5505703cb2087df7.json | 2 ++ .../cache/7d870ce9aa419a3893c0d18e3e2904f5.json | 2 ++ .../cache/7d91bcc945d933f5af6e1e468ae4ecf4.json | 2 ++ .../cache/8101aefca2eee2b8fb6cc34749c9891f.json | 2 ++ .../cache/9628de01f82e8d57abe1ca40a3145921.json | 2 ++ .../cache/98d61fd3dc609926e2d9ed8d866b0ca3.json | 2 ++ .../cache/ace2089a7d9190f715a07093a9276e98.json | 2 ++ .../cache/bfef8898939d13a4a34f0035d4718cf6.json | 2 ++ .../cache/c78ab4c23e92b597edada513514da04c.json | 2 ++ .../cache/ca73637f01f2f91a0068347eeb9ec94c.json | 2 ++ .../cache/cf51ece0b093233bb0adb1181e349246.json | 2 ++ .../cache/d46d0acf6fd632f8f6119d14bca4ce6a.json | 2 ++ .../cache/d765de4fb3d29a70866cbf36f4fab698.json | 2 ++ .../cache/e76eb6cb77a00f788ce64e76f562810b.json | 2 ++ .../cache/ebb2a53efc61a99e868bcaeccdedd60d.json | 2 ++ .../cache/ef5c696900a376aef83fb21941139a3c.json | 2 ++ .../cache/efd16d0abd5a1c7656466cad2eff1a82.json | 2 ++ .../cache/f24b0ea52a766197c49733f5567e5290.json | 2 ++ .../cache/3c2808a40bb021dbc99953e3c5324934.json | 2 ++ .../cache/49a728ea0e221f941984978faa18dc8b.json | 2 ++ .../cache/f11323e3ba20fea4dc00b0c0a4e8c75a.json | 2 ++ .../cache/bbd1bf207aff73a0add5c310a10d82fc.json | 2 ++ .../cache/d3af917ba88b4651ecd99c4782829b8d.json | 2 ++ .../cache/8824303ce7307ea0a6607b5ed4deb0ae.json | 2 ++ .../cache/974d21e0e97775d1697fc217acf09aae.json | 2 ++ .../cache/054ac21eccbda5823e3b61d57b70fa6e.json | 1 + .../cache/6f3bf79ad4f2c16243f68e50736057b2.json | 1 + .../cache/94a853062337d3984c131f4b925cf498.json | 2 ++ .../cache/ca8f374f313f9efd2a66850f6ce238ac.json | 2 ++ .../cache/54640927ace915eaf531f7d99162bff2.json | 2 ++ .../cache/cbef7a2678ffbb62f89898239a2300cf.json | 2 ++ .../cache/aa1fad5015602138db9f12fbfce39c6a.json | 2 ++ .../cache/c0a758625fc5806b2d004ce066f809f1.json | 2 ++ .../cache/cbef7a2678ffbb62f89898239a2300cf.json | 2 ++ .../cache/edcf65b50fa78c78cddb184cdd54ed56.json | 2 ++ .../cache/275f36697bf837a8e650d76b262a2972.json | 1 + .../cache/2d49dd2aa47e49570e397cc771e23a05.json | 2 ++ .../cache/47de988037a45f7d6177eadd7d8a885f.json | 2 ++ .../cache/69c6adb0d354ab9716344b82e02e28da.json | 2 ++ .../cache/aab17c8e0ce454a4c0284ffae858edf6.json | 1 + .../cache/bbe62e3cff4dcf2d16418512a09cc682.json | 1 + .../cache/cfd3a385e095a454ca4b030e22ce34d3.json | 2 ++ .../frame.0.session/cache/1c8e1bc5a936e2c520c323bce7927b1f.json | 2 ++ .../frame.0.session/cache/2de2447a32b00f58b6bf40b3b90caf3a.json | 2 ++ .../cache/02a5967e29d215a319e5d52aeea6ee2b.json | 2 ++ .../cache/578bba9c847de51c178d0337644fd81e.json | 2 ++ .../cache/7882f8daf0f62dd319b068a984bce5ae.json | 2 ++ .../cache/51f562f110aa57a99fb537f2987e09da.json | 2 ++ .../cache/9ec67e1127d3b8a1f5e26915449443c8.json | 2 ++ .../cache/caf3de3711d3f3c15ff182a47b1a66e9.json | 2 ++ .../cache/51f562f110aa57a99fb537f2987e09da.json | 2 ++ .../cache/9ec67e1127d3b8a1f5e26915449443c8.json | 2 ++ .../cache/caf3de3711d3f3c15ff182a47b1a66e9.json | 2 ++ .../cache/5725debb61cac997c8aec1f3b0b2205f.json | 2 ++ .../cache/bb2b7123541670aa64836bfff3d66a26.json | 1 + .../cache/48610aa4f300718739c914fc0b7c1f64.json | 2 ++ .../cache/cc6ee1d50b7c0fd64c3271bbc98f9c13.json | 2 ++ .../cache/ff456f15865e6d8f50db8ac0e7f19ea4.json | 2 ++ .../cache/5be9158693acc77d4d2e554e52149918.json | 2 ++ .../cache/974fb23dac4868107d647875f95df135.json | 2 ++ .../cache/c16ea120b56be33a00dc52be23af6d68.json | 2 ++ .../cache/ff88885f0f8ec902940c70c9b19e68bf.json | 2 ++ .../cache/420e102e36b2fd0c60d608072d4bbb2b.json | 1 + .../cache/06be40162d4388f79dad2e8636a6cc2a.json | 2 ++ .../cache/51299c47004a944cc0cab6fafc4a3bd8.json | 2 ++ .../cache/5dd650e35271706f2ad3881dca995525.json | 2 ++ .../cache/6e89f99f7bc6430de780b6cbd010c8b5.json | 2 ++ .../cache/91c84d4131059c3f2bbbe3b3f414e1fe.json | 2 ++ .../cache/f9cff23cc8636428a30178fe3fcc8a69.json | 2 ++ .../cache/02acba90a5e2994128860c40fb9f2ba4.json | 2 ++ .../cache/0b0769d38a9d9517197365e24d9ff7aa.json | 2 ++ .../cache/3c1410111850a62a3c903e678e48aa06.json | 2 ++ .../cache/3e77a926f2555c5bf515bd79563fc136.json | 2 ++ .../cache/437695130334113727cc1e91e1310860.json | 2 ++ .../cache/5702189f244cf06f51fa911ec3cfc217.json | 2 ++ .../cache/886d5e0abccf7e670b416c38f907864c.json | 2 ++ .../cache/a2e4a1bc7074fcc778279e99ec19077d.json | 2 ++ .../cache/aea9a4d6d52524ca1bda06c25330d453.json | 2 ++ .../cache/b526cd5eaf63d35c962f8df3f2312ce8.json | 2 ++ .../cache/b5efd7507bdfb8fc86984707ac9c09d0.json | 2 ++ .../cache/ea5f20db4ed84d856d7641ef17d0e541.json | 2 ++ .../cache/0afa9c7ed5285e03fb1e7ec3d0e1bcad.json | 2 ++ .../cache/2bf63647c8b8679f671cda4e96dd02c8.json | 2 ++ .../cache/4e990ccecbce16ae7813bf76856ed44b.json | 1 + .../cache/58c3647be66cbcb1d4b1f050100571a3.json | 2 ++ .../cache/6bdf496e41182821957a01191acc6df3.json | 1 + .../cache/93a87d49aa052b4a3426069f903e97d8.json | 1 + .../cache/a278c3684532efda2a8b0aa0b8328228.json | 2 ++ .../cache/c40097d18aabd35cf73be24de441cda4.json | 2 ++ .../cache/dbc2fcfa6ad5e92e7256df7e47ac4dfd.json | 2 ++ .../cache/5bfecd798741a31e1a9b75b1e76b6fb9.json | 1 + .../cache/874512731d488beab568aeedc8d4b813.json | 1 + .../cache/a857d63f4fb5a4a658f9459397c355f7.json | 1 + .../cache/0278cb04c10669bda8546d6aa4b5b1a2.json | 2 ++ .../cache/06a0f4a9e1bbdbde32bdf1f677d91181.json | 2 ++ .../cache/0ee2f3e078b2e5a06190ddebe6f3da08.json | 1 + .../cache/38d0f75717aeccc5685668c23c4874e6.json | 2 ++ .../cache/6b7331507db6c1572280eb515546680a.json | 2 ++ .../cache/44f847d26840ea2582d2f6cd48a9bbf2.json | 2 ++ .../cache/1618850a88ad1dcc80a2d9a980d52dc8.json | 1 + .../cache/94d26158a717c5e2cda72d3c71c02776.json | 2 ++ .../cache/bd7bc3c6aa2a16dd8cc830c3c57c3faa.json | 2 ++ .../cache/2b92804b7fb7ffdca664af595a966537.json | 2 ++ .../cache/41978d7b0067a89104bd5f2bbd577a3a.json | 2 ++ .../cache/458df2d4dbfc5fe724b9f06bbff664ab.json | 2 ++ .../cache/4794c66d9a48e1f6e50a71af3e78f625.json | 2 ++ .../cache/d47c18406856fd185a8c849853d341e2.json | 2 ++ .../cache/0d7ed916922dfd3cd88f04aa053382de.json | 2 ++ .../cache/1d2723c4a683647c25bef5fe4d0cf9d8.json | 2 ++ .../cache/24c6daff7425605b2807df8b79073aeb.json | 2 ++ .../cache/5760024d3d12da3af8d584a2e1a2b6c0.json | 2 ++ .../cache/60b70c5aacda3dc7239684d5c8a9143e.json | 2 ++ .../cache/72809963e95fe64166cd5b945b5d46cb.json | 2 ++ .../cache/9f2521dbb8d31c6d01c228e4aa27ff19.json | 2 ++ .../cache/b3b8f8b3c5dcdfa1b0a26f1f950a56fa.json | 2 ++ .../cache/d05062d51da49ab4e2231ed6e5b4617d.json | 2 ++ .../cache/d40dc9c872cb867b53026c481dc3559b.json | 2 ++ .../cache/4253c6f687ba6a60e8db3e685e84df59.json | 2 ++ .../cache/450fdb9fdd1ea7a682081dbc0af6e709.json | 2 ++ .../cache/688d69c32aabc5063535d39e5dc1b063.json | 2 ++ 448 files changed, 841 insertions(+) create mode 100644 src/plugins/wp/tests/wp/oracle_qualif/sharing.0.session/cache/08a266d8ed47524ea462446955f56846.json create mode 100644 src/plugins/wp/tests/wp_acsl/oracle_qualif/assigns_path.0.session/cache/9c4dd961e0443b101eb51979ae15b5c1.json create mode 100644 src/plugins/wp/tests/wp_acsl/oracle_qualif/assigns_path.0.session/cache/a789e11c15e566b594c893a9d69b77b8.json create mode 100644 src/plugins/wp/tests/wp_acsl/oracle_qualif/assigns_path.0.session/cache/f95876c31865b8f2909e450d06c08e6c.json create mode 100644 src/plugins/wp/tests/wp_acsl/oracle_qualif/axioms.0.session/cache/6044af008ca0e2c7fcccdd5236af32af.json create mode 100644 src/plugins/wp/tests/wp_acsl/oracle_qualif/axioms.0.session/cache/6094e7c19eba3f50fb8b90f9528226e9.json create mode 100644 src/plugins/wp/tests/wp_acsl/oracle_qualif/axioms.0.session/cache/78b4274586b7b6ac948dbd0f36d4c1e3.json create mode 100644 src/plugins/wp/tests/wp_acsl/oracle_qualif/axioms.0.session/cache/a7988461f3fa13ce0532e386a9323033.json create mode 100644 src/plugins/wp/tests/wp_acsl/oracle_qualif/axioms.0.session/cache/dbf4a65cfc0e20fdc41c28df5f546971.json create mode 100644 src/plugins/wp/tests/wp_acsl/oracle_qualif/axioms.0.session/cache/f4ca48ef31089fb2cf5facb451a37704.json create mode 100644 src/plugins/wp/tests/wp_acsl/oracle_qualif/axioms.0.session/cache/fa725e97995b55101c0cf42a29c0f813.json create mode 100644 src/plugins/wp/tests/wp_acsl/oracle_qualif/base_offset.0.session/cache/a36ac87b7682612f29171f0561dcd7f5.json create mode 100644 src/plugins/wp/tests/wp_acsl/oracle_qualif/classify_float.0.session/cache/0a905fe4d67333c2edc713c01cc378f7.json create mode 100644 src/plugins/wp/tests/wp_acsl/oracle_qualif/classify_float.0.session/cache/e415e5ac31242f42e0ec3f9659d65967.json create mode 100644 src/plugins/wp/tests/wp_acsl/oracle_qualif/classify_float.0.session/cache/f23d47414c80f975ea6a853ebf08af80.json create mode 100644 src/plugins/wp/tests/wp_acsl/oracle_qualif/equal.0.session/cache/37ca01b8d9af3adaa85337898f17bbcf.json create mode 100644 src/plugins/wp/tests/wp_acsl/oracle_qualif/equal.0.session/cache/e693f887cbaf3748fcba8d0e78496a04.json create mode 100644 src/plugins/wp/tests/wp_acsl/oracle_qualif/equal.0.session/cache/fb71b4e14680e40fdfe23d5a71f51776.json create mode 100644 src/plugins/wp/tests/wp_acsl/oracle_qualif/float_compare.0.session/cache/0d2abb971445d7e4694380d263060055.json create mode 100644 src/plugins/wp/tests/wp_acsl/oracle_qualif/float_compare.0.session/cache/1932508452358e4ae474447d8950a0af.json create mode 100644 src/plugins/wp/tests/wp_acsl/oracle_qualif/float_compare.0.session/cache/4529c9de8c01d20f9fbbf88ecaf071c5.json create mode 100644 src/plugins/wp/tests/wp_acsl/oracle_qualif/float_compare.0.session/cache/61d6a3a8bbf8eb3941c06207e0edcf6a.json create mode 100644 src/plugins/wp/tests/wp_acsl/oracle_qualif/float_compare.0.session/cache/62d262414e3d2e705480be1fdf742280.json create mode 100644 src/plugins/wp/tests/wp_acsl/oracle_qualif/float_compare.0.session/cache/7d7abc4aed08f6d397d86a95f08df503.json create mode 100644 src/plugins/wp/tests/wp_acsl/oracle_qualif/float_compare.0.session/cache/7e1f0d1b2e2f4fcb6f82eead533aaf21.json create mode 100644 src/plugins/wp/tests/wp_acsl/oracle_qualif/float_compare.0.session/cache/879774fa75e5c6e3931a522784aef644.json create mode 100644 src/plugins/wp/tests/wp_acsl/oracle_qualif/float_compare.0.session/cache/888ea152c7a0297037a8c6283858d6e4.json create mode 100644 src/plugins/wp/tests/wp_acsl/oracle_qualif/float_compare.0.session/cache/bbcaecdc16ceacd6d70aa7a3ad1466aa.json create mode 100644 src/plugins/wp/tests/wp_acsl/oracle_qualif/float_compare.0.session/cache/d3dbfa3988959e87318bcf002f3c4e47.json create mode 100644 src/plugins/wp/tests/wp_acsl/oracle_qualif/float_compare.0.session/cache/d8bb8e21e04ed3c720d63f31187ee652.json create mode 100644 src/plugins/wp/tests/wp_acsl/oracle_qualif/float_compare.0.session/cache/ece5499b76e2b762927d44b60311d491.json create mode 100644 src/plugins/wp/tests/wp_acsl/oracle_qualif/float_compare.0.session/cache/f983884d24497fe1e604b085bc61d42d.json create mode 100644 src/plugins/wp/tests/wp_acsl/oracle_qualif/float_const.0.session/cache/3eda240a1618c4e2129a56faa362aa41.json create mode 100644 src/plugins/wp/tests/wp_acsl/oracle_qualif/float_const.0.session/cache/566431057d4fc34ebe07842f87363104.json create mode 100644 src/plugins/wp/tests/wp_acsl/oracle_qualif/float_const.0.session/cache/90bad8d1a177f25e5355b292480850a8.json create mode 100644 src/plugins/wp/tests/wp_acsl/oracle_qualif/float_const.0.session/cache/d9555471b99fab97496429da35c60b85.json create mode 100644 src/plugins/wp/tests/wp_acsl/oracle_qualif/float_const.0.session/cache/ed750337872ba241506bb6b5482d452a.json create mode 100644 src/plugins/wp/tests/wp_acsl/oracle_qualif/float_const.0.session/cache/f61afc24017b7e4fa237b53dacd04d71.json create mode 100644 src/plugins/wp/tests/wp_acsl/oracle_qualif/float_const.0.session/cache/fe3b18624cd214c20103e2ccebb30e28.json create mode 100644 src/plugins/wp/tests/wp_acsl/oracle_qualif/float_const.0.session/cache/fed99e0d6926411c893b99634bf52d5c.json create mode 100644 src/plugins/wp/tests/wp_acsl/oracle_qualif/init_value_mem.0.session/cache/f9448d0b7eb7302bfe3607804bc64e21.json create mode 100644 src/plugins/wp/tests/wp_acsl/oracle_qualif/logic.0.session/cache/3c6e8a313ea22d4bc1727ce213fa7a32.json create mode 100644 src/plugins/wp/tests/wp_acsl/oracle_qualif/logic.0.session/cache/8ab45c40e1e4b7574dc56ff9ab462b9e.json create mode 100644 src/plugins/wp/tests/wp_acsl/oracle_qualif/logic.0.session/cache/b2dccb583e60d479c0d381f01ce67a42.json create mode 100644 src/plugins/wp/tests/wp_acsl/oracle_qualif/logic.0.session/cache/de909dc4b72d103e8cf9096883ab48c9.json create mode 100644 src/plugins/wp/tests/wp_acsl/oracle_qualif/looplabels.0.session/cache/087830674d518a84a70572bcc511f73c.json create mode 100644 src/plugins/wp/tests/wp_acsl/oracle_qualif/looplabels.0.session/cache/18a9a7122ae19461824b858ac602249a.json create mode 100644 src/plugins/wp/tests/wp_acsl/oracle_qualif/looplabels.0.session/cache/3fa100d08d6ab289efe6867d26dd6261.json create mode 100644 src/plugins/wp/tests/wp_acsl/oracle_qualif/looplabels.0.session/cache/bd55350a94ac10760699d752bc1585d3.json create mode 100644 src/plugins/wp/tests/wp_acsl/oracle_qualif/looplabels.0.session/cache/f42d568fbe3428bab8f1402c8db924d3.json create mode 100644 src/plugins/wp/tests/wp_acsl/oracle_qualif/null.0.session/cache/2112ab864e0651e150b5554b140c0721.json create mode 100644 src/plugins/wp/tests/wp_acsl/oracle_qualif/null.0.session/cache/aad81927bc4771f96d0db10c87c31bf1.json create mode 100644 src/plugins/wp/tests/wp_acsl/oracle_qualif/pointer.0.session/cache/47b74acd14f46caf2bab31cb3340e856.json create mode 100644 src/plugins/wp/tests/wp_acsl/oracle_qualif/pointer.0.session/cache/5bafa9923e7396335d9ee20e2716d4fc.json create mode 100644 src/plugins/wp/tests/wp_acsl/oracle_qualif/pointer.0.session/cache/df9f51a2a33abbdc1e33b3e88575ee88.json create mode 100644 src/plugins/wp/tests/wp_acsl/oracle_qualif/pointer.0.session/cache/e6079b75bc05ca97140090d4e0b21c18.json create mode 100644 src/plugins/wp/tests/wp_acsl/oracle_qualif/pointer.1.session/cache/47b74acd14f46caf2bab31cb3340e856.json create mode 100644 src/plugins/wp/tests/wp_acsl/oracle_qualif/pointer.1.session/cache/5bafa9923e7396335d9ee20e2716d4fc.json create mode 100644 src/plugins/wp/tests/wp_acsl/oracle_qualif/pointer.1.session/cache/df9f51a2a33abbdc1e33b3e88575ee88.json create mode 100644 src/plugins/wp/tests/wp_acsl/oracle_qualif/pointer.1.session/cache/e6079b75bc05ca97140090d4e0b21c18.json create mode 100644 src/plugins/wp/tests/wp_acsl/oracle_qualif/post_result.0.session/cache/aeba54fcd5bc6c917c8d92eb80efed6d.json create mode 100644 src/plugins/wp/tests/wp_acsl/oracle_qualif/reads.0.session/cache/0cbdd126867b26cc1e3fc3a5b279bb0d.json create mode 100644 src/plugins/wp/tests/wp_acsl/oracle_qualif/reads.0.session/cache/cd6211b4ab473cbfa4d355d0a774ef99.json create mode 100644 src/plugins/wp/tests/wp_acsl/oracle_qualif/simpl_is_type.0.session/cache/07b7a43b195fb4f33dd51c9d6bd273d4.json create mode 100644 src/plugins/wp/tests/wp_acsl/oracle_qualif/simpl_is_type.0.session/cache/22ae78621c875b3d3cafc538d7eb7ff4.json create mode 100644 src/plugins/wp/tests/wp_acsl/oracle_qualif/simpl_is_type.0.session/cache/2be784ca088c5e1a38cbb9ef0222a259.json create mode 100644 src/plugins/wp/tests/wp_acsl/oracle_qualif/simpl_is_type.0.session/cache/54f4913abf23075ad98087f17fc620ee.json create mode 100644 src/plugins/wp/tests/wp_acsl/oracle_qualif/simpl_is_type.0.session/cache/72b24ef7daf0640c07d9fffa1961d184.json create mode 100644 src/plugins/wp/tests/wp_acsl/oracle_qualif/simpl_is_type.0.session/cache/8445d12d440f5e77ee1f7f848cc15b68.json create mode 100644 src/plugins/wp/tests/wp_acsl/oracle_qualif/simpl_is_type.0.session/cache/8fb3eea396680aa56e7f96b68ebc2245.json create mode 100644 src/plugins/wp/tests/wp_acsl/oracle_qualif/simpl_is_type.0.session/cache/b583dc30d2074490b3fe0ec73cde2dba.json create mode 100644 src/plugins/wp/tests/wp_acsl/oracle_qualif/simpl_is_type.0.session/cache/ea5ad50dafc3e3b81b14b672b31faf00.json create mode 100644 src/plugins/wp/tests/wp_bts/oracle_qualif/bts779.0.session/cache/39afa23189acb8a1b45f730656f3293d.json create mode 100644 src/plugins/wp/tests/wp_bts/oracle_qualif/bts779.0.session/cache/b020d8fbac2c1f5a2bb5eff45748c8a2.json create mode 100644 src/plugins/wp/tests/wp_bts/oracle_qualif/bts986.0.session/cache/d9121cbf1bf929d8a33ed73cdc206552.json create mode 100644 src/plugins/wp/tests/wp_bts/oracle_qualif/bts_1360.0.session/cache/baf52c3966dd21bbba0c7a9c81245af2.json create mode 100644 src/plugins/wp/tests/wp_bts/oracle_qualif/bts_1360.0.session/cache/e832de44187e0b48e1388bf9d9475713.json create mode 100644 src/plugins/wp/tests/wp_bts/oracle_qualif/bts_1601.0.session/cache/75f6139d28d2176c962de1fda927c848.json create mode 100644 src/plugins/wp/tests/wp_bts/oracle_qualif/bts_1828.0.session/cache/420e102e36b2fd0c60d608072d4bbb2b.json create mode 100644 src/plugins/wp/tests/wp_bts/oracle_qualif/bts_1828.0.session/cache/e875e59da9e2107108c67c5c5e48fac1.json create mode 100644 src/plugins/wp/tests/wp_bts/oracle_qualif/bts_1828.0.session/cache/ffed0f9e761b9b65d16681ee125d45de.json create mode 100644 src/plugins/wp/tests/wp_bts/oracle_qualif/bts_1828.1.session/cache/e875e59da9e2107108c67c5c5e48fac1.json create mode 100644 src/plugins/wp/tests/wp_bts/oracle_qualif/issue-364.0.session/cache/2065ac6b91a5b85360f219bf4cb61e6f.json create mode 100644 src/plugins/wp/tests/wp_bts/oracle_qualif/issue-364.0.session/cache/834bd396ea03675670f1d7506bf20204.json create mode 100644 src/plugins/wp/tests/wp_bts/oracle_qualif/issue_494.0.session/cache/23393517d8e9a6945aaf5f8c70de67fd.json create mode 100644 src/plugins/wp/tests/wp_bts/oracle_qualif/issue_508.0.session/cache/1025ed1b7e69c8126064452d7cfa2035.json create mode 100644 src/plugins/wp/tests/wp_bts/oracle_qualif/issue_715_b.0.session/cache/9bd0456062678ca3e8613d336cf8a543.json create mode 100644 src/plugins/wp/tests/wp_bts/oracle_qualif/issue_751.0.session/cache/b02c74702da73481b452499d0feb4af7.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/find.0.session/cache/10e70a38e2154839eaae1f1af07fdefc.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/find.0.session/cache/135f708793f6fbdc42f4f9d1d1a915c3.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/find.0.session/cache/196d356f0ee751ff8133066d78d7929c.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/find.0.session/cache/19d9f4b1d3439b94533a38f9eb1a9457.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/find.0.session/cache/1a1c741b4fc7ec6915e77dfd6219af40.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/find.0.session/cache/1cdcca3d343f4d3666de43999a2859ca.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/find.0.session/cache/1eca7fb782936ff88f49a91e6dcd344c.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/find.0.session/cache/1f176d5e2b1db0d6e22c16c743220569.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/find.0.session/cache/2a7b0348cb3cbb4fcbfad39cfd486e74.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/find.0.session/cache/3505ecb809a014f95037869b0e9856e2.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/find.0.session/cache/3c7a12cba6964122ac5a406e963e0bac.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/find.0.session/cache/42a0fc36bd9559b12c9d5c9ca7e6e427.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/find.0.session/cache/493aed7b8f27b8c3737d5175c5888710.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/find.0.session/cache/5610a35160a9c2fa66735e0a84235057.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/find.0.session/cache/5b41f41e7e6bfe1b5f2a7e510adfcc40.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/find.0.session/cache/68bff29417d8a9a908b65a5cdcb559a8.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/find.0.session/cache/72222d01b03c631765b96be604890d30.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/find.0.session/cache/7c34d2375d6a48a8a2126c8574daacfd.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/find.0.session/cache/7dd61d8b30a0d3a1046e8cd99ddf1261.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/find.0.session/cache/84634dd1a45d865c6efeca0f4ab49056.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/find.0.session/cache/8496a6c0c66a6097c0cc03d173f00c85.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/find.0.session/cache/91c9d1dc4216af4315c0cc5b197aa492.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/find.0.session/cache/a37053af97bb1db4be167ff7423d4db8.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/find.0.session/cache/a97aa29b9f62010d94b1cbab03e4674f.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/find.0.session/cache/b3f4583c783aed5095d5f9366f0c583b.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/find.0.session/cache/bf04376f6c833a40b4eef1681e1b30f1.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/find.0.session/cache/e1499a3b76fe2f4b3db4526b4115ff49.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/find.0.session/cache/f6df7d034c012e8f2ce7865d478879d5.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo1_solved.0.session/cache/09bf4ce202d8fe39b4526829cb133533.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo1_solved.0.session/cache/12c217a27c7139d5f30742273bb085d0.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo1_solved.0.session/cache/14128ab2ffe87237e86d3203305033e7.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo1_solved.0.session/cache/1b66f8317c14095c081f7afd5b594741.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo1_solved.0.session/cache/40b6423d8ddcdc8d72f113ee27b56d23.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo1_solved.0.session/cache/415e18fe08911875e6c12f7bad3309c4.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo1_solved.0.session/cache/7622228a2ace3b4ea6973fb817034fe1.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo1_solved.0.session/cache/7841f539527a85329546eb99578ee528.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo1_solved.0.session/cache/f546de791b323fbc7cd8207ceb72043b.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo2_solved.0.session/cache/0446f6215cc2b5ece0a84642b8a23227.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo2_solved.0.session/cache/1ae181b24023bef5693b9686ebcfebc5.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo2_solved.0.session/cache/264a621e237c98dca54cad8896fc45f1.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo2_solved.0.session/cache/3ce33a0a8dd65193f55247eca68d0add.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo2_solved.0.session/cache/5ffb302fc24b5d55cfba13e1b133442e.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo2_solved.0.session/cache/646c4849b1b86e71a02ed6b4e22a5e5a.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo2_solved.0.session/cache/8328e1c16a7f7be1c88cb684053fd185.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo2_solved.0.session/cache/839040132fbcfc4d3618a0fd1ed7c357.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo2_solved.0.session/cache/93059dee8bcf5e3a31af3752b3b47c07.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo2_solved.0.session/cache/944a7d63361ee9d7e563e26d0a674bee.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo2_solved.0.session/cache/a6b4cc7471adb5a2d0e53268d885e407.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo2_solved.0.session/cache/d0e0a407fb1103313547ae958851d341.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo2_solved.0.session/cache/f2fc829e259a63aa018c8f5cf2ad51c0.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.0.session/cache/0126fde627766c5e80152d3092ba2aee.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.0.session/cache/0818d1c09010d257ad8c6815571d99c3.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.0.session/cache/102640ec6d1d7a8943086db5f48bebc0.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.0.session/cache/1241313db0937a5391841138a16626ef.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.0.session/cache/1722ca0d2e1d91ed7b209013be7aea8f.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.0.session/cache/4b25798e4a62bf641694ca833c687e01.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.0.session/cache/51a0fccaa9c5a1f25e08d0458ea80328.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.0.session/cache/55e7e2a928f55171c0e6181cae34c889.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.0.session/cache/5c661be4ce7386b877644ffa77d309d7.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.0.session/cache/61afefe4a097e7a7c785f3f4711f0081.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.0.session/cache/682f9aad475f771ccd7cdc3bf7f9c96a.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.0.session/cache/6ae4f6e0ab89bc7fc2e2cf55211c6247.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.0.session/cache/6f4fec2bff531d88deff253886a30de4.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.0.session/cache/94cad0bd9e2c593f0562adbf518c46e5.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.0.session/cache/a3d422cc76ed132eeee720e81a464390.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.0.session/cache/b1283c4ee81ea5f47112cda8ecef4271.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.0.session/cache/c20b5a7aa139ba61a8805faf4dae831d.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.0.session/cache/c849712dfd490b5807a8ff59bc39dc34.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.0.session/cache/d3420889a7d9c7949b2d1f7715ad1591.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.0.session/cache/d3ecbb7211cf7ee8fa1710e0d6276a98.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.0.session/cache/e7910d533bc9cd3f26f0a2db15a2628f.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.v2.0.session/cache/1da20b026e23dace33f59b4fe30cf704.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.v2.0.session/cache/26477daefc637e3827acaa7cf7867619.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.v2.0.session/cache/2e634a920437c83054eec1a07f763cd9.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.v2.0.session/cache/386154e29073d9acf9fbbc284ccff087.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.v2.0.session/cache/3be45a6c1d0da2f96f8c1e424a7ab67a.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.v2.0.session/cache/3f218707b6712edd9bd1d69daa728c14.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.v2.0.session/cache/4dab6dd8ae580689cfd0d1ba4875ec2d.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.v2.0.session/cache/4dd3ca5f4c88877a589aae7858e95d76.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.v2.0.session/cache/5502d8c13d4b19675da7ec1d6fde0e81.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.v2.0.session/cache/57a1707949cda96266d7a170ab0db4ed.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.v2.0.session/cache/597c3ce8a628b364884f7aae153eb0f7.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.v2.0.session/cache/69aed695592a136372272f0976cb7cb0.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.v2.0.session/cache/6d31b5b9261d0201d9d5d613d393fca5.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.v2.0.session/cache/70261faccb832e91f3b93fc06ab58117.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.v2.0.session/cache/76671ff5da324cf7df7b1795b2b206e2.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.v2.0.session/cache/82652d462ec64309a7df17f1c5d545e1.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.v2.0.session/cache/a7fffe44ad3c1effe6026e43591942ce.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.v2.0.session/cache/a8a8445ca94c28d23a1a736558e69c8c.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.v2.0.session/cache/b5e466768f27e36ace65e700da4c6762.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.v2.0.session/cache/b6b84b8aa7e49ae4e58e874d380e52ec.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.v2.0.session/cache/c0517fb8e7353916d3a8af59a55cfe96.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.v2.0.session/cache/f3c1620b867b46248a65cace35447c1f.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.v2.0.session/cache/f7589a89ccb1575e24730fc330fcf0d0.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.simplified.0.session/cache/0d38200a674100ddfe7feec44eb47f95.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.simplified.0.session/cache/146ba3796f4ee4106a5e8667bd7c3f50.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.simplified.0.session/cache/1c7541e16fa613b0a976bfc393da96ed.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.simplified.0.session/cache/1d98ee567fabc1936f14d72a0a2a19e6.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.simplified.0.session/cache/20c6bfbc4023e7a48004f3a7eb2ad3e5.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.simplified.0.session/cache/34b5e8da6fcfd4368079c11b0279db8f.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.simplified.0.session/cache/45db19c6faa1857dc87eb5a34ce27371.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.simplified.0.session/cache/56a7807ae39f0ecb4e627be901632939.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.simplified.0.session/cache/90300cb727c65d761a7f041a9b946827.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.simplified.0.session/cache/93fc40b2b5154a19653646b42b6c2df6.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.simplified.0.session/cache/951e03065266dffb0914d1775c1ad10c.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.simplified.0.session/cache/b4b46240c49a9f0ef2530dea215e1919.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.simplified.0.session/cache/c5d6eefd823963da7ca16544bc3f3912.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.simplified.0.session/cache/f17c3d079b701186ae67cf3c2a6a0277.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.simplified.0.session/cache/fb2a96c00753836cd4d75f4c8ebfd06f.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/059ee2fae3aa0fd30ca23f0159275ef3.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/07832109afbac0e38eb5d87932066e08.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/088564331bfc8b3af317aacddb4ccbea.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/08e74ef80a419837ad146845c97f173b.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/0c31169754f2628df2aefb14cc504990.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/0ec7f155931ed9e99efae24fd0898491.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/0f76081bfd4cb878c7ac624b1e0677ec.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/113dabb6f94d8c3225236c434a5d13a7.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/178e24799cae3dcec5f3257226b96a20.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/1b75b91371009810dc97ffa389bb5531.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/1da5cd2893da7c1322294978850c6fd3.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/1f482c6de3c7a19cda334e37d01fe177.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/2d2277efecc9ac0135f43533fb7fd64e.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/2d5464d4e8192a657d37126dca5910da.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/2ddd3e6ac842e9117c49c9ddaf740411.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/2e3c2cb35cef3cb6057febf0bdf10744.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/37377966b3e186a9febaac6df135d3e9.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/45124138476e1855a6f35cf90a0f7385.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/50c141eec33504c5c1bed095ab2c1934.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/5aa93b7609826cef11995c6f79edc54c.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/634fb439c79d4b2df9278efe8f97f1a2.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/6356a66f92291eedbf596c86247cdf40.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/66d43256948fe0b03dc360a4a2654dfb.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/69483893c71ff4f7f440dddd3e21f386.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/6c00a117f0e575dde2c838780b6a2b5f.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/6f907d24a6c6d51475fbbba7851998d4.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/737d7d224b95933e11e8630b0d5e1e67.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/744202b8726995ad41adcfd26dbd3977.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/784037581ab4f838952f762dd078ccd2.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/7b20ca91596a368e107ee308c5abb683.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/7e28eb621b6c70199ef921ecc2b766f9.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/82d303e4f3b78e54f806a99c19a64876.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/8421490fd39132bfdfa1fa54817bc682.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/85c2351bf7a38814cb9a0a47ea6c2ea7.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/865e884b2f3e33610e0aa609d35c6f09.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/88bebb3c661a1f33578350b8200b7c25.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/8a7b631f75a3073c3262178ccfedd3e7.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/8aafa7388f31a7314c199713ca0ae084.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/8e942fe174bf1f62bb36a5abab4deb26.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/92d2d156fb93ee5c5f2d3f2faa4c4275.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/9c97f1cddb0b9fcf61a6d1caddc3e897.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/9cab00be1ec378b961d688830f12c8b5.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/a2374beb942675808f3c1588a5f13a68.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/ae94fd34b628e3925ec2951d2ed0d153.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/b0969ad7ecf31664172fda8b609f8917.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/b57d3798758c77258d386ffb51fb4324.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/bd76bf896c68ddef8cbba6f20100fac8.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/be1d9ed1ba49360aaa18b8d4b577c56f.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/c57fbc674ee49672402990996b38e761.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/ca5e36cff267d97e2595ae3f8187bcdd.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/cd48e56312a247d0852ac3ca63754265.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/d39b5b1c24cd1c7d131652c2ca1dd878.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/d4b82b17f751426ee45e116de56f70bb.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/d51e6faa5980c6069ff809306e33fe61.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/e8bad62a574dfb263cbb0424c1f994cc.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/e997b52aca1d60592f0c918574d95bca.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/eec066c7871c347d05d218448003bb42.json create mode 100644 src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/fa144aad657dae3418db4f22e288c17e.json create mode 100644 src/plugins/wp/tests/wp_hoare/oracle_qualif/byref.0.session/cache/56b7eefc17044e0ff95c99434cf88399.json create mode 100644 src/plugins/wp/tests/wp_hoare/oracle_qualif/logicarr.0.session/cache/852210deac5464ecf4c672c0f6c67fb7.json create mode 100644 src/plugins/wp/tests/wp_hoare/oracle_qualif/logicarr.0.session/cache/aa862239bf067f3148dc841ef36e7c1a.json create mode 100644 src/plugins/wp/tests/wp_hoare/oracle_qualif/logicarr.0.session/cache/d85b1504de7e92963b9c333e4ba02d6f.json create mode 100644 src/plugins/wp/tests/wp_hoare/oracle_qualif/logicref.0.session/cache/6dd7fce5505a14bc287568321ce0111b.json create mode 100644 src/plugins/wp/tests/wp_hoare/oracle_qualif/logicref_simple.0.session/cache/2eb20108bba00807202ca8ddffbe9321.json create mode 100644 src/plugins/wp/tests/wp_hoare/oracle_qualif/logicref_simple.0.session/cache/84e7fceb770bfa7d815f522cfce14408.json create mode 100644 src/plugins/wp/tests/wp_hoare/oracle_qualif/logicref_simple.0.session/cache/8773bd69d274eceb0acf3767f4ae9575.json create mode 100644 src/plugins/wp/tests/wp_hoare/oracle_qualif/logicref_simple.0.session/cache/8d2421a35a8365649870fd7b2f8a1222.json create mode 100644 src/plugins/wp/tests/wp_hoare/oracle_qualif/reference_and_struct.0.session/cache/a514c4e0dbce3a19cb575797578db2ee.json create mode 100644 src/plugins/wp/tests/wp_hoare/oracle_qualif/reference_array.0.session/cache/1055ecf60b0251e2ce8a583866b59b5d.json create mode 100644 src/plugins/wp/tests/wp_hoare/oracle_qualif/reference_array.0.session/cache/3ad89ca7d6079981ace01e3d25910e63.json create mode 100644 src/plugins/wp/tests/wp_hoare/oracle_qualif/reference_array.0.session/cache/5518bc5769e51a2ec423d55457d4323c.json create mode 100644 src/plugins/wp/tests/wp_hoare/oracle_qualif/refguards.0.session/cache/5c4bdf85b0130c246990c9addb9d2556.json create mode 100644 src/plugins/wp/tests/wp_hoare/oracle_qualif/refguards.0.session/cache/aeb63d64f83c4e31d79d7e8e869de07e.json create mode 100644 src/plugins/wp/tests/wp_manual/oracle_qualif/manual.0.session/cache/1aa29de269f2b73adeae713ac86acec7.json create mode 100644 src/plugins/wp/tests/wp_manual/oracle_qualif/manual.1.session/cache/762ba8fbb24bdd2a875e3ac97bcdb1a0.json create mode 100644 src/plugins/wp/tests/wp_manual/oracle_qualif/manual.1.session/cache/b280eb527d15c1796693db544778a327.json create mode 100644 src/plugins/wp/tests/wp_manual/oracle_qualif/manual.1.session/cache/f55cc495403a5870a0396a5e15c05b4d.json create mode 100644 src/plugins/wp/tests/wp_manual/oracle_qualif/manual.2.session/cache/762ba8fbb24bdd2a875e3ac97bcdb1a0.json create mode 100644 src/plugins/wp/tests/wp_manual/oracle_qualif/manual.2.session/cache/b280eb527d15c1796693db544778a327.json create mode 100644 src/plugins/wp/tests/wp_manual/oracle_qualif/manual.2.session/cache/f55cc495403a5870a0396a5e15c05b4d.json create mode 100644 src/plugins/wp/tests/wp_plugin/oracle_qualif/copy.0.session/cache/05e5c5311bfe8997e3278f3e5c22829a.json create mode 100644 src/plugins/wp/tests/wp_plugin/oracle_qualif/copy.0.session/cache/074cb03898e8ed122caa93327a7b7a77.json create mode 100644 src/plugins/wp/tests/wp_plugin/oracle_qualif/copy.0.session/cache/58369c7fb3048b416fdd3fc5458c5b83.json create mode 100644 src/plugins/wp/tests/wp_plugin/oracle_qualif/copy.0.session/cache/65e3ef4a8586c488db122d88f499b0d9.json create mode 100644 src/plugins/wp/tests/wp_plugin/oracle_qualif/copy.0.session/cache/9df2b33683d9824243472af4e8d5c5f7.json create mode 100644 src/plugins/wp/tests/wp_plugin/oracle_qualif/copy.0.session/cache/d52a4f7a87fca3c71ec617296f285903.json create mode 100644 src/plugins/wp/tests/wp_plugin/oracle_qualif/dynamic.0.session/cache/7c61992a1e5557d753841a5f66eef4ae.json create mode 100644 src/plugins/wp/tests/wp_plugin/oracle_qualif/dynamic.0.session/cache/dd5c27a7c1200d3431d2c30bf2899942.json create mode 100644 src/plugins/wp/tests/wp_plugin/oracle_qualif/dynamic.0.session/cache/e2e624a33e02433818d9a93dc4b967fb.json create mode 100644 src/plugins/wp/tests/wp_plugin/oracle_qualif/dynamic.0.session/cache/f8e79502a4545e9f174c055480b11bad.json create mode 100644 src/plugins/wp/tests/wp_plugin/oracle_qualif/flash.0.session/cache/62c8c83348d53abd331942b7638c0e65.json create mode 100644 src/plugins/wp/tests/wp_plugin/oracle_qualif/flash.0.session/cache/ad24c8fdc842200098097f4c5b243a1b.json create mode 100644 src/plugins/wp/tests/wp_plugin/oracle_qualif/flash.0.session/cache/d57a0b96fe98d0e1d1578d06300ae6af.json create mode 100644 src/plugins/wp/tests/wp_plugin/oracle_qualif/flash.0.session/cache/e98f4a09d201fc4ff4b2c17441acaa8d.json create mode 100644 src/plugins/wp/tests/wp_plugin/oracle_qualif/flash.0.session/cache/fb1ff75dc8c936a96751f5ffdde36e50.json create mode 100644 src/plugins/wp/tests/wp_plugin/oracle_qualif/flash.1.session/cache/354efda647c2b52e3acf13bee479341a.json create mode 100644 src/plugins/wp/tests/wp_plugin/oracle_qualif/flash.1.session/cache/5a90230e76db08ca4977aaefa5af6afc.json create mode 100644 src/plugins/wp/tests/wp_plugin/oracle_qualif/flash.1.session/cache/687c6ba705dc05a8d976db9c98dbc1b7.json create mode 100644 src/plugins/wp/tests/wp_plugin/oracle_qualif/flash.1.session/cache/6d33d3e9e0c138689b7b7b81af41c61b.json create mode 100644 src/plugins/wp/tests/wp_plugin/oracle_qualif/flash.1.session/cache/d1203dcf4cb1b7eb56cc98aaeee8d670.json create mode 100644 src/plugins/wp/tests/wp_plugin/oracle_qualif/float_format.2.session/cache/7c52f41beefbdb46d7a18dde9bbf2bf8.json create mode 100644 src/plugins/wp/tests/wp_plugin/oracle_qualif/float_real.1.session/cache/6c499bc384463731f06e46d71bc8ca72.json create mode 100644 src/plugins/wp/tests/wp_plugin/oracle_qualif/frame.0.session/cache/b475650b9898e2e1a3a99a196f007c1d.json create mode 100644 src/plugins/wp/tests/wp_plugin/oracle_qualif/frame.0.session/cache/c226acb64e8c66b0e8ce990e608b7583.json create mode 100644 src/plugins/wp/tests/wp_plugin/oracle_qualif/init_const_guard.0.session/cache/22137e3a0e8bb8e5c6f558c96a8b0584.json create mode 100644 src/plugins/wp/tests/wp_plugin/oracle_qualif/init_const_guard.0.session/cache/3aa6fff5b9a5f4e04964329dadd25933.json create mode 100644 src/plugins/wp/tests/wp_plugin/oracle_qualif/init_const_guard.0.session/cache/eb1a359dc7730155217ac94756d7dffa.json create mode 100644 src/plugins/wp/tests/wp_plugin/oracle_qualif/initarr.0.session/cache/25c9ec98fb41e974a3fac1a61d027acc.json create mode 100644 src/plugins/wp/tests/wp_plugin/oracle_qualif/initarr.0.session/cache/42ee58e19309bd5df73821e3cfd04518.json create mode 100644 src/plugins/wp/tests/wp_plugin/oracle_qualif/loop.0.session/cache/185d1270b8988dc69c4d7d49e40360fe.json create mode 100644 src/plugins/wp/tests/wp_plugin/oracle_qualif/loop.0.session/cache/6094e7c19eba3f50fb8b90f9528226e9.json create mode 100644 src/plugins/wp/tests/wp_plugin/oracle_qualif/loop.0.session/cache/67237129e97d7ae8d5ff4b62d632af5c.json create mode 100644 src/plugins/wp/tests/wp_plugin/oracle_qualif/loop.0.session/cache/d9a9c67c0ce931a0559a5db9f619abd9.json create mode 100644 src/plugins/wp/tests/wp_plugin/oracle_qualif/loop.0.session/cache/ed73ec0948ff5ae6b53fce8a8adada7a.json create mode 100644 src/plugins/wp/tests/wp_plugin/oracle_qualif/loop.0.session/cache/fa725e97995b55101c0cf42a29c0f813.json create mode 100644 src/plugins/wp/tests/wp_plugin/oracle_qualif/overassign.0.session/cache/32e4d5d1ffef8a7dbb1fe8c7d536f845.json create mode 100644 src/plugins/wp/tests/wp_plugin/oracle_qualif/overassign.0.session/cache/3e0d119a220c45bb16b0d7612fae4738.json create mode 100644 src/plugins/wp/tests/wp_plugin/oracle_qualif/overassign.0.session/cache/725d46c74277558f772438a95d5ffa30.json create mode 100644 src/plugins/wp/tests/wp_plugin/oracle_qualif/overassign.0.session/cache/fff4cb231748d3746212595b0892b5f9.json create mode 100644 src/plugins/wp/tests/wp_plugin/oracle_qualif/prenex.0.session/cache/46c7ee5a8694d5a20e47282f25e34be5.json create mode 100644 src/plugins/wp/tests/wp_plugin/oracle_qualif/prenex.0.session/cache/8051f3e6d0df90db81f77cee4ad63859.json create mode 100644 src/plugins/wp/tests/wp_plugin/oracle_qualif/prenex.0.session/cache/8091b9c0849f4d1a46e4879e5348fdb0.json create mode 100644 src/plugins/wp/tests/wp_plugin/oracle_qualif/prenex.0.session/cache/8b223534ba1fa0aa7e4ef5bd8ff12d15.json create mode 100644 src/plugins/wp/tests/wp_plugin/oracle_qualif/prenex.0.session/cache/9e537d84dc915243e941b46128dbd193.json create mode 100644 src/plugins/wp/tests/wp_plugin/oracle_qualif/rte.0.session/cache/23ff27cd5de1ace498e0001fd798be43.json create mode 100644 src/plugins/wp/tests/wp_plugin/oracle_qualif/rte.0.session/cache/3de2cb0c1d0276cbaa7600ff25e6f29a.json create mode 100644 src/plugins/wp/tests/wp_plugin/oracle_qualif/rte.0.session/cache/56b7eefc17044e0ff95c99434cf88399.json create mode 100644 src/plugins/wp/tests/wp_plugin/oracle_qualif/rte.0.session/cache/f978123c614da8cddf33e186f24f3e67.json create mode 100644 src/plugins/wp/tests/wp_plugin/oracle_qualif/string_c.0.session/cache/33446f0a42119240b0b63f1a2c0bc6ff.json create mode 100644 src/plugins/wp/tests/wp_plugin/oracle_qualif/string_c.0.session/cache/3480784fd33fa9f4cae3b169a359cc57.json create mode 100644 src/plugins/wp/tests/wp_plugin/oracle_qualif/string_c.0.session/cache/4bc35b1105da43dc265e953cbf96035d.json create mode 100644 src/plugins/wp/tests/wp_plugin/oracle_qualif/string_c.0.session/cache/607e1a10e4ccbf9b5505703cb2087df7.json create mode 100644 src/plugins/wp/tests/wp_plugin/oracle_qualif/string_c.0.session/cache/7d870ce9aa419a3893c0d18e3e2904f5.json create mode 100644 src/plugins/wp/tests/wp_plugin/oracle_qualif/string_c.0.session/cache/7d91bcc945d933f5af6e1e468ae4ecf4.json create mode 100644 src/plugins/wp/tests/wp_plugin/oracle_qualif/string_c.0.session/cache/8101aefca2eee2b8fb6cc34749c9891f.json create mode 100644 src/plugins/wp/tests/wp_plugin/oracle_qualif/string_c.0.session/cache/9628de01f82e8d57abe1ca40a3145921.json create mode 100644 src/plugins/wp/tests/wp_plugin/oracle_qualif/string_c.0.session/cache/98d61fd3dc609926e2d9ed8d866b0ca3.json create mode 100644 src/plugins/wp/tests/wp_plugin/oracle_qualif/string_c.0.session/cache/ace2089a7d9190f715a07093a9276e98.json create mode 100644 src/plugins/wp/tests/wp_plugin/oracle_qualif/string_c.0.session/cache/bfef8898939d13a4a34f0035d4718cf6.json create mode 100644 src/plugins/wp/tests/wp_plugin/oracle_qualif/string_c.0.session/cache/c78ab4c23e92b597edada513514da04c.json create mode 100644 src/plugins/wp/tests/wp_plugin/oracle_qualif/string_c.0.session/cache/ca73637f01f2f91a0068347eeb9ec94c.json create mode 100644 src/plugins/wp/tests/wp_plugin/oracle_qualif/string_c.0.session/cache/cf51ece0b093233bb0adb1181e349246.json create mode 100644 src/plugins/wp/tests/wp_plugin/oracle_qualif/string_c.0.session/cache/d46d0acf6fd632f8f6119d14bca4ce6a.json create mode 100644 src/plugins/wp/tests/wp_plugin/oracle_qualif/string_c.0.session/cache/d765de4fb3d29a70866cbf36f4fab698.json create mode 100644 src/plugins/wp/tests/wp_plugin/oracle_qualif/string_c.0.session/cache/e76eb6cb77a00f788ce64e76f562810b.json create mode 100644 src/plugins/wp/tests/wp_plugin/oracle_qualif/string_c.0.session/cache/ebb2a53efc61a99e868bcaeccdedd60d.json create mode 100644 src/plugins/wp/tests/wp_plugin/oracle_qualif/string_c.0.session/cache/ef5c696900a376aef83fb21941139a3c.json create mode 100644 src/plugins/wp/tests/wp_plugin/oracle_qualif/string_c.0.session/cache/efd16d0abd5a1c7656466cad2eff1a82.json create mode 100644 src/plugins/wp/tests/wp_plugin/oracle_qualif/string_c.0.session/cache/f24b0ea52a766197c49733f5567e5290.json create mode 100644 src/plugins/wp/tests/wp_plugin/oracle_qualif/struct_hack.0.session/cache/3c2808a40bb021dbc99953e3c5324934.json create mode 100644 src/plugins/wp/tests/wp_plugin/oracle_qualif/struct_hack.0.session/cache/49a728ea0e221f941984978faa18dc8b.json create mode 100644 src/plugins/wp/tests/wp_plugin/oracle_qualif/subset.0.session/cache/f11323e3ba20fea4dc00b0c0a4e8c75a.json create mode 100644 src/plugins/wp/tests/wp_plugin/oracle_qualif/subset_fopen.0.session/cache/bbd1bf207aff73a0add5c310a10d82fc.json create mode 100644 src/plugins/wp/tests/wp_plugin/oracle_qualif/unsafe-arrays.0.session/cache/d3af917ba88b4651ecd99c4782829b8d.json create mode 100644 src/plugins/wp/tests/wp_store/oracle_qualif/nonaliasing.0.session/cache/8824303ce7307ea0a6607b5ed4deb0ae.json create mode 100644 src/plugins/wp/tests/wp_store/oracle_qualif/nonaliasing.0.session/cache/974d21e0e97775d1697fc217acf09aae.json create mode 100644 src/plugins/wp/tests/wp_store/oracle_qualif/nonaliasing.1.session/cache/054ac21eccbda5823e3b61d57b70fa6e.json create mode 100644 src/plugins/wp/tests/wp_store/oracle_qualif/nonaliasing.1.session/cache/6f3bf79ad4f2c16243f68e50736057b2.json create mode 100644 src/plugins/wp/tests/wp_store/oracle_qualif/struct.0.session/cache/94a853062337d3984c131f4b925cf498.json create mode 100644 src/plugins/wp/tests/wp_store/oracle_qualif/struct.0.session/cache/ca8f374f313f9efd2a66850f6ce238ac.json create mode 100644 src/plugins/wp/tests/wp_typed/oracle_qualif/array_initialized.0.session/cache/54640927ace915eaf531f7d99162bff2.json create mode 100644 src/plugins/wp/tests/wp_typed/oracle_qualif/array_initialized.0.session/cache/cbef7a2678ffbb62f89898239a2300cf.json create mode 100644 src/plugins/wp/tests/wp_typed/oracle_qualif/array_initialized.1.session/cache/aa1fad5015602138db9f12fbfce39c6a.json create mode 100644 src/plugins/wp/tests/wp_typed/oracle_qualif/array_initialized.1.session/cache/c0a758625fc5806b2d004ce066f809f1.json create mode 100644 src/plugins/wp/tests/wp_typed/oracle_qualif/array_initialized.1.session/cache/cbef7a2678ffbb62f89898239a2300cf.json create mode 100644 src/plugins/wp/tests/wp_typed/oracle_qualif/array_initialized.1.session/cache/edcf65b50fa78c78cddb184cdd54ed56.json create mode 100644 src/plugins/wp/tests/wp_typed/oracle_qualif/cast_fits.0.session/cache/275f36697bf837a8e650d76b262a2972.json create mode 100644 src/plugins/wp/tests/wp_typed/oracle_qualif/cast_fits.0.session/cache/2d49dd2aa47e49570e397cc771e23a05.json create mode 100644 src/plugins/wp/tests/wp_typed/oracle_qualif/cast_fits.0.session/cache/47de988037a45f7d6177eadd7d8a885f.json create mode 100644 src/plugins/wp/tests/wp_typed/oracle_qualif/cast_fits.0.session/cache/69c6adb0d354ab9716344b82e02e28da.json create mode 100644 src/plugins/wp/tests/wp_typed/oracle_qualif/cast_fits.0.session/cache/aab17c8e0ce454a4c0284ffae858edf6.json create mode 100644 src/plugins/wp/tests/wp_typed/oracle_qualif/cast_fits.0.session/cache/bbe62e3cff4dcf2d16418512a09cc682.json create mode 100644 src/plugins/wp/tests/wp_typed/oracle_qualif/cast_fits.0.session/cache/cfd3a385e095a454ca4b030e22ce34d3.json create mode 100644 src/plugins/wp/tests/wp_typed/oracle_qualif/frame.0.session/cache/1c8e1bc5a936e2c520c323bce7927b1f.json create mode 100644 src/plugins/wp/tests/wp_typed/oracle_qualif/frame.0.session/cache/2de2447a32b00f58b6bf40b3b90caf3a.json create mode 100644 src/plugins/wp/tests/wp_typed/oracle_qualif/shift_lemma.0.session/cache/02a5967e29d215a319e5d52aeea6ee2b.json create mode 100644 src/plugins/wp/tests/wp_typed/oracle_qualif/shift_lemma.0.session/cache/578bba9c847de51c178d0337644fd81e.json create mode 100644 src/plugins/wp/tests/wp_typed/oracle_qualif/shift_lemma.0.session/cache/7882f8daf0f62dd319b068a984bce5ae.json create mode 100644 src/plugins/wp/tests/wp_typed/oracle_qualif/unit_alloc.0.session/cache/51f562f110aa57a99fb537f2987e09da.json create mode 100644 src/plugins/wp/tests/wp_typed/oracle_qualif/unit_alloc.0.session/cache/9ec67e1127d3b8a1f5e26915449443c8.json create mode 100644 src/plugins/wp/tests/wp_typed/oracle_qualif/unit_alloc.0.session/cache/caf3de3711d3f3c15ff182a47b1a66e9.json create mode 100644 src/plugins/wp/tests/wp_typed/oracle_qualif/unit_alloc.1.session/cache/51f562f110aa57a99fb537f2987e09da.json create mode 100644 src/plugins/wp/tests/wp_typed/oracle_qualif/unit_alloc.1.session/cache/9ec67e1127d3b8a1f5e26915449443c8.json create mode 100644 src/plugins/wp/tests/wp_typed/oracle_qualif/unit_alloc.1.session/cache/caf3de3711d3f3c15ff182a47b1a66e9.json create mode 100644 src/plugins/wp/tests/wp_typed/oracle_qualif/unit_cast.0.session/cache/5725debb61cac997c8aec1f3b0b2205f.json create mode 100644 src/plugins/wp/tests/wp_typed/oracle_qualif/unit_hard.0.session/cache/bb2b7123541670aa64836bfff3d66a26.json create mode 100644 src/plugins/wp/tests/wp_typed/oracle_qualif/unit_labels.0.session/cache/48610aa4f300718739c914fc0b7c1f64.json create mode 100644 src/plugins/wp/tests/wp_typed/oracle_qualif/unit_labels.0.session/cache/cc6ee1d50b7c0fd64c3271bbc98f9c13.json create mode 100644 src/plugins/wp/tests/wp_typed/oracle_qualif/unit_labels.0.session/cache/ff456f15865e6d8f50db8ac0e7f19ea4.json create mode 100644 src/plugins/wp/tests/wp_typed/oracle_qualif/unit_local.0.session/cache/5be9158693acc77d4d2e554e52149918.json create mode 100644 src/plugins/wp/tests/wp_typed/oracle_qualif/unit_local.1.session/cache/974fb23dac4868107d647875f95df135.json create mode 100644 src/plugins/wp/tests/wp_typed/oracle_qualif/unit_local.1.session/cache/c16ea120b56be33a00dc52be23af6d68.json create mode 100644 src/plugins/wp/tests/wp_typed/oracle_qualif/unit_local.1.session/cache/ff88885f0f8ec902940c70c9b19e68bf.json create mode 100644 src/plugins/wp/tests/wp_typed/oracle_qualif/unit_loopscope.0.session/cache/420e102e36b2fd0c60d608072d4bbb2b.json create mode 100644 src/plugins/wp/tests/wp_typed/oracle_qualif/unit_string.0.session/cache/06be40162d4388f79dad2e8636a6cc2a.json create mode 100644 src/plugins/wp/tests/wp_typed/oracle_qualif/unit_string.0.session/cache/51299c47004a944cc0cab6fafc4a3bd8.json create mode 100644 src/plugins/wp/tests/wp_typed/oracle_qualif/unit_string.0.session/cache/5dd650e35271706f2ad3881dca995525.json create mode 100644 src/plugins/wp/tests/wp_typed/oracle_qualif/unit_string.0.session/cache/6e89f99f7bc6430de780b6cbd010c8b5.json create mode 100644 src/plugins/wp/tests/wp_typed/oracle_qualif/unit_string.0.session/cache/91c84d4131059c3f2bbbe3b3f414e1fe.json create mode 100644 src/plugins/wp/tests/wp_typed/oracle_qualif/unit_string.0.session/cache/f9cff23cc8636428a30178fe3fcc8a69.json create mode 100644 src/plugins/wp/tests/wp_typed/oracle_qualif/user_init.0.session/cache/02acba90a5e2994128860c40fb9f2ba4.json create mode 100644 src/plugins/wp/tests/wp_typed/oracle_qualif/user_init.0.session/cache/0b0769d38a9d9517197365e24d9ff7aa.json create mode 100644 src/plugins/wp/tests/wp_typed/oracle_qualif/user_init.0.session/cache/3c1410111850a62a3c903e678e48aa06.json create mode 100644 src/plugins/wp/tests/wp_typed/oracle_qualif/user_init.0.session/cache/3e77a926f2555c5bf515bd79563fc136.json create mode 100644 src/plugins/wp/tests/wp_typed/oracle_qualif/user_init.0.session/cache/437695130334113727cc1e91e1310860.json create mode 100644 src/plugins/wp/tests/wp_typed/oracle_qualif/user_init.0.session/cache/5702189f244cf06f51fa911ec3cfc217.json create mode 100644 src/plugins/wp/tests/wp_typed/oracle_qualif/user_init.0.session/cache/886d5e0abccf7e670b416c38f907864c.json create mode 100644 src/plugins/wp/tests/wp_typed/oracle_qualif/user_init.0.session/cache/a2e4a1bc7074fcc778279e99ec19077d.json create mode 100644 src/plugins/wp/tests/wp_typed/oracle_qualif/user_init.0.session/cache/aea9a4d6d52524ca1bda06c25330d453.json create mode 100644 src/plugins/wp/tests/wp_typed/oracle_qualif/user_init.0.session/cache/b526cd5eaf63d35c962f8df3f2312ce8.json create mode 100644 src/plugins/wp/tests/wp_typed/oracle_qualif/user_init.0.session/cache/b5efd7507bdfb8fc86984707ac9c09d0.json create mode 100644 src/plugins/wp/tests/wp_typed/oracle_qualif/user_init.0.session/cache/ea5f20db4ed84d856d7641ef17d0e541.json create mode 100644 src/plugins/wp/tests/wp_typed/oracle_qualif/user_init.1.session/cache/0afa9c7ed5285e03fb1e7ec3d0e1bcad.json create mode 100644 src/plugins/wp/tests/wp_typed/oracle_qualif/user_init.1.session/cache/2bf63647c8b8679f671cda4e96dd02c8.json create mode 100644 src/plugins/wp/tests/wp_typed/oracle_qualif/user_init.1.session/cache/4e990ccecbce16ae7813bf76856ed44b.json create mode 100644 src/plugins/wp/tests/wp_typed/oracle_qualif/user_init.1.session/cache/58c3647be66cbcb1d4b1f050100571a3.json create mode 100644 src/plugins/wp/tests/wp_typed/oracle_qualif/user_init.1.session/cache/6bdf496e41182821957a01191acc6df3.json create mode 100644 src/plugins/wp/tests/wp_typed/oracle_qualif/user_init.1.session/cache/93a87d49aa052b4a3426069f903e97d8.json create mode 100644 src/plugins/wp/tests/wp_typed/oracle_qualif/user_init.1.session/cache/a278c3684532efda2a8b0aa0b8328228.json create mode 100644 src/plugins/wp/tests/wp_typed/oracle_qualif/user_init.1.session/cache/c40097d18aabd35cf73be24de441cda4.json create mode 100644 src/plugins/wp/tests/wp_typed/oracle_qualif/user_init.1.session/cache/dbc2fcfa6ad5e92e7256df7e47ac4dfd.json create mode 100644 src/plugins/wp/tests/wp_typed/oracle_qualif/user_init.2.session/cache/5bfecd798741a31e1a9b75b1e76b6fb9.json create mode 100644 src/plugins/wp/tests/wp_typed/oracle_qualif/user_init.2.session/cache/874512731d488beab568aeedc8d4b813.json create mode 100644 src/plugins/wp/tests/wp_typed/oracle_qualif/user_init.2.session/cache/a857d63f4fb5a4a658f9459397c355f7.json create mode 100644 src/plugins/wp/tests/wp_typed/oracle_qualif/user_string.0.session/cache/0278cb04c10669bda8546d6aa4b5b1a2.json create mode 100644 src/plugins/wp/tests/wp_typed/oracle_qualif/user_string.0.session/cache/06a0f4a9e1bbdbde32bdf1f677d91181.json create mode 100644 src/plugins/wp/tests/wp_typed/oracle_qualif/user_string.0.session/cache/0ee2f3e078b2e5a06190ddebe6f3da08.json create mode 100644 src/plugins/wp/tests/wp_typed/oracle_qualif/user_string.0.session/cache/38d0f75717aeccc5685668c23c4874e6.json create mode 100644 src/plugins/wp/tests/wp_typed/oracle_qualif/user_string.0.session/cache/6b7331507db6c1572280eb515546680a.json create mode 100644 src/plugins/wp/tests/wp_typed/oracle_qualif/user_swap.0.session/cache/44f847d26840ea2582d2f6cd48a9bbf2.json create mode 100644 src/plugins/wp/tests/wp_usage/oracle_qualif/caveat2.0.session/cache/1618850a88ad1dcc80a2d9a980d52dc8.json create mode 100644 src/plugins/wp/tests/wp_usage/oracle_qualif/caveat2.0.session/cache/94d26158a717c5e2cda72d3c71c02776.json create mode 100644 src/plugins/wp/tests/wp_usage/oracle_qualif/caveat2.0.session/cache/bd7bc3c6aa2a16dd8cc830c3c57c3faa.json create mode 100644 src/plugins/wp/tests/wp_usage/oracle_qualif/caveat_range.0.session/cache/2b92804b7fb7ffdca664af595a966537.json create mode 100644 src/plugins/wp/tests/wp_usage/oracle_qualif/caveat_range.0.session/cache/41978d7b0067a89104bd5f2bbd577a3a.json create mode 100644 src/plugins/wp/tests/wp_usage/oracle_qualif/caveat_range.0.session/cache/458df2d4dbfc5fe724b9f06bbff664ab.json create mode 100644 src/plugins/wp/tests/wp_usage/oracle_qualif/caveat_range.0.session/cache/4794c66d9a48e1f6e50a71af3e78f625.json create mode 100644 src/plugins/wp/tests/wp_usage/oracle_qualif/caveat_range.0.session/cache/d47c18406856fd185a8c849853d341e2.json create mode 100644 src/plugins/wp/tests/wp_usage/oracle_qualif/issue-189-bis.0.session/cache/0d7ed916922dfd3cd88f04aa053382de.json create mode 100644 src/plugins/wp/tests/wp_usage/oracle_qualif/issue-189-bis.0.session/cache/1d2723c4a683647c25bef5fe4d0cf9d8.json create mode 100644 src/plugins/wp/tests/wp_usage/oracle_qualif/issue-189-bis.0.session/cache/24c6daff7425605b2807df8b79073aeb.json create mode 100644 src/plugins/wp/tests/wp_usage/oracle_qualif/issue-189-bis.0.session/cache/5760024d3d12da3af8d584a2e1a2b6c0.json create mode 100644 src/plugins/wp/tests/wp_usage/oracle_qualif/issue-189-bis.0.session/cache/60b70c5aacda3dc7239684d5c8a9143e.json create mode 100644 src/plugins/wp/tests/wp_usage/oracle_qualif/issue-189-bis.0.session/cache/72809963e95fe64166cd5b945b5d46cb.json create mode 100644 src/plugins/wp/tests/wp_usage/oracle_qualif/issue-189-bis.0.session/cache/9f2521dbb8d31c6d01c228e4aa27ff19.json create mode 100644 src/plugins/wp/tests/wp_usage/oracle_qualif/issue-189-bis.0.session/cache/b3b8f8b3c5dcdfa1b0a26f1f950a56fa.json create mode 100644 src/plugins/wp/tests/wp_usage/oracle_qualif/issue-189-bis.0.session/cache/d05062d51da49ab4e2231ed6e5b4617d.json create mode 100644 src/plugins/wp/tests/wp_usage/oracle_qualif/issue-189-bis.0.session/cache/d40dc9c872cb867b53026c481dc3559b.json create mode 100644 src/plugins/wp/tests/wp_usage/oracle_qualif/issue-189-bis.1.session/cache/4253c6f687ba6a60e8db3e685e84df59.json create mode 100644 src/plugins/wp/tests/wp_usage/oracle_qualif/issue-189-bis.1.session/cache/450fdb9fdd1ea7a682081dbc0af6e709.json create mode 100644 src/plugins/wp/tests/wp_usage/oracle_qualif/issue-189-bis.1.session/cache/688d69c32aabc5063535d39e5dc1b063.json diff --git a/src/plugins/wp/tests/wp/oracle_qualif/sharing.0.session/cache/08a266d8ed47524ea462446955f56846.json b/src/plugins/wp/tests/wp/oracle_qualif/sharing.0.session/cache/08a266d8ed47524ea462446955f56846.json new file mode 100644 index 00000000000..d8b699812c7 --- /dev/null +++ b/src/plugins/wp/tests/wp/oracle_qualif/sharing.0.session/cache/08a266d8ed47524ea462446955f56846.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.1839, + "steps": 35 } diff --git a/src/plugins/wp/tests/wp_acsl/oracle_qualif/assigns_path.0.session/cache/9c4dd961e0443b101eb51979ae15b5c1.json b/src/plugins/wp/tests/wp_acsl/oracle_qualif/assigns_path.0.session/cache/9c4dd961e0443b101eb51979ae15b5c1.json new file mode 100644 index 00000000000..4e76c1ef91e --- /dev/null +++ b/src/plugins/wp/tests/wp_acsl/oracle_qualif/assigns_path.0.session/cache/9c4dd961e0443b101eb51979ae15b5c1.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.029, + "steps": 23 } diff --git a/src/plugins/wp/tests/wp_acsl/oracle_qualif/assigns_path.0.session/cache/a789e11c15e566b594c893a9d69b77b8.json b/src/plugins/wp/tests/wp_acsl/oracle_qualif/assigns_path.0.session/cache/a789e11c15e566b594c893a9d69b77b8.json new file mode 100644 index 00000000000..8b36b323c7b --- /dev/null +++ b/src/plugins/wp/tests/wp_acsl/oracle_qualif/assigns_path.0.session/cache/a789e11c15e566b594c893a9d69b77b8.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0272, + "steps": 20 } diff --git a/src/plugins/wp/tests/wp_acsl/oracle_qualif/assigns_path.0.session/cache/f95876c31865b8f2909e450d06c08e6c.json b/src/plugins/wp/tests/wp_acsl/oracle_qualif/assigns_path.0.session/cache/f95876c31865b8f2909e450d06c08e6c.json new file mode 100644 index 00000000000..2bfea8fade7 --- /dev/null +++ b/src/plugins/wp/tests/wp_acsl/oracle_qualif/assigns_path.0.session/cache/f95876c31865b8f2909e450d06c08e6c.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0215, + "steps": 17 } diff --git a/src/plugins/wp/tests/wp_acsl/oracle_qualif/axioms.0.session/cache/6044af008ca0e2c7fcccdd5236af32af.json b/src/plugins/wp/tests/wp_acsl/oracle_qualif/axioms.0.session/cache/6044af008ca0e2c7fcccdd5236af32af.json new file mode 100644 index 00000000000..961e26140b1 --- /dev/null +++ b/src/plugins/wp/tests/wp_acsl/oracle_qualif/axioms.0.session/cache/6044af008ca0e2c7fcccdd5236af32af.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0521, + "steps": 70 } diff --git a/src/plugins/wp/tests/wp_acsl/oracle_qualif/axioms.0.session/cache/6094e7c19eba3f50fb8b90f9528226e9.json b/src/plugins/wp/tests/wp_acsl/oracle_qualif/axioms.0.session/cache/6094e7c19eba3f50fb8b90f9528226e9.json new file mode 100644 index 00000000000..773071bdef8 --- /dev/null +++ b/src/plugins/wp/tests/wp_acsl/oracle_qualif/axioms.0.session/cache/6094e7c19eba3f50fb8b90f9528226e9.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0214, + "steps": 14 } diff --git a/src/plugins/wp/tests/wp_acsl/oracle_qualif/axioms.0.session/cache/78b4274586b7b6ac948dbd0f36d4c1e3.json b/src/plugins/wp/tests/wp_acsl/oracle_qualif/axioms.0.session/cache/78b4274586b7b6ac948dbd0f36d4c1e3.json new file mode 100644 index 00000000000..b8e36e2803f --- /dev/null +++ b/src/plugins/wp/tests/wp_acsl/oracle_qualif/axioms.0.session/cache/78b4274586b7b6ac948dbd0f36d4c1e3.json @@ -0,0 +1 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "timeout", "time": 10. } diff --git a/src/plugins/wp/tests/wp_acsl/oracle_qualif/axioms.0.session/cache/a7988461f3fa13ce0532e386a9323033.json b/src/plugins/wp/tests/wp_acsl/oracle_qualif/axioms.0.session/cache/a7988461f3fa13ce0532e386a9323033.json new file mode 100644 index 00000000000..761b1f8728a --- /dev/null +++ b/src/plugins/wp/tests/wp_acsl/oracle_qualif/axioms.0.session/cache/a7988461f3fa13ce0532e386a9323033.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0339, + "steps": 32 } diff --git a/src/plugins/wp/tests/wp_acsl/oracle_qualif/axioms.0.session/cache/dbf4a65cfc0e20fdc41c28df5f546971.json b/src/plugins/wp/tests/wp_acsl/oracle_qualif/axioms.0.session/cache/dbf4a65cfc0e20fdc41c28df5f546971.json new file mode 100644 index 00000000000..19a36219937 --- /dev/null +++ b/src/plugins/wp/tests/wp_acsl/oracle_qualif/axioms.0.session/cache/dbf4a65cfc0e20fdc41c28df5f546971.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0233, + "steps": 19 } diff --git a/src/plugins/wp/tests/wp_acsl/oracle_qualif/axioms.0.session/cache/f4ca48ef31089fb2cf5facb451a37704.json b/src/plugins/wp/tests/wp_acsl/oracle_qualif/axioms.0.session/cache/f4ca48ef31089fb2cf5facb451a37704.json new file mode 100644 index 00000000000..d8f7dc139f2 --- /dev/null +++ b/src/plugins/wp/tests/wp_acsl/oracle_qualif/axioms.0.session/cache/f4ca48ef31089fb2cf5facb451a37704.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0382, + "steps": 45 } diff --git a/src/plugins/wp/tests/wp_acsl/oracle_qualif/axioms.0.session/cache/fa725e97995b55101c0cf42a29c0f813.json b/src/plugins/wp/tests/wp_acsl/oracle_qualif/axioms.0.session/cache/fa725e97995b55101c0cf42a29c0f813.json new file mode 100644 index 00000000000..b8e36e2803f --- /dev/null +++ b/src/plugins/wp/tests/wp_acsl/oracle_qualif/axioms.0.session/cache/fa725e97995b55101c0cf42a29c0f813.json @@ -0,0 +1 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "timeout", "time": 10. } diff --git a/src/plugins/wp/tests/wp_acsl/oracle_qualif/base_offset.0.session/cache/a36ac87b7682612f29171f0561dcd7f5.json b/src/plugins/wp/tests/wp_acsl/oracle_qualif/base_offset.0.session/cache/a36ac87b7682612f29171f0561dcd7f5.json new file mode 100644 index 00000000000..56c39550428 --- /dev/null +++ b/src/plugins/wp/tests/wp_acsl/oracle_qualif/base_offset.0.session/cache/a36ac87b7682612f29171f0561dcd7f5.json @@ -0,0 +1 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "unknown" } diff --git a/src/plugins/wp/tests/wp_acsl/oracle_qualif/classify_float.0.session/cache/0a905fe4d67333c2edc713c01cc378f7.json b/src/plugins/wp/tests/wp_acsl/oracle_qualif/classify_float.0.session/cache/0a905fe4d67333c2edc713c01cc378f7.json new file mode 100644 index 00000000000..1012157e678 --- /dev/null +++ b/src/plugins/wp/tests/wp_acsl/oracle_qualif/classify_float.0.session/cache/0a905fe4d67333c2edc713c01cc378f7.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0667, + "steps": 88 } diff --git a/src/plugins/wp/tests/wp_acsl/oracle_qualif/classify_float.0.session/cache/e415e5ac31242f42e0ec3f9659d65967.json b/src/plugins/wp/tests/wp_acsl/oracle_qualif/classify_float.0.session/cache/e415e5ac31242f42e0ec3f9659d65967.json new file mode 100644 index 00000000000..c0fd738d21a --- /dev/null +++ b/src/plugins/wp/tests/wp_acsl/oracle_qualif/classify_float.0.session/cache/e415e5ac31242f42e0ec3f9659d65967.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0687, + "steps": 86 } diff --git a/src/plugins/wp/tests/wp_acsl/oracle_qualif/classify_float.0.session/cache/f23d47414c80f975ea6a853ebf08af80.json b/src/plugins/wp/tests/wp_acsl/oracle_qualif/classify_float.0.session/cache/f23d47414c80f975ea6a853ebf08af80.json new file mode 100644 index 00000000000..71049b4947d --- /dev/null +++ b/src/plugins/wp/tests/wp_acsl/oracle_qualif/classify_float.0.session/cache/f23d47414c80f975ea6a853ebf08af80.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0968, + "steps": 88 } diff --git a/src/plugins/wp/tests/wp_acsl/oracle_qualif/equal.0.session/cache/37ca01b8d9af3adaa85337898f17bbcf.json b/src/plugins/wp/tests/wp_acsl/oracle_qualif/equal.0.session/cache/37ca01b8d9af3adaa85337898f17bbcf.json new file mode 100644 index 00000000000..a094a26e883 --- /dev/null +++ b/src/plugins/wp/tests/wp_acsl/oracle_qualif/equal.0.session/cache/37ca01b8d9af3adaa85337898f17bbcf.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0107, + "steps": 9 } diff --git a/src/plugins/wp/tests/wp_acsl/oracle_qualif/equal.0.session/cache/e693f887cbaf3748fcba8d0e78496a04.json b/src/plugins/wp/tests/wp_acsl/oracle_qualif/equal.0.session/cache/e693f887cbaf3748fcba8d0e78496a04.json new file mode 100644 index 00000000000..058ecb53439 --- /dev/null +++ b/src/plugins/wp/tests/wp_acsl/oracle_qualif/equal.0.session/cache/e693f887cbaf3748fcba8d0e78496a04.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0194, + "steps": 12 } diff --git a/src/plugins/wp/tests/wp_acsl/oracle_qualif/equal.0.session/cache/fb71b4e14680e40fdfe23d5a71f51776.json b/src/plugins/wp/tests/wp_acsl/oracle_qualif/equal.0.session/cache/fb71b4e14680e40fdfe23d5a71f51776.json new file mode 100644 index 00000000000..d80f0329219 --- /dev/null +++ b/src/plugins/wp/tests/wp_acsl/oracle_qualif/equal.0.session/cache/fb71b4e14680e40fdfe23d5a71f51776.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0238, + "steps": 26 } diff --git a/src/plugins/wp/tests/wp_acsl/oracle_qualif/float_compare.0.session/cache/0d2abb971445d7e4694380d263060055.json b/src/plugins/wp/tests/wp_acsl/oracle_qualif/float_compare.0.session/cache/0d2abb971445d7e4694380d263060055.json new file mode 100644 index 00000000000..7777628a60e --- /dev/null +++ b/src/plugins/wp/tests/wp_acsl/oracle_qualif/float_compare.0.session/cache/0d2abb971445d7e4694380d263060055.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0928, + "steps": 112 } diff --git a/src/plugins/wp/tests/wp_acsl/oracle_qualif/float_compare.0.session/cache/1932508452358e4ae474447d8950a0af.json b/src/plugins/wp/tests/wp_acsl/oracle_qualif/float_compare.0.session/cache/1932508452358e4ae474447d8950a0af.json new file mode 100644 index 00000000000..b69cf97ec3f --- /dev/null +++ b/src/plugins/wp/tests/wp_acsl/oracle_qualif/float_compare.0.session/cache/1932508452358e4ae474447d8950a0af.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0692, + "steps": 106 } diff --git a/src/plugins/wp/tests/wp_acsl/oracle_qualif/float_compare.0.session/cache/4529c9de8c01d20f9fbbf88ecaf071c5.json b/src/plugins/wp/tests/wp_acsl/oracle_qualif/float_compare.0.session/cache/4529c9de8c01d20f9fbbf88ecaf071c5.json new file mode 100644 index 00000000000..2c9d4fbaef7 --- /dev/null +++ b/src/plugins/wp/tests/wp_acsl/oracle_qualif/float_compare.0.session/cache/4529c9de8c01d20f9fbbf88ecaf071c5.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0903, + "steps": 135 } diff --git a/src/plugins/wp/tests/wp_acsl/oracle_qualif/float_compare.0.session/cache/61d6a3a8bbf8eb3941c06207e0edcf6a.json b/src/plugins/wp/tests/wp_acsl/oracle_qualif/float_compare.0.session/cache/61d6a3a8bbf8eb3941c06207e0edcf6a.json new file mode 100644 index 00000000000..0d8a494a81b --- /dev/null +++ b/src/plugins/wp/tests/wp_acsl/oracle_qualif/float_compare.0.session/cache/61d6a3a8bbf8eb3941c06207e0edcf6a.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0674, + "steps": 102 } diff --git a/src/plugins/wp/tests/wp_acsl/oracle_qualif/float_compare.0.session/cache/62d262414e3d2e705480be1fdf742280.json b/src/plugins/wp/tests/wp_acsl/oracle_qualif/float_compare.0.session/cache/62d262414e3d2e705480be1fdf742280.json new file mode 100644 index 00000000000..21e102ff29d --- /dev/null +++ b/src/plugins/wp/tests/wp_acsl/oracle_qualif/float_compare.0.session/cache/62d262414e3d2e705480be1fdf742280.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0795, + "steps": 107 } diff --git a/src/plugins/wp/tests/wp_acsl/oracle_qualif/float_compare.0.session/cache/7d7abc4aed08f6d397d86a95f08df503.json b/src/plugins/wp/tests/wp_acsl/oracle_qualif/float_compare.0.session/cache/7d7abc4aed08f6d397d86a95f08df503.json new file mode 100644 index 00000000000..dcd1645373b --- /dev/null +++ b/src/plugins/wp/tests/wp_acsl/oracle_qualif/float_compare.0.session/cache/7d7abc4aed08f6d397d86a95f08df503.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0708, + "steps": 112 } diff --git a/src/plugins/wp/tests/wp_acsl/oracle_qualif/float_compare.0.session/cache/7e1f0d1b2e2f4fcb6f82eead533aaf21.json b/src/plugins/wp/tests/wp_acsl/oracle_qualif/float_compare.0.session/cache/7e1f0d1b2e2f4fcb6f82eead533aaf21.json new file mode 100644 index 00000000000..b3453fe01b1 --- /dev/null +++ b/src/plugins/wp/tests/wp_acsl/oracle_qualif/float_compare.0.session/cache/7e1f0d1b2e2f4fcb6f82eead533aaf21.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0746, + "steps": 126 } diff --git a/src/plugins/wp/tests/wp_acsl/oracle_qualif/float_compare.0.session/cache/879774fa75e5c6e3931a522784aef644.json b/src/plugins/wp/tests/wp_acsl/oracle_qualif/float_compare.0.session/cache/879774fa75e5c6e3931a522784aef644.json new file mode 100644 index 00000000000..56295647c82 --- /dev/null +++ b/src/plugins/wp/tests/wp_acsl/oracle_qualif/float_compare.0.session/cache/879774fa75e5c6e3931a522784aef644.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0628, + "steps": 107 } diff --git a/src/plugins/wp/tests/wp_acsl/oracle_qualif/float_compare.0.session/cache/888ea152c7a0297037a8c6283858d6e4.json b/src/plugins/wp/tests/wp_acsl/oracle_qualif/float_compare.0.session/cache/888ea152c7a0297037a8c6283858d6e4.json new file mode 100644 index 00000000000..9208ba62953 --- /dev/null +++ b/src/plugins/wp/tests/wp_acsl/oracle_qualif/float_compare.0.session/cache/888ea152c7a0297037a8c6283858d6e4.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0852, + "steps": 121 } diff --git a/src/plugins/wp/tests/wp_acsl/oracle_qualif/float_compare.0.session/cache/bbcaecdc16ceacd6d70aa7a3ad1466aa.json b/src/plugins/wp/tests/wp_acsl/oracle_qualif/float_compare.0.session/cache/bbcaecdc16ceacd6d70aa7a3ad1466aa.json new file mode 100644 index 00000000000..3627d770916 --- /dev/null +++ b/src/plugins/wp/tests/wp_acsl/oracle_qualif/float_compare.0.session/cache/bbcaecdc16ceacd6d70aa7a3ad1466aa.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0756, + "steps": 112 } diff --git a/src/plugins/wp/tests/wp_acsl/oracle_qualif/float_compare.0.session/cache/d3dbfa3988959e87318bcf002f3c4e47.json b/src/plugins/wp/tests/wp_acsl/oracle_qualif/float_compare.0.session/cache/d3dbfa3988959e87318bcf002f3c4e47.json new file mode 100644 index 00000000000..c2cec72f35a --- /dev/null +++ b/src/plugins/wp/tests/wp_acsl/oracle_qualif/float_compare.0.session/cache/d3dbfa3988959e87318bcf002f3c4e47.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0697, + "steps": 87 } diff --git a/src/plugins/wp/tests/wp_acsl/oracle_qualif/float_compare.0.session/cache/d8bb8e21e04ed3c720d63f31187ee652.json b/src/plugins/wp/tests/wp_acsl/oracle_qualif/float_compare.0.session/cache/d8bb8e21e04ed3c720d63f31187ee652.json new file mode 100644 index 00000000000..0d769617093 --- /dev/null +++ b/src/plugins/wp/tests/wp_acsl/oracle_qualif/float_compare.0.session/cache/d8bb8e21e04ed3c720d63f31187ee652.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0598, + "steps": 112 } diff --git a/src/plugins/wp/tests/wp_acsl/oracle_qualif/float_compare.0.session/cache/ece5499b76e2b762927d44b60311d491.json b/src/plugins/wp/tests/wp_acsl/oracle_qualif/float_compare.0.session/cache/ece5499b76e2b762927d44b60311d491.json new file mode 100644 index 00000000000..fd4e3bdb356 --- /dev/null +++ b/src/plugins/wp/tests/wp_acsl/oracle_qualif/float_compare.0.session/cache/ece5499b76e2b762927d44b60311d491.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0968, + "steps": 108 } diff --git a/src/plugins/wp/tests/wp_acsl/oracle_qualif/float_compare.0.session/cache/f983884d24497fe1e604b085bc61d42d.json b/src/plugins/wp/tests/wp_acsl/oracle_qualif/float_compare.0.session/cache/f983884d24497fe1e604b085bc61d42d.json new file mode 100644 index 00000000000..15a4c57a35f --- /dev/null +++ b/src/plugins/wp/tests/wp_acsl/oracle_qualif/float_compare.0.session/cache/f983884d24497fe1e604b085bc61d42d.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0838, + "steps": 102 } diff --git a/src/plugins/wp/tests/wp_acsl/oracle_qualif/float_const.0.session/cache/3eda240a1618c4e2129a56faa362aa41.json b/src/plugins/wp/tests/wp_acsl/oracle_qualif/float_const.0.session/cache/3eda240a1618c4e2129a56faa362aa41.json new file mode 100644 index 00000000000..d5d7d432022 --- /dev/null +++ b/src/plugins/wp/tests/wp_acsl/oracle_qualif/float_const.0.session/cache/3eda240a1618c4e2129a56faa362aa41.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.2541, + "steps": 332 } diff --git a/src/plugins/wp/tests/wp_acsl/oracle_qualif/float_const.0.session/cache/566431057d4fc34ebe07842f87363104.json b/src/plugins/wp/tests/wp_acsl/oracle_qualif/float_const.0.session/cache/566431057d4fc34ebe07842f87363104.json new file mode 100644 index 00000000000..36b03c530bb --- /dev/null +++ b/src/plugins/wp/tests/wp_acsl/oracle_qualif/float_const.0.session/cache/566431057d4fc34ebe07842f87363104.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.3224, + "steps": 596 } diff --git a/src/plugins/wp/tests/wp_acsl/oracle_qualif/float_const.0.session/cache/90bad8d1a177f25e5355b292480850a8.json b/src/plugins/wp/tests/wp_acsl/oracle_qualif/float_const.0.session/cache/90bad8d1a177f25e5355b292480850a8.json new file mode 100644 index 00000000000..30a38a89671 --- /dev/null +++ b/src/plugins/wp/tests/wp_acsl/oracle_qualif/float_const.0.session/cache/90bad8d1a177f25e5355b292480850a8.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.2141, + "steps": 332 } diff --git a/src/plugins/wp/tests/wp_acsl/oracle_qualif/float_const.0.session/cache/d9555471b99fab97496429da35c60b85.json b/src/plugins/wp/tests/wp_acsl/oracle_qualif/float_const.0.session/cache/d9555471b99fab97496429da35c60b85.json new file mode 100644 index 00000000000..ef32c000dca --- /dev/null +++ b/src/plugins/wp/tests/wp_acsl/oracle_qualif/float_const.0.session/cache/d9555471b99fab97496429da35c60b85.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.1543, + "steps": 332 } diff --git a/src/plugins/wp/tests/wp_acsl/oracle_qualif/float_const.0.session/cache/ed750337872ba241506bb6b5482d452a.json b/src/plugins/wp/tests/wp_acsl/oracle_qualif/float_const.0.session/cache/ed750337872ba241506bb6b5482d452a.json new file mode 100644 index 00000000000..ef720689733 --- /dev/null +++ b/src/plugins/wp/tests/wp_acsl/oracle_qualif/float_const.0.session/cache/ed750337872ba241506bb6b5482d452a.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.2051, + "steps": 332 } diff --git a/src/plugins/wp/tests/wp_acsl/oracle_qualif/float_const.0.session/cache/f61afc24017b7e4fa237b53dacd04d71.json b/src/plugins/wp/tests/wp_acsl/oracle_qualif/float_const.0.session/cache/f61afc24017b7e4fa237b53dacd04d71.json new file mode 100644 index 00000000000..835d8ef735b --- /dev/null +++ b/src/plugins/wp/tests/wp_acsl/oracle_qualif/float_const.0.session/cache/f61afc24017b7e4fa237b53dacd04d71.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.5975, + "steps": 1145 } diff --git a/src/plugins/wp/tests/wp_acsl/oracle_qualif/float_const.0.session/cache/fe3b18624cd214c20103e2ccebb30e28.json b/src/plugins/wp/tests/wp_acsl/oracle_qualif/float_const.0.session/cache/fe3b18624cd214c20103e2ccebb30e28.json new file mode 100644 index 00000000000..1969b87896b --- /dev/null +++ b/src/plugins/wp/tests/wp_acsl/oracle_qualif/float_const.0.session/cache/fe3b18624cd214c20103e2ccebb30e28.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.3359, + "steps": 596 } diff --git a/src/plugins/wp/tests/wp_acsl/oracle_qualif/float_const.0.session/cache/fed99e0d6926411c893b99634bf52d5c.json b/src/plugins/wp/tests/wp_acsl/oracle_qualif/float_const.0.session/cache/fed99e0d6926411c893b99634bf52d5c.json new file mode 100644 index 00000000000..d7c10d8e736 --- /dev/null +++ b/src/plugins/wp/tests/wp_acsl/oracle_qualif/float_const.0.session/cache/fed99e0d6926411c893b99634bf52d5c.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.8856, + "steps": 1460 } diff --git a/src/plugins/wp/tests/wp_acsl/oracle_qualif/init_value_mem.0.session/cache/f9448d0b7eb7302bfe3607804bc64e21.json b/src/plugins/wp/tests/wp_acsl/oracle_qualif/init_value_mem.0.session/cache/f9448d0b7eb7302bfe3607804bc64e21.json new file mode 100644 index 00000000000..3b3b5db51bc --- /dev/null +++ b/src/plugins/wp/tests/wp_acsl/oracle_qualif/init_value_mem.0.session/cache/f9448d0b7eb7302bfe3607804bc64e21.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0307, + "steps": 35 } diff --git a/src/plugins/wp/tests/wp_acsl/oracle_qualif/logic.0.session/cache/3c6e8a313ea22d4bc1727ce213fa7a32.json b/src/plugins/wp/tests/wp_acsl/oracle_qualif/logic.0.session/cache/3c6e8a313ea22d4bc1727ce213fa7a32.json new file mode 100644 index 00000000000..43afa6298c6 --- /dev/null +++ b/src/plugins/wp/tests/wp_acsl/oracle_qualif/logic.0.session/cache/3c6e8a313ea22d4bc1727ce213fa7a32.json @@ -0,0 +1 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "stepout", "steps": 50 } diff --git a/src/plugins/wp/tests/wp_acsl/oracle_qualif/logic.0.session/cache/8ab45c40e1e4b7574dc56ff9ab462b9e.json b/src/plugins/wp/tests/wp_acsl/oracle_qualif/logic.0.session/cache/8ab45c40e1e4b7574dc56ff9ab462b9e.json new file mode 100644 index 00000000000..43afa6298c6 --- /dev/null +++ b/src/plugins/wp/tests/wp_acsl/oracle_qualif/logic.0.session/cache/8ab45c40e1e4b7574dc56ff9ab462b9e.json @@ -0,0 +1 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "stepout", "steps": 50 } diff --git a/src/plugins/wp/tests/wp_acsl/oracle_qualif/logic.0.session/cache/b2dccb583e60d479c0d381f01ce67a42.json b/src/plugins/wp/tests/wp_acsl/oracle_qualif/logic.0.session/cache/b2dccb583e60d479c0d381f01ce67a42.json new file mode 100644 index 00000000000..3db4264b0a4 --- /dev/null +++ b/src/plugins/wp/tests/wp_acsl/oracle_qualif/logic.0.session/cache/b2dccb583e60d479c0d381f01ce67a42.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0226, + "steps": 29 } diff --git a/src/plugins/wp/tests/wp_acsl/oracle_qualif/logic.0.session/cache/de909dc4b72d103e8cf9096883ab48c9.json b/src/plugins/wp/tests/wp_acsl/oracle_qualif/logic.0.session/cache/de909dc4b72d103e8cf9096883ab48c9.json new file mode 100644 index 00000000000..43afa6298c6 --- /dev/null +++ b/src/plugins/wp/tests/wp_acsl/oracle_qualif/logic.0.session/cache/de909dc4b72d103e8cf9096883ab48c9.json @@ -0,0 +1 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "stepout", "steps": 50 } diff --git a/src/plugins/wp/tests/wp_acsl/oracle_qualif/looplabels.0.session/cache/087830674d518a84a70572bcc511f73c.json b/src/plugins/wp/tests/wp_acsl/oracle_qualif/looplabels.0.session/cache/087830674d518a84a70572bcc511f73c.json new file mode 100644 index 00000000000..9fb781146d9 --- /dev/null +++ b/src/plugins/wp/tests/wp_acsl/oracle_qualif/looplabels.0.session/cache/087830674d518a84a70572bcc511f73c.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.4058, + "steps": 360 } diff --git a/src/plugins/wp/tests/wp_acsl/oracle_qualif/looplabels.0.session/cache/18a9a7122ae19461824b858ac602249a.json b/src/plugins/wp/tests/wp_acsl/oracle_qualif/looplabels.0.session/cache/18a9a7122ae19461824b858ac602249a.json new file mode 100644 index 00000000000..fc0ca24b6c0 --- /dev/null +++ b/src/plugins/wp/tests/wp_acsl/oracle_qualif/looplabels.0.session/cache/18a9a7122ae19461824b858ac602249a.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0127, + "steps": 22 } diff --git a/src/plugins/wp/tests/wp_acsl/oracle_qualif/looplabels.0.session/cache/3fa100d08d6ab289efe6867d26dd6261.json b/src/plugins/wp/tests/wp_acsl/oracle_qualif/looplabels.0.session/cache/3fa100d08d6ab289efe6867d26dd6261.json new file mode 100644 index 00000000000..771d264f003 --- /dev/null +++ b/src/plugins/wp/tests/wp_acsl/oracle_qualif/looplabels.0.session/cache/3fa100d08d6ab289efe6867d26dd6261.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0182, + "steps": 17 } diff --git a/src/plugins/wp/tests/wp_acsl/oracle_qualif/looplabels.0.session/cache/bd55350a94ac10760699d752bc1585d3.json b/src/plugins/wp/tests/wp_acsl/oracle_qualif/looplabels.0.session/cache/bd55350a94ac10760699d752bc1585d3.json new file mode 100644 index 00000000000..f70efdf335b --- /dev/null +++ b/src/plugins/wp/tests/wp_acsl/oracle_qualif/looplabels.0.session/cache/bd55350a94ac10760699d752bc1585d3.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0485, + "steps": 75 } diff --git a/src/plugins/wp/tests/wp_acsl/oracle_qualif/looplabels.0.session/cache/f42d568fbe3428bab8f1402c8db924d3.json b/src/plugins/wp/tests/wp_acsl/oracle_qualif/looplabels.0.session/cache/f42d568fbe3428bab8f1402c8db924d3.json new file mode 100644 index 00000000000..d194a9f8c58 --- /dev/null +++ b/src/plugins/wp/tests/wp_acsl/oracle_qualif/looplabels.0.session/cache/f42d568fbe3428bab8f1402c8db924d3.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0144, + "steps": 21 } diff --git a/src/plugins/wp/tests/wp_acsl/oracle_qualif/null.0.session/cache/2112ab864e0651e150b5554b140c0721.json b/src/plugins/wp/tests/wp_acsl/oracle_qualif/null.0.session/cache/2112ab864e0651e150b5554b140c0721.json new file mode 100644 index 00000000000..a7219b30ce1 --- /dev/null +++ b/src/plugins/wp/tests/wp_acsl/oracle_qualif/null.0.session/cache/2112ab864e0651e150b5554b140c0721.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0174, + "steps": 6 } diff --git a/src/plugins/wp/tests/wp_acsl/oracle_qualif/null.0.session/cache/aad81927bc4771f96d0db10c87c31bf1.json b/src/plugins/wp/tests/wp_acsl/oracle_qualif/null.0.session/cache/aad81927bc4771f96d0db10c87c31bf1.json new file mode 100644 index 00000000000..81b56ce9f88 --- /dev/null +++ b/src/plugins/wp/tests/wp_acsl/oracle_qualif/null.0.session/cache/aad81927bc4771f96d0db10c87c31bf1.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0124, + "steps": 6 } diff --git a/src/plugins/wp/tests/wp_acsl/oracle_qualif/pointer.0.session/cache/47b74acd14f46caf2bab31cb3340e856.json b/src/plugins/wp/tests/wp_acsl/oracle_qualif/pointer.0.session/cache/47b74acd14f46caf2bab31cb3340e856.json new file mode 100644 index 00000000000..56c39550428 --- /dev/null +++ b/src/plugins/wp/tests/wp_acsl/oracle_qualif/pointer.0.session/cache/47b74acd14f46caf2bab31cb3340e856.json @@ -0,0 +1 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "unknown" } diff --git a/src/plugins/wp/tests/wp_acsl/oracle_qualif/pointer.0.session/cache/5bafa9923e7396335d9ee20e2716d4fc.json b/src/plugins/wp/tests/wp_acsl/oracle_qualif/pointer.0.session/cache/5bafa9923e7396335d9ee20e2716d4fc.json new file mode 100644 index 00000000000..56c39550428 --- /dev/null +++ b/src/plugins/wp/tests/wp_acsl/oracle_qualif/pointer.0.session/cache/5bafa9923e7396335d9ee20e2716d4fc.json @@ -0,0 +1 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "unknown" } diff --git a/src/plugins/wp/tests/wp_acsl/oracle_qualif/pointer.0.session/cache/df9f51a2a33abbdc1e33b3e88575ee88.json b/src/plugins/wp/tests/wp_acsl/oracle_qualif/pointer.0.session/cache/df9f51a2a33abbdc1e33b3e88575ee88.json new file mode 100644 index 00000000000..56c39550428 --- /dev/null +++ b/src/plugins/wp/tests/wp_acsl/oracle_qualif/pointer.0.session/cache/df9f51a2a33abbdc1e33b3e88575ee88.json @@ -0,0 +1 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "unknown" } diff --git a/src/plugins/wp/tests/wp_acsl/oracle_qualif/pointer.0.session/cache/e6079b75bc05ca97140090d4e0b21c18.json b/src/plugins/wp/tests/wp_acsl/oracle_qualif/pointer.0.session/cache/e6079b75bc05ca97140090d4e0b21c18.json new file mode 100644 index 00000000000..56c39550428 --- /dev/null +++ b/src/plugins/wp/tests/wp_acsl/oracle_qualif/pointer.0.session/cache/e6079b75bc05ca97140090d4e0b21c18.json @@ -0,0 +1 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "unknown" } diff --git a/src/plugins/wp/tests/wp_acsl/oracle_qualif/pointer.1.session/cache/47b74acd14f46caf2bab31cb3340e856.json b/src/plugins/wp/tests/wp_acsl/oracle_qualif/pointer.1.session/cache/47b74acd14f46caf2bab31cb3340e856.json new file mode 100644 index 00000000000..56c39550428 --- /dev/null +++ b/src/plugins/wp/tests/wp_acsl/oracle_qualif/pointer.1.session/cache/47b74acd14f46caf2bab31cb3340e856.json @@ -0,0 +1 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "unknown" } diff --git a/src/plugins/wp/tests/wp_acsl/oracle_qualif/pointer.1.session/cache/5bafa9923e7396335d9ee20e2716d4fc.json b/src/plugins/wp/tests/wp_acsl/oracle_qualif/pointer.1.session/cache/5bafa9923e7396335d9ee20e2716d4fc.json new file mode 100644 index 00000000000..56c39550428 --- /dev/null +++ b/src/plugins/wp/tests/wp_acsl/oracle_qualif/pointer.1.session/cache/5bafa9923e7396335d9ee20e2716d4fc.json @@ -0,0 +1 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "unknown" } diff --git a/src/plugins/wp/tests/wp_acsl/oracle_qualif/pointer.1.session/cache/df9f51a2a33abbdc1e33b3e88575ee88.json b/src/plugins/wp/tests/wp_acsl/oracle_qualif/pointer.1.session/cache/df9f51a2a33abbdc1e33b3e88575ee88.json new file mode 100644 index 00000000000..56c39550428 --- /dev/null +++ b/src/plugins/wp/tests/wp_acsl/oracle_qualif/pointer.1.session/cache/df9f51a2a33abbdc1e33b3e88575ee88.json @@ -0,0 +1 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "unknown" } diff --git a/src/plugins/wp/tests/wp_acsl/oracle_qualif/pointer.1.session/cache/e6079b75bc05ca97140090d4e0b21c18.json b/src/plugins/wp/tests/wp_acsl/oracle_qualif/pointer.1.session/cache/e6079b75bc05ca97140090d4e0b21c18.json new file mode 100644 index 00000000000..56c39550428 --- /dev/null +++ b/src/plugins/wp/tests/wp_acsl/oracle_qualif/pointer.1.session/cache/e6079b75bc05ca97140090d4e0b21c18.json @@ -0,0 +1 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "unknown" } diff --git a/src/plugins/wp/tests/wp_acsl/oracle_qualif/post_result.0.session/cache/aeba54fcd5bc6c917c8d92eb80efed6d.json b/src/plugins/wp/tests/wp_acsl/oracle_qualif/post_result.0.session/cache/aeba54fcd5bc6c917c8d92eb80efed6d.json new file mode 100644 index 00000000000..43afa6298c6 --- /dev/null +++ b/src/plugins/wp/tests/wp_acsl/oracle_qualif/post_result.0.session/cache/aeba54fcd5bc6c917c8d92eb80efed6d.json @@ -0,0 +1 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "stepout", "steps": 50 } diff --git a/src/plugins/wp/tests/wp_acsl/oracle_qualif/reads.0.session/cache/0cbdd126867b26cc1e3fc3a5b279bb0d.json b/src/plugins/wp/tests/wp_acsl/oracle_qualif/reads.0.session/cache/0cbdd126867b26cc1e3fc3a5b279bb0d.json new file mode 100644 index 00000000000..74b5e4e71dd --- /dev/null +++ b/src/plugins/wp/tests/wp_acsl/oracle_qualif/reads.0.session/cache/0cbdd126867b26cc1e3fc3a5b279bb0d.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0178, + "steps": 15 } diff --git a/src/plugins/wp/tests/wp_acsl/oracle_qualif/reads.0.session/cache/cd6211b4ab473cbfa4d355d0a774ef99.json b/src/plugins/wp/tests/wp_acsl/oracle_qualif/reads.0.session/cache/cd6211b4ab473cbfa4d355d0a774ef99.json new file mode 100644 index 00000000000..ecb3dacb954 --- /dev/null +++ b/src/plugins/wp/tests/wp_acsl/oracle_qualif/reads.0.session/cache/cd6211b4ab473cbfa4d355d0a774ef99.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0216, + "steps": 21 } diff --git a/src/plugins/wp/tests/wp_acsl/oracle_qualif/simpl_is_type.0.session/cache/07b7a43b195fb4f33dd51c9d6bd273d4.json b/src/plugins/wp/tests/wp_acsl/oracle_qualif/simpl_is_type.0.session/cache/07b7a43b195fb4f33dd51c9d6bd273d4.json new file mode 100644 index 00000000000..739bdf84a3a --- /dev/null +++ b/src/plugins/wp/tests/wp_acsl/oracle_qualif/simpl_is_type.0.session/cache/07b7a43b195fb4f33dd51c9d6bd273d4.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0179, + "steps": 19 } diff --git a/src/plugins/wp/tests/wp_acsl/oracle_qualif/simpl_is_type.0.session/cache/22ae78621c875b3d3cafc538d7eb7ff4.json b/src/plugins/wp/tests/wp_acsl/oracle_qualif/simpl_is_type.0.session/cache/22ae78621c875b3d3cafc538d7eb7ff4.json new file mode 100644 index 00000000000..5eb0206d867 --- /dev/null +++ b/src/plugins/wp/tests/wp_acsl/oracle_qualif/simpl_is_type.0.session/cache/22ae78621c875b3d3cafc538d7eb7ff4.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0192, + "steps": 16 } diff --git a/src/plugins/wp/tests/wp_acsl/oracle_qualif/simpl_is_type.0.session/cache/2be784ca088c5e1a38cbb9ef0222a259.json b/src/plugins/wp/tests/wp_acsl/oracle_qualif/simpl_is_type.0.session/cache/2be784ca088c5e1a38cbb9ef0222a259.json new file mode 100644 index 00000000000..5dd92818c00 --- /dev/null +++ b/src/plugins/wp/tests/wp_acsl/oracle_qualif/simpl_is_type.0.session/cache/2be784ca088c5e1a38cbb9ef0222a259.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0299, + "steps": 31 } diff --git a/src/plugins/wp/tests/wp_acsl/oracle_qualif/simpl_is_type.0.session/cache/54f4913abf23075ad98087f17fc620ee.json b/src/plugins/wp/tests/wp_acsl/oracle_qualif/simpl_is_type.0.session/cache/54f4913abf23075ad98087f17fc620ee.json new file mode 100644 index 00000000000..952c3b9c4e3 --- /dev/null +++ b/src/plugins/wp/tests/wp_acsl/oracle_qualif/simpl_is_type.0.session/cache/54f4913abf23075ad98087f17fc620ee.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0283, + "steps": 29 } diff --git a/src/plugins/wp/tests/wp_acsl/oracle_qualif/simpl_is_type.0.session/cache/72b24ef7daf0640c07d9fffa1961d184.json b/src/plugins/wp/tests/wp_acsl/oracle_qualif/simpl_is_type.0.session/cache/72b24ef7daf0640c07d9fffa1961d184.json new file mode 100644 index 00000000000..4c66f3753df --- /dev/null +++ b/src/plugins/wp/tests/wp_acsl/oracle_qualif/simpl_is_type.0.session/cache/72b24ef7daf0640c07d9fffa1961d184.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0279, + "steps": 45 } diff --git a/src/plugins/wp/tests/wp_acsl/oracle_qualif/simpl_is_type.0.session/cache/8445d12d440f5e77ee1f7f848cc15b68.json b/src/plugins/wp/tests/wp_acsl/oracle_qualif/simpl_is_type.0.session/cache/8445d12d440f5e77ee1f7f848cc15b68.json new file mode 100644 index 00000000000..8fc02eb42f0 --- /dev/null +++ b/src/plugins/wp/tests/wp_acsl/oracle_qualif/simpl_is_type.0.session/cache/8445d12d440f5e77ee1f7f848cc15b68.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0285, + "steps": 21 } diff --git a/src/plugins/wp/tests/wp_acsl/oracle_qualif/simpl_is_type.0.session/cache/8fb3eea396680aa56e7f96b68ebc2245.json b/src/plugins/wp/tests/wp_acsl/oracle_qualif/simpl_is_type.0.session/cache/8fb3eea396680aa56e7f96b68ebc2245.json new file mode 100644 index 00000000000..1a29e643227 --- /dev/null +++ b/src/plugins/wp/tests/wp_acsl/oracle_qualif/simpl_is_type.0.session/cache/8fb3eea396680aa56e7f96b68ebc2245.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0323, + "steps": 43 } diff --git a/src/plugins/wp/tests/wp_acsl/oracle_qualif/simpl_is_type.0.session/cache/b583dc30d2074490b3fe0ec73cde2dba.json b/src/plugins/wp/tests/wp_acsl/oracle_qualif/simpl_is_type.0.session/cache/b583dc30d2074490b3fe0ec73cde2dba.json new file mode 100644 index 00000000000..5c6852eb4e4 --- /dev/null +++ b/src/plugins/wp/tests/wp_acsl/oracle_qualif/simpl_is_type.0.session/cache/b583dc30d2074490b3fe0ec73cde2dba.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0198, + "steps": 16 } diff --git a/src/plugins/wp/tests/wp_acsl/oracle_qualif/simpl_is_type.0.session/cache/ea5ad50dafc3e3b81b14b672b31faf00.json b/src/plugins/wp/tests/wp_acsl/oracle_qualif/simpl_is_type.0.session/cache/ea5ad50dafc3e3b81b14b672b31faf00.json new file mode 100644 index 00000000000..e61c0f80470 --- /dev/null +++ b/src/plugins/wp/tests/wp_acsl/oracle_qualif/simpl_is_type.0.session/cache/ea5ad50dafc3e3b81b14b672b31faf00.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.037, + "steps": 63 } diff --git a/src/plugins/wp/tests/wp_bts/oracle_qualif/bts779.0.session/cache/39afa23189acb8a1b45f730656f3293d.json b/src/plugins/wp/tests/wp_bts/oracle_qualif/bts779.0.session/cache/39afa23189acb8a1b45f730656f3293d.json new file mode 100644 index 00000000000..b8e36e2803f --- /dev/null +++ b/src/plugins/wp/tests/wp_bts/oracle_qualif/bts779.0.session/cache/39afa23189acb8a1b45f730656f3293d.json @@ -0,0 +1 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "timeout", "time": 10. } diff --git a/src/plugins/wp/tests/wp_bts/oracle_qualif/bts779.0.session/cache/b020d8fbac2c1f5a2bb5eff45748c8a2.json b/src/plugins/wp/tests/wp_bts/oracle_qualif/bts779.0.session/cache/b020d8fbac2c1f5a2bb5eff45748c8a2.json new file mode 100644 index 00000000000..4d64930cd12 --- /dev/null +++ b/src/plugins/wp/tests/wp_bts/oracle_qualif/bts779.0.session/cache/b020d8fbac2c1f5a2bb5eff45748c8a2.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0235, + "steps": 16 } diff --git a/src/plugins/wp/tests/wp_bts/oracle_qualif/bts986.0.session/cache/d9121cbf1bf929d8a33ed73cdc206552.json b/src/plugins/wp/tests/wp_bts/oracle_qualif/bts986.0.session/cache/d9121cbf1bf929d8a33ed73cdc206552.json new file mode 100644 index 00000000000..c7b6459aaa6 --- /dev/null +++ b/src/plugins/wp/tests/wp_bts/oracle_qualif/bts986.0.session/cache/d9121cbf1bf929d8a33ed73cdc206552.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0185, + "steps": 14 } diff --git a/src/plugins/wp/tests/wp_bts/oracle_qualif/bts_1360.0.session/cache/baf52c3966dd21bbba0c7a9c81245af2.json b/src/plugins/wp/tests/wp_bts/oracle_qualif/bts_1360.0.session/cache/baf52c3966dd21bbba0c7a9c81245af2.json new file mode 100644 index 00000000000..b8e36e2803f --- /dev/null +++ b/src/plugins/wp/tests/wp_bts/oracle_qualif/bts_1360.0.session/cache/baf52c3966dd21bbba0c7a9c81245af2.json @@ -0,0 +1 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "timeout", "time": 10. } diff --git a/src/plugins/wp/tests/wp_bts/oracle_qualif/bts_1360.0.session/cache/e832de44187e0b48e1388bf9d9475713.json b/src/plugins/wp/tests/wp_bts/oracle_qualif/bts_1360.0.session/cache/e832de44187e0b48e1388bf9d9475713.json new file mode 100644 index 00000000000..333dc80e3be --- /dev/null +++ b/src/plugins/wp/tests/wp_bts/oracle_qualif/bts_1360.0.session/cache/e832de44187e0b48e1388bf9d9475713.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0183, + "steps": 19 } diff --git a/src/plugins/wp/tests/wp_bts/oracle_qualif/bts_1601.0.session/cache/75f6139d28d2176c962de1fda927c848.json b/src/plugins/wp/tests/wp_bts/oracle_qualif/bts_1601.0.session/cache/75f6139d28d2176c962de1fda927c848.json new file mode 100644 index 00000000000..52114a906fe --- /dev/null +++ b/src/plugins/wp/tests/wp_bts/oracle_qualif/bts_1601.0.session/cache/75f6139d28d2176c962de1fda927c848.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.2655, + "steps": 429 } diff --git a/src/plugins/wp/tests/wp_bts/oracle_qualif/bts_1828.0.session/cache/420e102e36b2fd0c60d608072d4bbb2b.json b/src/plugins/wp/tests/wp_bts/oracle_qualif/bts_1828.0.session/cache/420e102e36b2fd0c60d608072d4bbb2b.json new file mode 100644 index 00000000000..56c39550428 --- /dev/null +++ b/src/plugins/wp/tests/wp_bts/oracle_qualif/bts_1828.0.session/cache/420e102e36b2fd0c60d608072d4bbb2b.json @@ -0,0 +1 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "unknown" } diff --git a/src/plugins/wp/tests/wp_bts/oracle_qualif/bts_1828.0.session/cache/e875e59da9e2107108c67c5c5e48fac1.json b/src/plugins/wp/tests/wp_bts/oracle_qualif/bts_1828.0.session/cache/e875e59da9e2107108c67c5c5e48fac1.json new file mode 100644 index 00000000000..28e4a902e10 --- /dev/null +++ b/src/plugins/wp/tests/wp_bts/oracle_qualif/bts_1828.0.session/cache/e875e59da9e2107108c67c5c5e48fac1.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0128, + "steps": 6 } diff --git a/src/plugins/wp/tests/wp_bts/oracle_qualif/bts_1828.0.session/cache/ffed0f9e761b9b65d16681ee125d45de.json b/src/plugins/wp/tests/wp_bts/oracle_qualif/bts_1828.0.session/cache/ffed0f9e761b9b65d16681ee125d45de.json new file mode 100644 index 00000000000..b8e36e2803f --- /dev/null +++ b/src/plugins/wp/tests/wp_bts/oracle_qualif/bts_1828.0.session/cache/ffed0f9e761b9b65d16681ee125d45de.json @@ -0,0 +1 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "timeout", "time": 10. } diff --git a/src/plugins/wp/tests/wp_bts/oracle_qualif/bts_1828.1.session/cache/e875e59da9e2107108c67c5c5e48fac1.json b/src/plugins/wp/tests/wp_bts/oracle_qualif/bts_1828.1.session/cache/e875e59da9e2107108c67c5c5e48fac1.json new file mode 100644 index 00000000000..bfb9931ec6c --- /dev/null +++ b/src/plugins/wp/tests/wp_bts/oracle_qualif/bts_1828.1.session/cache/e875e59da9e2107108c67c5c5e48fac1.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0157, + "steps": 6 } diff --git a/src/plugins/wp/tests/wp_bts/oracle_qualif/issue-364.0.session/cache/2065ac6b91a5b85360f219bf4cb61e6f.json b/src/plugins/wp/tests/wp_bts/oracle_qualif/issue-364.0.session/cache/2065ac6b91a5b85360f219bf4cb61e6f.json new file mode 100644 index 00000000000..009fab52dfc --- /dev/null +++ b/src/plugins/wp/tests/wp_bts/oracle_qualif/issue-364.0.session/cache/2065ac6b91a5b85360f219bf4cb61e6f.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0291, + "steps": 30 } diff --git a/src/plugins/wp/tests/wp_bts/oracle_qualif/issue-364.0.session/cache/834bd396ea03675670f1d7506bf20204.json b/src/plugins/wp/tests/wp_bts/oracle_qualif/issue-364.0.session/cache/834bd396ea03675670f1d7506bf20204.json new file mode 100644 index 00000000000..10aedde33da --- /dev/null +++ b/src/plugins/wp/tests/wp_bts/oracle_qualif/issue-364.0.session/cache/834bd396ea03675670f1d7506bf20204.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0233, + "steps": 22 } diff --git a/src/plugins/wp/tests/wp_bts/oracle_qualif/issue_494.0.session/cache/23393517d8e9a6945aaf5f8c70de67fd.json b/src/plugins/wp/tests/wp_bts/oracle_qualif/issue_494.0.session/cache/23393517d8e9a6945aaf5f8c70de67fd.json new file mode 100644 index 00000000000..1bd7d90332a --- /dev/null +++ b/src/plugins/wp/tests/wp_bts/oracle_qualif/issue_494.0.session/cache/23393517d8e9a6945aaf5f8c70de67fd.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0206, + "steps": 12 } diff --git a/src/plugins/wp/tests/wp_bts/oracle_qualif/issue_508.0.session/cache/1025ed1b7e69c8126064452d7cfa2035.json b/src/plugins/wp/tests/wp_bts/oracle_qualif/issue_508.0.session/cache/1025ed1b7e69c8126064452d7cfa2035.json new file mode 100644 index 00000000000..21d07dfcce6 --- /dev/null +++ b/src/plugins/wp/tests/wp_bts/oracle_qualif/issue_508.0.session/cache/1025ed1b7e69c8126064452d7cfa2035.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0425, + "steps": 58 } diff --git a/src/plugins/wp/tests/wp_bts/oracle_qualif/issue_715_b.0.session/cache/9bd0456062678ca3e8613d336cf8a543.json b/src/plugins/wp/tests/wp_bts/oracle_qualif/issue_715_b.0.session/cache/9bd0456062678ca3e8613d336cf8a543.json new file mode 100644 index 00000000000..67ddfe4ca31 --- /dev/null +++ b/src/plugins/wp/tests/wp_bts/oracle_qualif/issue_715_b.0.session/cache/9bd0456062678ca3e8613d336cf8a543.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0149, + "steps": 13 } diff --git a/src/plugins/wp/tests/wp_bts/oracle_qualif/issue_751.0.session/cache/b02c74702da73481b452499d0feb4af7.json b/src/plugins/wp/tests/wp_bts/oracle_qualif/issue_751.0.session/cache/b02c74702da73481b452499d0feb4af7.json new file mode 100644 index 00000000000..058bb4ba862 --- /dev/null +++ b/src/plugins/wp/tests/wp_bts/oracle_qualif/issue_751.0.session/cache/b02c74702da73481b452499d0feb4af7.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0635, + "steps": 47 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/find.0.session/cache/10e70a38e2154839eaae1f1af07fdefc.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/find.0.session/cache/10e70a38e2154839eaae1f1af07fdefc.json new file mode 100644 index 00000000000..f670c9122fd --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/find.0.session/cache/10e70a38e2154839eaae1f1af07fdefc.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.034, + "steps": 58 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/find.0.session/cache/135f708793f6fbdc42f4f9d1d1a915c3.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/find.0.session/cache/135f708793f6fbdc42f4f9d1d1a915c3.json new file mode 100644 index 00000000000..434184afe96 --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/find.0.session/cache/135f708793f6fbdc42f4f9d1d1a915c3.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0394, + "steps": 79 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/find.0.session/cache/196d356f0ee751ff8133066d78d7929c.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/find.0.session/cache/196d356f0ee751ff8133066d78d7929c.json new file mode 100644 index 00000000000..c709a343f42 --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/find.0.session/cache/196d356f0ee751ff8133066d78d7929c.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0427, + "steps": 106 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/find.0.session/cache/19d9f4b1d3439b94533a38f9eb1a9457.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/find.0.session/cache/19d9f4b1d3439b94533a38f9eb1a9457.json new file mode 100644 index 00000000000..a94f32a0734 --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/find.0.session/cache/19d9f4b1d3439b94533a38f9eb1a9457.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0128, + "steps": 14 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/find.0.session/cache/1a1c741b4fc7ec6915e77dfd6219af40.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/find.0.session/cache/1a1c741b4fc7ec6915e77dfd6219af40.json new file mode 100644 index 00000000000..b21eb75775a --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/find.0.session/cache/1a1c741b4fc7ec6915e77dfd6219af40.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0278, + "steps": 61 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/find.0.session/cache/1cdcca3d343f4d3666de43999a2859ca.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/find.0.session/cache/1cdcca3d343f4d3666de43999a2859ca.json new file mode 100644 index 00000000000..3ac53c81763 --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/find.0.session/cache/1cdcca3d343f4d3666de43999a2859ca.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0754, + "steps": 120 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/find.0.session/cache/1eca7fb782936ff88f49a91e6dcd344c.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/find.0.session/cache/1eca7fb782936ff88f49a91e6dcd344c.json new file mode 100644 index 00000000000..7a31f06fb91 --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/find.0.session/cache/1eca7fb782936ff88f49a91e6dcd344c.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0205, + "steps": 22 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/find.0.session/cache/1f176d5e2b1db0d6e22c16c743220569.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/find.0.session/cache/1f176d5e2b1db0d6e22c16c743220569.json new file mode 100644 index 00000000000..61f2a1a0e15 --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/find.0.session/cache/1f176d5e2b1db0d6e22c16c743220569.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0206, + "steps": 17 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/find.0.session/cache/2a7b0348cb3cbb4fcbfad39cfd486e74.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/find.0.session/cache/2a7b0348cb3cbb4fcbfad39cfd486e74.json new file mode 100644 index 00000000000..bffd6443d67 --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/find.0.session/cache/2a7b0348cb3cbb4fcbfad39cfd486e74.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.1732, + "steps": 221 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/find.0.session/cache/3505ecb809a014f95037869b0e9856e2.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/find.0.session/cache/3505ecb809a014f95037869b0e9856e2.json new file mode 100644 index 00000000000..9d250f0216d --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/find.0.session/cache/3505ecb809a014f95037869b0e9856e2.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0168, + "steps": 14 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/find.0.session/cache/3c7a12cba6964122ac5a406e963e0bac.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/find.0.session/cache/3c7a12cba6964122ac5a406e963e0bac.json new file mode 100644 index 00000000000..dd7fbf5566c --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/find.0.session/cache/3c7a12cba6964122ac5a406e963e0bac.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.018, + "steps": 13 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/find.0.session/cache/42a0fc36bd9559b12c9d5c9ca7e6e427.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/find.0.session/cache/42a0fc36bd9559b12c9d5c9ca7e6e427.json new file mode 100644 index 00000000000..0421126b2db --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/find.0.session/cache/42a0fc36bd9559b12c9d5c9ca7e6e427.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0142, + "steps": 22 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/find.0.session/cache/493aed7b8f27b8c3737d5175c5888710.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/find.0.session/cache/493aed7b8f27b8c3737d5175c5888710.json new file mode 100644 index 00000000000..08288b910b9 --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/find.0.session/cache/493aed7b8f27b8c3737d5175c5888710.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0307, + "steps": 69 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/find.0.session/cache/5610a35160a9c2fa66735e0a84235057.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/find.0.session/cache/5610a35160a9c2fa66735e0a84235057.json new file mode 100644 index 00000000000..c506aea2841 --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/find.0.session/cache/5610a35160a9c2fa66735e0a84235057.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.032, + "steps": 47 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/find.0.session/cache/5b41f41e7e6bfe1b5f2a7e510adfcc40.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/find.0.session/cache/5b41f41e7e6bfe1b5f2a7e510adfcc40.json new file mode 100644 index 00000000000..c7468e8581e --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/find.0.session/cache/5b41f41e7e6bfe1b5f2a7e510adfcc40.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0158, + "steps": 21 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/find.0.session/cache/68bff29417d8a9a908b65a5cdcb559a8.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/find.0.session/cache/68bff29417d8a9a908b65a5cdcb559a8.json new file mode 100644 index 00000000000..cc532b9dabc --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/find.0.session/cache/68bff29417d8a9a908b65a5cdcb559a8.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0157, + "steps": 12 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/find.0.session/cache/72222d01b03c631765b96be604890d30.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/find.0.session/cache/72222d01b03c631765b96be604890d30.json new file mode 100644 index 00000000000..9595cc22cc6 --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/find.0.session/cache/72222d01b03c631765b96be604890d30.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0147, + "steps": 13 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/find.0.session/cache/7c34d2375d6a48a8a2126c8574daacfd.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/find.0.session/cache/7c34d2375d6a48a8a2126c8574daacfd.json new file mode 100644 index 00000000000..a07c54a1e67 --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/find.0.session/cache/7c34d2375d6a48a8a2126c8574daacfd.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0242, + "steps": 32 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/find.0.session/cache/7dd61d8b30a0d3a1046e8cd99ddf1261.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/find.0.session/cache/7dd61d8b30a0d3a1046e8cd99ddf1261.json new file mode 100644 index 00000000000..c3d1c994791 --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/find.0.session/cache/7dd61d8b30a0d3a1046e8cd99ddf1261.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0184, + "steps": 25 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/find.0.session/cache/84634dd1a45d865c6efeca0f4ab49056.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/find.0.session/cache/84634dd1a45d865c6efeca0f4ab49056.json new file mode 100644 index 00000000000..419d06ca5df --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/find.0.session/cache/84634dd1a45d865c6efeca0f4ab49056.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0209, + "steps": 41 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/find.0.session/cache/8496a6c0c66a6097c0cc03d173f00c85.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/find.0.session/cache/8496a6c0c66a6097c0cc03d173f00c85.json new file mode 100644 index 00000000000..a7353a8dcfb --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/find.0.session/cache/8496a6c0c66a6097c0cc03d173f00c85.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0268, + "steps": 45 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/find.0.session/cache/91c9d1dc4216af4315c0cc5b197aa492.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/find.0.session/cache/91c9d1dc4216af4315c0cc5b197aa492.json new file mode 100644 index 00000000000..f8b172ef52a --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/find.0.session/cache/91c9d1dc4216af4315c0cc5b197aa492.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0185, + "steps": 30 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/find.0.session/cache/a37053af97bb1db4be167ff7423d4db8.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/find.0.session/cache/a37053af97bb1db4be167ff7423d4db8.json new file mode 100644 index 00000000000..595f9b1d615 --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/find.0.session/cache/a37053af97bb1db4be167ff7423d4db8.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0178, + "steps": 29 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/find.0.session/cache/a97aa29b9f62010d94b1cbab03e4674f.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/find.0.session/cache/a97aa29b9f62010d94b1cbab03e4674f.json new file mode 100644 index 00000000000..640fdc7ce09 --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/find.0.session/cache/a97aa29b9f62010d94b1cbab03e4674f.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0178, + "steps": 20 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/find.0.session/cache/b3f4583c783aed5095d5f9366f0c583b.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/find.0.session/cache/b3f4583c783aed5095d5f9366f0c583b.json new file mode 100644 index 00000000000..46ffc81e4b2 --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/find.0.session/cache/b3f4583c783aed5095d5f9366f0c583b.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.1054, + "steps": 177 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/find.0.session/cache/bf04376f6c833a40b4eef1681e1b30f1.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/find.0.session/cache/bf04376f6c833a40b4eef1681e1b30f1.json new file mode 100644 index 00000000000..2e660c334b0 --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/find.0.session/cache/bf04376f6c833a40b4eef1681e1b30f1.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0282, + "steps": 29 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/find.0.session/cache/e1499a3b76fe2f4b3db4526b4115ff49.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/find.0.session/cache/e1499a3b76fe2f4b3db4526b4115ff49.json new file mode 100644 index 00000000000..ae1766bb292 --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/find.0.session/cache/e1499a3b76fe2f4b3db4526b4115ff49.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0248, + "steps": 36 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/find.0.session/cache/f6df7d034c012e8f2ce7865d478879d5.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/find.0.session/cache/f6df7d034c012e8f2ce7865d478879d5.json new file mode 100644 index 00000000000..5932bc52077 --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/find.0.session/cache/f6df7d034c012e8f2ce7865d478879d5.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0417, + "steps": 54 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo1_solved.0.session/cache/09bf4ce202d8fe39b4526829cb133533.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo1_solved.0.session/cache/09bf4ce202d8fe39b4526829cb133533.json new file mode 100644 index 00000000000..a67ba7fad7e --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo1_solved.0.session/cache/09bf4ce202d8fe39b4526829cb133533.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0133, + "steps": 13 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo1_solved.0.session/cache/12c217a27c7139d5f30742273bb085d0.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo1_solved.0.session/cache/12c217a27c7139d5f30742273bb085d0.json new file mode 100644 index 00000000000..ff73660513c --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo1_solved.0.session/cache/12c217a27c7139d5f30742273bb085d0.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.028, + "steps": 51 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo1_solved.0.session/cache/14128ab2ffe87237e86d3203305033e7.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo1_solved.0.session/cache/14128ab2ffe87237e86d3203305033e7.json new file mode 100644 index 00000000000..9db7a92407f --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo1_solved.0.session/cache/14128ab2ffe87237e86d3203305033e7.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0294, + "steps": 47 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo1_solved.0.session/cache/1b66f8317c14095c081f7afd5b594741.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo1_solved.0.session/cache/1b66f8317c14095c081f7afd5b594741.json new file mode 100644 index 00000000000..596e6221f9d --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo1_solved.0.session/cache/1b66f8317c14095c081f7afd5b594741.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0732, + "steps": 163 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo1_solved.0.session/cache/40b6423d8ddcdc8d72f113ee27b56d23.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo1_solved.0.session/cache/40b6423d8ddcdc8d72f113ee27b56d23.json new file mode 100644 index 00000000000..97af8d5b090 --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo1_solved.0.session/cache/40b6423d8ddcdc8d72f113ee27b56d23.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0219, + "steps": 31 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo1_solved.0.session/cache/415e18fe08911875e6c12f7bad3309c4.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo1_solved.0.session/cache/415e18fe08911875e6c12f7bad3309c4.json new file mode 100644 index 00000000000..bc10b59a310 --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo1_solved.0.session/cache/415e18fe08911875e6c12f7bad3309c4.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0139, + "steps": 25 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo1_solved.0.session/cache/7622228a2ace3b4ea6973fb817034fe1.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo1_solved.0.session/cache/7622228a2ace3b4ea6973fb817034fe1.json new file mode 100644 index 00000000000..f4cb006c2a1 --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo1_solved.0.session/cache/7622228a2ace3b4ea6973fb817034fe1.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0208, + "steps": 36 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo1_solved.0.session/cache/7841f539527a85329546eb99578ee528.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo1_solved.0.session/cache/7841f539527a85329546eb99578ee528.json new file mode 100644 index 00000000000..2a52a12e552 --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo1_solved.0.session/cache/7841f539527a85329546eb99578ee528.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0361, + "steps": 51 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo1_solved.0.session/cache/f546de791b323fbc7cd8207ceb72043b.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo1_solved.0.session/cache/f546de791b323fbc7cd8207ceb72043b.json new file mode 100644 index 00000000000..e0bdb82d1bf --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo1_solved.0.session/cache/f546de791b323fbc7cd8207ceb72043b.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0148, + "steps": 20 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo2_solved.0.session/cache/0446f6215cc2b5ece0a84642b8a23227.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo2_solved.0.session/cache/0446f6215cc2b5ece0a84642b8a23227.json new file mode 100644 index 00000000000..b98ccd2f781 --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo2_solved.0.session/cache/0446f6215cc2b5ece0a84642b8a23227.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0211, + "steps": 31 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo2_solved.0.session/cache/1ae181b24023bef5693b9686ebcfebc5.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo2_solved.0.session/cache/1ae181b24023bef5693b9686ebcfebc5.json new file mode 100644 index 00000000000..713c9c9d04f --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo2_solved.0.session/cache/1ae181b24023bef5693b9686ebcfebc5.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0965, + "steps": 88 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo2_solved.0.session/cache/264a621e237c98dca54cad8896fc45f1.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo2_solved.0.session/cache/264a621e237c98dca54cad8896fc45f1.json new file mode 100644 index 00000000000..306d62ba68a --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo2_solved.0.session/cache/264a621e237c98dca54cad8896fc45f1.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0245, + "steps": 41 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo2_solved.0.session/cache/3ce33a0a8dd65193f55247eca68d0add.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo2_solved.0.session/cache/3ce33a0a8dd65193f55247eca68d0add.json new file mode 100644 index 00000000000..c3d0ba8cd90 --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo2_solved.0.session/cache/3ce33a0a8dd65193f55247eca68d0add.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0268, + "steps": 14 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo2_solved.0.session/cache/5ffb302fc24b5d55cfba13e1b133442e.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo2_solved.0.session/cache/5ffb302fc24b5d55cfba13e1b133442e.json new file mode 100644 index 00000000000..6657051d53b --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo2_solved.0.session/cache/5ffb302fc24b5d55cfba13e1b133442e.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0308, + "steps": 52 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo2_solved.0.session/cache/646c4849b1b86e71a02ed6b4e22a5e5a.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo2_solved.0.session/cache/646c4849b1b86e71a02ed6b4e22a5e5a.json new file mode 100644 index 00000000000..6d32ee5d789 --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo2_solved.0.session/cache/646c4849b1b86e71a02ed6b4e22a5e5a.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0233, + "steps": 17 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo2_solved.0.session/cache/8328e1c16a7f7be1c88cb684053fd185.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo2_solved.0.session/cache/8328e1c16a7f7be1c88cb684053fd185.json new file mode 100644 index 00000000000..aa7bae01e6e --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo2_solved.0.session/cache/8328e1c16a7f7be1c88cb684053fd185.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0398, + "steps": 61 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo2_solved.0.session/cache/839040132fbcfc4d3618a0fd1ed7c357.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo2_solved.0.session/cache/839040132fbcfc4d3618a0fd1ed7c357.json new file mode 100644 index 00000000000..81f56ee0213 --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo2_solved.0.session/cache/839040132fbcfc4d3618a0fd1ed7c357.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0365, + "steps": 32 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo2_solved.0.session/cache/93059dee8bcf5e3a31af3752b3b47c07.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo2_solved.0.session/cache/93059dee8bcf5e3a31af3752b3b47c07.json new file mode 100644 index 00000000000..f89608473a0 --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo2_solved.0.session/cache/93059dee8bcf5e3a31af3752b3b47c07.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0374, + "steps": 46 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo2_solved.0.session/cache/944a7d63361ee9d7e563e26d0a674bee.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo2_solved.0.session/cache/944a7d63361ee9d7e563e26d0a674bee.json new file mode 100644 index 00000000000..7aa6d00f113 --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo2_solved.0.session/cache/944a7d63361ee9d7e563e26d0a674bee.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.2937, + "steps": 531 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo2_solved.0.session/cache/a6b4cc7471adb5a2d0e53268d885e407.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo2_solved.0.session/cache/a6b4cc7471adb5a2d0e53268d885e407.json new file mode 100644 index 00000000000..2e7c9d72195 --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo2_solved.0.session/cache/a6b4cc7471adb5a2d0e53268d885e407.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0144, + "steps": 16 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo2_solved.0.session/cache/d0e0a407fb1103313547ae958851d341.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo2_solved.0.session/cache/d0e0a407fb1103313547ae958851d341.json new file mode 100644 index 00000000000..19bd1f91111 --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo2_solved.0.session/cache/d0e0a407fb1103313547ae958851d341.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.028, + "steps": 47 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo2_solved.0.session/cache/f2fc829e259a63aa018c8f5cf2ad51c0.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo2_solved.0.session/cache/f2fc829e259a63aa018c8f5cf2ad51c0.json new file mode 100644 index 00000000000..710cf5b30a1 --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo2_solved.0.session/cache/f2fc829e259a63aa018c8f5cf2ad51c0.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0638, + "steps": 140 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.0.session/cache/0126fde627766c5e80152d3092ba2aee.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.0.session/cache/0126fde627766c5e80152d3092ba2aee.json new file mode 100644 index 00000000000..ddd6f5521cd --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.0.session/cache/0126fde627766c5e80152d3092ba2aee.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0347, + "steps": 110 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.0.session/cache/0818d1c09010d257ad8c6815571d99c3.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.0.session/cache/0818d1c09010d257ad8c6815571d99c3.json new file mode 100644 index 00000000000..c5d54835903 --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.0.session/cache/0818d1c09010d257ad8c6815571d99c3.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0799, + "steps": 183 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.0.session/cache/102640ec6d1d7a8943086db5f48bebc0.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.0.session/cache/102640ec6d1d7a8943086db5f48bebc0.json new file mode 100644 index 00000000000..ca98c49b000 --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.0.session/cache/102640ec6d1d7a8943086db5f48bebc0.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 1.0526, + "steps": 587 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.0.session/cache/1241313db0937a5391841138a16626ef.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.0.session/cache/1241313db0937a5391841138a16626ef.json new file mode 100644 index 00000000000..ce1e185b09e --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.0.session/cache/1241313db0937a5391841138a16626ef.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.7961, + "steps": 443 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.0.session/cache/1722ca0d2e1d91ed7b209013be7aea8f.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.0.session/cache/1722ca0d2e1d91ed7b209013be7aea8f.json new file mode 100644 index 00000000000..0badff24098 --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.0.session/cache/1722ca0d2e1d91ed7b209013be7aea8f.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0472, + "steps": 119 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.0.session/cache/4b25798e4a62bf641694ca833c687e01.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.0.session/cache/4b25798e4a62bf641694ca833c687e01.json new file mode 100644 index 00000000000..00c336fba55 --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.0.session/cache/4b25798e4a62bf641694ca833c687e01.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.5583, + "steps": 327 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.0.session/cache/51a0fccaa9c5a1f25e08d0458ea80328.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.0.session/cache/51a0fccaa9c5a1f25e08d0458ea80328.json new file mode 100644 index 00000000000..90802945ba0 --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.0.session/cache/51a0fccaa9c5a1f25e08d0458ea80328.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0776, + "steps": 121 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.0.session/cache/55e7e2a928f55171c0e6181cae34c889.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.0.session/cache/55e7e2a928f55171c0e6181cae34c889.json new file mode 100644 index 00000000000..a6a2d85616e --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.0.session/cache/55e7e2a928f55171c0e6181cae34c889.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 1.1315, + "steps": 480 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.0.session/cache/5c661be4ce7386b877644ffa77d309d7.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.0.session/cache/5c661be4ce7386b877644ffa77d309d7.json new file mode 100644 index 00000000000..8dfec9e3cb7 --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.0.session/cache/5c661be4ce7386b877644ffa77d309d7.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0187, + "steps": 34 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.0.session/cache/61afefe4a097e7a7c785f3f4711f0081.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.0.session/cache/61afefe4a097e7a7c785f3f4711f0081.json new file mode 100644 index 00000000000..4fdaf6b766a --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.0.session/cache/61afefe4a097e7a7c785f3f4711f0081.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0425, + "steps": 88 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.0.session/cache/682f9aad475f771ccd7cdc3bf7f9c96a.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.0.session/cache/682f9aad475f771ccd7cdc3bf7f9c96a.json new file mode 100644 index 00000000000..919a3cc373f --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.0.session/cache/682f9aad475f771ccd7cdc3bf7f9c96a.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0347, + "steps": 100 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.0.session/cache/6ae4f6e0ab89bc7fc2e2cf55211c6247.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.0.session/cache/6ae4f6e0ab89bc7fc2e2cf55211c6247.json new file mode 100644 index 00000000000..d6f70c831e6 --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.0.session/cache/6ae4f6e0ab89bc7fc2e2cf55211c6247.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0173, + "steps": 25 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.0.session/cache/6f4fec2bff531d88deff253886a30de4.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.0.session/cache/6f4fec2bff531d88deff253886a30de4.json new file mode 100644 index 00000000000..0b26814ab8a --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.0.session/cache/6f4fec2bff531d88deff253886a30de4.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0731, + "steps": 148 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.0.session/cache/94cad0bd9e2c593f0562adbf518c46e5.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.0.session/cache/94cad0bd9e2c593f0562adbf518c46e5.json new file mode 100644 index 00000000000..047c8691baa --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.0.session/cache/94cad0bd9e2c593f0562adbf518c46e5.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.045, + "steps": 122 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.0.session/cache/a3d422cc76ed132eeee720e81a464390.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.0.session/cache/a3d422cc76ed132eeee720e81a464390.json new file mode 100644 index 00000000000..b1ca0306ed4 --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.0.session/cache/a3d422cc76ed132eeee720e81a464390.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0233, + "steps": 36 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.0.session/cache/b1283c4ee81ea5f47112cda8ecef4271.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.0.session/cache/b1283c4ee81ea5f47112cda8ecef4271.json new file mode 100644 index 00000000000..b8d0a2bbb72 --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.0.session/cache/b1283c4ee81ea5f47112cda8ecef4271.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0486, + "steps": 119 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.0.session/cache/c20b5a7aa139ba61a8805faf4dae831d.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.0.session/cache/c20b5a7aa139ba61a8805faf4dae831d.json new file mode 100644 index 00000000000..2d7d172993f --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.0.session/cache/c20b5a7aa139ba61a8805faf4dae831d.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0177, + "steps": 21 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.0.session/cache/c849712dfd490b5807a8ff59bc39dc34.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.0.session/cache/c849712dfd490b5807a8ff59bc39dc34.json new file mode 100644 index 00000000000..836c1303de9 --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.0.session/cache/c849712dfd490b5807a8ff59bc39dc34.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 1.028, + "steps": 312 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.0.session/cache/d3420889a7d9c7949b2d1f7715ad1591.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.0.session/cache/d3420889a7d9c7949b2d1f7715ad1591.json new file mode 100644 index 00000000000..a0c4e1cc3d4 --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.0.session/cache/d3420889a7d9c7949b2d1f7715ad1591.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0139, + "steps": 22 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.0.session/cache/d3ecbb7211cf7ee8fa1710e0d6276a98.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.0.session/cache/d3ecbb7211cf7ee8fa1710e0d6276a98.json new file mode 100644 index 00000000000..007b424c28b --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.0.session/cache/d3ecbb7211cf7ee8fa1710e0d6276a98.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.2094, + "steps": 245 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.0.session/cache/e7910d533bc9cd3f26f0a2db15a2628f.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.0.session/cache/e7910d533bc9cd3f26f0a2db15a2628f.json new file mode 100644 index 00000000000..9f75f9268d0 --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.0.session/cache/e7910d533bc9cd3f26f0a2db15a2628f.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0535, + "steps": 153 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.v2.0.session/cache/1da20b026e23dace33f59b4fe30cf704.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.v2.0.session/cache/1da20b026e23dace33f59b4fe30cf704.json new file mode 100644 index 00000000000..ef20f30e9c4 --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.v2.0.session/cache/1da20b026e23dace33f59b4fe30cf704.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.168, + "steps": 248 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.v2.0.session/cache/26477daefc637e3827acaa7cf7867619.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.v2.0.session/cache/26477daefc637e3827acaa7cf7867619.json new file mode 100644 index 00000000000..ad9932dd701 --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.v2.0.session/cache/26477daefc637e3827acaa7cf7867619.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0305, + "steps": 45 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.v2.0.session/cache/2e634a920437c83054eec1a07f763cd9.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.v2.0.session/cache/2e634a920437c83054eec1a07f763cd9.json new file mode 100644 index 00000000000..d7d80c5f3a2 --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.v2.0.session/cache/2e634a920437c83054eec1a07f763cd9.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0228, + "steps": 41 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.v2.0.session/cache/386154e29073d9acf9fbbc284ccff087.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.v2.0.session/cache/386154e29073d9acf9fbbc284ccff087.json new file mode 100644 index 00000000000..9b5c6ea23de --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.v2.0.session/cache/386154e29073d9acf9fbbc284ccff087.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0604, + "steps": 68 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.v2.0.session/cache/3be45a6c1d0da2f96f8c1e424a7ab67a.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.v2.0.session/cache/3be45a6c1d0da2f96f8c1e424a7ab67a.json new file mode 100644 index 00000000000..3f874576dfd --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.v2.0.session/cache/3be45a6c1d0da2f96f8c1e424a7ab67a.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0787, + "steps": 160 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.v2.0.session/cache/3f218707b6712edd9bd1d69daa728c14.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.v2.0.session/cache/3f218707b6712edd9bd1d69daa728c14.json new file mode 100644 index 00000000000..44223ecdd6d --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.v2.0.session/cache/3f218707b6712edd9bd1d69daa728c14.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.1211, + "steps": 263 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.v2.0.session/cache/4dab6dd8ae580689cfd0d1ba4875ec2d.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.v2.0.session/cache/4dab6dd8ae580689cfd0d1ba4875ec2d.json new file mode 100644 index 00000000000..469ddd3aca2 --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.v2.0.session/cache/4dab6dd8ae580689cfd0d1ba4875ec2d.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0314, + "steps": 70 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.v2.0.session/cache/4dd3ca5f4c88877a589aae7858e95d76.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.v2.0.session/cache/4dd3ca5f4c88877a589aae7858e95d76.json new file mode 100644 index 00000000000..7f5128346ef --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.v2.0.session/cache/4dd3ca5f4c88877a589aae7858e95d76.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0888, + "steps": 101 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.v2.0.session/cache/5502d8c13d4b19675da7ec1d6fde0e81.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.v2.0.session/cache/5502d8c13d4b19675da7ec1d6fde0e81.json new file mode 100644 index 00000000000..bfbc9fdd6d3 --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.v2.0.session/cache/5502d8c13d4b19675da7ec1d6fde0e81.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0265, + "steps": 29 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.v2.0.session/cache/57a1707949cda96266d7a170ab0db4ed.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.v2.0.session/cache/57a1707949cda96266d7a170ab0db4ed.json new file mode 100644 index 00000000000..7adcc594c86 --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.v2.0.session/cache/57a1707949cda96266d7a170ab0db4ed.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0323, + "steps": 48 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.v2.0.session/cache/597c3ce8a628b364884f7aae153eb0f7.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.v2.0.session/cache/597c3ce8a628b364884f7aae153eb0f7.json new file mode 100644 index 00000000000..cc01a769e36 --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.v2.0.session/cache/597c3ce8a628b364884f7aae153eb0f7.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.1069, + "steps": 182 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.v2.0.session/cache/69aed695592a136372272f0976cb7cb0.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.v2.0.session/cache/69aed695592a136372272f0976cb7cb0.json new file mode 100644 index 00000000000..53b4dd8bc9c --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.v2.0.session/cache/69aed695592a136372272f0976cb7cb0.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0249, + "steps": 30 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.v2.0.session/cache/6d31b5b9261d0201d9d5d613d393fca5.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.v2.0.session/cache/6d31b5b9261d0201d9d5d613d393fca5.json new file mode 100644 index 00000000000..00a668d1f99 --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.v2.0.session/cache/6d31b5b9261d0201d9d5d613d393fca5.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0345, + "steps": 70 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.v2.0.session/cache/70261faccb832e91f3b93fc06ab58117.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.v2.0.session/cache/70261faccb832e91f3b93fc06ab58117.json new file mode 100644 index 00000000000..2e3092ce8d6 --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.v2.0.session/cache/70261faccb832e91f3b93fc06ab58117.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0309, + "steps": 39 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.v2.0.session/cache/76671ff5da324cf7df7b1795b2b206e2.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.v2.0.session/cache/76671ff5da324cf7df7b1795b2b206e2.json new file mode 100644 index 00000000000..36a40ac37b5 --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.v2.0.session/cache/76671ff5da324cf7df7b1795b2b206e2.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0195, + "steps": 30 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.v2.0.session/cache/82652d462ec64309a7df17f1c5d545e1.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.v2.0.session/cache/82652d462ec64309a7df17f1c5d545e1.json new file mode 100644 index 00000000000..218ae2ed932 --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.v2.0.session/cache/82652d462ec64309a7df17f1c5d545e1.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0279, + "steps": 38 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.v2.0.session/cache/a7fffe44ad3c1effe6026e43591942ce.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.v2.0.session/cache/a7fffe44ad3c1effe6026e43591942ce.json new file mode 100644 index 00000000000..16191d44cd9 --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.v2.0.session/cache/a7fffe44ad3c1effe6026e43591942ce.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0276, + "steps": 39 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.v2.0.session/cache/a8a8445ca94c28d23a1a736558e69c8c.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.v2.0.session/cache/a8a8445ca94c28d23a1a736558e69c8c.json new file mode 100644 index 00000000000..306e6ae307f --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.v2.0.session/cache/a8a8445ca94c28d23a1a736558e69c8c.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0373, + "steps": 60 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.v2.0.session/cache/b5e466768f27e36ace65e700da4c6762.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.v2.0.session/cache/b5e466768f27e36ace65e700da4c6762.json new file mode 100644 index 00000000000..2b8186ff356 --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.v2.0.session/cache/b5e466768f27e36ace65e700da4c6762.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0507, + "steps": 54 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.v2.0.session/cache/b6b84b8aa7e49ae4e58e874d380e52ec.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.v2.0.session/cache/b6b84b8aa7e49ae4e58e874d380e52ec.json new file mode 100644 index 00000000000..bfb1979b47d --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.v2.0.session/cache/b6b84b8aa7e49ae4e58e874d380e52ec.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0346, + "steps": 42 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.v2.0.session/cache/c0517fb8e7353916d3a8af59a55cfe96.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.v2.0.session/cache/c0517fb8e7353916d3a8af59a55cfe96.json new file mode 100644 index 00000000000..784f0d60627 --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.v2.0.session/cache/c0517fb8e7353916d3a8af59a55cfe96.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.022, + "steps": 40 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.v2.0.session/cache/f3c1620b867b46248a65cace35447c1f.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.v2.0.session/cache/f3c1620b867b46248a65cace35447c1f.json new file mode 100644 index 00000000000..d2040ad1c53 --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.v2.0.session/cache/f3c1620b867b46248a65cace35447c1f.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0705, + "steps": 96 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.v2.0.session/cache/f7589a89ccb1575e24730fc330fcf0d0.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.v2.0.session/cache/f7589a89ccb1575e24730fc330fcf0d0.json new file mode 100644 index 00000000000..634c1bf1abc --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.old.v2.0.session/cache/f7589a89ccb1575e24730fc330fcf0d0.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.1556, + "steps": 151 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.simplified.0.session/cache/0d38200a674100ddfe7feec44eb47f95.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.simplified.0.session/cache/0d38200a674100ddfe7feec44eb47f95.json new file mode 100644 index 00000000000..eb0bd989f35 --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.simplified.0.session/cache/0d38200a674100ddfe7feec44eb47f95.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0211, + "steps": 50 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.simplified.0.session/cache/146ba3796f4ee4106a5e8667bd7c3f50.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.simplified.0.session/cache/146ba3796f4ee4106a5e8667bd7c3f50.json new file mode 100644 index 00000000000..53ae21925ee --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.simplified.0.session/cache/146ba3796f4ee4106a5e8667bd7c3f50.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0281, + "steps": 59 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.simplified.0.session/cache/1c7541e16fa613b0a976bfc393da96ed.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.simplified.0.session/cache/1c7541e16fa613b0a976bfc393da96ed.json new file mode 100644 index 00000000000..323a991058c --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.simplified.0.session/cache/1c7541e16fa613b0a976bfc393da96ed.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0162, + "steps": 25 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.simplified.0.session/cache/1d98ee567fabc1936f14d72a0a2a19e6.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.simplified.0.session/cache/1d98ee567fabc1936f14d72a0a2a19e6.json new file mode 100644 index 00000000000..93f8f903e6d --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.simplified.0.session/cache/1d98ee567fabc1936f14d72a0a2a19e6.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.053, + "steps": 62 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.simplified.0.session/cache/20c6bfbc4023e7a48004f3a7eb2ad3e5.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.simplified.0.session/cache/20c6bfbc4023e7a48004f3a7eb2ad3e5.json new file mode 100644 index 00000000000..28d63ba046f --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.simplified.0.session/cache/20c6bfbc4023e7a48004f3a7eb2ad3e5.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0139, + "steps": 17 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.simplified.0.session/cache/34b5e8da6fcfd4368079c11b0279db8f.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.simplified.0.session/cache/34b5e8da6fcfd4368079c11b0279db8f.json new file mode 100644 index 00000000000..68290fa0b6c --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.simplified.0.session/cache/34b5e8da6fcfd4368079c11b0279db8f.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0169, + "steps": 22 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.simplified.0.session/cache/45db19c6faa1857dc87eb5a34ce27371.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.simplified.0.session/cache/45db19c6faa1857dc87eb5a34ce27371.json new file mode 100644 index 00000000000..f57c130beec --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.simplified.0.session/cache/45db19c6faa1857dc87eb5a34ce27371.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.2493, + "steps": 154 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.simplified.0.session/cache/56a7807ae39f0ecb4e627be901632939.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.simplified.0.session/cache/56a7807ae39f0ecb4e627be901632939.json new file mode 100644 index 00000000000..6269a67dc59 --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.simplified.0.session/cache/56a7807ae39f0ecb4e627be901632939.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0229, + "steps": 50 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.simplified.0.session/cache/90300cb727c65d761a7f041a9b946827.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.simplified.0.session/cache/90300cb727c65d761a7f041a9b946827.json new file mode 100644 index 00000000000..f23c95c2d41 --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.simplified.0.session/cache/90300cb727c65d761a7f041a9b946827.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0289, + "steps": 46 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.simplified.0.session/cache/93fc40b2b5154a19653646b42b6c2df6.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.simplified.0.session/cache/93fc40b2b5154a19653646b42b6c2df6.json new file mode 100644 index 00000000000..61108d07ace --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.simplified.0.session/cache/93fc40b2b5154a19653646b42b6c2df6.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0264, + "steps": 48 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.simplified.0.session/cache/951e03065266dffb0914d1775c1ad10c.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.simplified.0.session/cache/951e03065266dffb0914d1775c1ad10c.json new file mode 100644 index 00000000000..7535763b8ff --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.simplified.0.session/cache/951e03065266dffb0914d1775c1ad10c.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.047, + "steps": 72 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.simplified.0.session/cache/b4b46240c49a9f0ef2530dea215e1919.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.simplified.0.session/cache/b4b46240c49a9f0ef2530dea215e1919.json new file mode 100644 index 00000000000..1e28fc19231 --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.simplified.0.session/cache/b4b46240c49a9f0ef2530dea215e1919.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0179, + "steps": 28 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.simplified.0.session/cache/c5d6eefd823963da7ca16544bc3f3912.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.simplified.0.session/cache/c5d6eefd823963da7ca16544bc3f3912.json new file mode 100644 index 00000000000..561c62c2308 --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.simplified.0.session/cache/c5d6eefd823963da7ca16544bc3f3912.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.059, + "steps": 101 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.simplified.0.session/cache/f17c3d079b701186ae67cf3c2a6a0277.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.simplified.0.session/cache/f17c3d079b701186ae67cf3c2a6a0277.json new file mode 100644 index 00000000000..88ebb6ea24e --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.simplified.0.session/cache/f17c3d079b701186ae67cf3c2a6a0277.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0142, + "steps": 18 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.simplified.0.session/cache/fb2a96c00753836cd4d75f4c8ebfd06f.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.simplified.0.session/cache/fb2a96c00753836cd4d75f4c8ebfd06f.json new file mode 100644 index 00000000000..b5f95779695 --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_exo3_solved.simplified.0.session/cache/fb2a96c00753836cd4d75f4c8ebfd06f.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0287, + "steps": 18 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/059ee2fae3aa0fd30ca23f0159275ef3.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/059ee2fae3aa0fd30ca23f0159275ef3.json new file mode 100644 index 00000000000..abad964a13d --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/059ee2fae3aa0fd30ca23f0159275ef3.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0808, + "steps": 133 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/07832109afbac0e38eb5d87932066e08.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/07832109afbac0e38eb5d87932066e08.json new file mode 100644 index 00000000000..8fd9260cd31 --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/07832109afbac0e38eb5d87932066e08.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0335, + "steps": 61 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/088564331bfc8b3af317aacddb4ccbea.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/088564331bfc8b3af317aacddb4ccbea.json new file mode 100644 index 00000000000..ecc07528b26 --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/088564331bfc8b3af317aacddb4ccbea.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0352, + "steps": 74 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/08e74ef80a419837ad146845c97f173b.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/08e74ef80a419837ad146845c97f173b.json new file mode 100644 index 00000000000..86d0f447754 --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/08e74ef80a419837ad146845c97f173b.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0184, + "steps": 29 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/0c31169754f2628df2aefb14cc504990.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/0c31169754f2628df2aefb14cc504990.json new file mode 100644 index 00000000000..910a47496bd --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/0c31169754f2628df2aefb14cc504990.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 2.1291, + "steps": 873 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/0ec7f155931ed9e99efae24fd0898491.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/0ec7f155931ed9e99efae24fd0898491.json new file mode 100644 index 00000000000..f33936f03db --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/0ec7f155931ed9e99efae24fd0898491.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0338, + "steps": 65 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/0f76081bfd4cb878c7ac624b1e0677ec.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/0f76081bfd4cb878c7ac624b1e0677ec.json new file mode 100644 index 00000000000..1c62f16177a --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/0f76081bfd4cb878c7ac624b1e0677ec.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.071, + "steps": 95 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/113dabb6f94d8c3225236c434a5d13a7.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/113dabb6f94d8c3225236c434a5d13a7.json new file mode 100644 index 00000000000..047e6f1e53c --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/113dabb6f94d8c3225236c434a5d13a7.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0299, + "steps": 65 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/178e24799cae3dcec5f3257226b96a20.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/178e24799cae3dcec5f3257226b96a20.json new file mode 100644 index 00000000000..94f3bb9c909 --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/178e24799cae3dcec5f3257226b96a20.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0181, + "steps": 22 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/1b75b91371009810dc97ffa389bb5531.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/1b75b91371009810dc97ffa389bb5531.json new file mode 100644 index 00000000000..7d3e23193e9 --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/1b75b91371009810dc97ffa389bb5531.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.368, + "steps": 210 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/1da5cd2893da7c1322294978850c6fd3.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/1da5cd2893da7c1322294978850c6fd3.json new file mode 100644 index 00000000000..feb98b34cfe --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/1da5cd2893da7c1322294978850c6fd3.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0322, + "steps": 42 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/1f482c6de3c7a19cda334e37d01fe177.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/1f482c6de3c7a19cda334e37d01fe177.json new file mode 100644 index 00000000000..821f69edf5e --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/1f482c6de3c7a19cda334e37d01fe177.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0357, + "steps": 38 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/2d2277efecc9ac0135f43533fb7fd64e.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/2d2277efecc9ac0135f43533fb7fd64e.json new file mode 100644 index 00000000000..0abc71957e0 --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/2d2277efecc9ac0135f43533fb7fd64e.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0196, + "steps": 33 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/2d5464d4e8192a657d37126dca5910da.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/2d5464d4e8192a657d37126dca5910da.json new file mode 100644 index 00000000000..f750557db77 --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/2d5464d4e8192a657d37126dca5910da.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0153, + "steps": 23 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/2ddd3e6ac842e9117c49c9ddaf740411.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/2ddd3e6ac842e9117c49c9ddaf740411.json new file mode 100644 index 00000000000..5fe9a6223c0 --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/2ddd3e6ac842e9117c49c9ddaf740411.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.066, + "steps": 64 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/2e3c2cb35cef3cb6057febf0bdf10744.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/2e3c2cb35cef3cb6057febf0bdf10744.json new file mode 100644 index 00000000000..7af695f6e6d --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/2e3c2cb35cef3cb6057febf0bdf10744.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0813, + "steps": 98 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/37377966b3e186a9febaac6df135d3e9.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/37377966b3e186a9febaac6df135d3e9.json new file mode 100644 index 00000000000..60cff8a3d9c --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/37377966b3e186a9febaac6df135d3e9.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0247, + "steps": 47 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/45124138476e1855a6f35cf90a0f7385.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/45124138476e1855a6f35cf90a0f7385.json new file mode 100644 index 00000000000..d25205285c9 --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/45124138476e1855a6f35cf90a0f7385.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.016, + "steps": 18 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/50c141eec33504c5c1bed095ab2c1934.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/50c141eec33504c5c1bed095ab2c1934.json new file mode 100644 index 00000000000..62c1a250c0c --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/50c141eec33504c5c1bed095ab2c1934.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0858, + "steps": 108 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/5aa93b7609826cef11995c6f79edc54c.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/5aa93b7609826cef11995c6f79edc54c.json new file mode 100644 index 00000000000..388f04a8c56 --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/5aa93b7609826cef11995c6f79edc54c.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.136, + "steps": 194 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/634fb439c79d4b2df9278efe8f97f1a2.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/634fb439c79d4b2df9278efe8f97f1a2.json new file mode 100644 index 00000000000..e8126a586a4 --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/634fb439c79d4b2df9278efe8f97f1a2.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.032, + "steps": 61 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/6356a66f92291eedbf596c86247cdf40.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/6356a66f92291eedbf596c86247cdf40.json new file mode 100644 index 00000000000..ba1ebe012e8 --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/6356a66f92291eedbf596c86247cdf40.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.1091, + "steps": 133 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/66d43256948fe0b03dc360a4a2654dfb.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/66d43256948fe0b03dc360a4a2654dfb.json new file mode 100644 index 00000000000..351c69260b1 --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/66d43256948fe0b03dc360a4a2654dfb.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0402, + "steps": 64 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/69483893c71ff4f7f440dddd3e21f386.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/69483893c71ff4f7f440dddd3e21f386.json new file mode 100644 index 00000000000..06cb64cc77d --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/69483893c71ff4f7f440dddd3e21f386.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0414, + "steps": 54 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/6c00a117f0e575dde2c838780b6a2b5f.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/6c00a117f0e575dde2c838780b6a2b5f.json new file mode 100644 index 00000000000..c5eca6b702f --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/6c00a117f0e575dde2c838780b6a2b5f.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.1224, + "steps": 119 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/6f907d24a6c6d51475fbbba7851998d4.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/6f907d24a6c6d51475fbbba7851998d4.json new file mode 100644 index 00000000000..7be33688065 --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/6f907d24a6c6d51475fbbba7851998d4.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0219, + "steps": 39 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/737d7d224b95933e11e8630b0d5e1e67.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/737d7d224b95933e11e8630b0d5e1e67.json new file mode 100644 index 00000000000..20bead46ea2 --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/737d7d224b95933e11e8630b0d5e1e67.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0213, + "steps": 25 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/744202b8726995ad41adcfd26dbd3977.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/744202b8726995ad41adcfd26dbd3977.json new file mode 100644 index 00000000000..8f687e1b197 --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/744202b8726995ad41adcfd26dbd3977.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.2803, + "steps": 249 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/784037581ab4f838952f762dd078ccd2.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/784037581ab4f838952f762dd078ccd2.json new file mode 100644 index 00000000000..27dc53199be --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/784037581ab4f838952f762dd078ccd2.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0313, + "steps": 32 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/7b20ca91596a368e107ee308c5abb683.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/7b20ca91596a368e107ee308c5abb683.json new file mode 100644 index 00000000000..0b1a8cfc07b --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/7b20ca91596a368e107ee308c5abb683.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0201, + "steps": 18 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/7e28eb621b6c70199ef921ecc2b766f9.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/7e28eb621b6c70199ef921ecc2b766f9.json new file mode 100644 index 00000000000..a49224f442c --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/7e28eb621b6c70199ef921ecc2b766f9.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 1.4606, + "steps": 586 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/82d303e4f3b78e54f806a99c19a64876.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/82d303e4f3b78e54f806a99c19a64876.json new file mode 100644 index 00000000000..794b083a3bf --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/82d303e4f3b78e54f806a99c19a64876.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0544, + "steps": 72 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/8421490fd39132bfdfa1fa54817bc682.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/8421490fd39132bfdfa1fa54817bc682.json new file mode 100644 index 00000000000..cd12ff0b274 --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/8421490fd39132bfdfa1fa54817bc682.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.012, + "steps": 20 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/85c2351bf7a38814cb9a0a47ea6c2ea7.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/85c2351bf7a38814cb9a0a47ea6c2ea7.json new file mode 100644 index 00000000000..3c284e70820 --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/85c2351bf7a38814cb9a0a47ea6c2ea7.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0241, + "steps": 18 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/865e884b2f3e33610e0aa609d35c6f09.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/865e884b2f3e33610e0aa609d35c6f09.json new file mode 100644 index 00000000000..9d8d6a00fe0 --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/865e884b2f3e33610e0aa609d35c6f09.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0564, + "steps": 111 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/88bebb3c661a1f33578350b8200b7c25.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/88bebb3c661a1f33578350b8200b7c25.json new file mode 100644 index 00000000000..ea55d0f710c --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/88bebb3c661a1f33578350b8200b7c25.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0614, + "steps": 76 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/8a7b631f75a3073c3262178ccfedd3e7.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/8a7b631f75a3073c3262178ccfedd3e7.json new file mode 100644 index 00000000000..1ec8ceeac6b --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/8a7b631f75a3073c3262178ccfedd3e7.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.1267, + "steps": 167 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/8aafa7388f31a7314c199713ca0ae084.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/8aafa7388f31a7314c199713ca0ae084.json new file mode 100644 index 00000000000..74c7c88edbf --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/8aafa7388f31a7314c199713ca0ae084.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0628, + "steps": 76 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/8e942fe174bf1f62bb36a5abab4deb26.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/8e942fe174bf1f62bb36a5abab4deb26.json new file mode 100644 index 00000000000..b6b6c98618e --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/8e942fe174bf1f62bb36a5abab4deb26.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0752, + "steps": 121 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/92d2d156fb93ee5c5f2d3f2faa4c4275.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/92d2d156fb93ee5c5f2d3f2faa4c4275.json new file mode 100644 index 00000000000..36db404c7ba --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/92d2d156fb93ee5c5f2d3f2faa4c4275.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0209, + "steps": 18 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/9c97f1cddb0b9fcf61a6d1caddc3e897.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/9c97f1cddb0b9fcf61a6d1caddc3e897.json new file mode 100644 index 00000000000..3dc3966fd35 --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/9c97f1cddb0b9fcf61a6d1caddc3e897.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0256, + "steps": 41 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/9cab00be1ec378b961d688830f12c8b5.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/9cab00be1ec378b961d688830f12c8b5.json new file mode 100644 index 00000000000..378f04a195d --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/9cab00be1ec378b961d688830f12c8b5.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0337, + "steps": 74 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/a2374beb942675808f3c1588a5f13a68.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/a2374beb942675808f3c1588a5f13a68.json new file mode 100644 index 00000000000..f649ab65754 --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/a2374beb942675808f3c1588a5f13a68.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.1312, + "steps": 138 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/ae94fd34b628e3925ec2951d2ed0d153.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/ae94fd34b628e3925ec2951d2ed0d153.json new file mode 100644 index 00000000000..26dbe45bbc6 --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/ae94fd34b628e3925ec2951d2ed0d153.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0864, + "steps": 92 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/b0969ad7ecf31664172fda8b609f8917.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/b0969ad7ecf31664172fda8b609f8917.json new file mode 100644 index 00000000000..de3e41e11ea --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/b0969ad7ecf31664172fda8b609f8917.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0655, + "steps": 87 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/b57d3798758c77258d386ffb51fb4324.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/b57d3798758c77258d386ffb51fb4324.json new file mode 100644 index 00000000000..bb2b182b1ef --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/b57d3798758c77258d386ffb51fb4324.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.1634, + "steps": 222 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/bd76bf896c68ddef8cbba6f20100fac8.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/bd76bf896c68ddef8cbba6f20100fac8.json new file mode 100644 index 00000000000..fe03fc572ca --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/bd76bf896c68ddef8cbba6f20100fac8.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0596, + "steps": 81 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/be1d9ed1ba49360aaa18b8d4b577c56f.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/be1d9ed1ba49360aaa18b8d4b577c56f.json new file mode 100644 index 00000000000..5df1900efa4 --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/be1d9ed1ba49360aaa18b8d4b577c56f.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0426, + "steps": 63 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/c57fbc674ee49672402990996b38e761.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/c57fbc674ee49672402990996b38e761.json new file mode 100644 index 00000000000..7e3ac4e98d5 --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/c57fbc674ee49672402990996b38e761.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0527, + "steps": 95 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/ca5e36cff267d97e2595ae3f8187bcdd.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/ca5e36cff267d97e2595ae3f8187bcdd.json new file mode 100644 index 00000000000..80b3bf0de70 --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/ca5e36cff267d97e2595ae3f8187bcdd.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.1654, + "steps": 178 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/cd48e56312a247d0852ac3ca63754265.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/cd48e56312a247d0852ac3ca63754265.json new file mode 100644 index 00000000000..33d7094aac6 --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/cd48e56312a247d0852ac3ca63754265.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0398, + "steps": 56 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/d39b5b1c24cd1c7d131652c2ca1dd878.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/d39b5b1c24cd1c7d131652c2ca1dd878.json new file mode 100644 index 00000000000..838225c2817 --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/d39b5b1c24cd1c7d131652c2ca1dd878.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.069, + "steps": 80 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/d4b82b17f751426ee45e116de56f70bb.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/d4b82b17f751426ee45e116de56f70bb.json new file mode 100644 index 00000000000..8fa7c83ab77 --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/d4b82b17f751426ee45e116de56f70bb.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.4659, + "steps": 240 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/d51e6faa5980c6069ff809306e33fe61.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/d51e6faa5980c6069ff809306e33fe61.json new file mode 100644 index 00000000000..e1894df8c63 --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/d51e6faa5980c6069ff809306e33fe61.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0157, + "steps": 17 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/e8bad62a574dfb263cbb0424c1f994cc.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/e8bad62a574dfb263cbb0424c1f994cc.json new file mode 100644 index 00000000000..6d7da0d9f4a --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/e8bad62a574dfb263cbb0424c1f994cc.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0941, + "steps": 95 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/e997b52aca1d60592f0c918574d95bca.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/e997b52aca1d60592f0c918574d95bca.json new file mode 100644 index 00000000000..5dbf762bfea --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/e997b52aca1d60592f0c918574d95bca.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0828, + "steps": 95 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/eec066c7871c347d05d218448003bb42.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/eec066c7871c347d05d218448003bb42.json new file mode 100644 index 00000000000..9fdc6170589 --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/eec066c7871c347d05d218448003bb42.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.3033, + "steps": 267 } diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/fa144aad657dae3418db4f22e288c17e.json b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/fa144aad657dae3418db4f22e288c17e.json new file mode 100644 index 00000000000..de86aca27e1 --- /dev/null +++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.0.session/cache/fa144aad657dae3418db4f22e288c17e.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0501, + "steps": 90 } diff --git a/src/plugins/wp/tests/wp_hoare/oracle_qualif/byref.0.session/cache/56b7eefc17044e0ff95c99434cf88399.json b/src/plugins/wp/tests/wp_hoare/oracle_qualif/byref.0.session/cache/56b7eefc17044e0ff95c99434cf88399.json new file mode 100644 index 00000000000..56c39550428 --- /dev/null +++ b/src/plugins/wp/tests/wp_hoare/oracle_qualif/byref.0.session/cache/56b7eefc17044e0ff95c99434cf88399.json @@ -0,0 +1 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "unknown" } diff --git a/src/plugins/wp/tests/wp_hoare/oracle_qualif/logicarr.0.session/cache/852210deac5464ecf4c672c0f6c67fb7.json b/src/plugins/wp/tests/wp_hoare/oracle_qualif/logicarr.0.session/cache/852210deac5464ecf4c672c0f6c67fb7.json new file mode 100644 index 00000000000..d1866353561 --- /dev/null +++ b/src/plugins/wp/tests/wp_hoare/oracle_qualif/logicarr.0.session/cache/852210deac5464ecf4c672c0f6c67fb7.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0276, + "steps": 28 } diff --git a/src/plugins/wp/tests/wp_hoare/oracle_qualif/logicarr.0.session/cache/aa862239bf067f3148dc841ef36e7c1a.json b/src/plugins/wp/tests/wp_hoare/oracle_qualif/logicarr.0.session/cache/aa862239bf067f3148dc841ef36e7c1a.json new file mode 100644 index 00000000000..5a2c7477c08 --- /dev/null +++ b/src/plugins/wp/tests/wp_hoare/oracle_qualif/logicarr.0.session/cache/aa862239bf067f3148dc841ef36e7c1a.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0307, + "steps": 27 } diff --git a/src/plugins/wp/tests/wp_hoare/oracle_qualif/logicarr.0.session/cache/d85b1504de7e92963b9c333e4ba02d6f.json b/src/plugins/wp/tests/wp_hoare/oracle_qualif/logicarr.0.session/cache/d85b1504de7e92963b9c333e4ba02d6f.json new file mode 100644 index 00000000000..d0150246ac2 --- /dev/null +++ b/src/plugins/wp/tests/wp_hoare/oracle_qualif/logicarr.0.session/cache/d85b1504de7e92963b9c333e4ba02d6f.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0342, + "steps": 28 } diff --git a/src/plugins/wp/tests/wp_hoare/oracle_qualif/logicref.0.session/cache/6dd7fce5505a14bc287568321ce0111b.json b/src/plugins/wp/tests/wp_hoare/oracle_qualif/logicref.0.session/cache/6dd7fce5505a14bc287568321ce0111b.json new file mode 100644 index 00000000000..5526663a21d --- /dev/null +++ b/src/plugins/wp/tests/wp_hoare/oracle_qualif/logicref.0.session/cache/6dd7fce5505a14bc287568321ce0111b.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0299, + "steps": 70 } diff --git a/src/plugins/wp/tests/wp_hoare/oracle_qualif/logicref_simple.0.session/cache/2eb20108bba00807202ca8ddffbe9321.json b/src/plugins/wp/tests/wp_hoare/oracle_qualif/logicref_simple.0.session/cache/2eb20108bba00807202ca8ddffbe9321.json new file mode 100644 index 00000000000..7bffe208ef4 --- /dev/null +++ b/src/plugins/wp/tests/wp_hoare/oracle_qualif/logicref_simple.0.session/cache/2eb20108bba00807202ca8ddffbe9321.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0137, + "steps": 13 } diff --git a/src/plugins/wp/tests/wp_hoare/oracle_qualif/logicref_simple.0.session/cache/84e7fceb770bfa7d815f522cfce14408.json b/src/plugins/wp/tests/wp_hoare/oracle_qualif/logicref_simple.0.session/cache/84e7fceb770bfa7d815f522cfce14408.json new file mode 100644 index 00000000000..e08281f17c2 --- /dev/null +++ b/src/plugins/wp/tests/wp_hoare/oracle_qualif/logicref_simple.0.session/cache/84e7fceb770bfa7d815f522cfce14408.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0188, + "steps": 15 } diff --git a/src/plugins/wp/tests/wp_hoare/oracle_qualif/logicref_simple.0.session/cache/8773bd69d274eceb0acf3767f4ae9575.json b/src/plugins/wp/tests/wp_hoare/oracle_qualif/logicref_simple.0.session/cache/8773bd69d274eceb0acf3767f4ae9575.json new file mode 100644 index 00000000000..355d38749c2 --- /dev/null +++ b/src/plugins/wp/tests/wp_hoare/oracle_qualif/logicref_simple.0.session/cache/8773bd69d274eceb0acf3767f4ae9575.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.022, + "steps": 16 } diff --git a/src/plugins/wp/tests/wp_hoare/oracle_qualif/logicref_simple.0.session/cache/8d2421a35a8365649870fd7b2f8a1222.json b/src/plugins/wp/tests/wp_hoare/oracle_qualif/logicref_simple.0.session/cache/8d2421a35a8365649870fd7b2f8a1222.json new file mode 100644 index 00000000000..ece64db1cc4 --- /dev/null +++ b/src/plugins/wp/tests/wp_hoare/oracle_qualif/logicref_simple.0.session/cache/8d2421a35a8365649870fd7b2f8a1222.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0167, + "steps": 9 } diff --git a/src/plugins/wp/tests/wp_hoare/oracle_qualif/reference_and_struct.0.session/cache/a514c4e0dbce3a19cb575797578db2ee.json b/src/plugins/wp/tests/wp_hoare/oracle_qualif/reference_and_struct.0.session/cache/a514c4e0dbce3a19cb575797578db2ee.json new file mode 100644 index 00000000000..e25fe48e954 --- /dev/null +++ b/src/plugins/wp/tests/wp_hoare/oracle_qualif/reference_and_struct.0.session/cache/a514c4e0dbce3a19cb575797578db2ee.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0152, + "steps": 18 } diff --git a/src/plugins/wp/tests/wp_hoare/oracle_qualif/reference_array.0.session/cache/1055ecf60b0251e2ce8a583866b59b5d.json b/src/plugins/wp/tests/wp_hoare/oracle_qualif/reference_array.0.session/cache/1055ecf60b0251e2ce8a583866b59b5d.json new file mode 100644 index 00000000000..61cf1fe7051 --- /dev/null +++ b/src/plugins/wp/tests/wp_hoare/oracle_qualif/reference_array.0.session/cache/1055ecf60b0251e2ce8a583866b59b5d.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0197, + "steps": 18 } diff --git a/src/plugins/wp/tests/wp_hoare/oracle_qualif/reference_array.0.session/cache/3ad89ca7d6079981ace01e3d25910e63.json b/src/plugins/wp/tests/wp_hoare/oracle_qualif/reference_array.0.session/cache/3ad89ca7d6079981ace01e3d25910e63.json new file mode 100644 index 00000000000..3d545f3673f --- /dev/null +++ b/src/plugins/wp/tests/wp_hoare/oracle_qualif/reference_array.0.session/cache/3ad89ca7d6079981ace01e3d25910e63.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0143, + "steps": 18 } diff --git a/src/plugins/wp/tests/wp_hoare/oracle_qualif/reference_array.0.session/cache/5518bc5769e51a2ec423d55457d4323c.json b/src/plugins/wp/tests/wp_hoare/oracle_qualif/reference_array.0.session/cache/5518bc5769e51a2ec423d55457d4323c.json new file mode 100644 index 00000000000..e2e340a604d --- /dev/null +++ b/src/plugins/wp/tests/wp_hoare/oracle_qualif/reference_array.0.session/cache/5518bc5769e51a2ec423d55457d4323c.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0152, + "steps": 23 } diff --git a/src/plugins/wp/tests/wp_hoare/oracle_qualif/refguards.0.session/cache/5c4bdf85b0130c246990c9addb9d2556.json b/src/plugins/wp/tests/wp_hoare/oracle_qualif/refguards.0.session/cache/5c4bdf85b0130c246990c9addb9d2556.json new file mode 100644 index 00000000000..465fcfae9d0 --- /dev/null +++ b/src/plugins/wp/tests/wp_hoare/oracle_qualif/refguards.0.session/cache/5c4bdf85b0130c246990c9addb9d2556.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0144, + "steps": 14 } diff --git a/src/plugins/wp/tests/wp_hoare/oracle_qualif/refguards.0.session/cache/aeb63d64f83c4e31d79d7e8e869de07e.json b/src/plugins/wp/tests/wp_hoare/oracle_qualif/refguards.0.session/cache/aeb63d64f83c4e31d79d7e8e869de07e.json new file mode 100644 index 00000000000..56c39550428 --- /dev/null +++ b/src/plugins/wp/tests/wp_hoare/oracle_qualif/refguards.0.session/cache/aeb63d64f83c4e31d79d7e8e869de07e.json @@ -0,0 +1 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "unknown" } diff --git a/src/plugins/wp/tests/wp_manual/oracle_qualif/manual.0.session/cache/1aa29de269f2b73adeae713ac86acec7.json b/src/plugins/wp/tests/wp_manual/oracle_qualif/manual.0.session/cache/1aa29de269f2b73adeae713ac86acec7.json new file mode 100644 index 00000000000..69626115453 --- /dev/null +++ b/src/plugins/wp/tests/wp_manual/oracle_qualif/manual.0.session/cache/1aa29de269f2b73adeae713ac86acec7.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0115, + "steps": 14 } diff --git a/src/plugins/wp/tests/wp_manual/oracle_qualif/manual.1.session/cache/762ba8fbb24bdd2a875e3ac97bcdb1a0.json b/src/plugins/wp/tests/wp_manual/oracle_qualif/manual.1.session/cache/762ba8fbb24bdd2a875e3ac97bcdb1a0.json new file mode 100644 index 00000000000..a2ea9f8b8de --- /dev/null +++ b/src/plugins/wp/tests/wp_manual/oracle_qualif/manual.1.session/cache/762ba8fbb24bdd2a875e3ac97bcdb1a0.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0117, + "steps": 20 } diff --git a/src/plugins/wp/tests/wp_manual/oracle_qualif/manual.1.session/cache/b280eb527d15c1796693db544778a327.json b/src/plugins/wp/tests/wp_manual/oracle_qualif/manual.1.session/cache/b280eb527d15c1796693db544778a327.json new file mode 100644 index 00000000000..828728f174d --- /dev/null +++ b/src/plugins/wp/tests/wp_manual/oracle_qualif/manual.1.session/cache/b280eb527d15c1796693db544778a327.json @@ -0,0 +1 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.01, "steps": 18 } diff --git a/src/plugins/wp/tests/wp_manual/oracle_qualif/manual.1.session/cache/f55cc495403a5870a0396a5e15c05b4d.json b/src/plugins/wp/tests/wp_manual/oracle_qualif/manual.1.session/cache/f55cc495403a5870a0396a5e15c05b4d.json new file mode 100644 index 00000000000..c0551468647 --- /dev/null +++ b/src/plugins/wp/tests/wp_manual/oracle_qualif/manual.1.session/cache/f55cc495403a5870a0396a5e15c05b4d.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0132, + "steps": 19 } diff --git a/src/plugins/wp/tests/wp_manual/oracle_qualif/manual.2.session/cache/762ba8fbb24bdd2a875e3ac97bcdb1a0.json b/src/plugins/wp/tests/wp_manual/oracle_qualif/manual.2.session/cache/762ba8fbb24bdd2a875e3ac97bcdb1a0.json new file mode 100644 index 00000000000..bdb57771153 --- /dev/null +++ b/src/plugins/wp/tests/wp_manual/oracle_qualif/manual.2.session/cache/762ba8fbb24bdd2a875e3ac97bcdb1a0.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0167, + "steps": 20 } diff --git a/src/plugins/wp/tests/wp_manual/oracle_qualif/manual.2.session/cache/b280eb527d15c1796693db544778a327.json b/src/plugins/wp/tests/wp_manual/oracle_qualif/manual.2.session/cache/b280eb527d15c1796693db544778a327.json new file mode 100644 index 00000000000..c6167acad6c --- /dev/null +++ b/src/plugins/wp/tests/wp_manual/oracle_qualif/manual.2.session/cache/b280eb527d15c1796693db544778a327.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0124, + "steps": 18 } diff --git a/src/plugins/wp/tests/wp_manual/oracle_qualif/manual.2.session/cache/f55cc495403a5870a0396a5e15c05b4d.json b/src/plugins/wp/tests/wp_manual/oracle_qualif/manual.2.session/cache/f55cc495403a5870a0396a5e15c05b4d.json new file mode 100644 index 00000000000..fdc442c3a92 --- /dev/null +++ b/src/plugins/wp/tests/wp_manual/oracle_qualif/manual.2.session/cache/f55cc495403a5870a0396a5e15c05b4d.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0116, + "steps": 19 } diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/copy.0.session/cache/05e5c5311bfe8997e3278f3e5c22829a.json b/src/plugins/wp/tests/wp_plugin/oracle_qualif/copy.0.session/cache/05e5c5311bfe8997e3278f3e5c22829a.json new file mode 100644 index 00000000000..b12df409cd0 --- /dev/null +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/copy.0.session/cache/05e5c5311bfe8997e3278f3e5c22829a.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0231, + "steps": 18 } diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/copy.0.session/cache/074cb03898e8ed122caa93327a7b7a77.json b/src/plugins/wp/tests/wp_plugin/oracle_qualif/copy.0.session/cache/074cb03898e8ed122caa93327a7b7a77.json new file mode 100644 index 00000000000..503c92e0674 --- /dev/null +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/copy.0.session/cache/074cb03898e8ed122caa93327a7b7a77.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0455, + "steps": 56 } diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/copy.0.session/cache/58369c7fb3048b416fdd3fc5458c5b83.json b/src/plugins/wp/tests/wp_plugin/oracle_qualif/copy.0.session/cache/58369c7fb3048b416fdd3fc5458c5b83.json new file mode 100644 index 00000000000..b63790bdbac --- /dev/null +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/copy.0.session/cache/58369c7fb3048b416fdd3fc5458c5b83.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0211, + "steps": 23 } diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/copy.0.session/cache/65e3ef4a8586c488db122d88f499b0d9.json b/src/plugins/wp/tests/wp_plugin/oracle_qualif/copy.0.session/cache/65e3ef4a8586c488db122d88f499b0d9.json new file mode 100644 index 00000000000..47e2078ec7c --- /dev/null +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/copy.0.session/cache/65e3ef4a8586c488db122d88f499b0d9.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.138, + "steps": 148 } diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/copy.0.session/cache/9df2b33683d9824243472af4e8d5c5f7.json b/src/plugins/wp/tests/wp_plugin/oracle_qualif/copy.0.session/cache/9df2b33683d9824243472af4e8d5c5f7.json new file mode 100644 index 00000000000..40dcd1d8b0d --- /dev/null +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/copy.0.session/cache/9df2b33683d9824243472af4e8d5c5f7.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0358, + "steps": 34 } diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/copy.0.session/cache/d52a4f7a87fca3c71ec617296f285903.json b/src/plugins/wp/tests/wp_plugin/oracle_qualif/copy.0.session/cache/d52a4f7a87fca3c71ec617296f285903.json new file mode 100644 index 00000000000..61edacfd56a --- /dev/null +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/copy.0.session/cache/d52a4f7a87fca3c71ec617296f285903.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0271, + "steps": 22 } diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/dynamic.0.session/cache/7c61992a1e5557d753841a5f66eef4ae.json b/src/plugins/wp/tests/wp_plugin/oracle_qualif/dynamic.0.session/cache/7c61992a1e5557d753841a5f66eef4ae.json new file mode 100644 index 00000000000..2d98e0d913a --- /dev/null +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/dynamic.0.session/cache/7c61992a1e5557d753841a5f66eef4ae.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0208, + "steps": 9 } diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/dynamic.0.session/cache/dd5c27a7c1200d3431d2c30bf2899942.json b/src/plugins/wp/tests/wp_plugin/oracle_qualif/dynamic.0.session/cache/dd5c27a7c1200d3431d2c30bf2899942.json new file mode 100644 index 00000000000..578c8dca137 --- /dev/null +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/dynamic.0.session/cache/dd5c27a7c1200d3431d2c30bf2899942.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0243, + "steps": 15 } diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/dynamic.0.session/cache/e2e624a33e02433818d9a93dc4b967fb.json b/src/plugins/wp/tests/wp_plugin/oracle_qualif/dynamic.0.session/cache/e2e624a33e02433818d9a93dc4b967fb.json new file mode 100644 index 00000000000..56c39550428 --- /dev/null +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/dynamic.0.session/cache/e2e624a33e02433818d9a93dc4b967fb.json @@ -0,0 +1 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "unknown" } diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/dynamic.0.session/cache/f8e79502a4545e9f174c055480b11bad.json b/src/plugins/wp/tests/wp_plugin/oracle_qualif/dynamic.0.session/cache/f8e79502a4545e9f174c055480b11bad.json new file mode 100644 index 00000000000..442ae3034e4 --- /dev/null +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/dynamic.0.session/cache/f8e79502a4545e9f174c055480b11bad.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0328, + "steps": 47 } diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/flash.0.session/cache/62c8c83348d53abd331942b7638c0e65.json b/src/plugins/wp/tests/wp_plugin/oracle_qualif/flash.0.session/cache/62c8c83348d53abd331942b7638c0e65.json new file mode 100644 index 00000000000..e4c3de15c1a --- /dev/null +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/flash.0.session/cache/62c8c83348d53abd331942b7638c0e65.json @@ -0,0 +1 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "timeout", "time": 1. } diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/flash.0.session/cache/ad24c8fdc842200098097f4c5b243a1b.json b/src/plugins/wp/tests/wp_plugin/oracle_qualif/flash.0.session/cache/ad24c8fdc842200098097f4c5b243a1b.json new file mode 100644 index 00000000000..e4c3de15c1a --- /dev/null +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/flash.0.session/cache/ad24c8fdc842200098097f4c5b243a1b.json @@ -0,0 +1 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "timeout", "time": 1. } diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/flash.0.session/cache/d57a0b96fe98d0e1d1578d06300ae6af.json b/src/plugins/wp/tests/wp_plugin/oracle_qualif/flash.0.session/cache/d57a0b96fe98d0e1d1578d06300ae6af.json new file mode 100644 index 00000000000..e4c3de15c1a --- /dev/null +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/flash.0.session/cache/d57a0b96fe98d0e1d1578d06300ae6af.json @@ -0,0 +1 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "timeout", "time": 1. } diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/flash.0.session/cache/e98f4a09d201fc4ff4b2c17441acaa8d.json b/src/plugins/wp/tests/wp_plugin/oracle_qualif/flash.0.session/cache/e98f4a09d201fc4ff4b2c17441acaa8d.json new file mode 100644 index 00000000000..e4c3de15c1a --- /dev/null +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/flash.0.session/cache/e98f4a09d201fc4ff4b2c17441acaa8d.json @@ -0,0 +1 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "timeout", "time": 1. } diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/flash.0.session/cache/fb1ff75dc8c936a96751f5ffdde36e50.json b/src/plugins/wp/tests/wp_plugin/oracle_qualif/flash.0.session/cache/fb1ff75dc8c936a96751f5ffdde36e50.json new file mode 100644 index 00000000000..e4c3de15c1a --- /dev/null +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/flash.0.session/cache/fb1ff75dc8c936a96751f5ffdde36e50.json @@ -0,0 +1 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "timeout", "time": 1. } diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/flash.1.session/cache/354efda647c2b52e3acf13bee479341a.json b/src/plugins/wp/tests/wp_plugin/oracle_qualif/flash.1.session/cache/354efda647c2b52e3acf13bee479341a.json new file mode 100644 index 00000000000..614749b24de --- /dev/null +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/flash.1.session/cache/354efda647c2b52e3acf13bee479341a.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.036, + "steps": 37 } diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/flash.1.session/cache/5a90230e76db08ca4977aaefa5af6afc.json b/src/plugins/wp/tests/wp_plugin/oracle_qualif/flash.1.session/cache/5a90230e76db08ca4977aaefa5af6afc.json new file mode 100644 index 00000000000..64ee4bae05a --- /dev/null +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/flash.1.session/cache/5a90230e76db08ca4977aaefa5af6afc.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0396, + "steps": 39 } diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/flash.1.session/cache/687c6ba705dc05a8d976db9c98dbc1b7.json b/src/plugins/wp/tests/wp_plugin/oracle_qualif/flash.1.session/cache/687c6ba705dc05a8d976db9c98dbc1b7.json new file mode 100644 index 00000000000..ba6b58882b3 --- /dev/null +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/flash.1.session/cache/687c6ba705dc05a8d976db9c98dbc1b7.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0335, + "steps": 34 } diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/flash.1.session/cache/6d33d3e9e0c138689b7b7b81af41c61b.json b/src/plugins/wp/tests/wp_plugin/oracle_qualif/flash.1.session/cache/6d33d3e9e0c138689b7b7b81af41c61b.json new file mode 100644 index 00000000000..e83db7513ec --- /dev/null +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/flash.1.session/cache/6d33d3e9e0c138689b7b7b81af41c61b.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.028, + "steps": 34 } diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/flash.1.session/cache/d1203dcf4cb1b7eb56cc98aaeee8d670.json b/src/plugins/wp/tests/wp_plugin/oracle_qualif/flash.1.session/cache/d1203dcf4cb1b7eb56cc98aaeee8d670.json new file mode 100644 index 00000000000..a2ca9a1e058 --- /dev/null +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/flash.1.session/cache/d1203dcf4cb1b7eb56cc98aaeee8d670.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0347, + "steps": 34 } diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/float_format.2.session/cache/7c52f41beefbdb46d7a18dde9bbf2bf8.json b/src/plugins/wp/tests/wp_plugin/oracle_qualif/float_format.2.session/cache/7c52f41beefbdb46d7a18dde9bbf2bf8.json new file mode 100644 index 00000000000..43afa6298c6 --- /dev/null +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/float_format.2.session/cache/7c52f41beefbdb46d7a18dde9bbf2bf8.json @@ -0,0 +1 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "stepout", "steps": 50 } diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/float_real.1.session/cache/6c499bc384463731f06e46d71bc8ca72.json b/src/plugins/wp/tests/wp_plugin/oracle_qualif/float_real.1.session/cache/6c499bc384463731f06e46d71bc8ca72.json new file mode 100644 index 00000000000..b8e36e2803f --- /dev/null +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/float_real.1.session/cache/6c499bc384463731f06e46d71bc8ca72.json @@ -0,0 +1 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "timeout", "time": 10. } diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/frame.0.session/cache/b475650b9898e2e1a3a99a196f007c1d.json b/src/plugins/wp/tests/wp_plugin/oracle_qualif/frame.0.session/cache/b475650b9898e2e1a3a99a196f007c1d.json new file mode 100644 index 00000000000..b8e36e2803f --- /dev/null +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/frame.0.session/cache/b475650b9898e2e1a3a99a196f007c1d.json @@ -0,0 +1 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "timeout", "time": 10. } diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/frame.0.session/cache/c226acb64e8c66b0e8ce990e608b7583.json b/src/plugins/wp/tests/wp_plugin/oracle_qualif/frame.0.session/cache/c226acb64e8c66b0e8ce990e608b7583.json new file mode 100644 index 00000000000..b8e36e2803f --- /dev/null +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/frame.0.session/cache/c226acb64e8c66b0e8ce990e608b7583.json @@ -0,0 +1 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "timeout", "time": 10. } diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/init_const_guard.0.session/cache/22137e3a0e8bb8e5c6f558c96a8b0584.json b/src/plugins/wp/tests/wp_plugin/oracle_qualif/init_const_guard.0.session/cache/22137e3a0e8bb8e5c6f558c96a8b0584.json new file mode 100644 index 00000000000..56c39550428 --- /dev/null +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/init_const_guard.0.session/cache/22137e3a0e8bb8e5c6f558c96a8b0584.json @@ -0,0 +1 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "unknown" } diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/init_const_guard.0.session/cache/3aa6fff5b9a5f4e04964329dadd25933.json b/src/plugins/wp/tests/wp_plugin/oracle_qualif/init_const_guard.0.session/cache/3aa6fff5b9a5f4e04964329dadd25933.json new file mode 100644 index 00000000000..78b3148f130 --- /dev/null +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/init_const_guard.0.session/cache/3aa6fff5b9a5f4e04964329dadd25933.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0249, + "steps": 20 } diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/init_const_guard.0.session/cache/eb1a359dc7730155217ac94756d7dffa.json b/src/plugins/wp/tests/wp_plugin/oracle_qualif/init_const_guard.0.session/cache/eb1a359dc7730155217ac94756d7dffa.json new file mode 100644 index 00000000000..a0460faedf5 --- /dev/null +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/init_const_guard.0.session/cache/eb1a359dc7730155217ac94756d7dffa.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0234, + "steps": 18 } diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/initarr.0.session/cache/25c9ec98fb41e974a3fac1a61d027acc.json b/src/plugins/wp/tests/wp_plugin/oracle_qualif/initarr.0.session/cache/25c9ec98fb41e974a3fac1a61d027acc.json new file mode 100644 index 00000000000..e6914672032 --- /dev/null +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/initarr.0.session/cache/25c9ec98fb41e974a3fac1a61d027acc.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0222, + "steps": 23 } diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/initarr.0.session/cache/42ee58e19309bd5df73821e3cfd04518.json b/src/plugins/wp/tests/wp_plugin/oracle_qualif/initarr.0.session/cache/42ee58e19309bd5df73821e3cfd04518.json new file mode 100644 index 00000000000..f7715aa6cf0 --- /dev/null +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/initarr.0.session/cache/42ee58e19309bd5df73821e3cfd04518.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0243, + "steps": 34 } diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/loop.0.session/cache/185d1270b8988dc69c4d7d49e40360fe.json b/src/plugins/wp/tests/wp_plugin/oracle_qualif/loop.0.session/cache/185d1270b8988dc69c4d7d49e40360fe.json new file mode 100644 index 00000000000..abc7eea4d61 --- /dev/null +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/loop.0.session/cache/185d1270b8988dc69c4d7d49e40360fe.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0329, + "steps": 32 } diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/loop.0.session/cache/6094e7c19eba3f50fb8b90f9528226e9.json b/src/plugins/wp/tests/wp_plugin/oracle_qualif/loop.0.session/cache/6094e7c19eba3f50fb8b90f9528226e9.json new file mode 100644 index 00000000000..2a15d2aa73c --- /dev/null +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/loop.0.session/cache/6094e7c19eba3f50fb8b90f9528226e9.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0224, + "steps": 14 } diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/loop.0.session/cache/67237129e97d7ae8d5ff4b62d632af5c.json b/src/plugins/wp/tests/wp_plugin/oracle_qualif/loop.0.session/cache/67237129e97d7ae8d5ff4b62d632af5c.json new file mode 100644 index 00000000000..a218d6a7733 --- /dev/null +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/loop.0.session/cache/67237129e97d7ae8d5ff4b62d632af5c.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0241, + "steps": 19 } diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/loop.0.session/cache/d9a9c67c0ce931a0559a5db9f619abd9.json b/src/plugins/wp/tests/wp_plugin/oracle_qualif/loop.0.session/cache/d9a9c67c0ce931a0559a5db9f619abd9.json new file mode 100644 index 00000000000..bdc8b60cd9e --- /dev/null +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/loop.0.session/cache/d9a9c67c0ce931a0559a5db9f619abd9.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0252, + "steps": 29 } diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/loop.0.session/cache/ed73ec0948ff5ae6b53fce8a8adada7a.json b/src/plugins/wp/tests/wp_plugin/oracle_qualif/loop.0.session/cache/ed73ec0948ff5ae6b53fce8a8adada7a.json new file mode 100644 index 00000000000..b28afb69283 --- /dev/null +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/loop.0.session/cache/ed73ec0948ff5ae6b53fce8a8adada7a.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.057, + "steps": 70 } diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/loop.0.session/cache/fa725e97995b55101c0cf42a29c0f813.json b/src/plugins/wp/tests/wp_plugin/oracle_qualif/loop.0.session/cache/fa725e97995b55101c0cf42a29c0f813.json new file mode 100644 index 00000000000..b8e36e2803f --- /dev/null +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/loop.0.session/cache/fa725e97995b55101c0cf42a29c0f813.json @@ -0,0 +1 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "timeout", "time": 10. } diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/overassign.0.session/cache/32e4d5d1ffef8a7dbb1fe8c7d536f845.json b/src/plugins/wp/tests/wp_plugin/oracle_qualif/overassign.0.session/cache/32e4d5d1ffef8a7dbb1fe8c7d536f845.json new file mode 100644 index 00000000000..56c39550428 --- /dev/null +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/overassign.0.session/cache/32e4d5d1ffef8a7dbb1fe8c7d536f845.json @@ -0,0 +1 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "unknown" } diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/overassign.0.session/cache/3e0d119a220c45bb16b0d7612fae4738.json b/src/plugins/wp/tests/wp_plugin/oracle_qualif/overassign.0.session/cache/3e0d119a220c45bb16b0d7612fae4738.json new file mode 100644 index 00000000000..e0bdb82d1bf --- /dev/null +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/overassign.0.session/cache/3e0d119a220c45bb16b0d7612fae4738.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0148, + "steps": 20 } diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/overassign.0.session/cache/725d46c74277558f772438a95d5ffa30.json b/src/plugins/wp/tests/wp_plugin/oracle_qualif/overassign.0.session/cache/725d46c74277558f772438a95d5ffa30.json new file mode 100644 index 00000000000..7f1fb800312 --- /dev/null +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/overassign.0.session/cache/725d46c74277558f772438a95d5ffa30.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0173, + "steps": 14 } diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/overassign.0.session/cache/fff4cb231748d3746212595b0892b5f9.json b/src/plugins/wp/tests/wp_plugin/oracle_qualif/overassign.0.session/cache/fff4cb231748d3746212595b0892b5f9.json new file mode 100644 index 00000000000..56c39550428 --- /dev/null +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/overassign.0.session/cache/fff4cb231748d3746212595b0892b5f9.json @@ -0,0 +1 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "unknown" } diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/prenex.0.session/cache/46c7ee5a8694d5a20e47282f25e34be5.json b/src/plugins/wp/tests/wp_plugin/oracle_qualif/prenex.0.session/cache/46c7ee5a8694d5a20e47282f25e34be5.json new file mode 100644 index 00000000000..88d6bbc43eb --- /dev/null +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/prenex.0.session/cache/46c7ee5a8694d5a20e47282f25e34be5.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0232, + "steps": 26 } diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/prenex.0.session/cache/8051f3e6d0df90db81f77cee4ad63859.json b/src/plugins/wp/tests/wp_plugin/oracle_qualif/prenex.0.session/cache/8051f3e6d0df90db81f77cee4ad63859.json new file mode 100644 index 00000000000..35313c16508 --- /dev/null +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/prenex.0.session/cache/8051f3e6d0df90db81f77cee4ad63859.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.1419, + "steps": 220 } diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/prenex.0.session/cache/8091b9c0849f4d1a46e4879e5348fdb0.json b/src/plugins/wp/tests/wp_plugin/oracle_qualif/prenex.0.session/cache/8091b9c0849f4d1a46e4879e5348fdb0.json new file mode 100644 index 00000000000..648156830de --- /dev/null +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/prenex.0.session/cache/8091b9c0849f4d1a46e4879e5348fdb0.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0235, + "steps": 23 } diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/prenex.0.session/cache/8b223534ba1fa0aa7e4ef5bd8ff12d15.json b/src/plugins/wp/tests/wp_plugin/oracle_qualif/prenex.0.session/cache/8b223534ba1fa0aa7e4ef5bd8ff12d15.json new file mode 100644 index 00000000000..01d1bbaf245 --- /dev/null +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/prenex.0.session/cache/8b223534ba1fa0aa7e4ef5bd8ff12d15.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0207, + "steps": 30 } diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/prenex.0.session/cache/9e537d84dc915243e941b46128dbd193.json b/src/plugins/wp/tests/wp_plugin/oracle_qualif/prenex.0.session/cache/9e537d84dc915243e941b46128dbd193.json new file mode 100644 index 00000000000..a791f9b3da3 --- /dev/null +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/prenex.0.session/cache/9e537d84dc915243e941b46128dbd193.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0272, + "steps": 31 } diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/rte.0.session/cache/23ff27cd5de1ace498e0001fd798be43.json b/src/plugins/wp/tests/wp_plugin/oracle_qualif/rte.0.session/cache/23ff27cd5de1ace498e0001fd798be43.json new file mode 100644 index 00000000000..56c39550428 --- /dev/null +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/rte.0.session/cache/23ff27cd5de1ace498e0001fd798be43.json @@ -0,0 +1 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "unknown" } diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/rte.0.session/cache/3de2cb0c1d0276cbaa7600ff25e6f29a.json b/src/plugins/wp/tests/wp_plugin/oracle_qualif/rte.0.session/cache/3de2cb0c1d0276cbaa7600ff25e6f29a.json new file mode 100644 index 00000000000..b8e36e2803f --- /dev/null +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/rte.0.session/cache/3de2cb0c1d0276cbaa7600ff25e6f29a.json @@ -0,0 +1 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "timeout", "time": 10. } diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/rte.0.session/cache/56b7eefc17044e0ff95c99434cf88399.json b/src/plugins/wp/tests/wp_plugin/oracle_qualif/rte.0.session/cache/56b7eefc17044e0ff95c99434cf88399.json new file mode 100644 index 00000000000..56c39550428 --- /dev/null +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/rte.0.session/cache/56b7eefc17044e0ff95c99434cf88399.json @@ -0,0 +1 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "unknown" } diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/rte.0.session/cache/f978123c614da8cddf33e186f24f3e67.json b/src/plugins/wp/tests/wp_plugin/oracle_qualif/rte.0.session/cache/f978123c614da8cddf33e186f24f3e67.json new file mode 100644 index 00000000000..b8e36e2803f --- /dev/null +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/rte.0.session/cache/f978123c614da8cddf33e186f24f3e67.json @@ -0,0 +1 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "timeout", "time": 10. } diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/string_c.0.session/cache/33446f0a42119240b0b63f1a2c0bc6ff.json b/src/plugins/wp/tests/wp_plugin/oracle_qualif/string_c.0.session/cache/33446f0a42119240b0b63f1a2c0bc6ff.json new file mode 100644 index 00000000000..06348a9946e --- /dev/null +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/string_c.0.session/cache/33446f0a42119240b0b63f1a2c0bc6ff.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0277, + "steps": 58 } diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/string_c.0.session/cache/3480784fd33fa9f4cae3b169a359cc57.json b/src/plugins/wp/tests/wp_plugin/oracle_qualif/string_c.0.session/cache/3480784fd33fa9f4cae3b169a359cc57.json new file mode 100644 index 00000000000..cb61223699d --- /dev/null +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/string_c.0.session/cache/3480784fd33fa9f4cae3b169a359cc57.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.5984, + "steps": 832 } diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/string_c.0.session/cache/4bc35b1105da43dc265e953cbf96035d.json b/src/plugins/wp/tests/wp_plugin/oracle_qualif/string_c.0.session/cache/4bc35b1105da43dc265e953cbf96035d.json new file mode 100644 index 00000000000..c1bbf657537 --- /dev/null +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/string_c.0.session/cache/4bc35b1105da43dc265e953cbf96035d.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0457, + "steps": 66 } diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/string_c.0.session/cache/607e1a10e4ccbf9b5505703cb2087df7.json b/src/plugins/wp/tests/wp_plugin/oracle_qualif/string_c.0.session/cache/607e1a10e4ccbf9b5505703cb2087df7.json new file mode 100644 index 00000000000..1d238a400f6 --- /dev/null +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/string_c.0.session/cache/607e1a10e4ccbf9b5505703cb2087df7.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0426, + "steps": 66 } diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/string_c.0.session/cache/7d870ce9aa419a3893c0d18e3e2904f5.json b/src/plugins/wp/tests/wp_plugin/oracle_qualif/string_c.0.session/cache/7d870ce9aa419a3893c0d18e3e2904f5.json new file mode 100644 index 00000000000..d7cd92c3ffc --- /dev/null +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/string_c.0.session/cache/7d870ce9aa419a3893c0d18e3e2904f5.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.4749, + "steps": 517 } diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/string_c.0.session/cache/7d91bcc945d933f5af6e1e468ae4ecf4.json b/src/plugins/wp/tests/wp_plugin/oracle_qualif/string_c.0.session/cache/7d91bcc945d933f5af6e1e468ae4ecf4.json new file mode 100644 index 00000000000..16ce60eb7e1 --- /dev/null +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/string_c.0.session/cache/7d91bcc945d933f5af6e1e468ae4ecf4.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0303, + "steps": 44 } diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/string_c.0.session/cache/8101aefca2eee2b8fb6cc34749c9891f.json b/src/plugins/wp/tests/wp_plugin/oracle_qualif/string_c.0.session/cache/8101aefca2eee2b8fb6cc34749c9891f.json new file mode 100644 index 00000000000..5a6d2bfd341 --- /dev/null +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/string_c.0.session/cache/8101aefca2eee2b8fb6cc34749c9891f.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0272, + "steps": 33 } diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/string_c.0.session/cache/9628de01f82e8d57abe1ca40a3145921.json b/src/plugins/wp/tests/wp_plugin/oracle_qualif/string_c.0.session/cache/9628de01f82e8d57abe1ca40a3145921.json new file mode 100644 index 00000000000..b053163ec5a --- /dev/null +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/string_c.0.session/cache/9628de01f82e8d57abe1ca40a3145921.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.9878, + "steps": 1149 } diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/string_c.0.session/cache/98d61fd3dc609926e2d9ed8d866b0ca3.json b/src/plugins/wp/tests/wp_plugin/oracle_qualif/string_c.0.session/cache/98d61fd3dc609926e2d9ed8d866b0ca3.json new file mode 100644 index 00000000000..4d015d8e273 --- /dev/null +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/string_c.0.session/cache/98d61fd3dc609926e2d9ed8d866b0ca3.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0616, + "steps": 92 } diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/string_c.0.session/cache/ace2089a7d9190f715a07093a9276e98.json b/src/plugins/wp/tests/wp_plugin/oracle_qualif/string_c.0.session/cache/ace2089a7d9190f715a07093a9276e98.json new file mode 100644 index 00000000000..b8fe1543566 --- /dev/null +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/string_c.0.session/cache/ace2089a7d9190f715a07093a9276e98.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0347, + "steps": 57 } diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/string_c.0.session/cache/bfef8898939d13a4a34f0035d4718cf6.json b/src/plugins/wp/tests/wp_plugin/oracle_qualif/string_c.0.session/cache/bfef8898939d13a4a34f0035d4718cf6.json new file mode 100644 index 00000000000..6f6550964d9 --- /dev/null +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/string_c.0.session/cache/bfef8898939d13a4a34f0035d4718cf6.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.1302, + "steps": 240 } diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/string_c.0.session/cache/c78ab4c23e92b597edada513514da04c.json b/src/plugins/wp/tests/wp_plugin/oracle_qualif/string_c.0.session/cache/c78ab4c23e92b597edada513514da04c.json new file mode 100644 index 00000000000..f49bee31304 --- /dev/null +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/string_c.0.session/cache/c78ab4c23e92b597edada513514da04c.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.7427, + "steps": 792 } diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/string_c.0.session/cache/ca73637f01f2f91a0068347eeb9ec94c.json b/src/plugins/wp/tests/wp_plugin/oracle_qualif/string_c.0.session/cache/ca73637f01f2f91a0068347eeb9ec94c.json new file mode 100644 index 00000000000..dcf968b29b0 --- /dev/null +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/string_c.0.session/cache/ca73637f01f2f91a0068347eeb9ec94c.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.6097, + "steps": 695 } diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/string_c.0.session/cache/cf51ece0b093233bb0adb1181e349246.json b/src/plugins/wp/tests/wp_plugin/oracle_qualif/string_c.0.session/cache/cf51ece0b093233bb0adb1181e349246.json new file mode 100644 index 00000000000..a8812b12606 --- /dev/null +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/string_c.0.session/cache/cf51ece0b093233bb0adb1181e349246.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0945, + "steps": 149 } diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/string_c.0.session/cache/d46d0acf6fd632f8f6119d14bca4ce6a.json b/src/plugins/wp/tests/wp_plugin/oracle_qualif/string_c.0.session/cache/d46d0acf6fd632f8f6119d14bca4ce6a.json new file mode 100644 index 00000000000..21c5f0a83cf --- /dev/null +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/string_c.0.session/cache/d46d0acf6fd632f8f6119d14bca4ce6a.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0488, + "steps": 72 } diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/string_c.0.session/cache/d765de4fb3d29a70866cbf36f4fab698.json b/src/plugins/wp/tests/wp_plugin/oracle_qualif/string_c.0.session/cache/d765de4fb3d29a70866cbf36f4fab698.json new file mode 100644 index 00000000000..475abbd0664 --- /dev/null +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/string_c.0.session/cache/d765de4fb3d29a70866cbf36f4fab698.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.1021, + "steps": 173 } diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/string_c.0.session/cache/e76eb6cb77a00f788ce64e76f562810b.json b/src/plugins/wp/tests/wp_plugin/oracle_qualif/string_c.0.session/cache/e76eb6cb77a00f788ce64e76f562810b.json new file mode 100644 index 00000000000..88e58a67440 --- /dev/null +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/string_c.0.session/cache/e76eb6cb77a00f788ce64e76f562810b.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0365, + "steps": 65 } diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/string_c.0.session/cache/ebb2a53efc61a99e868bcaeccdedd60d.json b/src/plugins/wp/tests/wp_plugin/oracle_qualif/string_c.0.session/cache/ebb2a53efc61a99e868bcaeccdedd60d.json new file mode 100644 index 00000000000..af499677627 --- /dev/null +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/string_c.0.session/cache/ebb2a53efc61a99e868bcaeccdedd60d.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.3147, + "steps": 322 } diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/string_c.0.session/cache/ef5c696900a376aef83fb21941139a3c.json b/src/plugins/wp/tests/wp_plugin/oracle_qualif/string_c.0.session/cache/ef5c696900a376aef83fb21941139a3c.json new file mode 100644 index 00000000000..258a750a137 --- /dev/null +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/string_c.0.session/cache/ef5c696900a376aef83fb21941139a3c.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.4215, + "steps": 584 } diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/string_c.0.session/cache/efd16d0abd5a1c7656466cad2eff1a82.json b/src/plugins/wp/tests/wp_plugin/oracle_qualif/string_c.0.session/cache/efd16d0abd5a1c7656466cad2eff1a82.json new file mode 100644 index 00000000000..bbeed980902 --- /dev/null +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/string_c.0.session/cache/efd16d0abd5a1c7656466cad2eff1a82.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0213, + "steps": 23 } diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/string_c.0.session/cache/f24b0ea52a766197c49733f5567e5290.json b/src/plugins/wp/tests/wp_plugin/oracle_qualif/string_c.0.session/cache/f24b0ea52a766197c49733f5567e5290.json new file mode 100644 index 00000000000..95b03ae2293 --- /dev/null +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/string_c.0.session/cache/f24b0ea52a766197c49733f5567e5290.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0435, + "steps": 66 } diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/struct_hack.0.session/cache/3c2808a40bb021dbc99953e3c5324934.json b/src/plugins/wp/tests/wp_plugin/oracle_qualif/struct_hack.0.session/cache/3c2808a40bb021dbc99953e3c5324934.json new file mode 100644 index 00000000000..cf7912a9eda --- /dev/null +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/struct_hack.0.session/cache/3c2808a40bb021dbc99953e3c5324934.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0259, + "steps": 23 } diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/struct_hack.0.session/cache/49a728ea0e221f941984978faa18dc8b.json b/src/plugins/wp/tests/wp_plugin/oracle_qualif/struct_hack.0.session/cache/49a728ea0e221f941984978faa18dc8b.json new file mode 100644 index 00000000000..51a6f9dd086 --- /dev/null +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/struct_hack.0.session/cache/49a728ea0e221f941984978faa18dc8b.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0281, + "steps": 25 } diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/subset.0.session/cache/f11323e3ba20fea4dc00b0c0a4e8c75a.json b/src/plugins/wp/tests/wp_plugin/oracle_qualif/subset.0.session/cache/f11323e3ba20fea4dc00b0c0a4e8c75a.json new file mode 100644 index 00000000000..1804a45ab81 --- /dev/null +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/subset.0.session/cache/f11323e3ba20fea4dc00b0c0a4e8c75a.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0489, + "steps": 118 } diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/subset_fopen.0.session/cache/bbd1bf207aff73a0add5c310a10d82fc.json b/src/plugins/wp/tests/wp_plugin/oracle_qualif/subset_fopen.0.session/cache/bbd1bf207aff73a0add5c310a10d82fc.json new file mode 100644 index 00000000000..ebdb398fc69 --- /dev/null +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/subset_fopen.0.session/cache/bbd1bf207aff73a0add5c310a10d82fc.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0658, + "steps": 99 } diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/unsafe-arrays.0.session/cache/d3af917ba88b4651ecd99c4782829b8d.json b/src/plugins/wp/tests/wp_plugin/oracle_qualif/unsafe-arrays.0.session/cache/d3af917ba88b4651ecd99c4782829b8d.json new file mode 100644 index 00000000000..22aacdd8025 --- /dev/null +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/unsafe-arrays.0.session/cache/d3af917ba88b4651ecd99c4782829b8d.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0241, + "steps": 17 } diff --git a/src/plugins/wp/tests/wp_store/oracle_qualif/nonaliasing.0.session/cache/8824303ce7307ea0a6607b5ed4deb0ae.json b/src/plugins/wp/tests/wp_store/oracle_qualif/nonaliasing.0.session/cache/8824303ce7307ea0a6607b5ed4deb0ae.json new file mode 100644 index 00000000000..aa30f1021ac --- /dev/null +++ b/src/plugins/wp/tests/wp_store/oracle_qualif/nonaliasing.0.session/cache/8824303ce7307ea0a6607b5ed4deb0ae.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0161, + "steps": 23 } diff --git a/src/plugins/wp/tests/wp_store/oracle_qualif/nonaliasing.0.session/cache/974d21e0e97775d1697fc217acf09aae.json b/src/plugins/wp/tests/wp_store/oracle_qualif/nonaliasing.0.session/cache/974d21e0e97775d1697fc217acf09aae.json new file mode 100644 index 00000000000..1806ea75779 --- /dev/null +++ b/src/plugins/wp/tests/wp_store/oracle_qualif/nonaliasing.0.session/cache/974d21e0e97775d1697fc217acf09aae.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0167, + "steps": 23 } diff --git a/src/plugins/wp/tests/wp_store/oracle_qualif/nonaliasing.1.session/cache/054ac21eccbda5823e3b61d57b70fa6e.json b/src/plugins/wp/tests/wp_store/oracle_qualif/nonaliasing.1.session/cache/054ac21eccbda5823e3b61d57b70fa6e.json new file mode 100644 index 00000000000..43afa6298c6 --- /dev/null +++ b/src/plugins/wp/tests/wp_store/oracle_qualif/nonaliasing.1.session/cache/054ac21eccbda5823e3b61d57b70fa6e.json @@ -0,0 +1 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "stepout", "steps": 50 } diff --git a/src/plugins/wp/tests/wp_store/oracle_qualif/nonaliasing.1.session/cache/6f3bf79ad4f2c16243f68e50736057b2.json b/src/plugins/wp/tests/wp_store/oracle_qualif/nonaliasing.1.session/cache/6f3bf79ad4f2c16243f68e50736057b2.json new file mode 100644 index 00000000000..43afa6298c6 --- /dev/null +++ b/src/plugins/wp/tests/wp_store/oracle_qualif/nonaliasing.1.session/cache/6f3bf79ad4f2c16243f68e50736057b2.json @@ -0,0 +1 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "stepout", "steps": 50 } diff --git a/src/plugins/wp/tests/wp_store/oracle_qualif/struct.0.session/cache/94a853062337d3984c131f4b925cf498.json b/src/plugins/wp/tests/wp_store/oracle_qualif/struct.0.session/cache/94a853062337d3984c131f4b925cf498.json new file mode 100644 index 00000000000..4fe43bc2d13 --- /dev/null +++ b/src/plugins/wp/tests/wp_store/oracle_qualif/struct.0.session/cache/94a853062337d3984c131f4b925cf498.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0315, + "steps": 35 } diff --git a/src/plugins/wp/tests/wp_store/oracle_qualif/struct.0.session/cache/ca8f374f313f9efd2a66850f6ce238ac.json b/src/plugins/wp/tests/wp_store/oracle_qualif/struct.0.session/cache/ca8f374f313f9efd2a66850f6ce238ac.json new file mode 100644 index 00000000000..e1eeffe9a6f --- /dev/null +++ b/src/plugins/wp/tests/wp_store/oracle_qualif/struct.0.session/cache/ca8f374f313f9efd2a66850f6ce238ac.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0144, + "steps": 17 } diff --git a/src/plugins/wp/tests/wp_typed/oracle_qualif/array_initialized.0.session/cache/54640927ace915eaf531f7d99162bff2.json b/src/plugins/wp/tests/wp_typed/oracle_qualif/array_initialized.0.session/cache/54640927ace915eaf531f7d99162bff2.json new file mode 100644 index 00000000000..d4c420642ac --- /dev/null +++ b/src/plugins/wp/tests/wp_typed/oracle_qualif/array_initialized.0.session/cache/54640927ace915eaf531f7d99162bff2.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0297, + "steps": 44 } diff --git a/src/plugins/wp/tests/wp_typed/oracle_qualif/array_initialized.0.session/cache/cbef7a2678ffbb62f89898239a2300cf.json b/src/plugins/wp/tests/wp_typed/oracle_qualif/array_initialized.0.session/cache/cbef7a2678ffbb62f89898239a2300cf.json new file mode 100644 index 00000000000..567235ebb30 --- /dev/null +++ b/src/plugins/wp/tests/wp_typed/oracle_qualif/array_initialized.0.session/cache/cbef7a2678ffbb62f89898239a2300cf.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0242, + "steps": 18 } diff --git a/src/plugins/wp/tests/wp_typed/oracle_qualif/array_initialized.1.session/cache/aa1fad5015602138db9f12fbfce39c6a.json b/src/plugins/wp/tests/wp_typed/oracle_qualif/array_initialized.1.session/cache/aa1fad5015602138db9f12fbfce39c6a.json new file mode 100644 index 00000000000..c9c887f8a27 --- /dev/null +++ b/src/plugins/wp/tests/wp_typed/oracle_qualif/array_initialized.1.session/cache/aa1fad5015602138db9f12fbfce39c6a.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0329, + "steps": 48 } diff --git a/src/plugins/wp/tests/wp_typed/oracle_qualif/array_initialized.1.session/cache/c0a758625fc5806b2d004ce066f809f1.json b/src/plugins/wp/tests/wp_typed/oracle_qualif/array_initialized.1.session/cache/c0a758625fc5806b2d004ce066f809f1.json new file mode 100644 index 00000000000..bb482c14eda --- /dev/null +++ b/src/plugins/wp/tests/wp_typed/oracle_qualif/array_initialized.1.session/cache/c0a758625fc5806b2d004ce066f809f1.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0591, + "steps": 115 } diff --git a/src/plugins/wp/tests/wp_typed/oracle_qualif/array_initialized.1.session/cache/cbef7a2678ffbb62f89898239a2300cf.json b/src/plugins/wp/tests/wp_typed/oracle_qualif/array_initialized.1.session/cache/cbef7a2678ffbb62f89898239a2300cf.json new file mode 100644 index 00000000000..567235ebb30 --- /dev/null +++ b/src/plugins/wp/tests/wp_typed/oracle_qualif/array_initialized.1.session/cache/cbef7a2678ffbb62f89898239a2300cf.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0242, + "steps": 18 } diff --git a/src/plugins/wp/tests/wp_typed/oracle_qualif/array_initialized.1.session/cache/edcf65b50fa78c78cddb184cdd54ed56.json b/src/plugins/wp/tests/wp_typed/oracle_qualif/array_initialized.1.session/cache/edcf65b50fa78c78cddb184cdd54ed56.json new file mode 100644 index 00000000000..8d4acf025ff --- /dev/null +++ b/src/plugins/wp/tests/wp_typed/oracle_qualif/array_initialized.1.session/cache/edcf65b50fa78c78cddb184cdd54ed56.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0131, + "steps": 12 } diff --git a/src/plugins/wp/tests/wp_typed/oracle_qualif/cast_fits.0.session/cache/275f36697bf837a8e650d76b262a2972.json b/src/plugins/wp/tests/wp_typed/oracle_qualif/cast_fits.0.session/cache/275f36697bf837a8e650d76b262a2972.json new file mode 100644 index 00000000000..b8e36e2803f --- /dev/null +++ b/src/plugins/wp/tests/wp_typed/oracle_qualif/cast_fits.0.session/cache/275f36697bf837a8e650d76b262a2972.json @@ -0,0 +1 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "timeout", "time": 10. } diff --git a/src/plugins/wp/tests/wp_typed/oracle_qualif/cast_fits.0.session/cache/2d49dd2aa47e49570e397cc771e23a05.json b/src/plugins/wp/tests/wp_typed/oracle_qualif/cast_fits.0.session/cache/2d49dd2aa47e49570e397cc771e23a05.json new file mode 100644 index 00000000000..3b4f2564d06 --- /dev/null +++ b/src/plugins/wp/tests/wp_typed/oracle_qualif/cast_fits.0.session/cache/2d49dd2aa47e49570e397cc771e23a05.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0208, + "steps": 23 } diff --git a/src/plugins/wp/tests/wp_typed/oracle_qualif/cast_fits.0.session/cache/47de988037a45f7d6177eadd7d8a885f.json b/src/plugins/wp/tests/wp_typed/oracle_qualif/cast_fits.0.session/cache/47de988037a45f7d6177eadd7d8a885f.json new file mode 100644 index 00000000000..89dcd109b79 --- /dev/null +++ b/src/plugins/wp/tests/wp_typed/oracle_qualif/cast_fits.0.session/cache/47de988037a45f7d6177eadd7d8a885f.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0212, + "steps": 12 } diff --git a/src/plugins/wp/tests/wp_typed/oracle_qualif/cast_fits.0.session/cache/69c6adb0d354ab9716344b82e02e28da.json b/src/plugins/wp/tests/wp_typed/oracle_qualif/cast_fits.0.session/cache/69c6adb0d354ab9716344b82e02e28da.json new file mode 100644 index 00000000000..806ce6a597c --- /dev/null +++ b/src/plugins/wp/tests/wp_typed/oracle_qualif/cast_fits.0.session/cache/69c6adb0d354ab9716344b82e02e28da.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0229, + "steps": 12 } diff --git a/src/plugins/wp/tests/wp_typed/oracle_qualif/cast_fits.0.session/cache/aab17c8e0ce454a4c0284ffae858edf6.json b/src/plugins/wp/tests/wp_typed/oracle_qualif/cast_fits.0.session/cache/aab17c8e0ce454a4c0284ffae858edf6.json new file mode 100644 index 00000000000..b8e36e2803f --- /dev/null +++ b/src/plugins/wp/tests/wp_typed/oracle_qualif/cast_fits.0.session/cache/aab17c8e0ce454a4c0284ffae858edf6.json @@ -0,0 +1 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "timeout", "time": 10. } diff --git a/src/plugins/wp/tests/wp_typed/oracle_qualif/cast_fits.0.session/cache/bbe62e3cff4dcf2d16418512a09cc682.json b/src/plugins/wp/tests/wp_typed/oracle_qualif/cast_fits.0.session/cache/bbe62e3cff4dcf2d16418512a09cc682.json new file mode 100644 index 00000000000..b8e36e2803f --- /dev/null +++ b/src/plugins/wp/tests/wp_typed/oracle_qualif/cast_fits.0.session/cache/bbe62e3cff4dcf2d16418512a09cc682.json @@ -0,0 +1 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "timeout", "time": 10. } diff --git a/src/plugins/wp/tests/wp_typed/oracle_qualif/cast_fits.0.session/cache/cfd3a385e095a454ca4b030e22ce34d3.json b/src/plugins/wp/tests/wp_typed/oracle_qualif/cast_fits.0.session/cache/cfd3a385e095a454ca4b030e22ce34d3.json new file mode 100644 index 00000000000..87262401f1a --- /dev/null +++ b/src/plugins/wp/tests/wp_typed/oracle_qualif/cast_fits.0.session/cache/cfd3a385e095a454ca4b030e22ce34d3.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0226, + "steps": 14 } diff --git a/src/plugins/wp/tests/wp_typed/oracle_qualif/frame.0.session/cache/1c8e1bc5a936e2c520c323bce7927b1f.json b/src/plugins/wp/tests/wp_typed/oracle_qualif/frame.0.session/cache/1c8e1bc5a936e2c520c323bce7927b1f.json new file mode 100644 index 00000000000..305d3e4e438 --- /dev/null +++ b/src/plugins/wp/tests/wp_typed/oracle_qualif/frame.0.session/cache/1c8e1bc5a936e2c520c323bce7927b1f.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0149, + "steps": 17 } diff --git a/src/plugins/wp/tests/wp_typed/oracle_qualif/frame.0.session/cache/2de2447a32b00f58b6bf40b3b90caf3a.json b/src/plugins/wp/tests/wp_typed/oracle_qualif/frame.0.session/cache/2de2447a32b00f58b6bf40b3b90caf3a.json new file mode 100644 index 00000000000..1e1d9aacca3 --- /dev/null +++ b/src/plugins/wp/tests/wp_typed/oracle_qualif/frame.0.session/cache/2de2447a32b00f58b6bf40b3b90caf3a.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0141, + "steps": 16 } diff --git a/src/plugins/wp/tests/wp_typed/oracle_qualif/shift_lemma.0.session/cache/02a5967e29d215a319e5d52aeea6ee2b.json b/src/plugins/wp/tests/wp_typed/oracle_qualif/shift_lemma.0.session/cache/02a5967e29d215a319e5d52aeea6ee2b.json new file mode 100644 index 00000000000..5da140c7b30 --- /dev/null +++ b/src/plugins/wp/tests/wp_typed/oracle_qualif/shift_lemma.0.session/cache/02a5967e29d215a319e5d52aeea6ee2b.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0209, + "steps": 13 } diff --git a/src/plugins/wp/tests/wp_typed/oracle_qualif/shift_lemma.0.session/cache/578bba9c847de51c178d0337644fd81e.json b/src/plugins/wp/tests/wp_typed/oracle_qualif/shift_lemma.0.session/cache/578bba9c847de51c178d0337644fd81e.json new file mode 100644 index 00000000000..b772d858a80 --- /dev/null +++ b/src/plugins/wp/tests/wp_typed/oracle_qualif/shift_lemma.0.session/cache/578bba9c847de51c178d0337644fd81e.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0225, + "steps": 22 } diff --git a/src/plugins/wp/tests/wp_typed/oracle_qualif/shift_lemma.0.session/cache/7882f8daf0f62dd319b068a984bce5ae.json b/src/plugins/wp/tests/wp_typed/oracle_qualif/shift_lemma.0.session/cache/7882f8daf0f62dd319b068a984bce5ae.json new file mode 100644 index 00000000000..73b69fce80d --- /dev/null +++ b/src/plugins/wp/tests/wp_typed/oracle_qualif/shift_lemma.0.session/cache/7882f8daf0f62dd319b068a984bce5ae.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0137, + "steps": 15 } diff --git a/src/plugins/wp/tests/wp_typed/oracle_qualif/unit_alloc.0.session/cache/51f562f110aa57a99fb537f2987e09da.json b/src/plugins/wp/tests/wp_typed/oracle_qualif/unit_alloc.0.session/cache/51f562f110aa57a99fb537f2987e09da.json new file mode 100644 index 00000000000..a5b1fd54b25 --- /dev/null +++ b/src/plugins/wp/tests/wp_typed/oracle_qualif/unit_alloc.0.session/cache/51f562f110aa57a99fb537f2987e09da.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0193, + "steps": 14 } diff --git a/src/plugins/wp/tests/wp_typed/oracle_qualif/unit_alloc.0.session/cache/9ec67e1127d3b8a1f5e26915449443c8.json b/src/plugins/wp/tests/wp_typed/oracle_qualif/unit_alloc.0.session/cache/9ec67e1127d3b8a1f5e26915449443c8.json new file mode 100644 index 00000000000..f9a2eaa9264 --- /dev/null +++ b/src/plugins/wp/tests/wp_typed/oracle_qualif/unit_alloc.0.session/cache/9ec67e1127d3b8a1f5e26915449443c8.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0234, + "steps": 20 } diff --git a/src/plugins/wp/tests/wp_typed/oracle_qualif/unit_alloc.0.session/cache/caf3de3711d3f3c15ff182a47b1a66e9.json b/src/plugins/wp/tests/wp_typed/oracle_qualif/unit_alloc.0.session/cache/caf3de3711d3f3c15ff182a47b1a66e9.json new file mode 100644 index 00000000000..c8b2450bb5c --- /dev/null +++ b/src/plugins/wp/tests/wp_typed/oracle_qualif/unit_alloc.0.session/cache/caf3de3711d3f3c15ff182a47b1a66e9.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0118, + "steps": 12 } diff --git a/src/plugins/wp/tests/wp_typed/oracle_qualif/unit_alloc.1.session/cache/51f562f110aa57a99fb537f2987e09da.json b/src/plugins/wp/tests/wp_typed/oracle_qualif/unit_alloc.1.session/cache/51f562f110aa57a99fb537f2987e09da.json new file mode 100644 index 00000000000..2a625a90949 --- /dev/null +++ b/src/plugins/wp/tests/wp_typed/oracle_qualif/unit_alloc.1.session/cache/51f562f110aa57a99fb537f2987e09da.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0194, + "steps": 14 } diff --git a/src/plugins/wp/tests/wp_typed/oracle_qualif/unit_alloc.1.session/cache/9ec67e1127d3b8a1f5e26915449443c8.json b/src/plugins/wp/tests/wp_typed/oracle_qualif/unit_alloc.1.session/cache/9ec67e1127d3b8a1f5e26915449443c8.json new file mode 100644 index 00000000000..1922024e1b4 --- /dev/null +++ b/src/plugins/wp/tests/wp_typed/oracle_qualif/unit_alloc.1.session/cache/9ec67e1127d3b8a1f5e26915449443c8.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0233, + "steps": 20 } diff --git a/src/plugins/wp/tests/wp_typed/oracle_qualif/unit_alloc.1.session/cache/caf3de3711d3f3c15ff182a47b1a66e9.json b/src/plugins/wp/tests/wp_typed/oracle_qualif/unit_alloc.1.session/cache/caf3de3711d3f3c15ff182a47b1a66e9.json new file mode 100644 index 00000000000..72ce61cd3a6 --- /dev/null +++ b/src/plugins/wp/tests/wp_typed/oracle_qualif/unit_alloc.1.session/cache/caf3de3711d3f3c15ff182a47b1a66e9.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0187, + "steps": 12 } diff --git a/src/plugins/wp/tests/wp_typed/oracle_qualif/unit_cast.0.session/cache/5725debb61cac997c8aec1f3b0b2205f.json b/src/plugins/wp/tests/wp_typed/oracle_qualif/unit_cast.0.session/cache/5725debb61cac997c8aec1f3b0b2205f.json new file mode 100644 index 00000000000..8201b078256 --- /dev/null +++ b/src/plugins/wp/tests/wp_typed/oracle_qualif/unit_cast.0.session/cache/5725debb61cac997c8aec1f3b0b2205f.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.019, + "steps": 15 } diff --git a/src/plugins/wp/tests/wp_typed/oracle_qualif/unit_hard.0.session/cache/bb2b7123541670aa64836bfff3d66a26.json b/src/plugins/wp/tests/wp_typed/oracle_qualif/unit_hard.0.session/cache/bb2b7123541670aa64836bfff3d66a26.json new file mode 100644 index 00000000000..56c39550428 --- /dev/null +++ b/src/plugins/wp/tests/wp_typed/oracle_qualif/unit_hard.0.session/cache/bb2b7123541670aa64836bfff3d66a26.json @@ -0,0 +1 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "unknown" } diff --git a/src/plugins/wp/tests/wp_typed/oracle_qualif/unit_labels.0.session/cache/48610aa4f300718739c914fc0b7c1f64.json b/src/plugins/wp/tests/wp_typed/oracle_qualif/unit_labels.0.session/cache/48610aa4f300718739c914fc0b7c1f64.json new file mode 100644 index 00000000000..868b9b1d766 --- /dev/null +++ b/src/plugins/wp/tests/wp_typed/oracle_qualif/unit_labels.0.session/cache/48610aa4f300718739c914fc0b7c1f64.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0227, + "steps": 20 } diff --git a/src/plugins/wp/tests/wp_typed/oracle_qualif/unit_labels.0.session/cache/cc6ee1d50b7c0fd64c3271bbc98f9c13.json b/src/plugins/wp/tests/wp_typed/oracle_qualif/unit_labels.0.session/cache/cc6ee1d50b7c0fd64c3271bbc98f9c13.json new file mode 100644 index 00000000000..e528693802b --- /dev/null +++ b/src/plugins/wp/tests/wp_typed/oracle_qualif/unit_labels.0.session/cache/cc6ee1d50b7c0fd64c3271bbc98f9c13.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0217, + "steps": 18 } diff --git a/src/plugins/wp/tests/wp_typed/oracle_qualif/unit_labels.0.session/cache/ff456f15865e6d8f50db8ac0e7f19ea4.json b/src/plugins/wp/tests/wp_typed/oracle_qualif/unit_labels.0.session/cache/ff456f15865e6d8f50db8ac0e7f19ea4.json new file mode 100644 index 00000000000..147a8ae5a0e --- /dev/null +++ b/src/plugins/wp/tests/wp_typed/oracle_qualif/unit_labels.0.session/cache/ff456f15865e6d8f50db8ac0e7f19ea4.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0221, + "steps": 18 } diff --git a/src/plugins/wp/tests/wp_typed/oracle_qualif/unit_local.0.session/cache/5be9158693acc77d4d2e554e52149918.json b/src/plugins/wp/tests/wp_typed/oracle_qualif/unit_local.0.session/cache/5be9158693acc77d4d2e554e52149918.json new file mode 100644 index 00000000000..b4eff8a25e7 --- /dev/null +++ b/src/plugins/wp/tests/wp_typed/oracle_qualif/unit_local.0.session/cache/5be9158693acc77d4d2e554e52149918.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0148, + "steps": 21 } diff --git a/src/plugins/wp/tests/wp_typed/oracle_qualif/unit_local.1.session/cache/974fb23dac4868107d647875f95df135.json b/src/plugins/wp/tests/wp_typed/oracle_qualif/unit_local.1.session/cache/974fb23dac4868107d647875f95df135.json new file mode 100644 index 00000000000..611114f233f --- /dev/null +++ b/src/plugins/wp/tests/wp_typed/oracle_qualif/unit_local.1.session/cache/974fb23dac4868107d647875f95df135.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.013, + "steps": 21 } diff --git a/src/plugins/wp/tests/wp_typed/oracle_qualif/unit_local.1.session/cache/c16ea120b56be33a00dc52be23af6d68.json b/src/plugins/wp/tests/wp_typed/oracle_qualif/unit_local.1.session/cache/c16ea120b56be33a00dc52be23af6d68.json new file mode 100644 index 00000000000..3f1905262a0 --- /dev/null +++ b/src/plugins/wp/tests/wp_typed/oracle_qualif/unit_local.1.session/cache/c16ea120b56be33a00dc52be23af6d68.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0123, + "steps": 22 } diff --git a/src/plugins/wp/tests/wp_typed/oracle_qualif/unit_local.1.session/cache/ff88885f0f8ec902940c70c9b19e68bf.json b/src/plugins/wp/tests/wp_typed/oracle_qualif/unit_local.1.session/cache/ff88885f0f8ec902940c70c9b19e68bf.json new file mode 100644 index 00000000000..a0c4e1cc3d4 --- /dev/null +++ b/src/plugins/wp/tests/wp_typed/oracle_qualif/unit_local.1.session/cache/ff88885f0f8ec902940c70c9b19e68bf.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0139, + "steps": 22 } diff --git a/src/plugins/wp/tests/wp_typed/oracle_qualif/unit_loopscope.0.session/cache/420e102e36b2fd0c60d608072d4bbb2b.json b/src/plugins/wp/tests/wp_typed/oracle_qualif/unit_loopscope.0.session/cache/420e102e36b2fd0c60d608072d4bbb2b.json new file mode 100644 index 00000000000..56c39550428 --- /dev/null +++ b/src/plugins/wp/tests/wp_typed/oracle_qualif/unit_loopscope.0.session/cache/420e102e36b2fd0c60d608072d4bbb2b.json @@ -0,0 +1 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "unknown" } diff --git a/src/plugins/wp/tests/wp_typed/oracle_qualif/unit_string.0.session/cache/06be40162d4388f79dad2e8636a6cc2a.json b/src/plugins/wp/tests/wp_typed/oracle_qualif/unit_string.0.session/cache/06be40162d4388f79dad2e8636a6cc2a.json new file mode 100644 index 00000000000..84cd684136b --- /dev/null +++ b/src/plugins/wp/tests/wp_typed/oracle_qualif/unit_string.0.session/cache/06be40162d4388f79dad2e8636a6cc2a.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0214, + "steps": 28 } diff --git a/src/plugins/wp/tests/wp_typed/oracle_qualif/unit_string.0.session/cache/51299c47004a944cc0cab6fafc4a3bd8.json b/src/plugins/wp/tests/wp_typed/oracle_qualif/unit_string.0.session/cache/51299c47004a944cc0cab6fafc4a3bd8.json new file mode 100644 index 00000000000..263347c369e --- /dev/null +++ b/src/plugins/wp/tests/wp_typed/oracle_qualif/unit_string.0.session/cache/51299c47004a944cc0cab6fafc4a3bd8.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.018, + "steps": 46 } diff --git a/src/plugins/wp/tests/wp_typed/oracle_qualif/unit_string.0.session/cache/5dd650e35271706f2ad3881dca995525.json b/src/plugins/wp/tests/wp_typed/oracle_qualif/unit_string.0.session/cache/5dd650e35271706f2ad3881dca995525.json new file mode 100644 index 00000000000..70b326a7dc9 --- /dev/null +++ b/src/plugins/wp/tests/wp_typed/oracle_qualif/unit_string.0.session/cache/5dd650e35271706f2ad3881dca995525.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0362, + "steps": 62 } diff --git a/src/plugins/wp/tests/wp_typed/oracle_qualif/unit_string.0.session/cache/6e89f99f7bc6430de780b6cbd010c8b5.json b/src/plugins/wp/tests/wp_typed/oracle_qualif/unit_string.0.session/cache/6e89f99f7bc6430de780b6cbd010c8b5.json new file mode 100644 index 00000000000..ade4366dfe8 --- /dev/null +++ b/src/plugins/wp/tests/wp_typed/oracle_qualif/unit_string.0.session/cache/6e89f99f7bc6430de780b6cbd010c8b5.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0297, + "steps": 59 } diff --git a/src/plugins/wp/tests/wp_typed/oracle_qualif/unit_string.0.session/cache/91c84d4131059c3f2bbbe3b3f414e1fe.json b/src/plugins/wp/tests/wp_typed/oracle_qualif/unit_string.0.session/cache/91c84d4131059c3f2bbbe3b3f414e1fe.json new file mode 100644 index 00000000000..3d45a52778f --- /dev/null +++ b/src/plugins/wp/tests/wp_typed/oracle_qualif/unit_string.0.session/cache/91c84d4131059c3f2bbbe3b3f414e1fe.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0392, + "steps": 70 } diff --git a/src/plugins/wp/tests/wp_typed/oracle_qualif/unit_string.0.session/cache/f9cff23cc8636428a30178fe3fcc8a69.json b/src/plugins/wp/tests/wp_typed/oracle_qualif/unit_string.0.session/cache/f9cff23cc8636428a30178fe3fcc8a69.json new file mode 100644 index 00000000000..4e431bc033f --- /dev/null +++ b/src/plugins/wp/tests/wp_typed/oracle_qualif/unit_string.0.session/cache/f9cff23cc8636428a30178fe3fcc8a69.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0395, + "steps": 62 } diff --git a/src/plugins/wp/tests/wp_typed/oracle_qualif/user_init.0.session/cache/02acba90a5e2994128860c40fb9f2ba4.json b/src/plugins/wp/tests/wp_typed/oracle_qualif/user_init.0.session/cache/02acba90a5e2994128860c40fb9f2ba4.json new file mode 100644 index 00000000000..c3521884803 --- /dev/null +++ b/src/plugins/wp/tests/wp_typed/oracle_qualif/user_init.0.session/cache/02acba90a5e2994128860c40fb9f2ba4.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.1924, + "steps": 195 } diff --git a/src/plugins/wp/tests/wp_typed/oracle_qualif/user_init.0.session/cache/0b0769d38a9d9517197365e24d9ff7aa.json b/src/plugins/wp/tests/wp_typed/oracle_qualif/user_init.0.session/cache/0b0769d38a9d9517197365e24d9ff7aa.json new file mode 100644 index 00000000000..679a691bc8f --- /dev/null +++ b/src/plugins/wp/tests/wp_typed/oracle_qualif/user_init.0.session/cache/0b0769d38a9d9517197365e24d9ff7aa.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0257, + "steps": 35 } diff --git a/src/plugins/wp/tests/wp_typed/oracle_qualif/user_init.0.session/cache/3c1410111850a62a3c903e678e48aa06.json b/src/plugins/wp/tests/wp_typed/oracle_qualif/user_init.0.session/cache/3c1410111850a62a3c903e678e48aa06.json new file mode 100644 index 00000000000..c5a5571ecbf --- /dev/null +++ b/src/plugins/wp/tests/wp_typed/oracle_qualif/user_init.0.session/cache/3c1410111850a62a3c903e678e48aa06.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.018, + "steps": 15 } diff --git a/src/plugins/wp/tests/wp_typed/oracle_qualif/user_init.0.session/cache/3e77a926f2555c5bf515bd79563fc136.json b/src/plugins/wp/tests/wp_typed/oracle_qualif/user_init.0.session/cache/3e77a926f2555c5bf515bd79563fc136.json new file mode 100644 index 00000000000..bc98bdf0e0a --- /dev/null +++ b/src/plugins/wp/tests/wp_typed/oracle_qualif/user_init.0.session/cache/3e77a926f2555c5bf515bd79563fc136.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0238, + "steps": 15 } diff --git a/src/plugins/wp/tests/wp_typed/oracle_qualif/user_init.0.session/cache/437695130334113727cc1e91e1310860.json b/src/plugins/wp/tests/wp_typed/oracle_qualif/user_init.0.session/cache/437695130334113727cc1e91e1310860.json new file mode 100644 index 00000000000..552a83b2341 --- /dev/null +++ b/src/plugins/wp/tests/wp_typed/oracle_qualif/user_init.0.session/cache/437695130334113727cc1e91e1310860.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0238, + "steps": 22 } diff --git a/src/plugins/wp/tests/wp_typed/oracle_qualif/user_init.0.session/cache/5702189f244cf06f51fa911ec3cfc217.json b/src/plugins/wp/tests/wp_typed/oracle_qualif/user_init.0.session/cache/5702189f244cf06f51fa911ec3cfc217.json new file mode 100644 index 00000000000..9ee69d6b1cd --- /dev/null +++ b/src/plugins/wp/tests/wp_typed/oracle_qualif/user_init.0.session/cache/5702189f244cf06f51fa911ec3cfc217.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0262, + "steps": 22 } diff --git a/src/plugins/wp/tests/wp_typed/oracle_qualif/user_init.0.session/cache/886d5e0abccf7e670b416c38f907864c.json b/src/plugins/wp/tests/wp_typed/oracle_qualif/user_init.0.session/cache/886d5e0abccf7e670b416c38f907864c.json new file mode 100644 index 00000000000..d52901c3db2 --- /dev/null +++ b/src/plugins/wp/tests/wp_typed/oracle_qualif/user_init.0.session/cache/886d5e0abccf7e670b416c38f907864c.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0251, + "steps": 15 } diff --git a/src/plugins/wp/tests/wp_typed/oracle_qualif/user_init.0.session/cache/a2e4a1bc7074fcc778279e99ec19077d.json b/src/plugins/wp/tests/wp_typed/oracle_qualif/user_init.0.session/cache/a2e4a1bc7074fcc778279e99ec19077d.json new file mode 100644 index 00000000000..c1e2b94f3c2 --- /dev/null +++ b/src/plugins/wp/tests/wp_typed/oracle_qualif/user_init.0.session/cache/a2e4a1bc7074fcc778279e99ec19077d.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0241, + "steps": 15 } diff --git a/src/plugins/wp/tests/wp_typed/oracle_qualif/user_init.0.session/cache/aea9a4d6d52524ca1bda06c25330d453.json b/src/plugins/wp/tests/wp_typed/oracle_qualif/user_init.0.session/cache/aea9a4d6d52524ca1bda06c25330d453.json new file mode 100644 index 00000000000..a43e3baf951 --- /dev/null +++ b/src/plugins/wp/tests/wp_typed/oracle_qualif/user_init.0.session/cache/aea9a4d6d52524ca1bda06c25330d453.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0196, + "steps": 28 } diff --git a/src/plugins/wp/tests/wp_typed/oracle_qualif/user_init.0.session/cache/b526cd5eaf63d35c962f8df3f2312ce8.json b/src/plugins/wp/tests/wp_typed/oracle_qualif/user_init.0.session/cache/b526cd5eaf63d35c962f8df3f2312ce8.json new file mode 100644 index 00000000000..c0e98b11ddb --- /dev/null +++ b/src/plugins/wp/tests/wp_typed/oracle_qualif/user_init.0.session/cache/b526cd5eaf63d35c962f8df3f2312ce8.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0386, + "steps": 56 } diff --git a/src/plugins/wp/tests/wp_typed/oracle_qualif/user_init.0.session/cache/b5efd7507bdfb8fc86984707ac9c09d0.json b/src/plugins/wp/tests/wp_typed/oracle_qualif/user_init.0.session/cache/b5efd7507bdfb8fc86984707ac9c09d0.json new file mode 100644 index 00000000000..9e434d4de04 --- /dev/null +++ b/src/plugins/wp/tests/wp_typed/oracle_qualif/user_init.0.session/cache/b5efd7507bdfb8fc86984707ac9c09d0.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0111, + "steps": 18 } diff --git a/src/plugins/wp/tests/wp_typed/oracle_qualif/user_init.0.session/cache/ea5f20db4ed84d856d7641ef17d0e541.json b/src/plugins/wp/tests/wp_typed/oracle_qualif/user_init.0.session/cache/ea5f20db4ed84d856d7641ef17d0e541.json new file mode 100644 index 00000000000..79ccdcedb0b --- /dev/null +++ b/src/plugins/wp/tests/wp_typed/oracle_qualif/user_init.0.session/cache/ea5f20db4ed84d856d7641ef17d0e541.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.215, + "steps": 193 } diff --git a/src/plugins/wp/tests/wp_typed/oracle_qualif/user_init.1.session/cache/0afa9c7ed5285e03fb1e7ec3d0e1bcad.json b/src/plugins/wp/tests/wp_typed/oracle_qualif/user_init.1.session/cache/0afa9c7ed5285e03fb1e7ec3d0e1bcad.json new file mode 100644 index 00000000000..ce60e79f356 --- /dev/null +++ b/src/plugins/wp/tests/wp_typed/oracle_qualif/user_init.1.session/cache/0afa9c7ed5285e03fb1e7ec3d0e1bcad.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0257, + "steps": 16 } diff --git a/src/plugins/wp/tests/wp_typed/oracle_qualif/user_init.1.session/cache/2bf63647c8b8679f671cda4e96dd02c8.json b/src/plugins/wp/tests/wp_typed/oracle_qualif/user_init.1.session/cache/2bf63647c8b8679f671cda4e96dd02c8.json new file mode 100644 index 00000000000..972b4fc44f4 --- /dev/null +++ b/src/plugins/wp/tests/wp_typed/oracle_qualif/user_init.1.session/cache/2bf63647c8b8679f671cda4e96dd02c8.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0205, + "steps": 16 } diff --git a/src/plugins/wp/tests/wp_typed/oracle_qualif/user_init.1.session/cache/4e990ccecbce16ae7813bf76856ed44b.json b/src/plugins/wp/tests/wp_typed/oracle_qualif/user_init.1.session/cache/4e990ccecbce16ae7813bf76856ed44b.json new file mode 100644 index 00000000000..b8e36e2803f --- /dev/null +++ b/src/plugins/wp/tests/wp_typed/oracle_qualif/user_init.1.session/cache/4e990ccecbce16ae7813bf76856ed44b.json @@ -0,0 +1 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "timeout", "time": 10. } diff --git a/src/plugins/wp/tests/wp_typed/oracle_qualif/user_init.1.session/cache/58c3647be66cbcb1d4b1f050100571a3.json b/src/plugins/wp/tests/wp_typed/oracle_qualif/user_init.1.session/cache/58c3647be66cbcb1d4b1f050100571a3.json new file mode 100644 index 00000000000..69e420d2117 --- /dev/null +++ b/src/plugins/wp/tests/wp_typed/oracle_qualif/user_init.1.session/cache/58c3647be66cbcb1d4b1f050100571a3.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0241, + "steps": 28 } diff --git a/src/plugins/wp/tests/wp_typed/oracle_qualif/user_init.1.session/cache/6bdf496e41182821957a01191acc6df3.json b/src/plugins/wp/tests/wp_typed/oracle_qualif/user_init.1.session/cache/6bdf496e41182821957a01191acc6df3.json new file mode 100644 index 00000000000..b8e36e2803f --- /dev/null +++ b/src/plugins/wp/tests/wp_typed/oracle_qualif/user_init.1.session/cache/6bdf496e41182821957a01191acc6df3.json @@ -0,0 +1 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "timeout", "time": 10. } diff --git a/src/plugins/wp/tests/wp_typed/oracle_qualif/user_init.1.session/cache/93a87d49aa052b4a3426069f903e97d8.json b/src/plugins/wp/tests/wp_typed/oracle_qualif/user_init.1.session/cache/93a87d49aa052b4a3426069f903e97d8.json new file mode 100644 index 00000000000..56c39550428 --- /dev/null +++ b/src/plugins/wp/tests/wp_typed/oracle_qualif/user_init.1.session/cache/93a87d49aa052b4a3426069f903e97d8.json @@ -0,0 +1 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "unknown" } diff --git a/src/plugins/wp/tests/wp_typed/oracle_qualif/user_init.1.session/cache/a278c3684532efda2a8b0aa0b8328228.json b/src/plugins/wp/tests/wp_typed/oracle_qualif/user_init.1.session/cache/a278c3684532efda2a8b0aa0b8328228.json new file mode 100644 index 00000000000..238e0b85b7f --- /dev/null +++ b/src/plugins/wp/tests/wp_typed/oracle_qualif/user_init.1.session/cache/a278c3684532efda2a8b0aa0b8328228.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0153, + "steps": 22 } diff --git a/src/plugins/wp/tests/wp_typed/oracle_qualif/user_init.1.session/cache/c40097d18aabd35cf73be24de441cda4.json b/src/plugins/wp/tests/wp_typed/oracle_qualif/user_init.1.session/cache/c40097d18aabd35cf73be24de441cda4.json new file mode 100644 index 00000000000..4d64ab92a78 --- /dev/null +++ b/src/plugins/wp/tests/wp_typed/oracle_qualif/user_init.1.session/cache/c40097d18aabd35cf73be24de441cda4.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.017, + "steps": 22 } diff --git a/src/plugins/wp/tests/wp_typed/oracle_qualif/user_init.1.session/cache/dbc2fcfa6ad5e92e7256df7e47ac4dfd.json b/src/plugins/wp/tests/wp_typed/oracle_qualif/user_init.1.session/cache/dbc2fcfa6ad5e92e7256df7e47ac4dfd.json new file mode 100644 index 00000000000..c8b2450bb5c --- /dev/null +++ b/src/plugins/wp/tests/wp_typed/oracle_qualif/user_init.1.session/cache/dbc2fcfa6ad5e92e7256df7e47ac4dfd.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0118, + "steps": 12 } diff --git a/src/plugins/wp/tests/wp_typed/oracle_qualif/user_init.2.session/cache/5bfecd798741a31e1a9b75b1e76b6fb9.json b/src/plugins/wp/tests/wp_typed/oracle_qualif/user_init.2.session/cache/5bfecd798741a31e1a9b75b1e76b6fb9.json new file mode 100644 index 00000000000..8f6e537c77c --- /dev/null +++ b/src/plugins/wp/tests/wp_typed/oracle_qualif/user_init.2.session/cache/5bfecd798741a31e1a9b75b1e76b6fb9.json @@ -0,0 +1 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "stepout", "steps": 300 } diff --git a/src/plugins/wp/tests/wp_typed/oracle_qualif/user_init.2.session/cache/874512731d488beab568aeedc8d4b813.json b/src/plugins/wp/tests/wp_typed/oracle_qualif/user_init.2.session/cache/874512731d488beab568aeedc8d4b813.json new file mode 100644 index 00000000000..8f6e537c77c --- /dev/null +++ b/src/plugins/wp/tests/wp_typed/oracle_qualif/user_init.2.session/cache/874512731d488beab568aeedc8d4b813.json @@ -0,0 +1 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "stepout", "steps": 300 } diff --git a/src/plugins/wp/tests/wp_typed/oracle_qualif/user_init.2.session/cache/a857d63f4fb5a4a658f9459397c355f7.json b/src/plugins/wp/tests/wp_typed/oracle_qualif/user_init.2.session/cache/a857d63f4fb5a4a658f9459397c355f7.json new file mode 100644 index 00000000000..56c39550428 --- /dev/null +++ b/src/plugins/wp/tests/wp_typed/oracle_qualif/user_init.2.session/cache/a857d63f4fb5a4a658f9459397c355f7.json @@ -0,0 +1 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "unknown" } diff --git a/src/plugins/wp/tests/wp_typed/oracle_qualif/user_string.0.session/cache/0278cb04c10669bda8546d6aa4b5b1a2.json b/src/plugins/wp/tests/wp_typed/oracle_qualif/user_string.0.session/cache/0278cb04c10669bda8546d6aa4b5b1a2.json new file mode 100644 index 00000000000..8801ce13041 --- /dev/null +++ b/src/plugins/wp/tests/wp_typed/oracle_qualif/user_string.0.session/cache/0278cb04c10669bda8546d6aa4b5b1a2.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0203, + "steps": 49 } diff --git a/src/plugins/wp/tests/wp_typed/oracle_qualif/user_string.0.session/cache/06a0f4a9e1bbdbde32bdf1f677d91181.json b/src/plugins/wp/tests/wp_typed/oracle_qualif/user_string.0.session/cache/06a0f4a9e1bbdbde32bdf1f677d91181.json new file mode 100644 index 00000000000..369c94f975e --- /dev/null +++ b/src/plugins/wp/tests/wp_typed/oracle_qualif/user_string.0.session/cache/06a0f4a9e1bbdbde32bdf1f677d91181.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0433, + "steps": 58 } diff --git a/src/plugins/wp/tests/wp_typed/oracle_qualif/user_string.0.session/cache/0ee2f3e078b2e5a06190ddebe6f3da08.json b/src/plugins/wp/tests/wp_typed/oracle_qualif/user_string.0.session/cache/0ee2f3e078b2e5a06190ddebe6f3da08.json new file mode 100644 index 00000000000..ff5f35d52a1 --- /dev/null +++ b/src/plugins/wp/tests/wp_typed/oracle_qualif/user_string.0.session/cache/0ee2f3e078b2e5a06190ddebe6f3da08.json @@ -0,0 +1 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.02, "steps": 34 } diff --git a/src/plugins/wp/tests/wp_typed/oracle_qualif/user_string.0.session/cache/38d0f75717aeccc5685668c23c4874e6.json b/src/plugins/wp/tests/wp_typed/oracle_qualif/user_string.0.session/cache/38d0f75717aeccc5685668c23c4874e6.json new file mode 100644 index 00000000000..737e617d449 --- /dev/null +++ b/src/plugins/wp/tests/wp_typed/oracle_qualif/user_string.0.session/cache/38d0f75717aeccc5685668c23c4874e6.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0518, + "steps": 128 } diff --git a/src/plugins/wp/tests/wp_typed/oracle_qualif/user_string.0.session/cache/6b7331507db6c1572280eb515546680a.json b/src/plugins/wp/tests/wp_typed/oracle_qualif/user_string.0.session/cache/6b7331507db6c1572280eb515546680a.json new file mode 100644 index 00000000000..8a3d1b64bd6 --- /dev/null +++ b/src/plugins/wp/tests/wp_typed/oracle_qualif/user_string.0.session/cache/6b7331507db6c1572280eb515546680a.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0297, + "steps": 46 } diff --git a/src/plugins/wp/tests/wp_typed/oracle_qualif/user_swap.0.session/cache/44f847d26840ea2582d2f6cd48a9bbf2.json b/src/plugins/wp/tests/wp_typed/oracle_qualif/user_swap.0.session/cache/44f847d26840ea2582d2f6cd48a9bbf2.json new file mode 100644 index 00000000000..a636bab232a --- /dev/null +++ b/src/plugins/wp/tests/wp_typed/oracle_qualif/user_swap.0.session/cache/44f847d26840ea2582d2f6cd48a9bbf2.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0147, + "steps": 17 } diff --git a/src/plugins/wp/tests/wp_usage/oracle_qualif/caveat2.0.session/cache/1618850a88ad1dcc80a2d9a980d52dc8.json b/src/plugins/wp/tests/wp_usage/oracle_qualif/caveat2.0.session/cache/1618850a88ad1dcc80a2d9a980d52dc8.json new file mode 100644 index 00000000000..29119310daa --- /dev/null +++ b/src/plugins/wp/tests/wp_usage/oracle_qualif/caveat2.0.session/cache/1618850a88ad1dcc80a2d9a980d52dc8.json @@ -0,0 +1 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.02, "steps": 17 } diff --git a/src/plugins/wp/tests/wp_usage/oracle_qualif/caveat2.0.session/cache/94d26158a717c5e2cda72d3c71c02776.json b/src/plugins/wp/tests/wp_usage/oracle_qualif/caveat2.0.session/cache/94d26158a717c5e2cda72d3c71c02776.json new file mode 100644 index 00000000000..cfad4d1f517 --- /dev/null +++ b/src/plugins/wp/tests/wp_usage/oracle_qualif/caveat2.0.session/cache/94d26158a717c5e2cda72d3c71c02776.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0167, + "steps": 21 } diff --git a/src/plugins/wp/tests/wp_usage/oracle_qualif/caveat2.0.session/cache/bd7bc3c6aa2a16dd8cc830c3c57c3faa.json b/src/plugins/wp/tests/wp_usage/oracle_qualif/caveat2.0.session/cache/bd7bc3c6aa2a16dd8cc830c3c57c3faa.json new file mode 100644 index 00000000000..eca1c5e5d9e --- /dev/null +++ b/src/plugins/wp/tests/wp_usage/oracle_qualif/caveat2.0.session/cache/bd7bc3c6aa2a16dd8cc830c3c57c3faa.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0186, + "steps": 24 } diff --git a/src/plugins/wp/tests/wp_usage/oracle_qualif/caveat_range.0.session/cache/2b92804b7fb7ffdca664af595a966537.json b/src/plugins/wp/tests/wp_usage/oracle_qualif/caveat_range.0.session/cache/2b92804b7fb7ffdca664af595a966537.json new file mode 100644 index 00000000000..920cab99f7d --- /dev/null +++ b/src/plugins/wp/tests/wp_usage/oracle_qualif/caveat_range.0.session/cache/2b92804b7fb7ffdca664af595a966537.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0247, + "steps": 20 } diff --git a/src/plugins/wp/tests/wp_usage/oracle_qualif/caveat_range.0.session/cache/41978d7b0067a89104bd5f2bbd577a3a.json b/src/plugins/wp/tests/wp_usage/oracle_qualif/caveat_range.0.session/cache/41978d7b0067a89104bd5f2bbd577a3a.json new file mode 100644 index 00000000000..640fdc7ce09 --- /dev/null +++ b/src/plugins/wp/tests/wp_usage/oracle_qualif/caveat_range.0.session/cache/41978d7b0067a89104bd5f2bbd577a3a.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0178, + "steps": 20 } diff --git a/src/plugins/wp/tests/wp_usage/oracle_qualif/caveat_range.0.session/cache/458df2d4dbfc5fe724b9f06bbff664ab.json b/src/plugins/wp/tests/wp_usage/oracle_qualif/caveat_range.0.session/cache/458df2d4dbfc5fe724b9f06bbff664ab.json new file mode 100644 index 00000000000..a696be0d759 --- /dev/null +++ b/src/plugins/wp/tests/wp_usage/oracle_qualif/caveat_range.0.session/cache/458df2d4dbfc5fe724b9f06bbff664ab.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0346, + "steps": 48 } diff --git a/src/plugins/wp/tests/wp_usage/oracle_qualif/caveat_range.0.session/cache/4794c66d9a48e1f6e50a71af3e78f625.json b/src/plugins/wp/tests/wp_usage/oracle_qualif/caveat_range.0.session/cache/4794c66d9a48e1f6e50a71af3e78f625.json new file mode 100644 index 00000000000..92db41d2496 --- /dev/null +++ b/src/plugins/wp/tests/wp_usage/oracle_qualif/caveat_range.0.session/cache/4794c66d9a48e1f6e50a71af3e78f625.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0134, + "steps": 14 } diff --git a/src/plugins/wp/tests/wp_usage/oracle_qualif/caveat_range.0.session/cache/d47c18406856fd185a8c849853d341e2.json b/src/plugins/wp/tests/wp_usage/oracle_qualif/caveat_range.0.session/cache/d47c18406856fd185a8c849853d341e2.json new file mode 100644 index 00000000000..93ddc0ff27e --- /dev/null +++ b/src/plugins/wp/tests/wp_usage/oracle_qualif/caveat_range.0.session/cache/d47c18406856fd185a8c849853d341e2.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0191, + "steps": 28 } diff --git a/src/plugins/wp/tests/wp_usage/oracle_qualif/issue-189-bis.0.session/cache/0d7ed916922dfd3cd88f04aa053382de.json b/src/plugins/wp/tests/wp_usage/oracle_qualif/issue-189-bis.0.session/cache/0d7ed916922dfd3cd88f04aa053382de.json new file mode 100644 index 00000000000..9a20cc2eb8a --- /dev/null +++ b/src/plugins/wp/tests/wp_usage/oracle_qualif/issue-189-bis.0.session/cache/0d7ed916922dfd3cd88f04aa053382de.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0801, + "steps": 104 } diff --git a/src/plugins/wp/tests/wp_usage/oracle_qualif/issue-189-bis.0.session/cache/1d2723c4a683647c25bef5fe4d0cf9d8.json b/src/plugins/wp/tests/wp_usage/oracle_qualif/issue-189-bis.0.session/cache/1d2723c4a683647c25bef5fe4d0cf9d8.json new file mode 100644 index 00000000000..dae850748a4 --- /dev/null +++ b/src/plugins/wp/tests/wp_usage/oracle_qualif/issue-189-bis.0.session/cache/1d2723c4a683647c25bef5fe4d0cf9d8.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0188, + "steps": 22 } diff --git a/src/plugins/wp/tests/wp_usage/oracle_qualif/issue-189-bis.0.session/cache/24c6daff7425605b2807df8b79073aeb.json b/src/plugins/wp/tests/wp_usage/oracle_qualif/issue-189-bis.0.session/cache/24c6daff7425605b2807df8b79073aeb.json new file mode 100644 index 00000000000..516ea73427d --- /dev/null +++ b/src/plugins/wp/tests/wp_usage/oracle_qualif/issue-189-bis.0.session/cache/24c6daff7425605b2807df8b79073aeb.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 1.0037, + "steps": 1031 } diff --git a/src/plugins/wp/tests/wp_usage/oracle_qualif/issue-189-bis.0.session/cache/5760024d3d12da3af8d584a2e1a2b6c0.json b/src/plugins/wp/tests/wp_usage/oracle_qualif/issue-189-bis.0.session/cache/5760024d3d12da3af8d584a2e1a2b6c0.json new file mode 100644 index 00000000000..2522ba884d5 --- /dev/null +++ b/src/plugins/wp/tests/wp_usage/oracle_qualif/issue-189-bis.0.session/cache/5760024d3d12da3af8d584a2e1a2b6c0.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0135, + "steps": 22 } diff --git a/src/plugins/wp/tests/wp_usage/oracle_qualif/issue-189-bis.0.session/cache/60b70c5aacda3dc7239684d5c8a9143e.json b/src/plugins/wp/tests/wp_usage/oracle_qualif/issue-189-bis.0.session/cache/60b70c5aacda3dc7239684d5c8a9143e.json new file mode 100644 index 00000000000..7397f05d461 --- /dev/null +++ b/src/plugins/wp/tests/wp_usage/oracle_qualif/issue-189-bis.0.session/cache/60b70c5aacda3dc7239684d5c8a9143e.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.1052, + "steps": 173 } diff --git a/src/plugins/wp/tests/wp_usage/oracle_qualif/issue-189-bis.0.session/cache/72809963e95fe64166cd5b945b5d46cb.json b/src/plugins/wp/tests/wp_usage/oracle_qualif/issue-189-bis.0.session/cache/72809963e95fe64166cd5b945b5d46cb.json new file mode 100644 index 00000000000..7dfbab66f28 --- /dev/null +++ b/src/plugins/wp/tests/wp_usage/oracle_qualif/issue-189-bis.0.session/cache/72809963e95fe64166cd5b945b5d46cb.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.1356, + "steps": 173 } diff --git a/src/plugins/wp/tests/wp_usage/oracle_qualif/issue-189-bis.0.session/cache/9f2521dbb8d31c6d01c228e4aa27ff19.json b/src/plugins/wp/tests/wp_usage/oracle_qualif/issue-189-bis.0.session/cache/9f2521dbb8d31c6d01c228e4aa27ff19.json new file mode 100644 index 00000000000..cb38646d40b --- /dev/null +++ b/src/plugins/wp/tests/wp_usage/oracle_qualif/issue-189-bis.0.session/cache/9f2521dbb8d31c6d01c228e4aa27ff19.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0782, + "steps": 97 } diff --git a/src/plugins/wp/tests/wp_usage/oracle_qualif/issue-189-bis.0.session/cache/b3b8f8b3c5dcdfa1b0a26f1f950a56fa.json b/src/plugins/wp/tests/wp_usage/oracle_qualif/issue-189-bis.0.session/cache/b3b8f8b3c5dcdfa1b0a26f1f950a56fa.json new file mode 100644 index 00000000000..de8dfd200fd --- /dev/null +++ b/src/plugins/wp/tests/wp_usage/oracle_qualif/issue-189-bis.0.session/cache/b3b8f8b3c5dcdfa1b0a26f1f950a56fa.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0674, + "steps": 95 } diff --git a/src/plugins/wp/tests/wp_usage/oracle_qualif/issue-189-bis.0.session/cache/d05062d51da49ab4e2231ed6e5b4617d.json b/src/plugins/wp/tests/wp_usage/oracle_qualif/issue-189-bis.0.session/cache/d05062d51da49ab4e2231ed6e5b4617d.json new file mode 100644 index 00000000000..0e65686ded9 --- /dev/null +++ b/src/plugins/wp/tests/wp_usage/oracle_qualif/issue-189-bis.0.session/cache/d05062d51da49ab4e2231ed6e5b4617d.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0912, + "steps": 104 } diff --git a/src/plugins/wp/tests/wp_usage/oracle_qualif/issue-189-bis.0.session/cache/d40dc9c872cb867b53026c481dc3559b.json b/src/plugins/wp/tests/wp_usage/oracle_qualif/issue-189-bis.0.session/cache/d40dc9c872cb867b53026c481dc3559b.json new file mode 100644 index 00000000000..a5f9b0076ec --- /dev/null +++ b/src/plugins/wp/tests/wp_usage/oracle_qualif/issue-189-bis.0.session/cache/d40dc9c872cb867b53026c481dc3559b.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 1.1785, + "steps": 1031 } diff --git a/src/plugins/wp/tests/wp_usage/oracle_qualif/issue-189-bis.1.session/cache/4253c6f687ba6a60e8db3e685e84df59.json b/src/plugins/wp/tests/wp_usage/oracle_qualif/issue-189-bis.1.session/cache/4253c6f687ba6a60e8db3e685e84df59.json new file mode 100644 index 00000000000..f7443c49dd7 --- /dev/null +++ b/src/plugins/wp/tests/wp_usage/oracle_qualif/issue-189-bis.1.session/cache/4253c6f687ba6a60e8db3e685e84df59.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0207, + "steps": 18 } diff --git a/src/plugins/wp/tests/wp_usage/oracle_qualif/issue-189-bis.1.session/cache/450fdb9fdd1ea7a682081dbc0af6e709.json b/src/plugins/wp/tests/wp_usage/oracle_qualif/issue-189-bis.1.session/cache/450fdb9fdd1ea7a682081dbc0af6e709.json new file mode 100644 index 00000000000..fbe4ed9b34a --- /dev/null +++ b/src/plugins/wp/tests/wp_usage/oracle_qualif/issue-189-bis.1.session/cache/450fdb9fdd1ea7a682081dbc0af6e709.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0644, + "steps": 63 } diff --git a/src/plugins/wp/tests/wp_usage/oracle_qualif/issue-189-bis.1.session/cache/688d69c32aabc5063535d39e5dc1b063.json b/src/plugins/wp/tests/wp_usage/oracle_qualif/issue-189-bis.1.session/cache/688d69c32aabc5063535d39e5dc1b063.json new file mode 100644 index 00000000000..3b7df3605ba --- /dev/null +++ b/src/plugins/wp/tests/wp_usage/oracle_qualif/issue-189-bis.1.session/cache/688d69c32aabc5063535d39e5dc1b063.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0145, + "steps": 18 } -- GitLab From 108f6b68777bde0333577a8e74783c30656840b2 Mon Sep 17 00:00:00 2001 From: Virgile Prevosto <virgile.prevosto@m4x.org> Date: Thu, 26 Mar 2020 15:25:22 +0100 Subject: [PATCH 020/218] [tests] avoid duplication definition warnings in oracles --- .../instantiate/tests/stdlib/oracle/calloc.res.oracle | 3 --- .../instantiate/tests/stdlib/oracle/free.res.oracle | 11 ----------- .../instantiate/tests/stdlib/oracle/malloc.res.oracle | 3 --- src/plugins/instantiate/tests/stdlib/test_config | 2 +- 4 files changed, 1 insertion(+), 18 deletions(-) diff --git a/src/plugins/instantiate/tests/stdlib/oracle/calloc.res.oracle b/src/plugins/instantiate/tests/stdlib/oracle/calloc.res.oracle index 81cf9b246df..28d42c036e3 100644 --- a/src/plugins/instantiate/tests/stdlib/oracle/calloc.res.oracle +++ b/src/plugins/instantiate/tests/stdlib/oracle/calloc.res.oracle @@ -272,9 +272,6 @@ int main(void) [kernel] Parsing tests/stdlib/result/calloc.c (with preprocessing) -[kernel] Parsing tests/stdlib/calloc.c (with preprocessing) -[kernel] tests/stdlib/calloc.c:14: Warning: - def'n of func main at tests/stdlib/calloc.c:14 (sum 7290) conflicts with the one at tests/stdlib/result/calloc.c:253 (sum 9064); keeping the one at tests/stdlib/result/calloc.c:253. /* Generated by Frama-C */ #include "stdlib.h" struct X { diff --git a/src/plugins/instantiate/tests/stdlib/oracle/free.res.oracle b/src/plugins/instantiate/tests/stdlib/oracle/free.res.oracle index 11f5ef65b0e..cfdb769ed8d 100644 --- a/src/plugins/instantiate/tests/stdlib/oracle/free.res.oracle +++ b/src/plugins/instantiate/tests/stdlib/oracle/free.res.oracle @@ -139,17 +139,6 @@ void with_incomplete(struct incomplete *t) [kernel] Parsing tests/stdlib/result/free.c (with preprocessing) -[kernel] Parsing tests/stdlib/free.c (with preprocessing) -[kernel] tests/stdlib/free.c:3: Warning: - dropping duplicate def'n of func foo at tests/stdlib/free.c:3 in favor of that at tests/stdlib/result/free.c:30 -[kernel] tests/stdlib/free.c:6: Warning: - dropping duplicate def'n of func bar at tests/stdlib/free.c:6 in favor of that at tests/stdlib/result/free.c:62 -[kernel] tests/stdlib/free.c:9: Warning: - dropping duplicate def'n of func baz at tests/stdlib/free.c:9 in favor of that at tests/stdlib/result/free.c:94 -[kernel] tests/stdlib/free.c:12: Warning: - dropping duplicate def'n of func with_void at tests/stdlib/free.c:12 in favor of that at tests/stdlib/result/free.c:100 -[kernel] tests/stdlib/free.c:15: Warning: - dropping duplicate def'n of func with_incomplete at tests/stdlib/free.c:15 in favor of that at tests/stdlib/result/free.c:132 /* Generated by Frama-C */ #include "stdlib.h" struct incomplete; diff --git a/src/plugins/instantiate/tests/stdlib/oracle/malloc.res.oracle b/src/plugins/instantiate/tests/stdlib/oracle/malloc.res.oracle index 485abcec7f4..6cec0abadff 100644 --- a/src/plugins/instantiate/tests/stdlib/oracle/malloc.res.oracle +++ b/src/plugins/instantiate/tests/stdlib/oracle/malloc.res.oracle @@ -217,9 +217,6 @@ int main(void) [kernel] Parsing tests/stdlib/result/malloc.c (with preprocessing) -[kernel] Parsing tests/stdlib/malloc.c (with preprocessing) -[kernel] tests/stdlib/malloc.c:16: Warning: - def'n of func main at tests/stdlib/malloc.c:16 (sum 7290) conflicts with the one at tests/stdlib/result/malloc.c:199 (sum 9064); keeping the one at tests/stdlib/result/malloc.c:199. /* Generated by Frama-C */ #include "stdlib.h" struct X { diff --git a/src/plugins/instantiate/tests/stdlib/test_config b/src/plugins/instantiate/tests/stdlib/test_config index dba5b7b5f4a..cc295b08655 100644 --- a/src/plugins/instantiate/tests/stdlib/test_config +++ b/src/plugins/instantiate/tests/stdlib/test_config @@ -1 +1 @@ -OPT: @PTEST_FILE@ -instantiate -print -check -then -ocode @PTEST_DIR@/result/@PTEST_NAME@.c -print -then -no-instantiate @PTEST_DIR@/result/@PTEST_NAME@.c @PTEST_FILE@ -ocode="" -print \ No newline at end of file +OPT: @PTEST_FILE@ -instantiate -print -check -then -ocode @PTEST_DIR@/result/@PTEST_NAME@.c -print -then -no-instantiate @PTEST_DIR@/result/@PTEST_NAME@.c -ocode="" -print -- GitLab From 47dffa32a5e1f2b748341fb599283752b5352336 Mon Sep 17 00:00:00 2001 From: Allan Blanchard <allan.blanchard@cea.fr> Date: Thu, 26 Mar 2020 15:36:37 +0100 Subject: [PATCH 021/218] [tests] avoid duplication definition warnings in oracles (string) --- .../tests/string/oracle/memcmp.res.oracle | 15 --------- .../tests/string/oracle/memcpy.res.oracle | 15 --------- .../tests/string/oracle/memmove.res.oracle | 15 --------- .../tests/string/oracle/memset_0.res.oracle | 21 ------------- .../tests/string/oracle/memset_FF.res.oracle | 31 ------------------- .../oracle/memset_nested_typedef.res.oracle | 3 -- .../oracle/memset_nested_union.res.oracle | 3 -- .../string/oracle/memset_value.res.oracle | 21 ------------- .../instantiate/tests/string/test_config | 2 +- 9 files changed, 1 insertion(+), 125 deletions(-) diff --git a/src/plugins/instantiate/tests/string/oracle/memcmp.res.oracle b/src/plugins/instantiate/tests/string/oracle/memcmp.res.oracle index 9d73f30f20f..18ada799c0a 100644 --- a/src/plugins/instantiate/tests/string/oracle/memcmp.res.oracle +++ b/src/plugins/instantiate/tests/string/oracle/memcmp.res.oracle @@ -161,21 +161,6 @@ int with_incomplete(struct incomplete *s1, struct incomplete *s2, int n) [kernel] Parsing tests/string/result/memcmp.c (with preprocessing) -[kernel] Parsing tests/string/memcmp.c (with preprocessing) -[kernel] tests/string/memcmp.c:10: Warning: - def'n of func integer at tests/string/memcmp.c:10 (sum 1085) conflicts with the one at tests/string/result/memcmp.c:35 (sum 1972); keeping the one at tests/string/result/memcmp.c:35. -[kernel] tests/string/memcmp.c:14: Warning: - def'n of func with_named at tests/string/memcmp.c:14 (sum 1085) conflicts with the one at tests/string/result/memcmp.c:42 (sum 1972); keeping the one at tests/string/result/memcmp.c:42. -[kernel] tests/string/memcmp.c:18: Warning: - def'n of func structure at tests/string/memcmp.c:18 (sum 1085) conflicts with the one at tests/string/result/memcmp.c:73 (sum 1972); keeping the one at tests/string/result/memcmp.c:73. -[kernel] tests/string/memcmp.c:22: Warning: - def'n of func pointers at tests/string/memcmp.c:22 (sum 1085) conflicts with the one at tests/string/result/memcmp.c:104 (sum 1972); keeping the one at tests/string/result/memcmp.c:104. -[kernel] tests/string/memcmp.c:26: Warning: - def'n of func nested at tests/string/memcmp.c:26 (sum 1087) conflicts with the one at tests/string/result/memcmp.c:138 (sum 1974); keeping the one at tests/string/result/memcmp.c:138. -[kernel] tests/string/memcmp.c:30: Warning: - def'n of func with_void at tests/string/memcmp.c:30 (sum 1087) conflicts with the one at tests/string/result/memcmp.c:145 (sum 1974); keeping the one at tests/string/result/memcmp.c:145. -[kernel] tests/string/memcmp.c:35: Warning: - def'n of func with_incomplete at tests/string/memcmp.c:35 (sum 1087) conflicts with the one at tests/string/result/memcmp.c:152 (sum 1974); keeping the one at tests/string/result/memcmp.c:152. /* Generated by Frama-C */ #include "stddef.h" #include "string.h" diff --git a/src/plugins/instantiate/tests/string/oracle/memcpy.res.oracle b/src/plugins/instantiate/tests/string/oracle/memcpy.res.oracle index a9bc6101a25..05681aeb44e 100644 --- a/src/plugins/instantiate/tests/string/oracle/memcpy.res.oracle +++ b/src/plugins/instantiate/tests/string/oracle/memcpy.res.oracle @@ -175,21 +175,6 @@ void with_incomplete(struct incomplete *src, struct incomplete *dest, int n) [kernel] Parsing tests/string/result/memcpy.c (with preprocessing) -[kernel] Parsing tests/string/memcpy.c (with preprocessing) -[kernel] tests/string/memcpy.c:10: Warning: - dropping duplicate def'n of func integer at tests/string/memcpy.c:10 in favor of that at tests/string/result/memcpy.c:37 -[kernel] tests/string/memcpy.c:15: Warning: - dropping duplicate def'n of func with_named at tests/string/memcpy.c:15 in favor of that at tests/string/result/memcpy.c:44 -[kernel] tests/string/memcpy.c:20: Warning: - dropping duplicate def'n of func structure at tests/string/memcpy.c:20 in favor of that at tests/string/result/memcpy.c:77 -[kernel] tests/string/memcpy.c:25: Warning: - dropping duplicate def'n of func pointers at tests/string/memcpy.c:25 in favor of that at tests/string/result/memcpy.c:110 -[kernel] tests/string/memcpy.c:30: Warning: - dropping duplicate def'n of func nested at tests/string/memcpy.c:30 in favor of that at tests/string/result/memcpy.c:148 -[kernel] tests/string/memcpy.c:35: Warning: - dropping duplicate def'n of func with_void at tests/string/memcpy.c:35 in favor of that at tests/string/result/memcpy.c:156 -[kernel] tests/string/memcpy.c:41: Warning: - dropping duplicate def'n of func with_incomplete at tests/string/memcpy.c:41 in favor of that at tests/string/result/memcpy.c:163 /* Generated by Frama-C */ #include "stddef.h" #include "string.h" diff --git a/src/plugins/instantiate/tests/string/oracle/memmove.res.oracle b/src/plugins/instantiate/tests/string/oracle/memmove.res.oracle index 9d8a290eff8..15c80507c4a 100644 --- a/src/plugins/instantiate/tests/string/oracle/memmove.res.oracle +++ b/src/plugins/instantiate/tests/string/oracle/memmove.res.oracle @@ -159,21 +159,6 @@ void with_incomplete(struct incomplete *src, struct incomplete *dest, int n) [kernel] Parsing tests/string/result/memmove.c (with preprocessing) -[kernel] Parsing tests/string/memmove.c (with preprocessing) -[kernel] tests/string/memmove.c:10: Warning: - dropping duplicate def'n of func integer at tests/string/memmove.c:10 in favor of that at tests/string/result/memmove.c:33 -[kernel] tests/string/memmove.c:15: Warning: - dropping duplicate def'n of func with_named at tests/string/memmove.c:15 in favor of that at tests/string/result/memmove.c:40 -[kernel] tests/string/memmove.c:20: Warning: - dropping duplicate def'n of func structure at tests/string/memmove.c:20 in favor of that at tests/string/result/memmove.c:69 -[kernel] tests/string/memmove.c:25: Warning: - dropping duplicate def'n of func pointers at tests/string/memmove.c:25 in favor of that at tests/string/result/memmove.c:98 -[kernel] tests/string/memmove.c:30: Warning: - dropping duplicate def'n of func nested at tests/string/memmove.c:30 in favor of that at tests/string/result/memmove.c:132 -[kernel] tests/string/memmove.c:35: Warning: - dropping duplicate def'n of func with_void at tests/string/memmove.c:35 in favor of that at tests/string/result/memmove.c:140 -[kernel] tests/string/memmove.c:41: Warning: - dropping duplicate def'n of func with_incomplete at tests/string/memmove.c:41 in favor of that at tests/string/result/memmove.c:147 /* Generated by Frama-C */ #include "stddef.h" #include "string.h" diff --git a/src/plugins/instantiate/tests/string/oracle/memset_0.res.oracle b/src/plugins/instantiate/tests/string/oracle/memset_0.res.oracle index 8936d80df52..1b7efe66ddf 100644 --- a/src/plugins/instantiate/tests/string/oracle/memset_0.res.oracle +++ b/src/plugins/instantiate/tests/string/oracle/memset_0.res.oracle @@ -235,27 +235,6 @@ void with_void(void *dest) [kernel] Parsing tests/string/result/memset_0.c (with preprocessing) -[kernel] Parsing tests/string/memset_0.c (with preprocessing) -[kernel] tests/string/memset_0.c:10: Warning: - dropping duplicate def'n of func chars at tests/string/memset_0.c:10 in favor of that at tests/string/result/memset_0.c:26 -[kernel] tests/string/memset_0.c:15: Warning: - dropping duplicate def'n of func uchars at tests/string/memset_0.c:15 in favor of that at tests/string/result/memset_0.c:50 -[kernel] tests/string/memset_0.c:20: Warning: - dropping duplicate def'n of func nested_chars at tests/string/memset_0.c:20 in favor of that at tests/string/result/memset_0.c:78 -[kernel] tests/string/memset_0.c:25: Warning: - dropping duplicate def'n of func integer at tests/string/memset_0.c:25 in favor of that at tests/string/result/memset_0.c:104 -[kernel] tests/string/memset_0.c:30: Warning: - dropping duplicate def'n of func floats at tests/string/memset_0.c:30 in favor of that at tests/string/result/memset_0.c:130 -[kernel] tests/string/memset_0.c:35: Warning: - dropping duplicate def'n of func with_named at tests/string/memset_0.c:35 in favor of that at tests/string/result/memset_0.c:137 -[kernel] tests/string/memset_0.c:40: Warning: - dropping duplicate def'n of func structure at tests/string/memset_0.c:40 in favor of that at tests/string/result/memset_0.c:164 -[kernel] tests/string/memset_0.c:45: Warning: - dropping duplicate def'n of func pointers at tests/string/memset_0.c:45 in favor of that at tests/string/result/memset_0.c:190 -[kernel] tests/string/memset_0.c:50: Warning: - dropping duplicate def'n of func nested at tests/string/memset_0.c:50 in favor of that at tests/string/result/memset_0.c:218 -[kernel] tests/string/memset_0.c:55: Warning: - dropping duplicate def'n of func with_void at tests/string/memset_0.c:55 in favor of that at tests/string/result/memset_0.c:226 /* Generated by Frama-C */ #include "stddef.h" #include "string.h" diff --git a/src/plugins/instantiate/tests/string/oracle/memset_FF.res.oracle b/src/plugins/instantiate/tests/string/oracle/memset_FF.res.oracle index c64a99baf96..ffe160d7caa 100644 --- a/src/plugins/instantiate/tests/string/oracle/memset_FF.res.oracle +++ b/src/plugins/instantiate/tests/string/oracle/memset_FF.res.oracle @@ -373,37 +373,6 @@ void with_void(void *dest) [kernel] Parsing tests/string/result/memset_FF.c (with preprocessing) -[kernel] Parsing tests/string/memset_FF.c (with preprocessing) -[kernel] tests/string/memset_FF.c:10: Warning: - dropping duplicate def'n of func chars at tests/string/memset_FF.c:10 in favor of that at tests/string/result/memset_FF.c:26 -[kernel] tests/string/memset_FF.c:15: Warning: - dropping duplicate def'n of func uchars at tests/string/memset_FF.c:15 in favor of that at tests/string/result/memset_FF.c:50 -[kernel] tests/string/memset_FF.c:20: Warning: - dropping duplicate def'n of func nested_chars at tests/string/memset_FF.c:20 in favor of that at tests/string/result/memset_FF.c:79 -[kernel] tests/string/memset_FF.c:25: Warning: - dropping duplicate def'n of func integer at tests/string/memset_FF.c:25 in favor of that at tests/string/result/memset_FF.c:105 -[kernel] tests/string/memset_FF.c:30: Warning: - dropping duplicate def'n of func unsigned_integer at tests/string/memset_FF.c:30 in favor of that at tests/string/result/memset_FF.c:131 -[kernel] tests/string/memset_FF.c:35: Warning: - dropping duplicate def'n of func long_integer at tests/string/memset_FF.c:35 in favor of that at tests/string/result/memset_FF.c:158 -[kernel] tests/string/memset_FF.c:40: Warning: - dropping duplicate def'n of func unsigned_long_integer at tests/string/memset_FF.c:40 in favor of that at tests/string/result/memset_FF.c:184 -[kernel] tests/string/memset_FF.c:45: Warning: - dropping duplicate def'n of func long_long_integer at tests/string/memset_FF.c:45 in favor of that at tests/string/result/memset_FF.c:212 -[kernel] tests/string/memset_FF.c:50: Warning: - dropping duplicate def'n of func unsigned_long_long_integer at tests/string/memset_FF.c:50 in favor of that at tests/string/result/memset_FF.c:240 -[kernel] tests/string/memset_FF.c:56: Warning: - dropping duplicate def'n of func floats at tests/string/memset_FF.c:56 in favor of that at tests/string/result/memset_FF.c:267 -[kernel] tests/string/memset_FF.c:61: Warning: - dropping duplicate def'n of func with_named at tests/string/memset_FF.c:61 in favor of that at tests/string/result/memset_FF.c:274 -[kernel] tests/string/memset_FF.c:66: Warning: - dropping duplicate def'n of func structure at tests/string/memset_FF.c:66 in favor of that at tests/string/result/memset_FF.c:302 -[kernel] tests/string/memset_FF.c:71: Warning: - dropping duplicate def'n of func pointers at tests/string/memset_FF.c:71 in favor of that at tests/string/result/memset_FF.c:328 -[kernel] tests/string/memset_FF.c:76: Warning: - dropping duplicate def'n of func nested at tests/string/memset_FF.c:76 in favor of that at tests/string/result/memset_FF.c:356 -[kernel] tests/string/memset_FF.c:81: Warning: - dropping duplicate def'n of func with_void at tests/string/memset_FF.c:81 in favor of that at tests/string/result/memset_FF.c:364 /* Generated by Frama-C */ #include "stddef.h" #include "string.h" diff --git a/src/plugins/instantiate/tests/string/oracle/memset_nested_typedef.res.oracle b/src/plugins/instantiate/tests/string/oracle/memset_nested_typedef.res.oracle index 27287ebadeb..c99bbab555a 100644 --- a/src/plugins/instantiate/tests/string/oracle/memset_nested_typedef.res.oracle +++ b/src/plugins/instantiate/tests/string/oracle/memset_nested_typedef.res.oracle @@ -35,9 +35,6 @@ void test(void) [kernel] Parsing tests/string/result/memset_nested_typedef.c (with preprocessing) -[kernel] Parsing tests/string/memset_nested_typedef.c (with preprocessing) -[kernel] tests/string/memset_nested_typedef.c:6: Warning: - dropping duplicate def'n of func test at tests/string/memset_nested_typedef.c:6 in favor of that at tests/string/result/memset_nested_typedef.c:28 /* Generated by Frama-C */ #include "stddef.h" #include "string.h" diff --git a/src/plugins/instantiate/tests/string/oracle/memset_nested_union.res.oracle b/src/plugins/instantiate/tests/string/oracle/memset_nested_union.res.oracle index 99b6125cfd4..f71268da3aa 100644 --- a/src/plugins/instantiate/tests/string/oracle/memset_nested_union.res.oracle +++ b/src/plugins/instantiate/tests/string/oracle/memset_nested_union.res.oracle @@ -21,9 +21,6 @@ void test(void) [kernel] Parsing tests/string/result/memset_nested_union.c (with preprocessing) -[kernel] Parsing tests/string/memset_nested_union.c (with preprocessing) -[kernel] tests/string/memset_nested_union.c:8: Warning: - dropping duplicate def'n of func test at tests/string/memset_nested_union.c:8 in favor of that at tests/string/result/memset_nested_union.c:12 /* Generated by Frama-C */ #include "stddef.h" #include "string.h" diff --git a/src/plugins/instantiate/tests/string/oracle/memset_value.res.oracle b/src/plugins/instantiate/tests/string/oracle/memset_value.res.oracle index e0a760dc1f0..462fc372857 100644 --- a/src/plugins/instantiate/tests/string/oracle/memset_value.res.oracle +++ b/src/plugins/instantiate/tests/string/oracle/memset_value.res.oracle @@ -165,27 +165,6 @@ void with_incomplete(struct incomplete *dest, int value) [kernel] Parsing tests/string/result/memset_value.c (with preprocessing) -[kernel] Parsing tests/string/memset_value.c (with preprocessing) -[kernel] tests/string/memset_value.c:10: Warning: - dropping duplicate def'n of func chars at tests/string/memset_value.c:10 in favor of that at tests/string/result/memset_value.c:27 -[kernel] tests/string/memset_value.c:15: Warning: - dropping duplicate def'n of func uchars at tests/string/memset_value.c:15 in favor of that at tests/string/result/memset_value.c:51 -[kernel] tests/string/memset_value.c:20: Warning: - dropping duplicate def'n of func nested_chars at tests/string/memset_value.c:20 in favor of that at tests/string/result/memset_value.c:79 -[kernel] tests/string/memset_value.c:25: Warning: - dropping duplicate def'n of func integer at tests/string/memset_value.c:25 in favor of that at tests/string/result/memset_value.c:86 -[kernel] tests/string/memset_value.c:30: Warning: - dropping duplicate def'n of func with_named at tests/string/memset_value.c:30 in favor of that at tests/string/result/memset_value.c:93 -[kernel] tests/string/memset_value.c:35: Warning: - dropping duplicate def'n of func structure at tests/string/memset_value.c:35 in favor of that at tests/string/result/memset_value.c:100 -[kernel] tests/string/memset_value.c:40: Warning: - dropping duplicate def'n of func pointers at tests/string/memset_value.c:40 in favor of that at tests/string/result/memset_value.c:108 -[kernel] tests/string/memset_value.c:45: Warning: - dropping duplicate def'n of func nested at tests/string/memset_value.c:45 in favor of that at tests/string/result/memset_value.c:115 -[kernel] tests/string/memset_value.c:50: Warning: - dropping duplicate def'n of func with_void at tests/string/memset_value.c:50 in favor of that at tests/string/result/memset_value.c:123 -[kernel] tests/string/memset_value.c:55: Warning: - dropping duplicate def'n of func with_incomplete at tests/string/memset_value.c:55 in favor of that at tests/string/result/memset_value.c:130 /* Generated by Frama-C */ #include "stddef.h" #include "string.h" diff --git a/src/plugins/instantiate/tests/string/test_config b/src/plugins/instantiate/tests/string/test_config index dba5b7b5f4a..0bfb9575133 100644 --- a/src/plugins/instantiate/tests/string/test_config +++ b/src/plugins/instantiate/tests/string/test_config @@ -1 +1 @@ -OPT: @PTEST_FILE@ -instantiate -print -check -then -ocode @PTEST_DIR@/result/@PTEST_NAME@.c -print -then -no-instantiate @PTEST_DIR@/result/@PTEST_NAME@.c @PTEST_FILE@ -ocode="" -print \ No newline at end of file +OPT: @PTEST_FILE@ -instantiate -print -check -then -ocode @PTEST_DIR@/result/@PTEST_NAME@.c -print -then -no-instantiate @PTEST_DIR@/result/@PTEST_NAME@.c -ocode="" -print \ No newline at end of file -- GitLab From 4ff612557bed4293bbe3d703296cfd851117e59d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20B=C3=BChler?= <david.buhler@cea.fr> Date: Wed, 25 Mar 2020 13:28:09 +0100 Subject: [PATCH 022/218] [slicing] Fixes a test that returned a function g instead of an integer G. --- tests/slicing/oracle/slice_no_body.res.oracle | 10 ++-------- tests/slicing/slice_no_body.i | 2 +- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/tests/slicing/oracle/slice_no_body.res.oracle b/tests/slicing/oracle/slice_no_body.res.oracle index 2960de9c498..dcba3c11fcc 100644 --- a/tests/slicing/oracle/slice_no_body.res.oracle +++ b/tests/slicing/oracle/slice_no_body.res.oracle @@ -102,7 +102,6 @@ Print slice = h_slice_1: /**/int h(void) { - /* <[---], [---]> */ int __retres; /* invisible call */ /* <[---], [---]> */ /* <[---], [---]> */ int a = f(1); /* invisible call */ /* <[---], [---]> */ @@ -117,9 +116,7 @@ Print slice = h_slice_1: G = g(c); } /* <[---], [---]> */ - __retres = (int)(& g); - /* <[---], [---]> */ - return __retres; + return G; } Slicing project worklist [default] = @@ -223,7 +220,6 @@ Print slice = h_slice_1: (InCtrl: <[---], [ S ]>) /**/int h(void) { - /* <[---], [---]> */ int __retres; /* sig call: (InCtrl: <[---], [ S ]>) (In1: <[---], [ S ]>) @@ -262,9 +258,7 @@ Print slice = h_slice_1: (InCtrl: <[---], [ S ]>) G = g(c); } /* <[---], [---]> */ - __retres = (int)(& g); - /* <[---], [---]> */ - return __retres; + return G; } Slicing project worklist [default] = diff --git a/tests/slicing/slice_no_body.i b/tests/slicing/slice_no_body.i index 8e97f4c920a..e2be30cc3c6 100644 --- a/tests/slicing/slice_no_body.i +++ b/tests/slicing/slice_no_body.i @@ -24,5 +24,5 @@ int h (void) { G = f (4); if (G > 0) G = g (c); - return (int)g; + return G; } -- GitLab From 4c30ce449a80bc38c1b26a83c93a8449fcaf7d57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20B=C3=BChler?= <david.buhler@cea.fr> Date: Wed, 25 Mar 2020 15:03:18 +0100 Subject: [PATCH 023/218] [Kernel] Adds the new option -warn-pointer-downcast. --- src/kernel_services/plugin_entry_points/kernel.ml | 11 +++++++++++ src/kernel_services/plugin_entry_points/kernel.mli | 3 +++ 2 files changed, 14 insertions(+) diff --git a/src/kernel_services/plugin_entry_points/kernel.ml b/src/kernel_services/plugin_entry_points/kernel.ml index 4dca12b991c..a7ffdfeb730 100644 --- a/src/kernel_services/plugin_entry_points/kernel.ml +++ b/src/kernel_services/plugin_entry_points/kernel.ml @@ -1440,6 +1440,17 @@ module UnsignedDowncast = destination range" end) +(* Pointer downcasts are undefined behaviors. *) +let () = Parameter_customize.set_group analysis_options +let () = Parameter_customize.do_not_reset_on_copy () +module PointerDowncast = + True + (struct + let module_name = "PointerDowncast" + let option_name = "-warn-pointer-downcast" + let help = "generate alarms when a pointer is converted into an integer \ + but may not be in the range of the destination type." + end) (* Not finite floats are ok, but might not always be a behavior the programmer wants. *) diff --git a/src/kernel_services/plugin_entry_points/kernel.mli b/src/kernel_services/plugin_entry_points/kernel.mli index 87ffd853c1c..04ef6317f0c 100644 --- a/src/kernel_services/plugin_entry_points/kernel.mli +++ b/src/kernel_services/plugin_entry_points/kernel.mli @@ -540,6 +540,9 @@ module SignedDowncast: Parameter_sig.Bool module UnsignedDowncast: Parameter_sig.Bool (** Behavior of option "-warn-unsigned-downcast" *) +module PointerDowncast: Parameter_sig.Bool +(** Behavior of option "-warn-pointer-downcast" *) + module SpecialFloat: Parameter_sig.String (** Behavior of option "-warn-special-float" *) -- GitLab From c2be7fad142bff70f670263d34c9d2f326697b5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20B=C3=BChler?= <david.buhler@cea.fr> Date: Thu, 26 Mar 2020 12:01:35 +0100 Subject: [PATCH 024/218] [Kernel] Alarms: new overflow_kind for pointer downcasts. --- src/kernel_services/ast_data/alarms.ml | 8 +++++++- src/kernel_services/ast_data/alarms.mli | 7 ++++--- src/plugins/value/alarmset.ml | 1 + 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/kernel_services/ast_data/alarms.ml b/src/kernel_services/ast_data/alarms.ml index ae9503e76ad..445efc3204d 100644 --- a/src/kernel_services/ast_data/alarms.ml +++ b/src/kernel_services/ast_data/alarms.ml @@ -23,7 +23,8 @@ open Cil_types open Cil_datatype -type overflow_kind = Signed | Unsigned | Signed_downcast | Unsigned_downcast +type overflow_kind = + Signed | Unsigned | Signed_downcast | Unsigned_downcast | Pointer_downcast type access_kind = For_reading | For_writing type bound_kind = Lower_bound | Upper_bound @@ -32,6 +33,7 @@ let string_of_overflow_kind = function | Unsigned -> "unsigned_overflow" | Signed_downcast -> "signed_downcast" | Unsigned_downcast -> "unsigned_downcast" + | Pointer_downcast -> "pointer_downcast" type alarm = | Division_by_zero of exp @@ -549,6 +551,10 @@ let create_predicate ?(loc=Location.unknown) alarm = (* n <= e or e <= n according to bound *) let loc = best_loc ~loc e.eloc in let t = match kind with + | Pointer_downcast -> + let t = Logic_utils.expr_to_term ~cast:true e in + let typ = Cil.theMachine.upointType in + Logic_const.tlogic_coerce ~loc t (Ctype typ) | Signed_downcast | Unsigned_downcast -> Logic_utils.expr_to_term ~cast:true e | _ -> diff --git a/src/kernel_services/ast_data/alarms.mli b/src/kernel_services/ast_data/alarms.mli index c301b2e797c..a369dc60f2b 100644 --- a/src/kernel_services/ast_data/alarms.mli +++ b/src/kernel_services/ast_data/alarms.mli @@ -25,9 +25,10 @@ open Cil_types -(** Only signed overflows int are really RTEs. The other kinds may be - meaningful nevertheless. *) -type overflow_kind = Signed | Unsigned | Signed_downcast | Unsigned_downcast +(** Only signed overflows and pointer downcasts are really RTEs. + The other kinds may be meaningful nevertheless. *) +type overflow_kind = + Signed | Unsigned | Signed_downcast | Unsigned_downcast | Pointer_downcast type access_kind = For_reading | For_writing type bound_kind = Lower_bound | Upper_bound diff --git a/src/plugins/value/alarmset.ml b/src/plugins/value/alarmset.ml index fa27012f076..1738ac4a35a 100644 --- a/src/plugins/value/alarmset.ml +++ b/src/plugins/value/alarmset.ml @@ -309,6 +309,7 @@ let emit_alarm kinstr alarm (status:status) = | Alarms.Unsigned -> "unsigned overflow" | Alarms.Signed_downcast -> "signed downcast" | Alarms.Unsigned_downcast -> "unsigned downcast" + | Alarms.Pointer_downcast -> "pointer downcast" in register_alarm str -- GitLab From ea6292535e5478a0a2c6be93eba985b99d1ed868 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20B=C3=BChler?= <david.buhler@cea.fr> Date: Fri, 10 Jan 2020 14:51:11 +0100 Subject: [PATCH 025/218] [Eva] Emits pointer downcasts alarms according to option -warn-pointer-downcast. --- src/plugins/value/engine/evaluation.ml | 31 +++++++++++++++----------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/src/plugins/value/engine/evaluation.ml b/src/plugins/value/engine/evaluation.ml index 43eb4404fe6..ab391eb3546 100644 --- a/src/plugins/value/engine/evaluation.ml +++ b/src/plugins/value/engine/evaluation.ml @@ -665,7 +665,7 @@ module Make in cast_integer Alarms.Signed_downcast expr ~src ~dst value - let cast_int_to_int expr ~src ~dst value = + let cast_int_to_int expr ~ptr ~src ~dst value = (* Regain some precision in case a transfer function was imprecise. This should probably be done in the transfer function, though. *) let value = @@ -675,16 +675,19 @@ module Make in if Eval_typ.range_inclusion src dst then return value (* Upcast, nothing to check. *) - else if dst.i_signed then (* Signed downcast. *) - if Kernel.SignedDowncast.get () - then cast_integer Alarms.Signed_downcast expr ~src ~dst value - else if Value_parameters.WarnSignedConvertedDowncast.get () + else + let overflow_kind, warn = + if ptr + then Alarms.Pointer_downcast, Kernel.PointerDowncast.get + else if dst.i_signed + then Alarms.Signed_downcast, Kernel.SignedDowncast.get + else Alarms.Unsigned_downcast, Kernel.UnsignedDowncast.get + in + if warn () + then cast_integer overflow_kind expr ~src ~dst value + else if dst.i_signed && Value_parameters.WarnSignedConvertedDowncast.get () then relaxed_signed_downcast expr ~src ~dst value else return (Value.rewrap_integer dst value) - else (* Unsigned downcast. *) - if Kernel.UnsignedDowncast.get () - then cast_integer Alarms.Unsigned_downcast expr ~src ~dst value - else return (Value.rewrap_integer dst value) (* Re-export type here *) type scalar_typ = Eval_typ.scalar_typ = @@ -728,15 +731,17 @@ module Make | Some src_type, Some dst_type -> let value, alarms = match src_type, dst_type with - | (TSInt src | TSPtr src), (TSInt dst | TSPtr dst) -> - cast_int_to_int ~src ~dst expr value + | TSPtr src, TSInt dst -> + cast_int_to_int ~ptr:true ~src ~dst expr value + | TSInt src, (TSInt dst | TSPtr dst) -> + cast_int_to_int ~ptr:false ~src ~dst expr value | TSFloat src, (TSInt dst | TSPtr dst) -> restrict_float ~reduce:true ~assume_finite:true expr src value >>= truncate_float src dst expr | (TSInt _ | TSPtr _), TSFloat _ -> (* Cannot overflow with 32 bits float. *) - `Value value, Alarmset.none - | TSFloat _, TSFloat _ -> `Value value, Alarmset.none + return value + | TSFloat _, TSFloat _ | TSPtr _, TSPtr _ -> return value in value >>- Value.forward_cast ~src_type ~dst_type, alarms -- GitLab From 4cd404818041f8d0828539ce28afe2616b10fcb2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20B=C3=BChler?= <david.buhler@cea.fr> Date: Tue, 3 Mar 2020 14:20:38 +0100 Subject: [PATCH 026/218] [Eva] Updates test oracles with pointer downcast alarms emitted by default. --- .../oracle/printf_garbled_mix.res.oracle | 3 + .../oracle/Longinit_sequencer.res.oracle | 49 ++++++------- tests/builtins/oracle/alloc.0.res.oracle | 2 + tests/builtins/oracle/alloc.1.res.oracle | 4 ++ tests/builtins/oracle/alloc_weak.res.oracle | 4 ++ .../oracle/imprecise-malloc-free.res.oracle | 16 +++++ tests/builtins/oracle/imprecise.res.oracle | 27 ++++--- tests/builtins/oracle/memchr.res.oracle | 2 + tests/builtins/oracle/memcpy.res.oracle | 23 +++++- tests/builtins/oracle/memset.res.oracle | 4 ++ tests/builtins/oracle/strchr.res.oracle | 6 ++ tests/builtins/oracle/strlen.res.oracle | 2 + tests/builtins/oracle/strnlen2.res.oracle | 2 + tests/builtins/oracle/wcslen.res.oracle | 9 +++ tests/float/oracle/builtins.res.oracle | 2 + tests/float/oracle/nonlin.0.res.oracle | 4 ++ tests/float/oracle/nonlin.1.res.oracle | 4 ++ tests/float/oracle/nonlin.2.res.oracle | 4 ++ tests/float/oracle/nonlin.3.res.oracle | 4 ++ tests/float/oracle/nonlin.4.res.oracle | 4 ++ tests/float/oracle/nonlin.5.res.oracle | 4 ++ .../syntax/oracle/ghost_else_bad.1.err.oracle | 1 - tests/value/oracle/addition.res.oracle | 70 ++++++++++++++++++- .../value/oracle/align_char_array.res.oracle | 18 ++++- tests/value/oracle/arith_pointer.res.oracle | 4 ++ tests/value/oracle/array_ptr.res.oracle | 2 + tests/value/oracle/assigns.res.oracle | 6 ++ tests/value/oracle/bitfield.res.oracle | 10 +++ tests/value/oracle/bitwise_pointer.res.oracle | 4 ++ tests/value/oracle/call.res.oracle | 2 + tests/value/oracle/cmp_ptr.0.res.oracle | 6 ++ tests/value/oracle/cmp_ptr.1.res.oracle | 6 ++ tests/value/oracle/context_free.res.oracle | 6 +- tests/value/oracle/conversion.res.oracle | 4 ++ tests/value/oracle/degeneration2.res.oracle | 2 + tests/value/oracle/deps_addr.res.oracle | 2 + tests/value/oracle/deps_mixed.res.oracle | 6 ++ tests/value/oracle/div.0.res.oracle | 12 +++- tests/value/oracle/div.1.res.oracle | 12 +++- tests/value/oracle/downcast.res.oracle | 70 +++++++++++-------- tests/value/oracle/eval_separated.res.oracle | 4 ++ tests/value/oracle/from_call.0.res.oracle | 4 ++ tests/value/oracle/from_call.1.res.oracle | 4 ++ tests/value/oracle/from_ptr.0.res.oracle | 4 ++ tests/value/oracle/from_ptr.1.res.oracle | 4 ++ tests/value/oracle/fun_ptr.1.res.oracle | 4 ++ tests/value/oracle/gauges.res.oracle | 4 ++ .../oracle/imprecise_invalid_write.res.oracle | 4 ++ tests/value/oracle/initialized.res.oracle | 2 + tests/value/oracle/join_misaligned.res.oracle | 4 ++ tests/value/oracle/label.res.oracle | 2 + tests/value/oracle/leaf2.res.oracle | 2 + tests/value/oracle/mini_pointrer.res.oracle | 2 + tests/value/oracle/nonlin.res.oracle | 2 + .../value/oracle/not_ct_array_arg.res.oracle | 2 + tests/value/oracle/offset_top.res.oracle | 2 + tests/value/oracle/offsetmap.0.res.oracle | 2 + tests/value/oracle/offsetmap.1.res.oracle | 2 + tests/value/oracle/origin.0.res.oracle | 23 ++++++ tests/value/oracle/origin.1.res.oracle | 2 + tests/value/oracle/period.res.oracle | 7 ++ .../oracle/pointer_comparison.0.res.oracle | 49 +++++++++++-- .../oracle/pointer_comparison.1.res.oracle | 49 +++++++++++-- .../value/oracle/pointer_int_cast.res.oracle | 2 + tests/value/oracle/shift.0.res.oracle | 2 + tests/value/oracle/shift.1.res.oracle | 2 + tests/value/oracle/sizeof.res.oracle | 3 + tests/value/oracle/struct3.res.oracle | 4 ++ tests/value/oracle/struct_array.res.oracle | 12 ++++ tests/value/oracle/struct_incl.res.oracle | 6 ++ tests/value/oracle/symbolic_locs.res.oracle | 2 + tests/value/oracle/test_arith.res.oracle | 2 + tests/value/oracle/val6.0.res.oracle | 2 + tests/value/oracle/volatile.res.oracle | 2 + tests/value/oracle/volatilestruct.res.oracle | 4 ++ 75 files changed, 561 insertions(+), 88 deletions(-) delete mode 100644 tests/syntax/oracle/ghost_else_bad.1.err.oracle diff --git a/src/plugins/variadic/tests/known/oracle/printf_garbled_mix.res.oracle b/src/plugins/variadic/tests/known/oracle/printf_garbled_mix.res.oracle index ec9df06d3ed..545c7824113 100644 --- a/src/plugins/variadic/tests/known/oracle/printf_garbled_mix.res.oracle +++ b/src/plugins/variadic/tests/known/oracle/printf_garbled_mix.res.oracle @@ -25,6 +25,8 @@ Assigning imprecise value to b. The imprecision originates from Arithmetic {tests/known/printf_garbled_mix.c:6} +[eva:alarm] tests/known/printf_garbled_mix.c:7: Warning: + pointer downcast. assert (unsigned int)b ≤ 2147483647; [eva] using specification for function printf_va_1 [eva] tests/known/printf_garbled_mix.c:8: Frama_C_show_each_nb_printed: [-2147483648..2147483647] @@ -67,6 +69,7 @@ void main(void) { int a[2] = {1, 2}; int *b = (int *)((unsigned int)(a) * (unsigned int)2); + /*@ assert Eva: pointer_downcast: (unsigned int)b ≤ 2147483647; */ int nb_printed = printf_va_1("%d",(int)b); Frama_C_show_each_nb_printed(nb_printed); b = (int *)0; diff --git a/tests/builtins/oracle/Longinit_sequencer.res.oracle b/tests/builtins/oracle/Longinit_sequencer.res.oracle index 2a0c3fd82a9..7593544dbd9 100644 --- a/tests/builtins/oracle/Longinit_sequencer.res.oracle +++ b/tests/builtins/oracle/Longinit_sequencer.res.oracle @@ -2,17 +2,14 @@ [kernel] Parsing tests/builtins/long_init.c (with preprocessing) [eva] Analyzing a complete application starting at main [eva] Computing initial state -[eva] tests/builtins/long_init.c:34: - Assigning imprecise value to garbled_mix. - The imprecision originates from Arithmetic {tests/builtins/long_init.c:34} +[eva:alarm] tests/builtins/long_init.c:34: Warning: + pointer downcast. assert (unsigned int)"abc" ≤ 127; [eva] Initial state computed [eva:initial-state] Values of globals at initialization nondet ∈ [--..--] a1[0..9] ∈ {0} stuff ∈ {0} - garbled_mix ∈ - {{ garbled mix of &{"abc"} - (origin: Arithmetic {tests/builtins/long_init.c:34}) }} + garbled_mix ∈ {{ "abc" }} s ∈ {{ "abc" }} pr ∈ {0} pr2 ∈ {0} @@ -73,6 +70,8 @@ [eva] tests/builtins/long_init.c:73: Call to builtin Frama_C_malloc_fresh for function malloc [eva] tests/builtins/long_init.c:73: allocating variable __malloc_init_inner_l73 +[eva:alarm] tests/builtins/long_init.c:74: Warning: + pointer downcast. assert (unsigned int)alloc1 ≤ 2147483647; [eva] tests/builtins/long_init.c:75: Call to builtin Frama_C_malloc_fresh for function malloc [eva] tests/builtins/long_init.c:75: allocating variable __malloc_init_inner_l75 @@ -130,9 +129,7 @@ .d[7] ∈ {21.875} .d[8] ∈ {25.} .d[9] ∈ {28.125} - garbled_mix ∈ - {{ garbled mix of &{"abc"} - (origin: Arithmetic {tests/builtins/long_init.c:34}) }} + garbled_mix ∈ {{ "abc" }} s ∈ {{ "abc" }} pr ∈ ESCAPINGADDR pr2 ∈ ESCAPINGADDR @@ -170,6 +167,8 @@ [eva] tests/builtins/long_init.c:104: allocating variable __malloc_main_l104 [eva] Recording results for main [eva] done for function main +[eva] tests/builtins/long_init.c:34: + cannot evaluate ACSL term, unsupported ACSL construct: constant strings [eva] Saving globals state after call to function: init_inner Values at end of function dmin: __retres ∈ [93.9166666667 .. 110.791666667] @@ -297,17 +296,14 @@ Values at end of function main: __retres ∈ {0}[kernel] Parsing tests/builtins/long_init2.c (with preprocessing) [eva] Analyzing a complete application starting at main [eva] Computing initial state -[eva] tests/builtins/long_init2.c:34: - Assigning imprecise value to garbled_mix. - The imprecision originates from Arithmetic {tests/builtins/long_init2.c:34} +[eva:alarm] tests/builtins/long_init2.c:34: Warning: + pointer downcast. assert (unsigned int)"abc" ≤ 127; [eva] Initial state computed [eva:initial-state] Values of globals at initialization nondet ∈ [--..--] a1[0..9] ∈ {0} stuff ∈ {0} - garbled_mix ∈ - {{ garbled mix of &{"abc"} - (origin: Arithmetic {tests/builtins/long_init2.c:34}) }} + garbled_mix ∈ {{ "abc" }} s ∈ {{ "abc" }} another_global ∈ {42} pr ∈ {0} @@ -325,7 +321,6 @@ Values at end of function main: Call to builtin Frama_C_load_state for function init_inner [eva] Skipping call to init_inner, loading globals state from file: tests/builtins/result/Longinit_sequencer.sav -[eva] Warning: importing garbled mix, locations may have changed [eva] Warning: variable `r' is not global, possibly an escaping value; ignoring [eva] Warning: variable `r2' is not global, possibly an escaping value; ignoring [eva] Warning: variable `r2' is not global, possibly an escaping value; ignoring @@ -371,9 +366,7 @@ Values at end of function main: .d[7] ∈ {21.875} .d[8] ∈ {25.} .d[9] ∈ {28.125} - garbled_mix ∈ - {{ garbled mix of &{"abc"} - (origin: Arithmetic {tests/builtins/long_init.c:34}) }} + garbled_mix ∈ {{ "abc" }} s ∈ {{ "abc" }} another_global ∈ {42} pr ∈ ESCAPINGADDR @@ -446,6 +439,8 @@ Values at end of function main: [eva] tests/builtins/long_init2.c:104: allocating variable __malloc_main_l104 [eva] Recording results for main [eva] done for function main +[eva] tests/builtins/long_init2.c:34: + cannot evaluate ACSL term, unsupported ACSL construct: constant strings [eva] Saving globals state after call to function: init_outer @@ -539,17 +534,14 @@ Values at end of function main: __retres ∈ {0}[kernel] Parsing tests/builtins/long_init3.c (with preprocessing) [eva] Analyzing a complete application starting at main [eva] Computing initial state -[eva] tests/builtins/long_init3.c:34: - Assigning imprecise value to garbled_mix. - The imprecision originates from Arithmetic {tests/builtins/long_init3.c:34} +[eva:alarm] tests/builtins/long_init3.c:34: Warning: + pointer downcast. assert (unsigned int)"abc" ≤ 127; [eva] Initial state computed [eva:initial-state] Values of globals at initialization nondet ∈ [--..--] a1[0..9] ∈ {0} stuff ∈ {0} - garbled_mix ∈ - {{ garbled mix of &{"abc"} - (origin: Arithmetic {tests/builtins/long_init3.c:34}) }} + garbled_mix ∈ {{ "abc" }} s ∈ {{ "abc" }} another_global ∈ {42} yet_another_global ∈ {43} @@ -566,7 +558,6 @@ Values at end of function main: Call to builtin Frama_C_load_state for function init_outer [eva] Skipping call to init_outer, loading globals state from file: tests/builtins/result/Longinit_sequencer.sav -[eva] Warning: importing garbled mix, locations may have changed [eva] Warning: found new global variable `yet_another_global' [eva] tests/builtins/long_init3.c:92: Frama_C_dump_each: @@ -607,9 +598,7 @@ Values at end of function main: .d[7] ∈ {21.875} .d[8] ∈ {25.} .d[9] ∈ {28.125} - garbled_mix ∈ - {{ garbled mix of &{"abc"} - (origin: Arithmetic {tests/builtins/long_init.c:34}) }} + garbled_mix ∈ {{ "abc" }} s ∈ {{ "abc" }} another_global ∈ {42} yet_another_global ∈ {43} @@ -683,6 +672,8 @@ Values at end of function main: [eva] tests/builtins/long_init3.c:104: allocating variable __malloc_main_l104 [eva] Recording results for main [eva] done for function main +[eva] tests/builtins/long_init3.c:34: + cannot evaluate ACSL term, unsupported ACSL construct: constant strings Values at end of function dmin: diff --git a/tests/builtins/oracle/alloc.0.res.oracle b/tests/builtins/oracle/alloc.0.res.oracle index 257776baaff..b124e2220d1 100644 --- a/tests/builtins/oracle/alloc.0.res.oracle +++ b/tests/builtins/oracle/alloc.0.res.oracle @@ -34,6 +34,8 @@ all target addresses were invalid. This path is assumed to be dead. [eva] tests/builtins/alloc.c:25: Call to builtin Frama_C_malloc_fresh [eva] tests/builtins/alloc.c:25: allocating variable __malloc_main_l25 +[eva:alarm] tests/builtins/alloc.c:26: Warning: + pointer downcast. assert (unsigned int)q ≤ 2147483647; [eva:alarm] tests/builtins/alloc.c:26: Warning: signed overflow. assert -2147483648 ≤ -((int)q); [eva:alarm] tests/builtins/alloc.c:26: Warning: diff --git a/tests/builtins/oracle/alloc.1.res.oracle b/tests/builtins/oracle/alloc.1.res.oracle index b4990cc4a79..48c4356d116 100644 --- a/tests/builtins/oracle/alloc.1.res.oracle +++ b/tests/builtins/oracle/alloc.1.res.oracle @@ -15,6 +15,8 @@ ch ∈ {44} [eva] tests/builtins/alloc.c:50: Call to builtin Frama_C_malloc_fresh [eva] tests/builtins/alloc.c:50: allocating variable __malloc_main_abs_l50 +[eva:alarm] tests/builtins/alloc.c:51: Warning: + pointer downcast. assert (unsigned int)q ≤ 2147483647; [eva:alarm] tests/builtins/alloc.c:51: Warning: signed overflow. assert -2147483648 ≤ -((int)q); [eva:alarm] tests/builtins/alloc.c:51: Warning: @@ -24,6 +26,8 @@ The imprecision originates from Arithmetic {tests/builtins/alloc.c:51} [eva:alarm] tests/builtins/alloc.c:54: Warning: out of bounds write. assert \valid(r); +[eva:alarm] tests/builtins/alloc.c:54: Warning: + pointer downcast. assert (unsigned int)r ≤ 2147483647; [eva:alarm] tests/builtins/alloc.c:56: Warning: signed overflow. assert -2147483648 ≤ *q + 1; [eva:alarm] tests/builtins/alloc.c:56: Warning: diff --git a/tests/builtins/oracle/alloc_weak.res.oracle b/tests/builtins/oracle/alloc_weak.res.oracle index 5a584e37268..7705984008d 100644 --- a/tests/builtins/oracle/alloc_weak.res.oracle +++ b/tests/builtins/oracle/alloc_weak.res.oracle @@ -41,6 +41,10 @@ Called from tests/builtins/alloc_weak.c:73. [eva] tests/builtins/alloc_weak.c:37: Call to builtin malloc [eva] tests/builtins/alloc_weak.c:37: allocating variable __malloc_main2_l37 +[eva:alarm] tests/builtins/alloc_weak.c:37: Warning: + pointer downcast. + assert (unsigned int)tmp ≤ 2147483647; + (tmp from malloc(sizeof(int))) [eva] tests/builtins/alloc_weak.c:40: Trace partitioning superposing up to 100 states [eva] tests/builtins/alloc_weak.c:40: diff --git a/tests/builtins/oracle/imprecise-malloc-free.res.oracle b/tests/builtins/oracle/imprecise-malloc-free.res.oracle index 82e150fd294..c748e18da98 100644 --- a/tests/builtins/oracle/imprecise-malloc-free.res.oracle +++ b/tests/builtins/oracle/imprecise-malloc-free.res.oracle @@ -4,6 +4,10 @@ [eva] Initial state computed [eva:initial-state] Values of globals at initialization i ∈ [--..--] +[eva:alarm] tests/builtins/imprecise-malloc-free.c:12: Warning: + pointer downcast. assert (unsigned int)&size1 + i ≤ 2147483647; +[eva:alarm] tests/builtins/imprecise-malloc-free.c:13: Warning: + pointer downcast. assert (unsigned int)&size2 ≤ 2147483647; [eva:alarm] tests/builtins/imprecise-malloc-free.c:13: Warning: signed overflow. assert -2147483648 ≤ i + (int)((int)(&size2) >> 1); [eva:alarm] tests/builtins/imprecise-malloc-free.c:13: Warning: @@ -12,6 +16,8 @@ Assigning imprecise value to size2. The imprecision originates from Arithmetic {tests/builtins/imprecise-malloc-free.c:13} +[eva:alarm] tests/builtins/imprecise-malloc-free.c:14: Warning: + pointer downcast. assert (unsigned int)&i ≤ 2147483647; [eva] tests/builtins/imprecise-malloc-free.c:14: Call to builtin malloc [eva] tests/builtins/imprecise-malloc-free.c:14: allocating variable __malloc_main_l14 @@ -30,15 +36,25 @@ (origin: Arithmetic {tests/builtins/imprecise-malloc-free.c:19}) }} [eva:alarm] tests/builtins/imprecise-malloc-free.c:21: Warning: out of bounds write. assert \valid(p); +[eva:alarm] tests/builtins/imprecise-malloc-free.c:21: Warning: + pointer downcast. assert (unsigned int)p + 1 ≤ 2147483647; [eva:alarm] tests/builtins/imprecise-malloc-free.c:22: Warning: out of bounds write. assert \valid(q); +[eva:alarm] tests/builtins/imprecise-malloc-free.c:22: Warning: + pointer downcast. assert (unsigned int)q + 2 ≤ 2147483647; [eva:alarm] tests/builtins/imprecise-malloc-free.c:23: Warning: out of bounds write. assert \valid(r); +[eva:alarm] tests/builtins/imprecise-malloc-free.c:23: Warning: + pointer downcast. assert (unsigned int)r + 3 ≤ 2147483647; +[eva:alarm] tests/builtins/imprecise-malloc-free.c:25: Warning: + pointer downcast. assert (unsigned int)p ≤ 2147483647; [eva] tests/builtins/imprecise-malloc-free.c:25: Call to builtin free [eva:alarm] tests/builtins/imprecise-malloc-free.c:25: Warning: function free: precondition 'freeable' got status unknown. [eva:malloc] tests/builtins/imprecise-malloc-free.c:25: weak free on bases: {__malloc_main_l14} +[eva:alarm] tests/builtins/imprecise-malloc-free.c:26: Warning: + pointer downcast. assert (unsigned int)r ≤ 2147483647; [eva] tests/builtins/imprecise-malloc-free.c:26: Call to builtin free [eva:alarm] tests/builtins/imprecise-malloc-free.c:26: Warning: function free: precondition 'freeable' got status unknown. diff --git a/tests/builtins/oracle/imprecise.res.oracle b/tests/builtins/oracle/imprecise.res.oracle index 35235461d13..240ad0e4b03 100644 --- a/tests/builtins/oracle/imprecise.res.oracle +++ b/tests/builtins/oracle/imprecise.res.oracle @@ -48,6 +48,8 @@ [eva] Done for function invalid_assigns_imprecise [eva] computing for function write_garbled <- main. Called from tests/builtins/imprecise.c:145. +[eva:alarm] tests/builtins/imprecise.c:19: Warning: + pointer downcast. assert (unsigned int)&k ≤ 2147483647; [eva] tests/builtins/imprecise.c:19: Assigning imprecise value to p. The imprecision originates from Arithmetic {tests/builtins/imprecise.c:19} @@ -78,6 +80,8 @@ s1.[bits 0 to ..] ∈ {0} or UNINITIALIZED s2.[bits 0 to ..] ∈ {0} or UNINITIALIZED ==END OF DUMP== +[eva:alarm] tests/builtins/imprecise.c:22: Warning: + pointer downcast. assert (unsigned int)p ≤ 2147483647; [eva] Recording results for write_garbled [from] Computing for function write_garbled [from] Done for function write_garbled @@ -105,6 +109,8 @@ cannot evaluate ACSL term, unsupported ACSL construct: logic function memset [eva:alarm] tests/builtins/imprecise.c:53: Warning: out of bounds write. assert \valid(p2); +[eva:alarm] tests/builtins/imprecise.c:53: Warning: + pointer downcast. assert (unsigned int)&addr ≤ 2147483647; [eva:alarm] tests/builtins/imprecise.c:56: Warning: out of bounds write. assert \valid(p4); [eva:alarm] tests/builtins/imprecise.c:58: Warning: @@ -117,9 +123,8 @@ [eva] Done for function abstract_structs [eva] computing for function cast_address <- main. Called from tests/builtins/imprecise.c:147. -[eva] tests/builtins/imprecise.c:66: - Assigning imprecise value to c1. - The imprecision originates from Arithmetic {tests/builtins/imprecise.c:66} +[eva:alarm] tests/builtins/imprecise.c:66: Warning: + pointer downcast. assert (unsigned int)p ≤ 127; [eva:alarm] tests/builtins/imprecise.c:68: Warning: signed overflow. assert -2147483648 ≤ (int)*((char *)(&p)) + 0; [eva:alarm] tests/builtins/imprecise.c:68: Warning: @@ -276,9 +281,7 @@ [eva] ====== VALUES COMPUTED ====== [eva:final-states] Values at end of function cast_address: p ∈ {{ &x }} - c1 ∈ - {{ garbled mix of &{x} - (origin: Arithmetic {tests/builtins/imprecise.c:66}) }} + c1 ∈ {{ (char)&x }} c2# ∈ {{ (? *)&x }}%32, bits 0 to 7 c3 ∈ {{ garbled mix of &{x} @@ -621,6 +624,8 @@ [eva] Done for function invalid_assigns_imprecise [eva] computing for function write_garbled <- main. Called from tests/builtins/imprecise.c:145. +[eva:alarm] tests/builtins/imprecise.c:19: Warning: + pointer downcast. assert (unsigned int)&k ≤ 2147483647; [eva:alarm] tests/builtins/imprecise.c:20: Warning: out of bounds write. assert \valid(p); [eva] tests/builtins/imprecise.c:21: @@ -657,6 +662,8 @@ S_0_S_p_gm_null[0..1] ∈ [--..--] S_1_S_p_gm_null[0..1] ∈ [--..--] ==END OF DUMP== +[eva:alarm] tests/builtins/imprecise.c:22: Warning: + pointer downcast. assert (unsigned int)p ≤ 2147483647; [eva] Recording results for write_garbled [from] Computing for function write_garbled [from] Done for function write_garbled @@ -678,6 +685,8 @@ [eva] tests/builtins/imprecise.c:51: Call to builtin memset [eva:alarm] tests/builtins/imprecise.c:53: Warning: out of bounds write. assert \valid(p2); +[eva:alarm] tests/builtins/imprecise.c:53: Warning: + pointer downcast. assert (unsigned int)&addr ≤ 2147483647; [eva:alarm] tests/builtins/imprecise.c:56: Warning: out of bounds write. assert \valid(p4); [eva:alarm] tests/builtins/imprecise.c:58: Warning: @@ -690,6 +699,8 @@ [eva] Done for function abstract_structs [eva] computing for function cast_address <- main. Called from tests/builtins/imprecise.c:147. +[eva:alarm] tests/builtins/imprecise.c:66: Warning: + pointer downcast. assert (unsigned int)p ≤ 127; [eva:alarm] tests/builtins/imprecise.c:68: Warning: signed overflow. assert -2147483648 ≤ (int)*((char *)(&p)) + 0; [eva:alarm] tests/builtins/imprecise.c:68: Warning: @@ -826,9 +837,7 @@ [eva] ====== VALUES COMPUTED ====== [eva:final-states] Values at end of function cast_address: p ∈ {{ &x }} - c1 ∈ - {{ garbled mix of &{x} - (origin: Arithmetic {tests/builtins/imprecise.c:66}) }} + c1 ∈ {{ (char)&x }} c2# ∈ {{ (? *)&x }}%32, bits 0 to 7 c3 ∈ {{ garbled mix of &{x} diff --git a/tests/builtins/oracle/memchr.res.oracle b/tests/builtins/oracle/memchr.res.oracle index 228d7406ba2..452e93e5b6d 100644 --- a/tests/builtins/oracle/memchr.res.oracle +++ b/tests/builtins/oracle/memchr.res.oracle @@ -477,6 +477,8 @@ [eva] Done for function memchr_bitfields2 [eva] computing for function memchr_escaping <- main. Called from tests/builtins/memchr.c:662. +[eva:alarm] tests/builtins/memchr.c:264: Warning: + pointer downcast. assert (unsigned int)&x ≤ 2147483647; [eva:locals-escaping] tests/builtins/memchr.c:264: Warning: locals {x} escaping the scope of a block of memchr_escaping through s [eva] tests/builtins/memchr.c:267: Call to builtin memchr diff --git a/tests/builtins/oracle/memcpy.res.oracle b/tests/builtins/oracle/memcpy.res.oracle index 8e73401933c..b6358392e62 100644 --- a/tests/builtins/oracle/memcpy.res.oracle +++ b/tests/builtins/oracle/memcpy.res.oracle @@ -128,6 +128,8 @@ function memcpy: precondition 'valid_src' got status valid. [eva] tests/builtins/memcpy.c:85: function memcpy: precondition 'separation' got status valid. +[eva:alarm] tests/builtins/memcpy.c:87: Warning: + pointer downcast. assert (unsigned int)(struct t1 *)t ≤ 2147483647; [eva] tests/builtins/memcpy.c:87: Call to builtin memcpy [eva] tests/builtins/memcpy.c:87: function memcpy: precondition 'valid_dest' got status valid. @@ -135,6 +137,8 @@ function memcpy: precondition 'valid_src' got status unknown. [eva] tests/builtins/memcpy.c:87: function memcpy: precondition 'separation' got status valid. +[eva:alarm] tests/builtins/memcpy.c:89: Warning: + pointer downcast. assert (unsigned int)&v4 ≤ 2147483647; [eva] tests/builtins/memcpy.c:89: Call to builtin memcpy [eva:alarm] tests/builtins/memcpy.c:89: Warning: function memcpy: precondition 'valid_dest' got status unknown. @@ -145,6 +149,10 @@ [kernel] tests/builtins/memcpy.c:89: writing somewhere in {NULL; v4} because of Arithmetic {tests/builtins/memcpy.c:89}. +[eva:alarm] tests/builtins/memcpy.c:90: Warning: + pointer downcast. assert (unsigned int)(struct t1 *)t ≤ 2147483647; +[eva:alarm] tests/builtins/memcpy.c:91: Warning: + pointer downcast. assert (unsigned int)&v5 ≤ 2147483647; [eva] tests/builtins/memcpy.c:91: Call to builtin memcpy [eva:alarm] tests/builtins/memcpy.c:91: Warning: function memcpy: precondition 'valid_dest' got status unknown. @@ -452,6 +460,7 @@ [from] Non-terminating function main_all (no dependencies) [from] Done for function main_all [eva] done for function main_all +[scope:rm_asserts] removing 1 assertion(s) [eva] ====== VALUES COMPUTED ====== [eva:final-states] Values at end of function init: src[0] ∈ {1} @@ -1871,6 +1880,15 @@ tried with Eva. [ - ] Assertion (file tests/builtins/memcpy.c, line 152) tried with Eva. +[ - ] Assertion 'Eva,pointer_downcast' (file tests/builtins/memcpy.c, line 87) + tried with Eva. +[ - ] Assertion 'Eva,pointer_downcast' (file tests/builtins/memcpy.c, line 89) + tried with Eva. +[ Partial ] Assertion 'Eva,pointer_downcast' (file tests/builtins/memcpy.c, line 90) + By RedundantAlarms, with pending: + - Assertion 'Eva,pointer_downcast' (file tests/builtins/memcpy.c, line 87) +[ - ] Assertion 'Eva,pointer_downcast' (file tests/builtins/memcpy.c, line 91) + tried with Eva. [ Valid ] Instance of 'Pre-condition 'valid_dest'' at call 'memcpy' (file tests/builtins/memcpy.c, line 68) by Eva. @@ -2221,8 +2239,9 @@ --- Status Report Summary -------------------------------------------------------------------------------- 162 Completely validated + 1 Locally validated 239 Considered valid - 29 To be validated + 32 To be validated 4 Alarms emitted - 434 Total + 438 Total -------------------------------------------------------------------------------- diff --git a/tests/builtins/oracle/memset.res.oracle b/tests/builtins/oracle/memset.res.oracle index c53d0987526..11215767505 100644 --- a/tests/builtins/oracle/memset.res.oracle +++ b/tests/builtins/oracle/memset.res.oracle @@ -25,6 +25,8 @@ function memset: precondition 'valid_s' got status valid. [eva] share/libc/string.h:118: cannot evaluate ACSL term, unsupported ACSL construct: logic function memset +[eva:alarm] tests/builtins/memset.c:34: Warning: + pointer downcast. assert (unsigned int)(int *)t2 ≤ 2147483647; [eva] tests/builtins/memset.c:34: Call to builtin memset [eva:alarm] tests/builtins/memset.c:34: Warning: function memset: precondition 'valid_s' got status unknown. @@ -42,6 +44,8 @@ [eva] tests/builtins/memset.c:38: Call to builtin memset [eva:alarm] tests/builtins/memset.c:38: Warning: function memset: precondition 'valid_s' got status invalid. +[eva:alarm] tests/builtins/memset.c:41: Warning: + pointer downcast. assert (unsigned int)(int *)t1 ≤ 2147483647; [eva] tests/builtins/memset.c:41: Call to builtin memset [eva] tests/builtins/memset.c:41: function memset: precondition 'valid_s' got status valid. diff --git a/tests/builtins/oracle/strchr.res.oracle b/tests/builtins/oracle/strchr.res.oracle index 8a69adef239..6139567781a 100644 --- a/tests/builtins/oracle/strchr.res.oracle +++ b/tests/builtins/oracle/strchr.res.oracle @@ -316,6 +316,8 @@ [eva] Done for function strchr_bitfields2 [eva] computing for function strchr_escaping <- main. Called from tests/builtins/strchr.c:556. +[eva:alarm] tests/builtins/strchr.c:258: Warning: + pointer downcast. assert (unsigned int)&x ≤ 2147483647; [eva:locals-escaping] tests/builtins/strchr.c:258: Warning: locals {x} escaping the scope of a block of strchr_escaping through s [eva] tests/builtins/strchr.c:261: Call to builtin strchr @@ -669,9 +671,13 @@ [eva] Done for function strchr_invalid [eva] computing for function strchr_garbled_mix_in_char <- main. Called from tests/builtins/strchr.c:562. +[eva:alarm] tests/builtins/strchr.c:541: Warning: + pointer downcast. assert (unsigned int)&x ≤ 2147483647; [eva] tests/builtins/strchr.c:541: Assigning imprecise value to garbled. The imprecision originates from Arithmetic {tests/builtins/strchr.c:541} +[eva:alarm] tests/builtins/strchr.c:542: Warning: + pointer downcast. assert (unsigned int)garbled ≤ 2147483647; [eva] tests/builtins/strchr.c:542: Call to builtin strchr [eva:alarm] tests/builtins/strchr.c:542: Warning: function strchr: precondition 'valid_string_s' got status invalid. diff --git a/tests/builtins/oracle/strlen.res.oracle b/tests/builtins/oracle/strlen.res.oracle index 7d20e2bba7e..900d168bdba 100644 --- a/tests/builtins/oracle/strlen.res.oracle +++ b/tests/builtins/oracle/strlen.res.oracle @@ -261,6 +261,8 @@ [eva] Done for function bitfields2 [eva] computing for function escaping <- main. Called from tests/builtins/strlen.c:342. +[eva:alarm] tests/builtins/strlen.c:222: Warning: + pointer downcast. assert (unsigned int)&x ≤ 2147483647; [eva:locals-escaping] tests/builtins/strlen.c:222: Warning: locals {x} escaping the scope of a block of escaping through s [eva] tests/builtins/strlen.c:225: Call to builtin strlen diff --git a/tests/builtins/oracle/strnlen2.res.oracle b/tests/builtins/oracle/strnlen2.res.oracle index 903c30f5d3a..b04e6e5abe4 100644 --- a/tests/builtins/oracle/strnlen2.res.oracle +++ b/tests/builtins/oracle/strnlen2.res.oracle @@ -261,6 +261,8 @@ [eva] Done for function bitfields2 [eva] computing for function escaping <- main. Called from tests/builtins/strnlen2.c:522. +[eva:alarm] tests/builtins/strnlen2.c:196: Warning: + pointer downcast. assert (unsigned int)&x ≤ 2147483647; [eva:locals-escaping] tests/builtins/strnlen2.c:196: Warning: locals {x} escaping the scope of a block of escaping through s [eva] tests/builtins/strnlen2.c:199: Call to builtin strnlen diff --git a/tests/builtins/oracle/wcslen.res.oracle b/tests/builtins/oracle/wcslen.res.oracle index f5a97cc8574..0c9295b364c 100644 --- a/tests/builtins/oracle/wcslen.res.oracle +++ b/tests/builtins/oracle/wcslen.res.oracle @@ -261,6 +261,14 @@ [eva] Done for function bitfields2 [eva] computing for function escaping <- main. Called from tests/builtins/wcslen.c:347. +[eva:alarm] tests/builtins/wcslen.c:222: Warning: + pointer downcast. assert (unsigned int)&x ≤ 2147483647; +[eva:alarm] tests/builtins/wcslen.c:222: Warning: + pointer downcast. assert (unsigned int)&x ≤ 2147483647; +[eva:alarm] tests/builtins/wcslen.c:222: Warning: + pointer downcast. assert (unsigned int)&x ≤ 2147483647; +[eva:alarm] tests/builtins/wcslen.c:222: Warning: + pointer downcast. assert (unsigned int)&x ≤ 2147483647; [eva:locals-escaping] tests/builtins/wcslen.c:222: Warning: locals {x} escaping the scope of a block of escaping through s [eva] tests/builtins/wcslen.c:225: Call to builtin wcslen @@ -358,6 +366,7 @@ [eva] Done for function negative_offsets [eva] Recording results for main [eva] done for function main +[scope:rm_asserts] removing 3 assertion(s) [eva] ====== VALUES COMPUTED ====== [eva:final-states] Values at end of function init_array_nondet: from ∈ {-1} diff --git a/tests/float/oracle/builtins.res.oracle b/tests/float/oracle/builtins.res.oracle index 0bfa3b88df2..00d692def3c 100644 --- a/tests/float/oracle/builtins.res.oracle +++ b/tests/float/oracle/builtins.res.oracle @@ -134,6 +134,8 @@ function exp: precondition 'finite_arg' got status valid. [eva] tests/float/builtins.c:104: function exp: precondition 'finite_domain' got status valid. +[eva:alarm] tests/float/builtins.c:107: Warning: + pointer downcast. assert (unsigned int)&d ≤ 2147483647; [eva:alarm] tests/float/builtins.c:107: Warning: non-finite double value. assert \is_finite((double)((int)(&d))); [eva] tests/float/builtins.c:107: Call to builtin log diff --git a/tests/float/oracle/nonlin.0.res.oracle b/tests/float/oracle/nonlin.0.res.oracle index 648a1ae9af5..6324ceb920c 100644 --- a/tests/float/oracle/nonlin.0.res.oracle +++ b/tests/float/oracle/nonlin.0.res.oracle @@ -230,6 +230,10 @@ [eva] Done for function norm [eva] computing for function garbled <- main. Called from tests/float/nonlin.c:148. +[eva:alarm] tests/float/nonlin.c:98: Warning: + pointer downcast. assert (unsigned int)&x_0 ≤ 2147483647; +[eva:alarm] tests/float/nonlin.c:98: Warning: + pointer downcast. assert (unsigned int)&x_0 + (int)(&x_0) ≤ 2147483647; [eva:alarm] tests/float/nonlin.c:98: Warning: non-finite float value. assert \is_finite((float)((int)(&x_0 + (int)(&x_0)))); diff --git a/tests/float/oracle/nonlin.1.res.oracle b/tests/float/oracle/nonlin.1.res.oracle index 3ddef66ef49..9f4864b2625 100644 --- a/tests/float/oracle/nonlin.1.res.oracle +++ b/tests/float/oracle/nonlin.1.res.oracle @@ -253,6 +253,10 @@ [eva] Done for function norm [eva] computing for function garbled <- main. Called from tests/float/nonlin.c:148. +[eva:alarm] tests/float/nonlin.c:98: Warning: + pointer downcast. assert (unsigned int)&x_0 ≤ 2147483647; +[eva:alarm] tests/float/nonlin.c:98: Warning: + pointer downcast. assert (unsigned int)&x_0 + (int)(&x_0) ≤ 2147483647; [eva:alarm] tests/float/nonlin.c:98: Warning: non-finite float value. assert \is_finite((float)((int)(&x_0 + (int)(&x_0)))); diff --git a/tests/float/oracle/nonlin.2.res.oracle b/tests/float/oracle/nonlin.2.res.oracle index ba81c19d44c..a0b3a97b62f 100644 --- a/tests/float/oracle/nonlin.2.res.oracle +++ b/tests/float/oracle/nonlin.2.res.oracle @@ -240,6 +240,10 @@ [eva] Done for function norm [eva] computing for function garbled <- main. Called from tests/float/nonlin.c:148. +[eva:alarm] tests/float/nonlin.c:98: Warning: + pointer downcast. assert (unsigned int)&x_0 ≤ 2147483647; +[eva:alarm] tests/float/nonlin.c:98: Warning: + pointer downcast. assert (unsigned int)&x_0 + (int)(&x_0) ≤ 2147483647; [eva] tests/float/nonlin.c:98: Assigning imprecise value to a_0. The imprecision originates from Arithmetic {tests/float/nonlin.c:98} diff --git a/tests/float/oracle/nonlin.3.res.oracle b/tests/float/oracle/nonlin.3.res.oracle index c3e1e9cdb8b..52fc170f4f8 100644 --- a/tests/float/oracle/nonlin.3.res.oracle +++ b/tests/float/oracle/nonlin.3.res.oracle @@ -230,6 +230,10 @@ [eva] Done for function norm [eva] computing for function garbled <- main. Called from tests/float/nonlin.c:148. +[eva:alarm] tests/float/nonlin.c:98: Warning: + pointer downcast. assert (unsigned int)&x_0 ≤ 2147483647; +[eva:alarm] tests/float/nonlin.c:98: Warning: + pointer downcast. assert (unsigned int)&x_0 + (int)(&x_0) ≤ 2147483647; [eva:alarm] tests/float/nonlin.c:98: Warning: non-finite float value. assert \is_finite((float)((int)(&x_0 + (int)(&x_0)))); diff --git a/tests/float/oracle/nonlin.4.res.oracle b/tests/float/oracle/nonlin.4.res.oracle index 2f06c2710cf..2d45c975ffb 100644 --- a/tests/float/oracle/nonlin.4.res.oracle +++ b/tests/float/oracle/nonlin.4.res.oracle @@ -253,6 +253,10 @@ [eva] Done for function norm [eva] computing for function garbled <- main. Called from tests/float/nonlin.c:148. +[eva:alarm] tests/float/nonlin.c:98: Warning: + pointer downcast. assert (unsigned int)&x_0 ≤ 2147483647; +[eva:alarm] tests/float/nonlin.c:98: Warning: + pointer downcast. assert (unsigned int)&x_0 + (int)(&x_0) ≤ 2147483647; [eva:alarm] tests/float/nonlin.c:98: Warning: non-finite float value. assert \is_finite((float)((int)(&x_0 + (int)(&x_0)))); diff --git a/tests/float/oracle/nonlin.5.res.oracle b/tests/float/oracle/nonlin.5.res.oracle index a26018dc5a7..667b1228b96 100644 --- a/tests/float/oracle/nonlin.5.res.oracle +++ b/tests/float/oracle/nonlin.5.res.oracle @@ -240,6 +240,10 @@ [eva] Done for function norm [eva] computing for function garbled <- main. Called from tests/float/nonlin.c:148. +[eva:alarm] tests/float/nonlin.c:98: Warning: + pointer downcast. assert (unsigned int)&x_0 ≤ 2147483647; +[eva:alarm] tests/float/nonlin.c:98: Warning: + pointer downcast. assert (unsigned int)&x_0 + (int)(&x_0) ≤ 2147483647; [eva] tests/float/nonlin.c:98: Assigning imprecise value to a_0. The imprecision originates from Arithmetic {tests/float/nonlin.c:98} diff --git a/tests/syntax/oracle/ghost_else_bad.1.err.oracle b/tests/syntax/oracle/ghost_else_bad.1.err.oracle deleted file mode 100644 index b7f5dc572a0..00000000000 --- a/tests/syntax/oracle/ghost_else_bad.1.err.oracle +++ /dev/null @@ -1 +0,0 @@ -Warning: tests/syntax/ghost_else_bad.c:32: Invalid ghost else ignored diff --git a/tests/value/oracle/addition.res.oracle b/tests/value/oracle/addition.res.oracle index f601e53058b..81d6deca427 100644 --- a/tests/value/oracle/addition.res.oracle +++ b/tests/value/oracle/addition.res.oracle @@ -59,27 +59,54 @@ [eva] tests/value/addition.i:34: Assigning imprecise value to p1. The imprecision originates from Arithmetic {tests/value/addition.i:34} +[eva:alarm] tests/value/addition.i:36: Warning: + pointer downcast. assert (unsigned int)&p1 ≤ 2147483647; [eva] tests/value/addition.i:36: Assigning imprecise value to p2. The imprecision originates from Arithmetic {tests/value/addition.i:36} +[eva:alarm] tests/value/addition.i:38: Warning: + pointer downcast. assert (unsigned int)&p1 ≤ 127; +[eva:alarm] tests/value/addition.i:38: Warning: + pointer downcast. assert (unsigned int)&t[(char)(&p1)] ≤ 2147483647; [eva] tests/value/addition.i:38: Assigning imprecise value to p3. The imprecision originates from Arithmetic {tests/value/addition.i:38} +[eva:alarm] tests/value/addition.i:40: Warning: + pointer downcast. assert (unsigned int)&p1 ≤ 127; +[eva:alarm] tests/value/addition.i:40: Warning: + pointer downcast. assert (unsigned int)&tt[(char)(&p1)].a ≤ 2147483647; [eva] tests/value/addition.i:40: Assigning imprecise value to p4. The imprecision originates from Arithmetic {tests/value/addition.i:40} +[eva:alarm] tests/value/addition.i:42: Warning: + pointer downcast. assert (unsigned int)&p1 ≤ 127; +[eva:alarm] tests/value/addition.i:42: Warning: + pointer downcast. assert (unsigned int)&p2 ≤ 127; +[eva:alarm] tests/value/addition.i:42: Warning: + pointer downcast. + assert (unsigned int)&ttt[(char)(&p1)][(char)(&p2)] ≤ 2147483647; [eva] tests/value/addition.i:42: Assigning imprecise value to p5. The imprecision originates from Arithmetic {tests/value/addition.i:42} +[eva:alarm] tests/value/addition.i:44: Warning: + pointer downcast. assert (unsigned int)&p1 ≤ 127; +[eva:alarm] tests/value/addition.i:44: Warning: + pointer downcast. assert (unsigned int)&ttt[(char)(&p1)][u2] ≤ 2147483647; [eva] tests/value/addition.i:44: Assigning imprecise value to p6. The imprecision originates from Arithmetic {tests/value/addition.i:44} +[eva:alarm] tests/value/addition.i:46: Warning: + pointer downcast. assert (unsigned int)&p2 ≤ 127; +[eva:alarm] tests/value/addition.i:46: Warning: + pointer downcast. assert (unsigned int)&ttt[u2][(char)(&p2)] ≤ 2147483647; [eva] tests/value/addition.i:46: Assigning imprecise value to p7. The imprecision originates from Arithmetic {tests/value/addition.i:46} [eva:alarm] tests/value/addition.i:48: Warning: pointer comparison. assert \pointer_comparable((void *)(&p1 + 1), (void *)(&p2)); +[eva:alarm] tests/value/addition.i:50: Warning: + pointer downcast. assert (unsigned int)&p1 ≤ 2147483647; [eva:alarm] tests/value/addition.i:50: Warning: signed overflow. assert -2147483648 ≤ (int)(&p1) / 2; [eva:alarm] tests/value/addition.i:50: Warning: @@ -87,9 +114,15 @@ [eva] tests/value/addition.i:50: Assigning imprecise value to p9. The imprecision originates from Arithmetic {tests/value/addition.i:50} +[eva:alarm] tests/value/addition.i:52: Warning: + pointer downcast. assert (unsigned int)&p1 ≤ 2147483647; [eva] tests/value/addition.i:52: Assigning imprecise value to p10. The imprecision originates from Arithmetic {tests/value/addition.i:52} +[eva:alarm] tests/value/addition.i:56: Warning: + pointer downcast. assert (unsigned int)&p1 ≤ 2147483647; +[eva:alarm] tests/value/addition.i:56: Warning: + pointer downcast. assert (unsigned int)&p2 ≤ 2147483647; [eva] tests/value/addition.i:56: Assigning imprecise value to p12. The imprecision originates from Arithmetic {tests/value/addition.i:56} @@ -130,7 +163,7 @@ {{ garbled mix of &{p1} (origin: Arithmetic {tests/value/addition.i:56}) }} {{ garbled mix of &{p1} (origin: Misaligned {tests/value/addition.i:59}) }} {{ garbled mix of &{p1} (origin: Misaligned {tests/value/addition.i:61}) }} -[scope:rm_asserts] removing 2 assertion(s) +[scope:rm_asserts] removing 9 assertion(s) [eva] ====== VALUES COMPUTED ====== [eva:final-states] Values at end of function main: t[0] ∈ {0} @@ -323,13 +356,46 @@ signed overflow. assert -2147483648 ≤ &p2 - &p3; [eva:alarm] tests/value/addition.i:34: Warning: signed overflow. assert &p2 - &p3 ≤ 2147483647; +[eva:alarm] tests/value/addition.i:36: Warning: + pointer downcast. assert (unsigned int)&p1 ≤ 2147483647; +[eva:alarm] tests/value/addition.i:38: Warning: + pointer downcast. assert (unsigned int)&p1 ≤ 127; +[eva:alarm] tests/value/addition.i:38: Warning: + pointer downcast. assert (unsigned int)&t[(char)(&p1)] ≤ 2147483647; +[eva:alarm] tests/value/addition.i:40: Warning: + pointer downcast. assert (unsigned int)&p1 ≤ 127; +[eva:alarm] tests/value/addition.i:40: Warning: + pointer downcast. assert (unsigned int)&tt[(char)(&p1)].a ≤ 2147483647; +[eva:alarm] tests/value/addition.i:42: Warning: + pointer downcast. assert (unsigned int)&p1 ≤ 127; +[eva:alarm] tests/value/addition.i:42: Warning: + pointer downcast. assert (unsigned int)&p2 ≤ 127; +[eva:alarm] tests/value/addition.i:42: Warning: + pointer downcast. + assert (unsigned int)&ttt[(char)(&p1)][(char)(&p2)] ≤ 2147483647; +[eva:alarm] tests/value/addition.i:44: Warning: + pointer downcast. assert (unsigned int)&p1 ≤ 127; +[eva:alarm] tests/value/addition.i:44: Warning: + pointer downcast. assert (unsigned int)&ttt[(char)(&p1)][u2] ≤ 2147483647; +[eva:alarm] tests/value/addition.i:46: Warning: + pointer downcast. assert (unsigned int)&p2 ≤ 127; +[eva:alarm] tests/value/addition.i:46: Warning: + pointer downcast. assert (unsigned int)&ttt[u2][(char)(&p2)] ≤ 2147483647; [eva:alarm] tests/value/addition.i:48: Warning: pointer comparison. assert \pointer_comparable((void *)(&p1 + 1), (void *)(&p2)); +[eva:alarm] tests/value/addition.i:50: Warning: + pointer downcast. assert (unsigned int)&p1 ≤ 2147483647; [eva:alarm] tests/value/addition.i:50: Warning: signed overflow. assert -2147483648 ≤ (int)(&p1) / 2; [eva:alarm] tests/value/addition.i:50: Warning: signed overflow. assert (int)(&p1) / 2 ≤ 2147483647; +[eva:alarm] tests/value/addition.i:52: Warning: + pointer downcast. assert (unsigned int)&p1 ≤ 2147483647; +[eva:alarm] tests/value/addition.i:56: Warning: + pointer downcast. assert (unsigned int)&p1 ≤ 2147483647; +[eva:alarm] tests/value/addition.i:56: Warning: + pointer downcast. assert (unsigned int)&p2 ≤ 2147483647; [eva:alarm] tests/value/addition.i:59: Warning: signed overflow. assert -2147483648 ≤ (int)*((char *)(&q1)) + 2; [eva:alarm] tests/value/addition.i:59: Warning: @@ -360,7 +426,7 @@ {{ garbled mix of &{p1} (origin: Arithmetic {tests/value/addition.i:56}) }} {{ garbled mix of &{p1} (origin: Misaligned {tests/value/addition.i:59}) }} {{ garbled mix of &{p1} (origin: Misaligned {tests/value/addition.i:61}) }} -[scope:rm_asserts] removing 2 assertion(s) +[scope:rm_asserts] removing 9 assertion(s) [eva] ====== VALUES COMPUTED ====== [eva:final-states] Values at end of function main: t[0] ∈ {0} diff --git a/tests/value/oracle/align_char_array.res.oracle b/tests/value/oracle/align_char_array.res.oracle index 82c0a105954..c84e281414a 100644 --- a/tests/value/oracle/align_char_array.res.oracle +++ b/tests/value/oracle/align_char_array.res.oracle @@ -15,25 +15,41 @@ overlapread2 ∈ {0} overlapread3 ∈ {0} overlapread4 ∈ {0} +[eva:alarm] tests/value/align_char_array.c:21: Warning: + pointer downcast. assert (unsigned int)&S.a ≤ 2147483647; +[eva:alarm] tests/value/align_char_array.c:21: Warning: + pointer downcast. assert (unsigned int)&S.c ≤ 2147483647; +[eva:alarm] tests/value/align_char_array.c:23: Warning: + pointer downcast. assert (unsigned int)&t[2][2] ≤ 2147483647; +[eva:alarm] tests/value/align_char_array.c:23: Warning: + pointer downcast. assert (unsigned int)&t[0][0] ≤ 2147483647; +[eva:alarm] tests/value/align_char_array.c:25: Warning: + pointer downcast. assert (unsigned int)(char (*)[10])t ≤ 2147483647; [eva:alarm] tests/value/align_char_array.c:25: Warning: signed overflow. assert -2147483648 ≤ (int)((char (*)[10])t) + 3; [eva:alarm] tests/value/align_char_array.c:25: Warning: signed overflow. assert (int)((char (*)[10])t) + 3 ≤ 2147483647; +[eva:alarm] tests/value/align_char_array.c:26: Warning: + pointer downcast. assert (unsigned int)(char (*)[10])t ≤ 2147483647; [eva:alarm] tests/value/align_char_array.c:26: Warning: signed overflow. assert -2147483648 ≤ (int)((char (*)[10])t) + 3; [eva:alarm] tests/value/align_char_array.c:26: Warning: signed overflow. assert (int)((char (*)[10])t) + 3 ≤ 2147483647; +[eva:alarm] tests/value/align_char_array.c:27: Warning: + pointer downcast. assert (unsigned int)(char (*)[10])t ≤ 2147483647; [eva:alarm] tests/value/align_char_array.c:27: Warning: signed overflow. assert -2147483648 ≤ (int)((char (*)[10])t) + 2; [eva:alarm] tests/value/align_char_array.c:27: Warning: signed overflow. assert (int)((char (*)[10])t) + 2 ≤ 2147483647; +[eva:alarm] tests/value/align_char_array.c:28: Warning: + pointer downcast. assert (unsigned int)(char (*)[10])t ≤ 2147483647; [eva:alarm] tests/value/align_char_array.c:28: Warning: signed overflow. assert -2147483648 ≤ (int)((char (*)[10])t) + 2; [eva:alarm] tests/value/align_char_array.c:28: Warning: signed overflow. assert (int)((char (*)[10])t) + 2 ≤ 2147483647; [eva] Recording results for main [eva] done for function main -[scope:rm_asserts] removing 4 assertion(s) +[scope:rm_asserts] removing 7 assertion(s) [eva] ====== VALUES COMPUTED ====== [eva:final-states] Values at end of function main: d1 ∈ {1} diff --git a/tests/value/oracle/arith_pointer.res.oracle b/tests/value/oracle/arith_pointer.res.oracle index 3ec14d1a31c..b8a89b48a6c 100644 --- a/tests/value/oracle/arith_pointer.res.oracle +++ b/tests/value/oracle/arith_pointer.res.oracle @@ -22,6 +22,8 @@ [eva:alarm] tests/value/arith_pointer.c:51: Warning: pointer subtraction. assert \base_addr(p2) ≡ \base_addr(p2); [eva] tests/value/arith_pointer.c:52: Frama_C_show_each: {0} +[eva:alarm] tests/value/arith_pointer.c:54: Warning: + pointer downcast. assert (unsigned int)&x ≤ 2147483647; [eva] tests/value/arith_pointer.c:54: Assigning imprecise value to p1. The imprecision originates from Arithmetic {tests/value/arith_pointer.c:54} @@ -148,6 +150,8 @@ Frama_C_show_each: {{ garbled mix of &{x; y} (origin: Arithmetic {tests/value/arith_pointer.c:51}) }} +[eva:alarm] tests/value/arith_pointer.c:54: Warning: + pointer downcast. assert (unsigned int)&x ≤ 2147483647; [eva:alarm] tests/value/arith_pointer.c:56: Warning: signed overflow. assert -2147483648 ≤ p2 - p1; [eva:alarm] tests/value/arith_pointer.c:56: Warning: diff --git a/tests/value/oracle/array_ptr.res.oracle b/tests/value/oracle/array_ptr.res.oracle index 76ce304e41d..2d14be30289 100644 --- a/tests/value/oracle/array_ptr.res.oracle +++ b/tests/value/oracle/array_ptr.res.oracle @@ -6,6 +6,8 @@ G ∈ {1} l[0] ∈ {1} [1..19] ∈ {0} +[eva:alarm] tests/value/array_ptr.i:14: Warning: + pointer downcast. assert (unsigned int)&l ≤ 2147483647; [eva] computing for function f <- main. Called from tests/value/array_ptr.i:15. [eva] Recording results for f diff --git a/tests/value/oracle/assigns.res.oracle b/tests/value/oracle/assigns.res.oracle index 0edee1de714..40501b7b144 100644 --- a/tests/value/oracle/assigns.res.oracle +++ b/tests/value/oracle/assigns.res.oracle @@ -44,6 +44,8 @@ [eva] computing for function f <- main1 <- main. Called from tests/value/assigns.i:49. [eva] Done for function f +[eva:alarm] tests/value/assigns.i:51: Warning: + pointer downcast. assert (unsigned int)&T ≤ 2147483647; [eva:alarm] tests/value/assigns.i:51: Warning: signed overflow. assert -2147483648 ≤ 2 * (int)(&T); [eva:alarm] tests/value/assigns.i:51: Warning: @@ -52,6 +54,8 @@ Called from tests/value/assigns.i:51. [eva] using specification for function g [eva] Done for function g +[eva:alarm] tests/value/assigns.i:52: Warning: + pointer downcast. assert (unsigned int)&t3 ≤ 2147483647; [eva:alarm] tests/value/assigns.i:52: Warning: signed overflow. assert -2147483648 ≤ 2 * (int)(&t3); [eva:alarm] tests/value/assigns.i:52: Warning: @@ -931,9 +935,11 @@ void main1(void) i ++; } } + /*@ assert Eva: pointer_downcast: (unsigned int)&T ≤ 2147483647; */ /*@ assert Eva: signed_overflow: -2147483648 ≤ 2 * (int)(&T); */ /*@ assert Eva: signed_overflow: 2 * (int)(&T) ≤ 2147483647; */ g(2 * (int)(& T)); + /*@ assert Eva: pointer_downcast: (unsigned int)&t3 ≤ 2147483647; */ /*@ assert Eva: signed_overflow: -2147483648 ≤ 2 * (int)(&t3); */ /*@ assert Eva: signed_overflow: 2 * (int)(&t3) ≤ 2147483647; */ h((int *)(2 * (int)(& t3))); diff --git a/tests/value/oracle/bitfield.res.oracle b/tests/value/oracle/bitfield.res.oracle index 05b0967b052..54cf0bfdba6 100644 --- a/tests/value/oracle/bitfield.res.oracle +++ b/tests/value/oracle/bitfield.res.oracle @@ -28,9 +28,13 @@ Called from tests/value/bitfield.i:164. [eva] tests/value/bitfield.i:113: Frama_C_show_each: {1} [eva] tests/value/bitfield.i:117: Frama_C_show_each: {3} +[eva:alarm] tests/value/bitfield.i:123: Warning: + pointer downcast. assert (unsigned int)&v ≤ 2147483647; [eva] tests/value/bitfield.i:123: Assigning imprecise value to v.c. The imprecision originates from Arithmetic {tests/value/bitfield.i:123} +[eva:alarm] tests/value/bitfield.i:124: Warning: + pointer downcast. assert (unsigned int)&v + 1 ≤ 2147483647; [eva:alarm] tests/value/bitfield.i:125: Warning: signed overflow. assert -2147483648 ≤ (int)v.d + 1; [eva:alarm] tests/value/bitfield.i:125: Warning: @@ -77,6 +81,8 @@ signed overflow. assert -2147483648 ≤ foo + foo; [eva:alarm] tests/value/bitfield.i:129: Warning: signed overflow. assert foo + foo ≤ 2147483647; +[eva:alarm] tests/value/bitfield.i:130: Warning: + pointer downcast. assert (unsigned int)&v + 1 ≤ 2147483647; [eva] tests/value/bitfield.i:130: Assigning imprecise value to h.c. The imprecision originates from Arithmetic {tests/value/bitfield.i:130} @@ -207,6 +213,7 @@ [eva] done for function main [eva] tests/value/bitfield.i:102: assertion 'Eva,initialization' got final status invalid. +[scope:rm_asserts] removing 1 assertion(s) [eva] ====== VALUES COMPUTED ====== [eva:final-states] Values at end of function char_short: S.c ∈ {1} @@ -550,7 +557,9 @@ void main_old(void) else Frama_C_show_each(3); VV = (unsigned int)h.a; h.a = (unsigned int __attribute__((__FRAMA_C_BITFIELD_SIZE__(2))))VV; + /*@ assert Eva: pointer_downcast: (unsigned int)&v ≤ 2147483647; */ v.c = (int __attribute__((__FRAMA_C_BITFIELD_SIZE__(22))))((int)(& v)); + /*@ assert Eva: pointer_downcast: (unsigned int)&v + 1 ≤ 2147483647; */ v.d = (int __attribute__((__FRAMA_C_BITFIELD_SIZE__(32))))((int)(& v + 1)); /*@ assert Eva: signed_overflow: -2147483648 ≤ (int)v.d + 1; */ /*@ assert Eva: signed_overflow: (int)v.d + 1 ≤ 2147483647; */ @@ -561,6 +570,7 @@ void main_old(void) /*@ assert Eva: signed_overflow: -2147483648 ≤ foo + foo; */ /*@ assert Eva: signed_overflow: foo + foo ≤ 2147483647; */ h.b = (int __attribute__((__FRAMA_C_BITFIELD_SIZE__(4))))(((foo + foo) + (int)h.a) + (int)h.b); + /*@ assert Eva: pointer_downcast: (unsigned int)&v + 1 ≤ 2147483647; */ h.c = (int __attribute__((__FRAMA_C_BITFIELD_SIZE__(22))))((int)(& v + 1)); k8.b = (int __attribute__((__FRAMA_C_BITFIELD_SIZE__(4))))8; tmp = return_8(); diff --git a/tests/value/oracle/bitwise_pointer.res.oracle b/tests/value/oracle/bitwise_pointer.res.oracle index c1a1f86bba1..a0538f60c8e 100644 --- a/tests/value/oracle/bitwise_pointer.res.oracle +++ b/tests/value/oracle/bitwise_pointer.res.oracle @@ -29,11 +29,15 @@ [10..99] ∈ {0} p1 ∈ {0} x1 ∈ {0} +[eva:alarm] tests/value/bitwise_pointer.i:18: Warning: + pointer downcast. assert (unsigned int)&t[7] ≤ 2147483647; [eva] tests/value/bitwise_pointer.i:18: Assigning imprecise value to p. The imprecision originates from Arithmetic {tests/value/bitwise_pointer.i:18} [eva:alarm] tests/value/bitwise_pointer.i:19: Warning: out of bounds write. assert \valid(p); +[eva:alarm] tests/value/bitwise_pointer.i:22: Warning: + pointer downcast. assert (unsigned int)&t1[mask] ≤ 2147483647; [eva] tests/value/bitwise_pointer.i:22: Assigning imprecise value to p1. The imprecision originates from Arithmetic {tests/value/bitwise_pointer.i:22} diff --git a/tests/value/oracle/call.res.oracle b/tests/value/oracle/call.res.oracle index bd70d167383..14437324954 100644 --- a/tests/value/oracle/call.res.oracle +++ b/tests/value/oracle/call.res.oracle @@ -10,6 +10,8 @@ x ∈ {0} [eva:alarm] tests/value/call.i:19: Warning: out of bounds read. assert \valid_read(v + 1); +[eva:alarm] tests/value/call.i:19: Warning: + pointer downcast. assert (unsigned int)*(v + 1) ≤ 2147483647; [eva] computing for function leaf_fun_int <- main. Called from tests/value/call.i:19. [kernel:annot:missing-spec] tests/value/call.i:19: Warning: diff --git a/tests/value/oracle/cmp_ptr.0.res.oracle b/tests/value/oracle/cmp_ptr.0.res.oracle index b3a90b9fbe1..08d4b95eafc 100644 --- a/tests/value/oracle/cmp_ptr.0.res.oracle +++ b/tests/value/oracle/cmp_ptr.0.res.oracle @@ -45,12 +45,18 @@ invalid pointer comparison: invalid pointer(s) [eva:alarm] tests/value/cmp_ptr.i:22: Warning: pointer comparison. assert \pointer_comparable((void *)0, (void *)(&y + 2)); +[eva:alarm] tests/value/cmp_ptr.i:23: Warning: + pointer downcast. assert (unsigned int)&y + 2 ≤ 2147483647; [eva:pointer-comparison] tests/value/cmp_ptr.i:24: invalid pointer comparison: invalid pointer(s) [eva:alarm] tests/value/cmp_ptr.i:24: Warning: non-finite float value. assert \is_finite(ff); [eva:pointer-comparison] tests/value/cmp_ptr.i:28: invalid pointer comparison: invalid pointer(s) +[eva:alarm] tests/value/cmp_ptr.i:28: Warning: + pointer downcast. + assert (unsigned int)tmp_0 ≤ 2147483647; + (tmp_0 from u?& f:& g) [eva:alarm] tests/value/cmp_ptr.i:28: Warning: signed overflow. assert -2147483648 ≤ 1 + (int)tmp_0; diff --git a/tests/value/oracle/cmp_ptr.1.res.oracle b/tests/value/oracle/cmp_ptr.1.res.oracle index 36b9efb6f47..ea6793941d4 100644 --- a/tests/value/oracle/cmp_ptr.1.res.oracle +++ b/tests/value/oracle/cmp_ptr.1.res.oracle @@ -59,12 +59,18 @@ evaluating condition to {0; 1} instead of {0} because of UPCPA [eva:alarm] tests/value/cmp_ptr.i:22: Warning: pointer comparison. assert \pointer_comparable((void *)0, (void *)(&y + 2)); +[eva:alarm] tests/value/cmp_ptr.i:23: Warning: + pointer downcast. assert (unsigned int)&y + 2 ≤ 2147483647; [eva:pointer-comparison] tests/value/cmp_ptr.i:24: invalid pointer comparison: invalid pointer(s) [eva:alarm] tests/value/cmp_ptr.i:24: Warning: non-finite float value. assert \is_finite(ff); [eva:pointer-comparison] tests/value/cmp_ptr.i:28: invalid pointer comparison: invalid pointer(s) +[eva:alarm] tests/value/cmp_ptr.i:28: Warning: + pointer downcast. + assert (unsigned int)tmp_0 ≤ 2147483647; + (tmp_0 from u?& f:& g) [eva:alarm] tests/value/cmp_ptr.i:28: Warning: signed overflow. assert -2147483648 ≤ 1 + (int)tmp_0; diff --git a/tests/value/oracle/context_free.res.oracle b/tests/value/oracle/context_free.res.oracle index b244fecc83c..f8869049442 100644 --- a/tests/value/oracle/context_free.res.oracle +++ b/tests/value/oracle/context_free.res.oracle @@ -101,10 +101,8 @@ The imprecision originates from Well [eva:alarm] tests/value/context_free.i:61: Warning: out of bounds write. assert \valid(pvoid); -[eva] tests/value/context_free.i:61: - Assigning imprecise value to *pvoid - (pointing to S_qvoid with offsets [0..34359738360],0%8). - The imprecision originates from Arithmetic {tests/value/context_free.i:61} +[eva:alarm] tests/value/context_free.i:61: Warning: + pointer downcast. assert (unsigned int)&pvoid ≤ 127; [eva:alarm] tests/value/context_free.i:62: Warning: pointer to function with incompatible type. assert \valid_function(g); [eva] Recording results for f diff --git a/tests/value/oracle/conversion.res.oracle b/tests/value/oracle/conversion.res.oracle index d9ed842d845..26374aad66f 100644 --- a/tests/value/oracle/conversion.res.oracle +++ b/tests/value/oracle/conversion.res.oracle @@ -57,6 +57,8 @@ f ∈ [3. .. 5.] l ∈ UNINITIALIZED ==END OF DUMP== +[eva:alarm] tests/value/conversion.i:38: Warning: + pointer downcast. assert (unsigned int)&x ≤ 2147483647; [eva] tests/value/conversion.i:40: Frama_C_dump_each: # Cvalue domain: @@ -161,6 +163,8 @@ f ∈ [3. .. 5.] l ∈ UNINITIALIZED ==END OF DUMP== +[eva:alarm] tests/value/conversion.i:38: Warning: + pointer downcast. assert (unsigned int)&x ≤ 2147483647; [eva:alarm] tests/value/conversion.i:39: Warning: non-finite float value. assert \is_finite(*((float *)(&x))); [eva] tests/value/conversion.i:39: diff --git a/tests/value/oracle/degeneration2.res.oracle b/tests/value/oracle/degeneration2.res.oracle index feb99e8fb71..8ba6db66b55 100644 --- a/tests/value/oracle/degeneration2.res.oracle +++ b/tests/value/oracle/degeneration2.res.oracle @@ -6,6 +6,8 @@ v ∈ [--..--] [eva:alarm] tests/value/degeneration2.i:14: Warning: accessing uninitialized left-value. assert \initialized(&A); +[eva:alarm] tests/value/degeneration2.i:14: Warning: + pointer downcast. assert (unsigned int)A ≤ 2147483647; [eva:alarm] tests/value/degeneration2.i:14: Warning: signed overflow. assert -2147483648 ≤ -((int)A); [eva:alarm] tests/value/degeneration2.i:14: Warning: diff --git a/tests/value/oracle/deps_addr.res.oracle b/tests/value/oracle/deps_addr.res.oracle index 093935ed643..0c2afa4364c 100644 --- a/tests/value/oracle/deps_addr.res.oracle +++ b/tests/value/oracle/deps_addr.res.oracle @@ -6,6 +6,8 @@ t ∈ {0} a ∈ {0} tt[0..4][0..4] ∈ {0} +[eva:alarm] tests/value/deps_addr.i:6: Warning: + pointer downcast. assert (unsigned int)&a ≤ 2147483647; [eva:alarm] tests/value/deps_addr.i:6: Warning: out of bounds read. assert \valid_read(t + (int)(&a)); [eva] Recording results for main diff --git a/tests/value/oracle/deps_mixed.res.oracle b/tests/value/oracle/deps_mixed.res.oracle index b33c688ba94..e7af15348e5 100644 --- a/tests/value/oracle/deps_mixed.res.oracle +++ b/tests/value/oracle/deps_mixed.res.oracle @@ -12,6 +12,8 @@ v ∈ [--..--] t[0] ∈ {{ &f }} [1] ∈ {{ &g }} +[eva:alarm] tests/value/deps_mixed.i:20: Warning: + pointer downcast. assert (unsigned int)q ≤ 2147483647; [eva:alarm] tests/value/deps_mixed.i:20: Warning: out of bounds read. assert \valid_read(p + (int)q); [eva:alarm] tests/value/deps_mixed.i:22: Warning: @@ -26,6 +28,10 @@ Called from tests/value/deps_mixed.i:22. [eva] Recording results for f [eva] Done for function f +[eva:alarm] tests/value/deps_mixed.i:24: Warning: + pointer downcast. assert (unsigned int)q ≤ 2147483647; +[eva:alarm] tests/value/deps_mixed.i:24: Warning: + pointer downcast. assert (unsigned int)p + (int)q ≤ 2147483647; [eva] tests/value/deps_mixed.i:24: Assigning imprecise value to __retres. The imprecision originates from Arithmetic {tests/value/deps_mixed.i:24} diff --git a/tests/value/oracle/div.0.res.oracle b/tests/value/oracle/div.0.res.oracle index b0c33659a01..4f8b786e02d 100644 --- a/tests/value/oracle/div.0.res.oracle +++ b/tests/value/oracle/div.0.res.oracle @@ -35,6 +35,8 @@ signed overflow. assert X + 1 ≤ 2147483647; [eva:alarm] tests/value/div.i:32: Warning: division by zero. assert Z2 ≢ 0; [eva:alarm] tests/value/div.i:33: Warning: division by zero. assert Z2 ≢ 0; +[eva:alarm] tests/value/div.i:33: Warning: + pointer downcast. assert (unsigned int)&Z2 ≤ 2147483647; [eva:alarm] tests/value/div.i:33: Warning: signed overflow. assert -2147483648 ≤ (int)(&Z2) / Z2; [eva:alarm] tests/value/div.i:33: Warning: @@ -42,6 +44,8 @@ [eva] tests/value/div.i:33: Assigning imprecise value to b. The imprecision originates from Arithmetic {tests/value/div.i:33} +[eva:alarm] tests/value/div.i:34: Warning: + pointer downcast. assert (unsigned int)&X + 2 ≤ 2147483647; [eva:alarm] tests/value/div.i:34: Warning: division by zero. assert (int)(&X + 2) ≢ 0; [eva:alarm] tests/value/div.i:34: Warning: @@ -51,6 +55,8 @@ [eva] tests/value/div.i:34: Assigning imprecise value to d2. The imprecision originates from Arithmetic {tests/value/div.i:34} +[eva:alarm] tests/value/div.i:35: Warning: + pointer downcast. assert (unsigned int)&X + 1 ≤ 2147483647; [eva:alarm] tests/value/div.i:35: Warning: signed overflow. assert -2147483648 ≤ 100 / (int)(&X + 1); [eva:alarm] tests/value/div.i:35: Warning: @@ -58,6 +64,8 @@ [eva] tests/value/div.i:35: Assigning imprecise value to d1. The imprecision originates from Arithmetic {tests/value/div.i:35} +[eva:alarm] tests/value/div.i:36: Warning: + pointer downcast. assert (unsigned int)&X ≤ 2147483647; [eva:alarm] tests/value/div.i:36: Warning: signed overflow. assert -2147483648 ≤ 100 / (int)(&X); [eva:alarm] tests/value/div.i:36: Warning: @@ -65,6 +73,8 @@ [eva] tests/value/div.i:36: Assigning imprecise value to d0. The imprecision originates from Arithmetic {tests/value/div.i:36} +[eva:alarm] tests/value/div.i:37: Warning: + pointer downcast. assert (unsigned int)&X ≤ 2147483647; [eva:alarm] tests/value/div.i:37: Warning: signed overflow. assert -2147483648 ≤ -((int)(&X)); [eva:alarm] tests/value/div.i:37: Warning: @@ -74,7 +84,7 @@ The imprecision originates from Arithmetic {tests/value/div.i:37} [eva] Recording results for main [eva] done for function main -[scope:rm_asserts] removing 1 assertion(s) +[scope:rm_asserts] removing 2 assertion(s) [eva] ====== VALUES COMPUTED ====== [eva:final-states] Values at end of function main: X ∈ [--..--] diff --git a/tests/value/oracle/div.1.res.oracle b/tests/value/oracle/div.1.res.oracle index e333aa05c13..02145cd0576 100644 --- a/tests/value/oracle/div.1.res.oracle +++ b/tests/value/oracle/div.1.res.oracle @@ -55,6 +55,8 @@ [eva:alarm] tests/value/div.i:33: Warning: assertion 'rte,signed_overflow' got status unknown. [eva:alarm] tests/value/div.i:33: Warning: division by zero. assert Z2 ≢ 0; +[eva:alarm] tests/value/div.i:33: Warning: + pointer downcast. assert (unsigned int)&Z2 ≤ 2147483647; [eva:alarm] tests/value/div.i:33: Warning: signed overflow. assert -2147483648 ≤ (int)(&Z2) / Z2; [eva:alarm] tests/value/div.i:33: Warning: @@ -64,6 +66,8 @@ The imprecision originates from Arithmetic {tests/value/div.i:33} [eva:alarm] tests/value/div.i:34: Warning: assertion 'rte,division_by_zero' got status unknown. +[eva:alarm] tests/value/div.i:34: Warning: + pointer downcast. assert (unsigned int)&X + 2 ≤ 2147483647; [eva:alarm] tests/value/div.i:34: Warning: division by zero. assert (int)(&X + 2) ≢ 0; [eva:alarm] tests/value/div.i:34: Warning: @@ -74,6 +78,8 @@ Assigning imprecise value to d2. The imprecision originates from Arithmetic {tests/value/div.i:34} [eva] tests/value/div.i:35: assertion 'rte,division_by_zero' got status valid. +[eva:alarm] tests/value/div.i:35: Warning: + pointer downcast. assert (unsigned int)&X + 1 ≤ 2147483647; [eva:alarm] tests/value/div.i:35: Warning: signed overflow. assert -2147483648 ≤ 100 / (int)(&X + 1); [eva:alarm] tests/value/div.i:35: Warning: @@ -82,6 +88,8 @@ Assigning imprecise value to d1. The imprecision originates from Arithmetic {tests/value/div.i:35} [eva] tests/value/div.i:36: assertion 'rte,division_by_zero' got status valid. +[eva:alarm] tests/value/div.i:36: Warning: + pointer downcast. assert (unsigned int)&X ≤ 2147483647; [eva:alarm] tests/value/div.i:36: Warning: signed overflow. assert -2147483648 ≤ 100 / (int)(&X); [eva:alarm] tests/value/div.i:36: Warning: @@ -91,6 +99,8 @@ The imprecision originates from Arithmetic {tests/value/div.i:36} [eva:alarm] tests/value/div.i:37: Warning: assertion 'rte,signed_overflow' got status unknown. +[eva:alarm] tests/value/div.i:37: Warning: + pointer downcast. assert (unsigned int)&X ≤ 2147483647; [eva:alarm] tests/value/div.i:37: Warning: signed overflow. assert -2147483648 ≤ -((int)(&X)); [eva:alarm] tests/value/div.i:37: Warning: @@ -110,7 +120,7 @@ assertion 'rte,division_by_zero' got final status valid. [eva] tests/value/div.i:36: assertion 'rte,division_by_zero' got final status valid. -[scope:rm_asserts] removing 1 assertion(s) +[scope:rm_asserts] removing 2 assertion(s) [eva] ====== VALUES COMPUTED ====== [eva:final-states] Values at end of function main: X ∈ [--..--] diff --git a/tests/value/oracle/downcast.res.oracle b/tests/value/oracle/downcast.res.oracle index 18b563a5f18..2e160ded6f0 100644 --- a/tests/value/oracle/downcast.res.oracle +++ b/tests/value/oracle/downcast.res.oracle @@ -71,12 +71,11 @@ [eva:alarm] tests/value/downcast.i:87: Warning: signed downcast. assert e_1 ≤ 32767; [eva:alarm] tests/value/downcast.i:91: Warning: - signed downcast. assert p ≤ 2147483647; + pointer downcast. assert (unsigned int)p ≤ 2147483647; [eva:alarm] tests/value/downcast.i:92: Warning: - signed downcast. assert p ≤ 32767; -[eva] tests/value/downcast.i:93: - Assigning imprecise value to z. - The imprecision originates from Arithmetic {tests/value/downcast.i:93} + pointer downcast. assert (unsigned int)p ≤ 32767; +[eva:alarm] tests/value/downcast.i:93: Warning: + pointer downcast. assert (unsigned int)p ≤ 65535; [eva] Recording results for main6_val_warn_converted_signed [eva] Done for function main6_val_warn_converted_signed [eva] computing for function main7_signed_upcast <- main. @@ -354,9 +353,11 @@ [ Alarm ] Assertion 'Eva,signed_downcast' (file tests/value/downcast.i, line 87) By Eva, with pending: - Unreachable initialization of 'b_1' (file tests/value/downcast.i, line 87) -[ - ] Assertion 'Eva,signed_downcast' (file tests/value/downcast.i, line 91) +[ - ] Assertion 'Eva,pointer_downcast' (file tests/value/downcast.i, line 91) tried with Eva. -[ - ] Assertion 'Eva,signed_downcast' (file tests/value/downcast.i, line 92) +[ - ] Assertion 'Eva,pointer_downcast' (file tests/value/downcast.i, line 92) + tried with Eva. +[ - ] Assertion 'Eva,pointer_downcast' (file tests/value/downcast.i, line 93) tried with Eva. -------------------------------------------------------------------------------- @@ -407,11 +408,11 @@ --- Status Report Summary -------------------------------------------------------------------------------- 2 Completely validated - 14 To be validated + 15 To be validated 11 Alarms emitted 1 Dead property 1 Unreachable - 29 Total + 30 Total -------------------------------------------------------------------------------- /* Generated by Frama-C */ struct s { @@ -536,10 +537,11 @@ void main6_val_warn_converted_signed(void) } if (v) { int *p = (int *)(& v); - /*@ assert Eva: signed_downcast: p ≤ 2147483647; */ + /*@ assert Eva: pointer_downcast: (unsigned int)p ≤ 2147483647; */ int x_0 = (int)p; - /*@ assert Eva: signed_downcast: p ≤ 32767; */ + /*@ assert Eva: pointer_downcast: (unsigned int)p ≤ 32767; */ short y = (short)p; + /*@ assert Eva: pointer_downcast: (unsigned int)p ≤ 65535; */ unsigned short z = (unsigned short)p; } return; @@ -691,11 +693,12 @@ void main(void) unsigned downcast. assert 0 ≤ (int)(-12); [eva:alarm] tests/value/downcast.i:86: Warning: unsigned downcast. assert 0 ≤ (int)(-64000); -[eva] tests/value/downcast.i:92: - Assigning imprecise value to y. - The imprecision originates from Arithmetic {tests/value/downcast.i:92} +[eva:alarm] tests/value/downcast.i:91: Warning: + pointer downcast. assert (unsigned int)p ≤ 2147483647; +[eva:alarm] tests/value/downcast.i:92: Warning: + pointer downcast. assert (unsigned int)p ≤ 32767; [eva:alarm] tests/value/downcast.i:93: Warning: - unsigned downcast. assert p ≤ 65535; + pointer downcast. assert (unsigned int)p ≤ 65535; [eva] Recording results for main6_val_warn_converted_signed [eva] Done for function main6_val_warn_converted_signed [eva] computing for function main7_signed_upcast <- main. @@ -942,7 +945,11 @@ void main(void) [ Alarm ] Assertion 'Eva,unsigned_downcast' (file tests/value/downcast.i, line 86) By Eva, with pending: - Unreachable initialization of 'e_1' (file tests/value/downcast.i, line 86) -[ - ] Assertion 'Eva,unsigned_downcast' (file tests/value/downcast.i, line 93) +[ - ] Assertion 'Eva,pointer_downcast' (file tests/value/downcast.i, line 91) + tried with Eva. +[ - ] Assertion 'Eva,pointer_downcast' (file tests/value/downcast.i, line 92) + tried with Eva. +[ - ] Assertion 'Eva,pointer_downcast' (file tests/value/downcast.i, line 93) tried with Eva. -------------------------------------------------------------------------------- @@ -965,9 +972,9 @@ void main(void) --- Status Report Summary -------------------------------------------------------------------------------- 2 Completely validated - 15 To be validated + 17 To be validated 3 Alarms emitted - 20 Total + 22 Total -------------------------------------------------------------------------------- /* Generated by Frama-C */ struct s { @@ -1092,9 +1099,11 @@ void main6_val_warn_converted_signed(void) } if (v) { int *p = (int *)(& v); + /*@ assert Eva: pointer_downcast: (unsigned int)p ≤ 2147483647; */ int x_0 = (int)p; + /*@ assert Eva: pointer_downcast: (unsigned int)p ≤ 32767; */ short y = (short)p; - /*@ assert Eva: unsigned_downcast: p ≤ 65535; */ + /*@ assert Eva: pointer_downcast: (unsigned int)p ≤ 65535; */ unsigned short z = (unsigned short)p; } return; @@ -1235,10 +1244,12 @@ void main(void) signed downcast. assert (int)65300u ≤ 32767; [eva:alarm] tests/value/downcast.i:87: Warning: signed downcast. assert -32768 ≤ (int)e_1; +[eva:alarm] tests/value/downcast.i:91: Warning: + pointer downcast. assert (unsigned int)p ≤ 2147483647; [eva:alarm] tests/value/downcast.i:92: Warning: - signed downcast. assert -32768 ≤ (int)p; -[eva:alarm] tests/value/downcast.i:92: Warning: - signed downcast. assert (int)p ≤ 32767; + pointer downcast. assert (unsigned int)p ≤ 32767; +[eva:alarm] tests/value/downcast.i:93: Warning: + pointer downcast. assert (unsigned int)p ≤ 65535; [eva] Recording results for main6_val_warn_converted_signed [eva] Done for function main6_val_warn_converted_signed [eva] computing for function main7_signed_upcast <- main. @@ -1483,9 +1494,11 @@ void main(void) [ Alarm ] Assertion 'Eva,signed_downcast' (file tests/value/downcast.i, line 87) By Eva, with pending: - Unreachable initialization of 'b_1' (file tests/value/downcast.i, line 87) -[ - ] Assertion 'Eva,signed_downcast' (file tests/value/downcast.i, line 92) +[ - ] Assertion 'Eva,pointer_downcast' (file tests/value/downcast.i, line 91) + tried with Eva. +[ - ] Assertion 'Eva,pointer_downcast' (file tests/value/downcast.i, line 92) tried with Eva. -[ - ] Assertion 'Eva,signed_downcast' (file tests/value/downcast.i, line 92) +[ - ] Assertion 'Eva,pointer_downcast' (file tests/value/downcast.i, line 93) tried with Eva. -------------------------------------------------------------------------------- @@ -1525,9 +1538,9 @@ void main(void) --- Status Report Summary -------------------------------------------------------------------------------- 2 Completely validated - 14 To be validated + 15 To be validated 7 Alarms emitted - 23 Total + 24 Total -------------------------------------------------------------------------------- /* Generated by Frama-C */ struct s { @@ -1650,10 +1663,11 @@ void main6_val_warn_converted_signed(void) } if (v) { int *p = (int *)(& v); + /*@ assert Eva: pointer_downcast: (unsigned int)p ≤ 2147483647; */ int x_0 = (int)p; - /*@ assert Eva: signed_downcast: -32768 ≤ (int)p; */ - /*@ assert Eva: signed_downcast: (int)p ≤ 32767; */ + /*@ assert Eva: pointer_downcast: (unsigned int)p ≤ 32767; */ short y = (short)p; + /*@ assert Eva: pointer_downcast: (unsigned int)p ≤ 65535; */ unsigned short z = (unsigned short)p; } return; diff --git a/tests/value/oracle/eval_separated.res.oracle b/tests/value/oracle/eval_separated.res.oracle index 0c3fea76b47..60f0db91f1e 100644 --- a/tests/value/oracle/eval_separated.res.oracle +++ b/tests/value/oracle/eval_separated.res.oracle @@ -11,6 +11,8 @@ [eva] tests/value/eval_separated.c:6: assertion got status valid. [eva] tests/value/eval_separated.c:8: assertion got status valid. [eva] tests/value/eval_separated.c:9: assertion got status valid. +[eva:alarm] tests/value/eval_separated.c:11: Warning: + pointer downcast. assert (unsigned int)&q ≤ 2147483647; [eva:alarm] tests/value/eval_separated.c:11: Warning: signed overflow. assert -2147483648 ≤ (int)(&q) + (int)(&q); [eva:alarm] tests/value/eval_separated.c:11: Warning: @@ -18,6 +20,8 @@ [eva] tests/value/eval_separated.c:11: Assigning imprecise value to q. The imprecision originates from Arithmetic {tests/value/eval_separated.c:11} +[eva:alarm] tests/value/eval_separated.c:12: Warning: + pointer downcast. assert (unsigned int)&r ≤ 2147483647; [eva:alarm] tests/value/eval_separated.c:12: Warning: signed overflow. assert -2147483648 ≤ (int)(&r) + (int)(&r); [eva:alarm] tests/value/eval_separated.c:12: Warning: diff --git a/tests/value/oracle/from_call.0.res.oracle b/tests/value/oracle/from_call.0.res.oracle index 5f8aacfb014..f06f8231e21 100644 --- a/tests/value/oracle/from_call.0.res.oracle +++ b/tests/value/oracle/from_call.0.res.oracle @@ -1,6 +1,10 @@ [kernel] Parsing tests/value/from_call.i (no preprocessing) [eva] Analyzing a complete application starting at main [eva] Computing initial state +[eva:alarm] tests/value/from_call.i:70: Warning: + pointer downcast. assert (unsigned int)&AA ≤ 2147483647; +[eva:alarm] tests/value/from_call.i:71: Warning: + pointer downcast. assert (unsigned int)&AA ≤ 2147483647; [eva] Initial state computed [eva:initial-state] Values of globals at initialization a ∈ {0} diff --git a/tests/value/oracle/from_call.1.res.oracle b/tests/value/oracle/from_call.1.res.oracle index e8c864534dc..a11fbdf9fa2 100644 --- a/tests/value/oracle/from_call.1.res.oracle +++ b/tests/value/oracle/from_call.1.res.oracle @@ -1,6 +1,10 @@ [kernel] Parsing tests/value/from_call.i (no preprocessing) [eva] Analyzing a complete application starting at main [eva] Computing initial state +[eva:alarm] tests/value/from_call.i:70: Warning: + pointer downcast. assert (unsigned int)&AA ≤ 2147483647; +[eva:alarm] tests/value/from_call.i:71: Warning: + pointer downcast. assert (unsigned int)&AA ≤ 2147483647; [eva] Initial state computed [eva:initial-state] Values of globals at initialization a ∈ {0} diff --git a/tests/value/oracle/from_ptr.0.res.oracle b/tests/value/oracle/from_ptr.0.res.oracle index 46f997dc35f..f58c5770d44 100644 --- a/tests/value/oracle/from_ptr.0.res.oracle +++ b/tests/value/oracle/from_ptr.0.res.oracle @@ -15,6 +15,10 @@ b ∈ {0} p[0..9][0..9][0..9] ∈ {0} q ∈ {0} +[eva:alarm] tests/value/from_ptr.i:12: Warning: + pointer downcast. assert (unsigned int)&p[11] ≤ 2147483647; +[eva:alarm] tests/value/from_ptr.i:13: Warning: + pointer downcast. assert (unsigned int)&p[10] ≤ 2147483647; [eva:alarm] tests/value/from_ptr.i:17: Warning: out of bounds write. assert \valid((int *)i); [kernel] tests/value/from_ptr.i:17: Warning: diff --git a/tests/value/oracle/from_ptr.1.res.oracle b/tests/value/oracle/from_ptr.1.res.oracle index f1dd5f2cc2c..d1824131817 100644 --- a/tests/value/oracle/from_ptr.1.res.oracle +++ b/tests/value/oracle/from_ptr.1.res.oracle @@ -15,6 +15,10 @@ b ∈ {0} p[0..9][0..9][0..9] ∈ {0} q ∈ {0} +[eva:alarm] tests/value/from_ptr.i:24: Warning: + pointer downcast. assert (unsigned int)&p[1] ≤ 2147483647; +[eva:alarm] tests/value/from_ptr.i:25: Warning: + pointer downcast. assert (unsigned int)(int (*)[10][10])p ≤ 2147483647; [eva] Recording results for main1 [eva] done for function main1 [eva] ====== VALUES COMPUTED ====== diff --git a/tests/value/oracle/fun_ptr.1.res.oracle b/tests/value/oracle/fun_ptr.1.res.oracle index f8b69ef751a..f99360712b5 100644 --- a/tests/value/oracle/fun_ptr.1.res.oracle +++ b/tests/value/oracle/fun_ptr.1.res.oracle @@ -8,6 +8,10 @@ expected 'short *' but got argument of type 'int *': & x [eva] Analyzing a complete application starting at main [eva] Computing initial state +[eva:alarm] tests/value/fun_ptr.i:21: Warning: + pointer downcast. assert (unsigned __int64)&f ≤ 9223372036854775807; +[eva:alarm] tests/value/fun_ptr.i:21: Warning: + pointer downcast. assert (unsigned __int64)&g ≤ 9223372036854775807; [eva] Initial state computed [eva:initial-state] Values of globals at initialization t[0] ∈ {{ (__int64)&f }} diff --git a/tests/value/oracle/gauges.res.oracle b/tests/value/oracle/gauges.res.oracle index fa19ee9d0ef..7cf52beab44 100644 --- a/tests/value/oracle/gauges.res.oracle +++ b/tests/value/oracle/gauges.res.oracle @@ -240,6 +240,10 @@ [eva] computing for function main9 <- main. Called from tests/value/gauges.c:361. [eva] tests/value/gauges.c:186: starting to merge loop iterations +[eva:alarm] tests/value/gauges.c:188: Warning: + pointer downcast. assert (unsigned int)p ≤ 2147483647; +[eva:alarm] tests/value/gauges.c:188: Warning: + pointer downcast. assert (unsigned int)q ≤ 2147483647; [eva:alarm] tests/value/gauges.c:188: Warning: signed overflow. assert -2147483648 ≤ (int)p + (int)q; [eva:alarm] tests/value/gauges.c:188: Warning: diff --git a/tests/value/oracle/imprecise_invalid_write.res.oracle b/tests/value/oracle/imprecise_invalid_write.res.oracle index 3442108db92..611d2093add 100644 --- a/tests/value/oracle/imprecise_invalid_write.res.oracle +++ b/tests/value/oracle/imprecise_invalid_write.res.oracle @@ -21,6 +21,8 @@ [eva] Done for function main1 [eva] computing for function main2 <- main. Called from tests/value/imprecise_invalid_write.i:25. +[eva:alarm] tests/value/imprecise_invalid_write.i:9: Warning: + pointer downcast. assert (unsigned int)&main1 ≤ 2147483647; [eva] tests/value/imprecise_invalid_write.i:9: Assigning imprecise value to p. The imprecision originates from Arithmetic @@ -33,6 +35,8 @@ [eva] Done for function main2 [eva] computing for function main3 <- main. Called from tests/value/imprecise_invalid_write.i:28. +[eva:alarm] tests/value/imprecise_invalid_write.i:16: Warning: + pointer downcast. assert (unsigned int)s ≤ 2147483647; [eva] tests/value/imprecise_invalid_write.i:16: Assigning imprecise value to p. The imprecision originates from Arithmetic diff --git a/tests/value/oracle/initialized.res.oracle b/tests/value/oracle/initialized.res.oracle index f3d1c20aa17..8ca94ab19cf 100644 --- a/tests/value/oracle/initialized.res.oracle +++ b/tests/value/oracle/initialized.res.oracle @@ -66,6 +66,8 @@ [eva] Done for function g1 [eva] computing for function g2 <- main. Called from tests/value/initialized.c:194. +[eva:alarm] tests/value/initialized.c:50: Warning: + pointer downcast. assert (unsigned int)&b4 ≤ 2147483647; [eva:alarm] tests/value/initialized.c:50: Warning: signed overflow. assert -2147483648 ≤ (int)(&b4) + (int)(&b4); [eva:alarm] tests/value/initialized.c:50: Warning: diff --git a/tests/value/oracle/join_misaligned.res.oracle b/tests/value/oracle/join_misaligned.res.oracle index cb31ee65e40..2194180b285 100644 --- a/tests/value/oracle/join_misaligned.res.oracle +++ b/tests/value/oracle/join_misaligned.res.oracle @@ -14,6 +14,10 @@ z[0..4] ∈ {255} a ∈ {0} va ∈ [--..--] +[eva:alarm] tests/value/join_misaligned.i:23: Warning: + pointer downcast. assert (unsigned int)&t ≤ 2147483647; +[eva:alarm] tests/value/join_misaligned.i:37: Warning: + pointer downcast. assert (unsigned int)&u ≤ 2147483647; [eva] Recording results for main [eva] done for function main [eva:garbled-mix] Warning: diff --git a/tests/value/oracle/label.res.oracle b/tests/value/oracle/label.res.oracle index a7dfd612adb..3c3c61be0c2 100644 --- a/tests/value/oracle/label.res.oracle +++ b/tests/value/oracle/label.res.oracle @@ -10,6 +10,8 @@ i ∈ {0} p ∈ {0} q ∈ {0} +[eva:alarm] tests/value/label.i:14: Warning: + pointer downcast. assert (unsigned int)&d + 1 ≤ 2147483647; [eva] tests/value/label.i:18: Assigning imprecise value to *((char *)(& p) + i) (pointing to p with offsets {0}). diff --git a/tests/value/oracle/leaf2.res.oracle b/tests/value/oracle/leaf2.res.oracle index db427e105c3..41082946d0a 100644 --- a/tests/value/oracle/leaf2.res.oracle +++ b/tests/value/oracle/leaf2.res.oracle @@ -6,6 +6,8 @@ G ∈ {0} H ∈ {0} I ∈ {0} +[eva:alarm] tests/value/leaf2.i:6: Warning: + pointer downcast. assert (unsigned int)&I ≤ 2147483647; [eva] computing for function f <- main. Called from tests/value/leaf2.i:6. [kernel:annot:missing-spec] tests/value/leaf2.i:6: Warning: diff --git a/tests/value/oracle/mini_pointrer.res.oracle b/tests/value/oracle/mini_pointrer.res.oracle index 2c0b41b4d4a..65092ae89c4 100644 --- a/tests/value/oracle/mini_pointrer.res.oracle +++ b/tests/value/oracle/mini_pointrer.res.oracle @@ -11,6 +11,8 @@ accessing out of bounds index. assert 0 ≤ c1; [eva:alarm] tests/value/mini_pointrer.i:6: Warning: accessing out of bounds index. assert c1 < 2; +[eva:alarm] tests/value/mini_pointrer.i:6: Warning: + pointer downcast. assert (unsigned int)&T[c1] ≤ 2147483647; [eva:alarm] tests/value/mini_pointrer.i:8: Warning: out of bounds read. assert \valid_read(ppp); [eva:alarm] tests/value/mini_pointrer.i:8: Warning: diff --git a/tests/value/oracle/nonlin.res.oracle b/tests/value/oracle/nonlin.res.oracle index de062d28c58..b5be0d8bcaa 100644 --- a/tests/value/oracle/nonlin.res.oracle +++ b/tests/value/oracle/nonlin.res.oracle @@ -63,6 +63,8 @@ [eva:nonlin] tests/value/nonlin.c:21: subdividing on i [eva:alarm] tests/value/nonlin.c:21: Warning: out of bounds read. assert \valid_read((p + i) - i); +[eva:alarm] tests/value/nonlin.c:23: Warning: + pointer downcast. assert (unsigned int)&x ≤ 2147483647; [eva:alarm] tests/value/nonlin.c:24: Warning: out of bounds read. assert \valid_read((p + i) - i); [eva] Recording results for subdivide_pointer diff --git a/tests/value/oracle/not_ct_array_arg.res.oracle b/tests/value/oracle/not_ct_array_arg.res.oracle index b6c5638c803..776fa403f15 100644 --- a/tests/value/oracle/not_ct_array_arg.res.oracle +++ b/tests/value/oracle/not_ct_array_arg.res.oracle @@ -24,6 +24,8 @@ ==END OF DUMP== [eva:alarm] tests/value/not_ct_array_arg.i:12: Warning: out of bounds write. assert \valid(&(*(tb + 9))[100]); +[eva:alarm] tests/value/not_ct_array_arg.i:12: Warning: + pointer downcast. assert (unsigned int)&tb ≤ 2147483647; [eva] tests/value/not_ct_array_arg.i:13: Frama_C_dump_each: # Cvalue domain: diff --git a/tests/value/oracle/offset_top.res.oracle b/tests/value/oracle/offset_top.res.oracle index bc18f222647..6c6287b4bff 100644 --- a/tests/value/oracle/offset_top.res.oracle +++ b/tests/value/oracle/offset_top.res.oracle @@ -6,6 +6,8 @@ NULL[rbits 0 to 2047] ∈ [--..--] T ∈ {0} TAB[0..9] ∈ {0} +[eva:alarm] tests/value/offset_top.i:10: Warning: + pointer downcast. assert (unsigned int)&TAB[*T] ≤ 2147483647; [eva] Recording results for main [eva] done for function main [eva] ====== VALUES COMPUTED ====== diff --git a/tests/value/oracle/offsetmap.0.res.oracle b/tests/value/oracle/offsetmap.0.res.oracle index ed60e2eb746..2a076ba31dc 100644 --- a/tests/value/oracle/offsetmap.0.res.oracle +++ b/tests/value/oracle/offsetmap.0.res.oracle @@ -27,6 +27,8 @@ Called from tests/value/offsetmap.i:75. [eva] tests/value/offsetmap.i:19: starting to merge loop iterations [eva] tests/value/offsetmap.i:29: starting to merge loop iterations +[eva:alarm] tests/value/offsetmap.i:51: Warning: + pointer downcast. assert (unsigned int)&x2 ≤ 2147483647; [eva] Recording results for f [eva] Done for function f [eva] computing for function g <- main. diff --git a/tests/value/oracle/offsetmap.1.res.oracle b/tests/value/oracle/offsetmap.1.res.oracle index dbf10008a7f..115819f9674 100644 --- a/tests/value/oracle/offsetmap.1.res.oracle +++ b/tests/value/oracle/offsetmap.1.res.oracle @@ -27,6 +27,8 @@ Called from tests/value/offsetmap.i:75. [eva] tests/value/offsetmap.i:19: starting to merge loop iterations [eva] tests/value/offsetmap.i:29: starting to merge loop iterations +[eva:alarm] tests/value/offsetmap.i:51: Warning: + pointer downcast. assert (unsigned int)&x2 ≤ 2147483647; [eva] Recording results for f [eva] Done for function f [eva] computing for function g <- main. diff --git a/tests/value/oracle/origin.0.res.oracle b/tests/value/oracle/origin.0.res.oracle index 64ee1af6621..cd433bd1e2f 100644 --- a/tests/value/oracle/origin.0.res.oracle +++ b/tests/value/oracle/origin.0.res.oracle @@ -54,6 +54,8 @@ S_gpp[0..1] ∈ [--..--] [eva] computing for function origin_arithmetic_1 <- main. Called from tests/value/origin.i:94. +[eva:alarm] tests/value/origin.i:14: Warning: + pointer downcast. assert (unsigned int)(int *)ta1 ≤ 2147483647; [eva:alarm] tests/value/origin.i:14: Warning: signed overflow. assert -2147483648 ≤ -((int)((int *)ta1)); [eva:alarm] tests/value/origin.i:14: Warning: @@ -67,6 +69,8 @@ [eva] Done for function origin_arithmetic_1 [eva] computing for function origin_arithmetic_2 <- main. Called from tests/value/origin.i:95. +[eva:alarm] tests/value/origin.i:19: Warning: + pointer downcast. assert (unsigned int)(int *)ta2 ≤ 2147483647; [eva:alarm] tests/value/origin.i:19: Warning: signed overflow. assert -2147483648 ≤ -((int)((int *)ta2)); [eva:alarm] tests/value/origin.i:19: Warning: @@ -77,6 +81,8 @@ [eva] tests/value/origin.i:20: Assigning imprecise value to qa2. The imprecision originates from Arithmetic {tests/value/origin.i:19} +[eva:alarm] tests/value/origin.i:20: Warning: + pointer downcast. assert (unsigned int)(int *)tta2 ≤ 2147483647; [eva:alarm] tests/value/origin.i:20: Warning: signed overflow. assert -2147483648 ≤ -((int)((int *)tta2)); [eva:alarm] tests/value/origin.i:20: Warning: @@ -86,10 +92,14 @@ The imprecision originates from Arithmetic {tests/value/origin.i:20} [eva:alarm] tests/value/origin.i:21: Warning: out of bounds write. assert \valid(qa2); +[eva:alarm] tests/value/origin.i:21: Warning: + pointer downcast. assert (unsigned int)&aa2 ≤ 2147483647; [eva] Recording results for origin_arithmetic_2 [eva] Done for function origin_arithmetic_2 [eva] computing for function origin_arithmetic_3 <- main. Called from tests/value/origin.i:96. +[eva:alarm] tests/value/origin.i:25: Warning: + pointer downcast. assert (unsigned int)(int *)ta3 ≤ 2147483647; [eva:alarm] tests/value/origin.i:25: Warning: signed overflow. assert -2147483648 ≤ -((int)((int *)ta3)); [eva:alarm] tests/value/origin.i:25: Warning: @@ -148,6 +158,8 @@ {{ garbled mix of &{a; b} (origin: Misaligned {tests/value/origin.i:54}) }} [eva:alarm] tests/value/origin.i:56: Warning: out of bounds write. assert \valid(qm2); +[eva:alarm] tests/value/origin.i:56: Warning: + pointer downcast. assert (unsigned int)&a ≤ 2147483647; [eva] Recording results for origin_misalign_2 [eva] Done for function origin_misalign_2 [eva] computing for function origin_uninitialized_1 <- main. @@ -166,6 +178,12 @@ [eva] Done for function origin_uninitialized_2 [eva] computing for function local_escape_1 <- main. Called from tests/value/origin.i:108. +[eva:alarm] tests/value/origin.i:83: Warning: + pointer downcast. assert (unsigned int)&arg ≤ 2147483647; +[eva:alarm] tests/value/origin.i:84: Warning: + pointer downcast. assert (unsigned int)&local1 ≤ 2147483647; +[eva:alarm] tests/value/origin.i:85: Warning: + pointer downcast. assert (unsigned int)&arg ≤ 2147483647; [eva:alarm] tests/value/origin.i:85: Warning: signed overflow. assert -2147483648 ≤ -((int)(&arg)); [eva:alarm] tests/value/origin.i:85: Warning: @@ -173,6 +191,10 @@ [eva] tests/value/origin.i:85: Assigning imprecise value to esc3. The imprecision originates from Arithmetic {tests/value/origin.i:85} +[eva:alarm] tests/value/origin.i:87: Warning: + pointer downcast. assert (unsigned int)&local1 ≤ 2147483647; +[eva:alarm] tests/value/origin.i:88: Warning: + pointer downcast. assert (unsigned int)&esc1 ≤ 2147483647; [eva] Recording results for local_escape_1 [eva] Done for function local_escape_1 [eva:locals-escaping] tests/value/origin.i:108: Warning: @@ -187,6 +209,7 @@ [eva] done for function main [eva] tests/value/origin.i:75: assertion 'Eva,initialization' got final status invalid. +[scope:rm_asserts] removing 2 assertion(s) [eva] ====== VALUES COMPUTED ====== [eva:final-states] Values at end of function local_escape_1: esc1 ∈ {{ (int)&arg }} diff --git a/tests/value/oracle/origin.1.res.oracle b/tests/value/oracle/origin.1.res.oracle index b8a6b3cb99b..6e3283d9304 100644 --- a/tests/value/oracle/origin.1.res.oracle +++ b/tests/value/oracle/origin.1.res.oracle @@ -64,6 +64,8 @@ [eva] tests/value/origin.i:129: Assigning imprecise value to r.t[0]. The imprecision originates from Merge {tests/value/origin.i:129} +[eva:alarm] tests/value/origin.i:130: Warning: + pointer downcast. assert (unsigned int)&x ≤ 2147483647; [eva:alarm] tests/value/origin.i:130: Warning: signed overflow. assert -2147483648 ≤ -((int)(&x)); [eva:alarm] tests/value/origin.i:130: Warning: diff --git a/tests/value/oracle/period.res.oracle b/tests/value/oracle/period.res.oracle index 0283e81195e..156c9148c10 100644 --- a/tests/value/oracle/period.res.oracle +++ b/tests/value/oracle/period.res.oracle @@ -78,18 +78,25 @@ Gt ∈ {12} Ht ∈ {1} ==END OF DUMP== +[eva:alarm] tests/value/period.c:51: Warning: + pointer downcast. assert (unsigned int)&g ≤ 2147483647; [eva] tests/value/period.c:51: Assigning imprecise value to p. The imprecision originates from Arithmetic {tests/value/period.c:51} [eva:alarm] tests/value/period.c:52: Warning: out of bounds write. assert \valid(p); +[eva:alarm] tests/value/period.c:53: Warning: + pointer downcast. assert (unsigned int)&g ≤ 2147483647; [eva] tests/value/period.c:53: Assigning imprecise value to p. The imprecision originates from Arithmetic {tests/value/period.c:53} [eva:alarm] tests/value/period.c:54: Warning: out of bounds read. assert \valid_read(p); +[eva:alarm] tests/value/period.c:55: Warning: + pointer downcast. assert (unsigned int)&vg ≤ 2147483647; [eva] Recording results for main [eva] done for function main +[scope:rm_asserts] removing 1 assertion(s) [eva] ====== VALUES COMPUTED ====== [eva:final-states] Values at end of function main: g[0..9] ∈ diff --git a/tests/value/oracle/pointer_comparison.0.res.oracle b/tests/value/oracle/pointer_comparison.0.res.oracle index c58a323eab8..fcd954b8df5 100644 --- a/tests/value/oracle/pointer_comparison.0.res.oracle +++ b/tests/value/oracle/pointer_comparison.0.res.oracle @@ -18,6 +18,10 @@ [eva] tests/value/pointer_comparison.c:14: Frama_C_show_each_4: {{ &x + {16} }} [eva:pointer-comparison] tests/value/pointer_comparison.c:16: invalid pointer comparison: invalid pointer(s) +[eva:alarm] tests/value/pointer_comparison.c:16: Warning: + pointer downcast. assert (unsigned int)p ≤ 2147483647; +[eva:alarm] tests/value/pointer_comparison.c:16: Warning: + pointer downcast. assert (unsigned int)&y ≤ 2147483647; [eva] tests/value/pointer_comparison.c:16: Frama_C_show_each_5: {{ &x + {16} }} [eva] tests/value/pointer_comparison.c:17: Frama_C_show_each_5e: {{ &x + {16} }} [eva:pointer-comparison] tests/value/pointer_comparison.c:18: @@ -48,8 +52,23 @@ [inout] Inputs for function main: p [report] Computing properties status... + +-------------------------------------------------------------------------------- +--- Properties of Function 'main' +-------------------------------------------------------------------------------- + +[ - ] Assertion 'Eva,pointer_downcast' (file tests/value/pointer_comparison.c, line 16) + assert Eva: pointer_downcast: (unsigned int)p ≤ 2147483647; + tried with Eva. +[ - ] Assertion 'Eva,pointer_downcast' (file tests/value/pointer_comparison.c, line 16) + assert Eva: pointer_downcast: (unsigned int)&y ≤ 2147483647; + tried with Eva. + -------------------------------------------------------------------------------- ---- No status to report +--- Status Report Summary +-------------------------------------------------------------------------------- + 2 To be validated + 2 Total -------------------------------------------------------------------------------- [eva] Analyzing a complete application starting at main [eva] Computing initial state @@ -74,6 +93,10 @@ assert \pointer_comparable((void *)tmp_2, (void *)(&y)); (tmp_2 from p++) [eva] tests/value/pointer_comparison.c:14: Frama_C_show_each_4: {{ &x + {16} }} +[eva:alarm] tests/value/pointer_comparison.c:16: Warning: + pointer downcast. assert (unsigned int)p ≤ 2147483647; +[eva:alarm] tests/value/pointer_comparison.c:16: Warning: + pointer downcast. assert (unsigned int)&y ≤ 2147483647; [eva] tests/value/pointer_comparison.c:16: Frama_C_show_each_5: {{ &x + {16} }} [eva] tests/value/pointer_comparison.c:17: Frama_C_show_each_5e: {{ &x + {16} }} [eva:alarm] tests/value/pointer_comparison.c:18: Warning: @@ -125,6 +148,12 @@ Eva: ptr_comparison: \pointer_comparable((void *)tmp_2, (void *)(&y)); tried with Eva. +[ - ] Assertion 'Eva,pointer_downcast' (file tests/value/pointer_comparison.c, line 16) + assert Eva: pointer_downcast: (unsigned int)p ≤ 2147483647; + tried with Eva. +[ - ] Assertion 'Eva,pointer_downcast' (file tests/value/pointer_comparison.c, line 16) + assert Eva: pointer_downcast: (unsigned int)&y ≤ 2147483647; + tried with Eva. [ - ] Assertion 'Eva,ptr_comparison' (file tests/value/pointer_comparison.c, line 18) assert Eva: ptr_comparison: @@ -134,8 +163,8 @@ -------------------------------------------------------------------------------- --- Status Report Summary -------------------------------------------------------------------------------- - 4 To be validated - 4 Total + 6 To be validated + 6 Total -------------------------------------------------------------------------------- [eva] Analyzing a complete application starting at main [eva] Computing initial state @@ -160,6 +189,10 @@ assert \pointer_comparable((void *)tmp_2, (void *)(&y)); (tmp_2 from p++) [eva] tests/value/pointer_comparison.c:14: Frama_C_show_each_4: {{ &x + {16} }} +[eva:alarm] tests/value/pointer_comparison.c:16: Warning: + pointer downcast. assert (unsigned int)p ≤ 2147483647; +[eva:alarm] tests/value/pointer_comparison.c:16: Warning: + pointer downcast. assert (unsigned int)&y ≤ 2147483647; [eva:alarm] tests/value/pointer_comparison.c:16: Warning: pointer comparison. assert \pointer_comparable((void *)p, (void *)(&y)); [eva] tests/value/pointer_comparison.c:16: Frama_C_show_each_5: {{ &x + {16} }} @@ -213,6 +246,12 @@ Eva: ptr_comparison: \pointer_comparable((void *)tmp_2, (void *)(&y)); tried with Eva. +[ - ] Assertion 'Eva,pointer_downcast' (file tests/value/pointer_comparison.c, line 16) + assert Eva: pointer_downcast: (unsigned int)p ≤ 2147483647; + tried with Eva. +[ - ] Assertion 'Eva,pointer_downcast' (file tests/value/pointer_comparison.c, line 16) + assert Eva: pointer_downcast: (unsigned int)&y ≤ 2147483647; + tried with Eva. [ - ] Assertion 'Eva,ptr_comparison' (file tests/value/pointer_comparison.c, line 16) assert Eva: ptr_comparison: \pointer_comparable((void *)p, (void *)(&y)); @@ -226,6 +265,6 @@ -------------------------------------------------------------------------------- --- Status Report Summary -------------------------------------------------------------------------------- - 5 To be validated - 5 Total + 7 To be validated + 7 Total -------------------------------------------------------------------------------- diff --git a/tests/value/oracle/pointer_comparison.1.res.oracle b/tests/value/oracle/pointer_comparison.1.res.oracle index 890e9690c6c..af00458ed51 100644 --- a/tests/value/oracle/pointer_comparison.1.res.oracle +++ b/tests/value/oracle/pointer_comparison.1.res.oracle @@ -33,6 +33,10 @@ [eva] tests/value/pointer_comparison.c:15: Frama_C_show_each_4e: {{ &x + {16} }} [eva:pointer-comparison] tests/value/pointer_comparison.c:16: invalid pointer comparison: invalid pointer(s) +[eva:alarm] tests/value/pointer_comparison.c:16: Warning: + pointer downcast. assert (unsigned int)p ≤ 2147483647; +[eva:alarm] tests/value/pointer_comparison.c:16: Warning: + pointer downcast. assert (unsigned int)&y ≤ 2147483647; [eva] tests/value/pointer_comparison.c:16: Frama_C_show_each_5: {{ &x + {16} }} [eva] tests/value/pointer_comparison.c:17: Frama_C_show_each_5e: {{ &x + {16} }} [eva:pointer-comparison] tests/value/pointer_comparison.c:18: @@ -68,8 +72,23 @@ [inout] Inputs for function main: p [report] Computing properties status... + +-------------------------------------------------------------------------------- +--- Properties of Function 'main' +-------------------------------------------------------------------------------- + +[ - ] Assertion 'Eva,pointer_downcast' (file tests/value/pointer_comparison.c, line 16) + assert Eva: pointer_downcast: (unsigned int)p ≤ 2147483647; + tried with Eva. +[ - ] Assertion 'Eva,pointer_downcast' (file tests/value/pointer_comparison.c, line 16) + assert Eva: pointer_downcast: (unsigned int)&y ≤ 2147483647; + tried with Eva. + -------------------------------------------------------------------------------- ---- No status to report +--- Status Report Summary +-------------------------------------------------------------------------------- + 2 To be validated + 2 Total -------------------------------------------------------------------------------- [eva] Analyzing a complete application starting at main [eva] Computing initial state @@ -97,6 +116,10 @@ (tmp_2 from p++) [eva] tests/value/pointer_comparison.c:14: Frama_C_show_each_4: {{ &x + {16} }} [eva] tests/value/pointer_comparison.c:15: Frama_C_show_each_4e: {{ &x + {16} }} +[eva:alarm] tests/value/pointer_comparison.c:16: Warning: + pointer downcast. assert (unsigned int)p ≤ 2147483647; +[eva:alarm] tests/value/pointer_comparison.c:16: Warning: + pointer downcast. assert (unsigned int)&y ≤ 2147483647; [eva] tests/value/pointer_comparison.c:16: Frama_C_show_each_5: {{ &x + {16} }} [eva] tests/value/pointer_comparison.c:17: Frama_C_show_each_5e: {{ &x + {16} }} [eva:alarm] tests/value/pointer_comparison.c:18: Warning: @@ -149,6 +172,12 @@ Eva: ptr_comparison: \pointer_comparable((void *)tmp_2, (void *)(&y)); tried with Eva. +[ - ] Assertion 'Eva,pointer_downcast' (file tests/value/pointer_comparison.c, line 16) + assert Eva: pointer_downcast: (unsigned int)p ≤ 2147483647; + tried with Eva. +[ - ] Assertion 'Eva,pointer_downcast' (file tests/value/pointer_comparison.c, line 16) + assert Eva: pointer_downcast: (unsigned int)&y ≤ 2147483647; + tried with Eva. [ - ] Assertion 'Eva,ptr_comparison' (file tests/value/pointer_comparison.c, line 18) assert Eva: ptr_comparison: @@ -158,8 +187,8 @@ -------------------------------------------------------------------------------- --- Status Report Summary -------------------------------------------------------------------------------- - 4 To be validated - 4 Total + 6 To be validated + 6 Total -------------------------------------------------------------------------------- [eva] Analyzing a complete application starting at main [eva] Computing initial state @@ -187,6 +216,10 @@ (tmp_2 from p++) [eva] tests/value/pointer_comparison.c:14: Frama_C_show_each_4: {{ &x + {16} }} [eva] tests/value/pointer_comparison.c:15: Frama_C_show_each_4e: {{ &x + {16} }} +[eva:alarm] tests/value/pointer_comparison.c:16: Warning: + pointer downcast. assert (unsigned int)p ≤ 2147483647; +[eva:alarm] tests/value/pointer_comparison.c:16: Warning: + pointer downcast. assert (unsigned int)&y ≤ 2147483647; [eva:alarm] tests/value/pointer_comparison.c:16: Warning: pointer comparison. assert \pointer_comparable((void *)p, (void *)(&y)); [eva] tests/value/pointer_comparison.c:16: Frama_C_show_each_5: {{ &x + {16} }} @@ -241,6 +274,12 @@ Eva: ptr_comparison: \pointer_comparable((void *)tmp_2, (void *)(&y)); tried with Eva. +[ - ] Assertion 'Eva,pointer_downcast' (file tests/value/pointer_comparison.c, line 16) + assert Eva: pointer_downcast: (unsigned int)p ≤ 2147483647; + tried with Eva. +[ - ] Assertion 'Eva,pointer_downcast' (file tests/value/pointer_comparison.c, line 16) + assert Eva: pointer_downcast: (unsigned int)&y ≤ 2147483647; + tried with Eva. [ - ] Assertion 'Eva,ptr_comparison' (file tests/value/pointer_comparison.c, line 16) assert Eva: ptr_comparison: \pointer_comparable((void *)p, (void *)(&y)); @@ -254,6 +293,6 @@ -------------------------------------------------------------------------------- --- Status Report Summary -------------------------------------------------------------------------------- - 5 To be validated - 5 Total + 7 To be validated + 7 Total -------------------------------------------------------------------------------- diff --git a/tests/value/oracle/pointer_int_cast.res.oracle b/tests/value/oracle/pointer_int_cast.res.oracle index 078dfbbd5be..75c12b7d3ab 100644 --- a/tests/value/oracle/pointer_int_cast.res.oracle +++ b/tests/value/oracle/pointer_int_cast.res.oracle @@ -8,6 +8,8 @@ q ∈ {0} x ∈ {0} y ∈ {0} +[eva:alarm] tests/value/pointer_int_cast.i:9: Warning: + pointer downcast. assert (unsigned int)&y ≤ 2147483647; [eva] Recording results for g [eva] done for function g [eva] ====== VALUES COMPUTED ====== diff --git a/tests/value/oracle/shift.0.res.oracle b/tests/value/oracle/shift.0.res.oracle index aa83c00acb6..4e0d35dc30a 100644 --- a/tests/value/oracle/shift.0.res.oracle +++ b/tests/value/oracle/shift.0.res.oracle @@ -44,6 +44,8 @@ [eva] tests/value/shift.i:52: Assigning imprecise value to r. The imprecision originates from Arithmetic {tests/value/shift.i:52} +[eva:alarm] tests/value/shift.i:53: Warning: + pointer downcast. assert (unsigned int)(char *)t ≤ 2147483647; [eva:alarm] tests/value/shift.i:53: Warning: invalid LHS operand for left shift. assert 0 ≤ (long)((char *)t); [eva:alarm] tests/value/shift.i:53: Warning: diff --git a/tests/value/oracle/shift.1.res.oracle b/tests/value/oracle/shift.1.res.oracle index 076532ff712..46103bb62cc 100644 --- a/tests/value/oracle/shift.1.res.oracle +++ b/tests/value/oracle/shift.1.res.oracle @@ -38,6 +38,8 @@ [eva] tests/value/shift.i:52: Assigning imprecise value to r. The imprecision originates from Arithmetic {tests/value/shift.i:52} +[eva:alarm] tests/value/shift.i:53: Warning: + pointer downcast. assert (unsigned int)(char *)t ≤ 2147483647; [eva:alarm] tests/value/shift.i:53: Warning: signed overflow. assert -2147483648 ≤ (long)((char *)t) << 8; [eva:alarm] tests/value/shift.i:53: Warning: diff --git a/tests/value/oracle/sizeof.res.oracle b/tests/value/oracle/sizeof.res.oracle index 90ea60d5201..23b0674bd22 100644 --- a/tests/value/oracle/sizeof.res.oracle +++ b/tests/value/oracle/sizeof.res.oracle @@ -18,6 +18,8 @@ [eva] Done for function main1 [eva] computing for function main2 <- main. Called from tests/value/sizeof.i:41. +[eva:alarm] tests/value/sizeof.i:32: Warning: + pointer downcast. assert (unsigned int)&s1 ≤ 2147483647; [eva] tests/value/sizeof.i:32: Assigning imprecise value to p. The imprecision originates from Arithmetic {tests/value/sizeof.i:32} @@ -124,6 +126,7 @@ struct s s1; int volatile i; void main2(void) { + /*@ assert Eva: pointer_downcast: (unsigned int)&s1 ≤ 2147483647; */ struct s *p = (& s1 + (int)(& s1)) - (int)(& s1); /*@ assert Eva: index_bound: (unsigned int)(sizeof(s1.t) - (unsigned int)i) < 10; diff --git a/tests/value/oracle/struct3.res.oracle b/tests/value/oracle/struct3.res.oracle index 73e5ba0ea06..44c891f6674 100644 --- a/tests/value/oracle/struct3.res.oracle +++ b/tests/value/oracle/struct3.res.oracle @@ -19,6 +19,10 @@ accessing out of bounds index. assert 10 < 10; [kernel] tests/value/struct3.i:42: Warning: all target addresses were invalid. This path is assumed to be dead. +[eva:alarm] tests/value/struct3.i:46: Warning: + pointer downcast. assert (unsigned int)s2.c ≤ 2147483647; +[eva:alarm] tests/value/struct3.i:46: Warning: + pointer downcast. assert (unsigned int)s2.c + (int)s2.c ≤ 2147483647; [eva] tests/value/struct3.i:46: Assigning imprecise value to s2.a. The imprecision originates from Arithmetic {tests/value/struct3.i:46} diff --git a/tests/value/oracle/struct_array.res.oracle b/tests/value/oracle/struct_array.res.oracle index faf7f29e81b..c0df48148db 100644 --- a/tests/value/oracle/struct_array.res.oracle +++ b/tests/value/oracle/struct_array.res.oracle @@ -1,6 +1,12 @@ [kernel] Parsing tests/value/struct_array.i (no preprocessing) [eva] Analyzing a complete application starting at main [eva] Computing initial state +[eva:alarm] tests/value/struct_array.i:15: Warning: + pointer downcast. assert (unsigned int)&z1 ≤ 2147483647; +[eva:alarm] tests/value/struct_array.i:15: Warning: + pointer downcast. assert (unsigned int)&z2 ≤ 2147483647; +[eva:alarm] tests/value/struct_array.i:15: Warning: + pointer downcast. assert (unsigned int)&z4 ≤ 2147483647; [eva] Initial state computed [eva:initial-state] Values of globals at initialization v ∈ [--..--] @@ -234,6 +240,12 @@ [19].p; [20].p; [21].p}; s; s1; s2; s3 [eva] Analyzing a complete application starting at main [eva] Computing initial state +[eva:alarm] tests/value/struct_array.i:15: Warning: + pointer downcast. assert (unsigned int)&z1 ≤ 2147483647; +[eva:alarm] tests/value/struct_array.i:15: Warning: + pointer downcast. assert (unsigned int)&z2 ≤ 2147483647; +[eva:alarm] tests/value/struct_array.i:15: Warning: + pointer downcast. assert (unsigned int)&z4 ≤ 2147483647; [eva] Initial state computed [eva:initial-state] Values of globals at initialization v ∈ [--..--] diff --git a/tests/value/oracle/struct_incl.res.oracle b/tests/value/oracle/struct_incl.res.oracle index 7f41406ae88..e8e83a5e446 100644 --- a/tests/value/oracle/struct_incl.res.oracle +++ b/tests/value/oracle/struct_incl.res.oracle @@ -22,6 +22,12 @@ z ∈ {0} t ∈ {0} v ∈ [--..--] +[eva:alarm] tests/value/struct_incl.i:28: Warning: + pointer downcast. assert (unsigned int)&s1.d[9] ≤ 2147483647; +[eva:alarm] tests/value/struct_incl.i:29: Warning: + pointer downcast. assert (unsigned int)&s1.d[10] ≤ 2147483647; +[eva:alarm] tests/value/struct_incl.i:30: Warning: + pointer downcast. assert (unsigned int)&s1.b ≤ 2147483647; [eva:alarm] tests/value/struct_incl.i:48: Warning: accessing out of bounds index. assert 10 < 10; [kernel] tests/value/struct_incl.i:48: Warning: diff --git a/tests/value/oracle/symbolic_locs.res.oracle b/tests/value/oracle/symbolic_locs.res.oracle index 154a7b55ae6..744e5e6a72f 100644 --- a/tests/value/oracle/symbolic_locs.res.oracle +++ b/tests/value/oracle/symbolic_locs.res.oracle @@ -64,6 +64,8 @@ Called from tests/value/symbolic_locs.i:121. [eva:alarm] tests/value/symbolic_locs.i:51: Warning: assertion got status unknown. +[eva:alarm] tests/value/symbolic_locs.i:54: Warning: + pointer downcast. assert (unsigned int)&x ≤ 2147483647; [eva] tests/value/symbolic_locs.i:55: Frama_C_dump_each: # Cvalue domain: diff --git a/tests/value/oracle/test_arith.res.oracle b/tests/value/oracle/test_arith.res.oracle index 8e462c9e595..0eacce08467 100644 --- a/tests/value/oracle/test_arith.res.oracle +++ b/tests/value/oracle/test_arith.res.oracle @@ -17,6 +17,8 @@ G ∈ {0} [eva:alarm] tests/value/test_arith.c:16: Warning: signed overflow. assert n + 1 ≤ 2147483647; +[eva:alarm] tests/value/test_arith.c:18: Warning: + pointer downcast. assert (unsigned int)ptr ≤ 2147483647; [eva:alarm] tests/value/test_arith.c:18: Warning: signed overflow. assert -2147483648 ≤ (int)ptr + 1; [eva:alarm] tests/value/test_arith.c:18: Warning: diff --git a/tests/value/oracle/val6.0.res.oracle b/tests/value/oracle/val6.0.res.oracle index 4e2b3892316..6f55e391605 100644 --- a/tests/value/oracle/val6.0.res.oracle +++ b/tests/value/oracle/val6.0.res.oracle @@ -9,6 +9,8 @@ b ∈ {0} y ∈ {0} x ∈ {0} +[eva:alarm] tests/value/val6.i:13: Warning: + pointer downcast. assert (unsigned int)c ≤ 2147483647; [eva] Recording results for f [eva] done for function f [eva] ====== VALUES COMPUTED ====== diff --git a/tests/value/oracle/volatile.res.oracle b/tests/value/oracle/volatile.res.oracle index fe1efbbfceb..5298041bed3 100644 --- a/tests/value/oracle/volatile.res.oracle +++ b/tests/value/oracle/volatile.res.oracle @@ -90,6 +90,8 @@ [eva] Done for function main1 [eva] computing for function main2 <- main. Called from tests/value/volatile.c:177. +[eva:alarm] tests/value/volatile.c:83: Warning: + pointer downcast. assert (unsigned int)&X ≤ 2147483647; [eva] Recording results for main2 [eva] Done for function main2 [eva] computing for function main3 <- main. diff --git a/tests/value/oracle/volatilestruct.res.oracle b/tests/value/oracle/volatilestruct.res.oracle index ed81eece0db..256e74cfbac 100644 --- a/tests/value/oracle/volatilestruct.res.oracle +++ b/tests/value/oracle/volatilestruct.res.oracle @@ -7,6 +7,8 @@ s2 ∈ {0} x ∈ {0} y ∈ {0} +[eva:alarm] tests/value/volatilestruct.c:31: Warning: + pointer downcast. assert (unsigned int)p->f4.f2 ≤ 2147483647; [eva:alarm] tests/value/volatilestruct.c:33: Warning: signed overflow. assert -2147483648 ≤ &x - p->f4.f1; [eva:alarm] tests/value/volatilestruct.c:33: Warning: @@ -53,6 +55,8 @@ s2 ∈ {0} x ∈ {0} y ∈ {0} +[eva:alarm] tests/value/volatilestruct.c:31: Warning: + pointer downcast. assert (unsigned int)p->f4.f2 ≤ 2147483647; [eva:signed-overflow] tests/value/volatilestruct.c:33: Warning: 2's complement assumed for overflow [eva:signed-overflow] tests/value/volatilestruct.c:34: Warning: -- GitLab From afd5b5a79afb38e9333e9769271c1113ba2f7fca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20B=C3=BChler?= <david.buhler@cea.fr> Date: Wed, 25 Mar 2020 09:57:26 +0100 Subject: [PATCH 027/218] [Eva] Removes -print and -report from the downcast test: less verbose oracle. --- tests/value/downcast.i | 2 +- tests/value/oracle/downcast.res.oracle | 999 ------------------------- 2 files changed, 1 insertion(+), 1000 deletions(-) diff --git a/tests/value/downcast.i b/tests/value/downcast.i index e979236ea12..1211d0061a2 100644 --- a/tests/value/downcast.i +++ b/tests/value/downcast.i @@ -1,5 +1,5 @@ /* run.config* - STDOPT: +"-load-module report -report -warn-signed-downcast -lib-entry -print -then -no-warn-signed-downcast -warn-unsigned-downcast -then -no-warn-unsigned-downcast -eva-warn-signed-converted-downcast -then -main main5_wrap_signed -slevel 2 -no-print" + STDOPT: +"-warn-signed-downcast -lib-entry -then -no-warn-signed-downcast -warn-unsigned-downcast -then -no-warn-unsigned-downcast -eva-warn-signed-converted-downcast -then -main main5_wrap_signed -slevel 2" */ signed char sx,sy,sz; diff --git a/tests/value/oracle/downcast.res.oracle b/tests/value/oracle/downcast.res.oracle index 2e160ded6f0..7a4b220648e 100644 --- a/tests/value/oracle/downcast.res.oracle +++ b/tests/value/oracle/downcast.res.oracle @@ -284,349 +284,6 @@ sz; uc; x; ux; s [inout] Inputs for function main: sx; sy; x; uy; uz; v -[report] Computing properties status... - --------------------------------------------------------------------------------- ---- Properties of Function 'main1' --------------------------------------------------------------------------------- - -[ - ] Assertion 'Eva,signed_downcast' (file tests/value/downcast.i, line 19) - tried with Eva. -[ - ] Assertion 'Eva,signed_downcast' (file tests/value/downcast.i, line 19) - tried with Eva. -[ - ] Assertion 'Eva,signed_downcast' (file tests/value/downcast.i, line 22) - tried with Eva. - --------------------------------------------------------------------------------- ---- Properties of Function 'main2_bitfield' --------------------------------------------------------------------------------- - -[ Alarm ] Assertion 'Eva,signed_downcast' (file tests/value/downcast.i, line 32) - By Eva, with pending: - - Unreachable instruction (file tests/value/downcast.i, line 32) - --------------------------------------------------------------------------------- ---- Properties of Function 'main3_reduction' --------------------------------------------------------------------------------- - -[ - ] Assertion 'Eva,signed_downcast' (file tests/value/downcast.i, line 38) - tried with Eva. -[ - ] Assertion 'Eva,signed_downcast' (file tests/value/downcast.i, line 38) - tried with Eva. - --------------------------------------------------------------------------------- ---- Properties of Function 'main4_pointer' --------------------------------------------------------------------------------- - -[ - ] Assertion 'Eva,signed_overflow' (file tests/value/downcast.i, line 50) - tried with Eva. -[ - ] Assertion 'Eva,signed_overflow' (file tests/value/downcast.i, line 50) - tried with Eva. -[ - ] Assertion 'Eva,signed_downcast' (file tests/value/downcast.i, line 52) - tried with Eva. -[ - ] Assertion 'Eva,signed_downcast' (file tests/value/downcast.i, line 52) - tried with Eva. - --------------------------------------------------------------------------------- ---- Properties of Function 'main5_wrap_signed' --------------------------------------------------------------------------------- - -[ - ] Assertion 'ASSUME' (file tests/value/downcast.i, line 58) - tried with Eva. -[ Valid ] Assertion (file tests/value/downcast.i, line 59) - by Eva. -[ Valid ] Assertion (file tests/value/downcast.i, line 64) - by Eva. -[ - ] Assertion 'Eva,signed_downcast' (file tests/value/downcast.i, line 62) - tried with Eva. - --------------------------------------------------------------------------------- ---- Properties of Function 'main6_val_warn_converted_signed' --------------------------------------------------------------------------------- - -[ Alarm ] Assertion 'Eva,signed_downcast' (file tests/value/downcast.i, line 71) - By Eva, with pending: - - Unreachable initialization of 's_0' (file tests/value/downcast.i, line 71) -[ Alarm ] Assertion 'Eva,signed_downcast' (file tests/value/downcast.i, line 82) - By Eva, with pending: - - Unreachable initialization of 'b_0' (file tests/value/downcast.i, line 82) -[ Alarm ] Assertion 'Eva,signed_downcast' (file tests/value/downcast.i, line 87) - By Eva, with pending: - - Unreachable initialization of 'b_1' (file tests/value/downcast.i, line 87) -[ - ] Assertion 'Eva,pointer_downcast' (file tests/value/downcast.i, line 91) - tried with Eva. -[ - ] Assertion 'Eva,pointer_downcast' (file tests/value/downcast.i, line 92) - tried with Eva. -[ - ] Assertion 'Eva,pointer_downcast' (file tests/value/downcast.i, line 93) - tried with Eva. - --------------------------------------------------------------------------------- ---- Properties of Function 'main8_bitfields' --------------------------------------------------------------------------------- - -[ Alarm ] Assertion 'Eva,signed_downcast' (file tests/value/downcast.i, line 114) - By Eva, with pending: - - Unreachable instruction (file tests/value/downcast.i, line 114) -[ Alarm ] Assertion 'Eva,signed_downcast' (file tests/value/downcast.i, line 115) - By Eva, with pending: - - Unreachable instruction (file tests/value/downcast.i, line 115) -[ Alarm ] Assertion 'Eva,signed_downcast' (file tests/value/downcast.i, line 119) - By Eva, with pending: - - Unreachable instruction (file tests/value/downcast.i, line 119) -[ Alarm ] Assertion 'Eva,signed_downcast' (file tests/value/downcast.i, line 120) - By Eva, with pending: - - Unreachable instruction (file tests/value/downcast.i, line 120) -[ Alarm ] Assertion 'Eva,signed_downcast' (file tests/value/downcast.i, line 124) - By Eva, with pending: - - Unreachable instruction (file tests/value/downcast.i, line 124) - --------------------------------------------------------------------------------- ---- Properties of Function 'main9_bitfield' --------------------------------------------------------------------------------- - -[ Dead ] Assertion (file tests/value/downcast.i, line 134) - Locally valid, but unreachable. - By Eva because: - - Unreachable program point (file tests/value/downcast.i, line 134) -[ Alarm ] Assertion 'Eva,signed_downcast' (file tests/value/downcast.i, line 133) - By Eva, with pending: - - Unreachable initialization of 'signed_a' (file tests/value/downcast.i, line 133) -[ Alarm ] Assertion 'Eva,signed_downcast' (file tests/value/downcast.i, line 137) - By Eva, with pending: - - Unreachable instruction (file tests/value/downcast.i, line 137) -[Unreachable] Unreachable program point (file tests/value/downcast.i, line 134) - by Eva. - --------------------------------------------------------------------------------- ---- Properties of Function 'main10_loop' --------------------------------------------------------------------------------- - -[ - ] Assertion 'Eva,signed_downcast' (file tests/value/downcast.i, line 147) - tried with Eva. - --------------------------------------------------------------------------------- ---- Status Report Summary --------------------------------------------------------------------------------- - 2 Completely validated - 15 To be validated - 11 Alarms emitted - 1 Dead property - 1 Unreachable - 30 Total --------------------------------------------------------------------------------- -/* Generated by Frama-C */ -struct s { - int i : 5 ; - unsigned int j : 5 ; -}; -struct bitf { - unsigned int i1 : 18 ; - int i2 : 6 ; -}; -struct __anonstruct_bf_1 { - unsigned int a : 11 ; -}; -struct __anonstruct_bf_2 { - unsigned int b : 10 ; -}; -signed char sx; -signed char sy; -signed char sz; -unsigned char uc; -int x; -unsigned int ux; -unsigned int uy; -unsigned int uz; -unsigned short s; -int volatile v; -void main1(void) -{ - /*@ assert Eva: signed_downcast: -128 ≤ (int)((int)sx + (int)sy); */ - /*@ assert Eva: signed_downcast: (int)((int)sx + (int)sy) ≤ 127; */ - sz = (signed char)((int)sx + (int)sy); - uc = (unsigned char)((int)sx + (int)sy); - uc = (unsigned char)x; - /*@ assert Eva: signed_downcast: (unsigned int)(uy + uz) ≤ 2147483647; */ - x = (int)(uy + uz); - ux = uy + uz; - s = (unsigned short)(uy + uz); - return; -} - -void main2_bitfield(void) -{ - struct s ss; - int i = 117; - unsigned int j = (unsigned int)254; - if (v) - /*@ assert Eva: signed_downcast: i ≤ 15; */ - ss.i = (int)i; - if (v) ss.j = (unsigned int)j; - return; -} - -void main3_reduction(void) -{ - int x_0 = v; - /*@ assert Eva: signed_downcast: -128 ≤ x_0; */ - /*@ assert Eva: signed_downcast: x_0 ≤ 127; */ - char c = (char)x_0; - unsigned int y = (unsigned int)v; - unsigned char d = (unsigned char)y; - return; -} - -void main4_pointer(void) -{ - int x_0; - long long p = (long long)(& x_0); - /*@ assert - Eva: signed_overflow: -9223372036854775808 ≤ p + (long long)100; - */ - /*@ assert - Eva: signed_overflow: p + (long long)100 ≤ 9223372036854775807; - */ - p += (long long)100; - unsigned int q = (unsigned int)p; - /*@ assert Eva: signed_downcast: -2147483648 ≤ p; */ - /*@ assert Eva: signed_downcast: p ≤ 2147483647; */ - int r = (int)p; - return; -} - -/*@ assigns \result; - assigns \result \from \nothing; */ -extern int ( /* missing proto */ Frama_C_show_each)(); - -void main5_wrap_signed(void) -{ - int x_0 = v; - /*@ assert ASSUME: x_0 ≥ 100000; */ ; - /*@ assert x_0 > 0x7FFFFFFF - 145 ∨ x_0 ≤ 0x7FFFFFFF - 145; */ ; - unsigned int y = (unsigned int)x_0; - y += (unsigned int)145; - /*@ assert Eva: signed_downcast: y ≤ 2147483647; */ - int z = (int)y; - Frama_C_show_each(x_0,y,z); - /*@ assert z ≥ 100000 + 145 ∨ z ≤ (int)(0x7FFFFFFF + 145); */ ; - return; -} - -void main6_val_warn_converted_signed(void) -{ - if (v) { - /*@ assert Eva: signed_downcast: 65300u ≤ 32767; */ - short s_0 = (short)65300u; - } - if (v) { - unsigned short u = (unsigned short)65300u; - } - if (v) { - unsigned long e = (unsigned long)17; - short b = (short)e; - } - if (v) { - unsigned long e_0 = (unsigned long)(-12); - /*@ assert Eva: signed_downcast: e_0 ≤ 32767; */ - short b_0 = (short)e_0; - } - if (v) { - unsigned int e_1 = (unsigned int)(-64000); - /*@ assert Eva: signed_downcast: e_1 ≤ 32767; */ - short b_1 = (short)e_1; - } - if (v) { - int *p = (int *)(& v); - /*@ assert Eva: pointer_downcast: (unsigned int)p ≤ 2147483647; */ - int x_0 = (int)p; - /*@ assert Eva: pointer_downcast: (unsigned int)p ≤ 32767; */ - short y = (short)p; - /*@ assert Eva: pointer_downcast: (unsigned int)p ≤ 65535; */ - unsigned short z = (unsigned short)p; - } - return; -} - -void main7_signed_upcast(void) -{ - unsigned char c = (unsigned char)240; - int i = (int)c; - return; -} - -void main8_bitfields(void) -{ - struct bitf S; - signed char c; - S.i1 = (unsigned int)0x3FFFF; - if (v) - /*@ assert Eva: signed_downcast: S.i1 ≤ 31; */ - S.i2 = (int)S.i1; - if (v) - /*@ assert Eva: signed_downcast: S.i1 ≤ 127; */ - c = (signed char)S.i1; - S.i1 = (unsigned int)257u; - if (v) - /*@ assert Eva: signed_downcast: S.i1 ≤ 31; */ - S.i2 = (int)S.i1; - if (v) - /*@ assert Eva: signed_downcast: S.i1 ≤ 127; */ - c = (signed char)S.i1; - S.i1 = (unsigned int)65u; - if (v) - /*@ assert Eva: signed_downcast: S.i1 ≤ 31; */ - S.i2 = (int)S.i1; - if (v) c = (signed char)S.i1; - return; -} - -void main9_bitfield(void) -{ - struct __anonstruct_bf_1 bf; - signed char c; - bf.a = (unsigned int)1648; - if (v) { - /*@ assert Eva: signed_downcast: bf.a ≤ 1023; */ - int signed_a = (int)((int)bf.a); - /*@ assert signed_a ≡ -400; */ ; - } - if (v) - /*@ assert Eva: signed_downcast: bf.a ≤ 127; */ - c = (signed char)bf.a; - return; -} - -void main10_loop(void) -{ - signed char c; - struct __anonstruct_bf_2 bf; - int k = 0; - while (k < 10) { - bf.b = (unsigned int)v; - if (v) - /*@ assert Eva: signed_downcast: bf.b ≤ 127; */ - c = (signed char)bf.b; - k ++; - } - return; -} - -void main(void) -{ - main1(); - main2_bitfield(); - main3_reduction(); - main4_pointer(); - main5_wrap_signed(); - main6_val_warn_converted_signed(); - main7_signed_upcast(); - main8_bitfields(); - main9_bitfield(); - main10_loop(); - return; -} - - [eva] Analyzing an incomplete application starting at main [eva] Computing initial state [eva] Initial state computed @@ -879,310 +536,6 @@ void main(void) sz; uc; x; ux; s [inout] Inputs for function main: sx; sy; x; uy; uz; v -[report] Computing properties status... - --------------------------------------------------------------------------------- ---- Properties of Function 'main1' --------------------------------------------------------------------------------- - -[ - ] Assertion 'Eva,unsigned_downcast' (file tests/value/downcast.i, line 20) - tried with Eva. -[ - ] Assertion 'Eva,unsigned_downcast' (file tests/value/downcast.i, line 21) - tried with Eva. -[ - ] Assertion 'Eva,unsigned_downcast' (file tests/value/downcast.i, line 21) - tried with Eva. -[ - ] Assertion 'Eva,unsigned_downcast' (file tests/value/downcast.i, line 24) - tried with Eva. - --------------------------------------------------------------------------------- ---- Properties of Function 'main2_bitfield' --------------------------------------------------------------------------------- - -[ Alarm ] Assertion 'Eva,unsigned_downcast' (file tests/value/downcast.i, line 33) - By Eva, with pending: - - Unreachable instruction (file tests/value/downcast.i, line 33) - --------------------------------------------------------------------------------- ---- Properties of Function 'main3_reduction' --------------------------------------------------------------------------------- - -[ - ] Assertion 'Eva,unsigned_downcast' (file tests/value/downcast.i, line 40) - tried with Eva. -[ - ] Assertion 'Eva,unsigned_downcast' (file tests/value/downcast.i, line 41) - tried with Eva. - --------------------------------------------------------------------------------- ---- Properties of Function 'main4_pointer' --------------------------------------------------------------------------------- - -[ - ] Assertion 'Eva,signed_overflow' (file tests/value/downcast.i, line 50) - tried with Eva. -[ - ] Assertion 'Eva,signed_overflow' (file tests/value/downcast.i, line 50) - tried with Eva. -[ - ] Assertion 'Eva,unsigned_downcast' (file tests/value/downcast.i, line 51) - tried with Eva. -[ - ] Assertion 'Eva,unsigned_downcast' (file tests/value/downcast.i, line 51) - tried with Eva. - --------------------------------------------------------------------------------- ---- Properties of Function 'main5_wrap_signed' --------------------------------------------------------------------------------- - -[ - ] Assertion 'ASSUME' (file tests/value/downcast.i, line 58) - tried with Eva. -[ Valid ] Assertion (file tests/value/downcast.i, line 59) - by Eva. -[ - ] Assertion (file tests/value/downcast.i, line 64) - tried with Eva. - --------------------------------------------------------------------------------- ---- Properties of Function 'main6_val_warn_converted_signed' --------------------------------------------------------------------------------- - -[ Alarm ] Assertion 'Eva,unsigned_downcast' (file tests/value/downcast.i, line 81) - By Eva, with pending: - - Unreachable initialization of 'e_0' (file tests/value/downcast.i, line 81) -[ Alarm ] Assertion 'Eva,unsigned_downcast' (file tests/value/downcast.i, line 86) - By Eva, with pending: - - Unreachable initialization of 'e_1' (file tests/value/downcast.i, line 86) -[ - ] Assertion 'Eva,pointer_downcast' (file tests/value/downcast.i, line 91) - tried with Eva. -[ - ] Assertion 'Eva,pointer_downcast' (file tests/value/downcast.i, line 92) - tried with Eva. -[ - ] Assertion 'Eva,pointer_downcast' (file tests/value/downcast.i, line 93) - tried with Eva. - --------------------------------------------------------------------------------- ---- Properties of Function 'main9_bitfield' --------------------------------------------------------------------------------- - -[ Valid ] Assertion (file tests/value/downcast.i, line 134) - by Eva. - --------------------------------------------------------------------------------- ---- Properties of Function 'main10_loop' --------------------------------------------------------------------------------- - -[ - ] Assertion 'Eva,unsigned_downcast' (file tests/value/downcast.i, line 146) - tried with Eva. -[ - ] Assertion 'Eva,unsigned_downcast' (file tests/value/downcast.i, line 146) - tried with Eva. - --------------------------------------------------------------------------------- ---- Status Report Summary --------------------------------------------------------------------------------- - 2 Completely validated - 17 To be validated - 3 Alarms emitted - 22 Total --------------------------------------------------------------------------------- -/* Generated by Frama-C */ -struct s { - int i : 5 ; - unsigned int j : 5 ; -}; -struct bitf { - unsigned int i1 : 18 ; - int i2 : 6 ; -}; -struct __anonstruct_bf_1 { - unsigned int a : 11 ; -}; -struct __anonstruct_bf_2 { - unsigned int b : 10 ; -}; -signed char sx; -signed char sy; -signed char sz; -unsigned char uc; -int x; -unsigned int ux; -unsigned int uy; -unsigned int uz; -unsigned short s; -int volatile v; -void main1(void) -{ - sz = (signed char)((int)sx + (int)sy); - /*@ assert Eva: unsigned_downcast: 0 ≤ (int)((int)sx + (int)sy); */ - uc = (unsigned char)((int)sx + (int)sy); - /*@ assert Eva: unsigned_downcast: 0 ≤ x; */ - /*@ assert Eva: unsigned_downcast: x ≤ 255; */ - uc = (unsigned char)x; - x = (int)(uy + uz); - ux = uy + uz; - /*@ assert Eva: unsigned_downcast: (unsigned int)(uy + uz) ≤ 65535; */ - s = (unsigned short)(uy + uz); - return; -} - -void main2_bitfield(void) -{ - struct s ss; - int i = 117; - unsigned int j = (unsigned int)254; - if (v) - ss.i = (int)i; - if (v) - /*@ assert Eva: unsigned_downcast: j ≤ 31; */ - ss.j = (unsigned int)j; - return; -} - -void main3_reduction(void) -{ - int x_0 = v; - char c = (char)x_0; - /*@ assert Eva: unsigned_downcast: 0 ≤ v; */ - unsigned int y = (unsigned int)v; - /*@ assert Eva: unsigned_downcast: y ≤ 255; */ - unsigned char d = (unsigned char)y; - return; -} - -void main4_pointer(void) -{ - int x_0; - long long p = (long long)(& x_0); - /*@ assert - Eva: signed_overflow: -9223372036854775808 ≤ p + (long long)100; - */ - /*@ assert - Eva: signed_overflow: p + (long long)100 ≤ 9223372036854775807; - */ - p += (long long)100; - /*@ assert Eva: unsigned_downcast: 0 ≤ p; */ - /*@ assert Eva: unsigned_downcast: p ≤ 4294967295; */ - unsigned int q = (unsigned int)p; - int r = (int)p; - return; -} - -/*@ assigns \result; - assigns \result \from \nothing; */ -extern int ( /* missing proto */ Frama_C_show_each)(); - -void main5_wrap_signed(void) -{ - int x_0 = v; - /*@ assert ASSUME: x_0 ≥ 100000; */ ; - /*@ assert x_0 > 0x7FFFFFFF - 145 ∨ x_0 ≤ 0x7FFFFFFF - 145; */ ; - unsigned int y = (unsigned int)x_0; - y += (unsigned int)145; - int z = (int)y; - Frama_C_show_each(x_0,y,z); - /*@ assert z ≥ 100000 + 145 ∨ z ≤ (int)(0x7FFFFFFF + 145); */ ; - return; -} - -void main6_val_warn_converted_signed(void) -{ - if (v) { - short s_0 = (short)65300u; - } - if (v) { - unsigned short u = (unsigned short)65300u; - } - if (v) { - unsigned long e = (unsigned long)17; - short b = (short)e; - } - if (v) { - /*@ assert Eva: unsigned_downcast: 0 ≤ (int)(-12); */ - unsigned long e_0 = (unsigned long)(-12); - short b_0 = (short)e_0; - } - if (v) { - /*@ assert Eva: unsigned_downcast: 0 ≤ (int)(-64000); */ - unsigned int e_1 = (unsigned int)(-64000); - short b_1 = (short)e_1; - } - if (v) { - int *p = (int *)(& v); - /*@ assert Eva: pointer_downcast: (unsigned int)p ≤ 2147483647; */ - int x_0 = (int)p; - /*@ assert Eva: pointer_downcast: (unsigned int)p ≤ 32767; */ - short y = (short)p; - /*@ assert Eva: pointer_downcast: (unsigned int)p ≤ 65535; */ - unsigned short z = (unsigned short)p; - } - return; -} - -void main7_signed_upcast(void) -{ - unsigned char c = (unsigned char)240; - int i = (int)c; - return; -} - -void main8_bitfields(void) -{ - struct bitf S; - signed char c; - S.i1 = (unsigned int)0x3FFFF; - if (v) - S.i2 = (int)S.i1; - if (v) - c = (signed char)S.i1; - S.i1 = (unsigned int)257u; - if (v) - S.i2 = (int)S.i1; - if (v) - c = (signed char)S.i1; - S.i1 = (unsigned int)65u; - if (v) - S.i2 = (int)S.i1; - if (v) c = (signed char)S.i1; - return; -} - -void main9_bitfield(void) -{ - struct __anonstruct_bf_1 bf; - signed char c; - bf.a = (unsigned int)1648; - if (v) { - int signed_a = (int)((int)bf.a); - /*@ assert signed_a ≡ -400; */ ; - } - if (v) - c = (signed char)bf.a; - return; -} - -void main10_loop(void) -{ - signed char c; - struct __anonstruct_bf_2 bf; - int k = 0; - while (k < 10) { - /*@ assert Eva: unsigned_downcast: 0 ≤ v; */ - /*@ assert Eva: unsigned_downcast: v ≤ 1023; */ - bf.b = (unsigned int)v; - if (v) - c = (signed char)bf.b; - k ++; - } - return; -} - -void main(void) -{ - main1(); - main2_bitfield(); - main3_reduction(); - main4_pointer(); - main5_wrap_signed(); - main6_val_warn_converted_signed(); - main7_signed_upcast(); - main8_bitfields(); - main9_bitfield(); - main10_loop(); - return; -} - - [eva] Analyzing an incomplete application starting at main [eva] Computing initial state [eva] Initial state computed @@ -1432,325 +785,6 @@ void main(void) sz; uc; x; ux; s [inout] Inputs for function main: sx; sy; x; uy; uz; v -[report] Computing properties status... - --------------------------------------------------------------------------------- ---- Properties of Function 'main1' --------------------------------------------------------------------------------- - -[ - ] Assertion 'Eva,signed_downcast' (file tests/value/downcast.i, line 19) - tried with Eva. -[ - ] Assertion 'Eva,signed_downcast' (file tests/value/downcast.i, line 19) - tried with Eva. - --------------------------------------------------------------------------------- ---- Properties of Function 'main2_bitfield' --------------------------------------------------------------------------------- - -[ Alarm ] Assertion 'Eva,signed_downcast' (file tests/value/downcast.i, line 32) - By Eva, with pending: - - Unreachable instruction (file tests/value/downcast.i, line 32) - --------------------------------------------------------------------------------- ---- Properties of Function 'main3_reduction' --------------------------------------------------------------------------------- - -[ - ] Assertion 'Eva,signed_downcast' (file tests/value/downcast.i, line 38) - tried with Eva. -[ - ] Assertion 'Eva,signed_downcast' (file tests/value/downcast.i, line 38) - tried with Eva. - --------------------------------------------------------------------------------- ---- Properties of Function 'main4_pointer' --------------------------------------------------------------------------------- - -[ - ] Assertion 'Eva,signed_overflow' (file tests/value/downcast.i, line 50) - tried with Eva. -[ - ] Assertion 'Eva,signed_overflow' (file tests/value/downcast.i, line 50) - tried with Eva. -[ - ] Assertion 'Eva,signed_downcast' (file tests/value/downcast.i, line 52) - tried with Eva. -[ - ] Assertion 'Eva,signed_downcast' (file tests/value/downcast.i, line 52) - tried with Eva. - --------------------------------------------------------------------------------- ---- Properties of Function 'main5_wrap_signed' --------------------------------------------------------------------------------- - -[ - ] Assertion 'ASSUME' (file tests/value/downcast.i, line 58) - tried with Eva. -[ Valid ] Assertion (file tests/value/downcast.i, line 59) - by Eva. -[ - ] Assertion (file tests/value/downcast.i, line 64) - tried with Eva. - --------------------------------------------------------------------------------- ---- Properties of Function 'main6_val_warn_converted_signed' --------------------------------------------------------------------------------- - -[ Alarm ] Assertion 'Eva,signed_downcast' (file tests/value/downcast.i, line 71) - By Eva, with pending: - - Unreachable initialization of 's_0' (file tests/value/downcast.i, line 71) -[ Alarm ] Assertion 'Eva,signed_downcast' (file tests/value/downcast.i, line 87) - By Eva, with pending: - - Unreachable initialization of 'b_1' (file tests/value/downcast.i, line 87) -[ - ] Assertion 'Eva,pointer_downcast' (file tests/value/downcast.i, line 91) - tried with Eva. -[ - ] Assertion 'Eva,pointer_downcast' (file tests/value/downcast.i, line 92) - tried with Eva. -[ - ] Assertion 'Eva,pointer_downcast' (file tests/value/downcast.i, line 93) - tried with Eva. - --------------------------------------------------------------------------------- ---- Properties of Function 'main8_bitfields' --------------------------------------------------------------------------------- - -[ Alarm ] Assertion 'Eva,signed_downcast' (file tests/value/downcast.i, line 119) - By Eva, with pending: - - Unreachable instruction (file tests/value/downcast.i, line 119) -[ Alarm ] Assertion 'Eva,signed_downcast' (file tests/value/downcast.i, line 120) - By Eva, with pending: - - Unreachable instruction (file tests/value/downcast.i, line 120) -[ Alarm ] Assertion 'Eva,signed_downcast' (file tests/value/downcast.i, line 124) - By Eva, with pending: - - Unreachable instruction (file tests/value/downcast.i, line 124) - --------------------------------------------------------------------------------- ---- Properties of Function 'main9_bitfield' --------------------------------------------------------------------------------- - -[ Valid ] Assertion (file tests/value/downcast.i, line 134) - by Eva. -[ Alarm ] Assertion 'Eva,signed_downcast' (file tests/value/downcast.i, line 137) - By Eva, with pending: - - Unreachable instruction (file tests/value/downcast.i, line 137) - --------------------------------------------------------------------------------- ---- Properties of Function 'main10_loop' --------------------------------------------------------------------------------- - -[ - ] Assertion 'Eva,signed_downcast' (file tests/value/downcast.i, line 147) - tried with Eva. -[ - ] Assertion 'Eva,signed_downcast' (file tests/value/downcast.i, line 147) - tried with Eva. - --------------------------------------------------------------------------------- ---- Status Report Summary --------------------------------------------------------------------------------- - 2 Completely validated - 15 To be validated - 7 Alarms emitted - 24 Total --------------------------------------------------------------------------------- -/* Generated by Frama-C */ -struct s { - int i : 5 ; - unsigned int j : 5 ; -}; -struct bitf { - unsigned int i1 : 18 ; - int i2 : 6 ; -}; -struct __anonstruct_bf_1 { - unsigned int a : 11 ; -}; -struct __anonstruct_bf_2 { - unsigned int b : 10 ; -}; -signed char sx; -signed char sy; -signed char sz; -unsigned char uc; -int x; -unsigned int ux; -unsigned int uy; -unsigned int uz; -unsigned short s; -int volatile v; -void main1(void) -{ - /*@ assert Eva: signed_downcast: -128 ≤ (int)((int)sx + (int)sy); */ - /*@ assert Eva: signed_downcast: (int)((int)sx + (int)sy) ≤ 127; */ - sz = (signed char)((int)sx + (int)sy); - uc = (unsigned char)((int)sx + (int)sy); - uc = (unsigned char)x; - x = (int)(uy + uz); - ux = uy + uz; - s = (unsigned short)(uy + uz); - return; -} - -void main2_bitfield(void) -{ - struct s ss; - int i = 117; - unsigned int j = (unsigned int)254; - if (v) - /*@ assert Eva: signed_downcast: i ≤ 15; */ - ss.i = (int)i; - if (v) - ss.j = (unsigned int)j; - return; -} - -void main3_reduction(void) -{ - int x_0 = v; - /*@ assert Eva: signed_downcast: -128 ≤ x_0; */ - /*@ assert Eva: signed_downcast: x_0 ≤ 127; */ - char c = (char)x_0; - unsigned int y = (unsigned int)v; - unsigned char d = (unsigned char)y; - return; -} - -void main4_pointer(void) -{ - int x_0; - long long p = (long long)(& x_0); - /*@ assert - Eva: signed_overflow: -9223372036854775808 ≤ p + (long long)100; - */ - /*@ assert - Eva: signed_overflow: p + (long long)100 ≤ 9223372036854775807; - */ - p += (long long)100; - unsigned int q = (unsigned int)p; - /*@ assert Eva: signed_downcast: -2147483648 ≤ p; */ - /*@ assert Eva: signed_downcast: p ≤ 2147483647; */ - int r = (int)p; - return; -} - -/*@ assigns \result; - assigns \result \from \nothing; */ -extern int ( /* missing proto */ Frama_C_show_each)(); - -void main5_wrap_signed(void) -{ - int x_0 = v; - /*@ assert ASSUME: x_0 ≥ 100000; */ ; - /*@ assert x_0 > 0x7FFFFFFF - 145 ∨ x_0 ≤ 0x7FFFFFFF - 145; */ ; - unsigned int y = (unsigned int)x_0; - y += (unsigned int)145; - int z = (int)y; - Frama_C_show_each(x_0,y,z); - /*@ assert z ≥ 100000 + 145 ∨ z ≤ (int)(0x7FFFFFFF + 145); */ ; - return; -} - -void main6_val_warn_converted_signed(void) -{ - if (v) { - /*@ assert Eva: signed_downcast: (int)65300u ≤ 32767; */ - short s_0 = (short)65300u; - } - if (v) { - unsigned short u = (unsigned short)65300u; - } - if (v) { - unsigned long e = (unsigned long)17; - short b = (short)e; - } - if (v) { - unsigned long e_0 = (unsigned long)(-12); - short b_0 = (short)e_0; - } - if (v) { - unsigned int e_1 = (unsigned int)(-64000); - /*@ assert Eva: signed_downcast: -32768 ≤ (int)e_1; */ - short b_1 = (short)e_1; - } - if (v) { - int *p = (int *)(& v); - /*@ assert Eva: pointer_downcast: (unsigned int)p ≤ 2147483647; */ - int x_0 = (int)p; - /*@ assert Eva: pointer_downcast: (unsigned int)p ≤ 32767; */ - short y = (short)p; - /*@ assert Eva: pointer_downcast: (unsigned int)p ≤ 65535; */ - unsigned short z = (unsigned short)p; - } - return; -} - -void main7_signed_upcast(void) -{ - unsigned char c = (unsigned char)240; - int i = (int)c; - return; -} - -void main8_bitfields(void) -{ - struct bitf S; - signed char c; - S.i1 = (unsigned int)0x3FFFF; - if (v) - S.i2 = (int)S.i1; - if (v) - c = (signed char)S.i1; - S.i1 = (unsigned int)257u; - if (v) - /*@ assert Eva: signed_downcast: (int)S.i1 ≤ 31; */ - S.i2 = (int)S.i1; - if (v) - /*@ assert Eva: signed_downcast: (int)S.i1 ≤ 127; */ - c = (signed char)S.i1; - S.i1 = (unsigned int)65u; - if (v) - /*@ assert Eva: signed_downcast: (int)S.i1 ≤ 31; */ - S.i2 = (int)S.i1; - if (v) c = (signed char)S.i1; - return; -} - -void main9_bitfield(void) -{ - struct __anonstruct_bf_1 bf; - signed char c; - bf.a = (unsigned int)1648; - if (v) { - int signed_a = (int)((int)bf.a); - /*@ assert signed_a ≡ -400; */ ; - } - if (v) - /*@ assert Eva: signed_downcast: -128 ≤ (int)bf.a; */ - c = (signed char)bf.a; - return; -} - -void main10_loop(void) -{ - signed char c; - struct __anonstruct_bf_2 bf; - int k = 0; - while (k < 10) { - bf.b = (unsigned int)v; - if (v) - /*@ assert Eva: signed_downcast: -128 ≤ (int)bf.b; */ - /*@ assert Eva: signed_downcast: (int)bf.b ≤ 127; */ - c = (signed char)bf.b; - k ++; - } - return; -} - -void main(void) -{ - main1(); - main2_bitfield(); - main3_reduction(); - main4_pointer(); - main5_wrap_signed(); - main6_val_warn_converted_signed(); - main7_signed_upcast(); - main8_bitfields(); - main9_bitfield(); - main10_loop(); - return; -} - - [eva] Analyzing an incomplete application starting at main5_wrap_signed [eva] Computing initial state [eva] Initial state computed @@ -1791,36 +825,3 @@ void main(void) x_0; y; z [inout] Inputs for function main5_wrap_signed: v -[report] Computing properties status... - --------------------------------------------------------------------------------- ---- Properties of Function 'main5_wrap_signed' --------------------------------------------------------------------------------- - -[ - ] Assertion 'ASSUME' (file tests/value/downcast.i, line 58) - tried with Eva (v2). -[ Valid ] Assertion (file tests/value/downcast.i, line 59) - by Eva (v2). -[ Valid ] Assertion (file tests/value/downcast.i, line 64) - by Eva (v2). - --------------------------------------------------------------------------------- ---- Properties of Function 'main9_bitfield' --------------------------------------------------------------------------------- - -[ Dead ] Assertion (file tests/value/downcast.i, line 134) - Locally valid, but unreachable. - By Eva (v2) because: - - Unreachable program point (file tests/value/downcast.i, line 134) -[Unreachable] Unreachable program point (file tests/value/downcast.i, line 134) - by Eva (v2). - --------------------------------------------------------------------------------- ---- Status Report Summary --------------------------------------------------------------------------------- - 2 Completely validated - 1 To be validated - 1 Dead property - 1 Unreachable - 5 Total --------------------------------------------------------------------------------- -- GitLab From b2b8be5995634bb25d4d9eb0233471fcd3137f0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20B=C3=BChler?= <david.buhler@cea.fr> Date: Wed, 25 Mar 2020 09:11:31 +0100 Subject: [PATCH 028/218] [Eva] Splits the downcast test into 5 runs. Also tests -no-warn-pointer-downcast. Run 0 tests the default configuration of Frama-C: no downcast alarms, except for pointers. Runs 1 to 3 correspond to the previous run with successive -then, and test: - emission of signed downcast alarms (option -warn-signed-downcast) - emission of unsigned downcast alarms (option -warn-unsigned-downcast) - the relaxed semantics of the Eva option -eva-warn-signed-converted-downcast Run 4 disables all downcast alarms, including downcast of pointer values. --- tests/value/downcast.i | 6 +- tests/value/oracle/downcast.0.res.oracle | 231 +++++++ tests/value/oracle/downcast.1.res.oracle | 286 ++++++++ tests/value/oracle/downcast.2.res.oracle | 257 +++++++ tests/value/oracle/downcast.3.res.oracle | 270 ++++++++ tests/value/oracle/downcast.4.res.oracle | 226 +++++++ tests/value/oracle/downcast.res.oracle | 827 ----------------------- 7 files changed, 1275 insertions(+), 828 deletions(-) create mode 100644 tests/value/oracle/downcast.0.res.oracle create mode 100644 tests/value/oracle/downcast.1.res.oracle create mode 100644 tests/value/oracle/downcast.2.res.oracle create mode 100644 tests/value/oracle/downcast.3.res.oracle create mode 100644 tests/value/oracle/downcast.4.res.oracle delete mode 100644 tests/value/oracle/downcast.res.oracle diff --git a/tests/value/downcast.i b/tests/value/downcast.i index 1211d0061a2..6c01c21fd74 100644 --- a/tests/value/downcast.i +++ b/tests/value/downcast.i @@ -1,5 +1,9 @@ /* run.config* - STDOPT: +"-warn-signed-downcast -lib-entry -then -no-warn-signed-downcast -warn-unsigned-downcast -then -no-warn-unsigned-downcast -eva-warn-signed-converted-downcast -then -main main5_wrap_signed -slevel 2" + STDOPT: +"-lib-entry -no-warn-signed-downcast -no-warn-unsigned-downcast -warn-pointer-downcast -eva-slevel-function main5_wrap_signed:2" + STDOPT: +"-lib-entry -warn-signed-downcast -no-warn-unsigned-downcast -warn-pointer-downcast" + STDOPT: +"-lib-entry -no-warn-signed-downcast -warn-unsigned-downcast -warn-pointer-downcast" + STDOPT: +"-lib-entry -no-warn-signed-downcast -no-warn-unsigned-downcast -warn-pointer-downcast -eva-warn-signed-converted-downcast" + STDOPT: +"-lib-entry -no-warn-signed-downcast -no-warn-unsigned-downcast -no-warn-pointer-downcast" */ signed char sx,sy,sz; diff --git a/tests/value/oracle/downcast.0.res.oracle b/tests/value/oracle/downcast.0.res.oracle new file mode 100644 index 00000000000..c27a3ff663f --- /dev/null +++ b/tests/value/oracle/downcast.0.res.oracle @@ -0,0 +1,231 @@ +[kernel] Parsing tests/value/downcast.i (no preprocessing) +[eva] Analyzing an incomplete application starting at main +[eva] Computing initial state +[eva] Initial state computed +[eva:initial-state] Values of globals at initialization + sx ∈ [--..--] + sy ∈ [--..--] + sz ∈ [--..--] + uc ∈ [--..--] + x ∈ [--..--] + ux ∈ [--..--] + uy ∈ [--..--] + uz ∈ [--..--] + s ∈ [--..--] + v ∈ [--..--] +[eva] computing for function main1 <- main. + Called from tests/value/downcast.i:156. +[eva] Recording results for main1 +[eva] Done for function main1 +[eva] computing for function main2_bitfield <- main. + Called from tests/value/downcast.i:157. +[eva] Recording results for main2_bitfield +[eva] Done for function main2_bitfield +[eva] computing for function main3_reduction <- main. + Called from tests/value/downcast.i:158. +[eva] Recording results for main3_reduction +[eva] Done for function main3_reduction +[eva] computing for function main4_pointer <- main. + Called from tests/value/downcast.i:159. +[eva:alarm] tests/value/downcast.i:54: Warning: + signed overflow. assert -9223372036854775808 ≤ p + (long long)100; +[eva:alarm] tests/value/downcast.i:54: Warning: + signed overflow. assert p + (long long)100 ≤ 9223372036854775807; +[eva] Recording results for main4_pointer +[eva] Done for function main4_pointer +[eva] computing for function main5_wrap_signed <- main. + Called from tests/value/downcast.i:160. +[eva:alarm] tests/value/downcast.i:62: Warning: + assertion 'ASSUME' got status unknown. +[eva] tests/value/downcast.i:63: assertion got status valid. +[eva] tests/value/downcast.i:67: + Frama_C_show_each: + [2147483503..2147483647], + [2147483648..2147483792], + [-2147483648..-2147483504] +[eva] tests/value/downcast.i:67: + Frama_C_show_each: + [100000..2147483502], [100145..2147483647], [100145..2147483647] +[eva] tests/value/downcast.i:68: assertion got status valid. +[eva] Recording results for main5_wrap_signed +[eva] Done for function main5_wrap_signed +[eva] computing for function main6_val_warn_converted_signed <- main. + Called from tests/value/downcast.i:161. +[eva:alarm] tests/value/downcast.i:95: Warning: + pointer downcast. assert (unsigned int)p ≤ 2147483647; +[eva:alarm] tests/value/downcast.i:96: Warning: + pointer downcast. assert (unsigned int)p ≤ 32767; +[eva:alarm] tests/value/downcast.i:97: Warning: + pointer downcast. assert (unsigned int)p ≤ 65535; +[eva] Recording results for main6_val_warn_converted_signed +[eva] Done for function main6_val_warn_converted_signed +[eva] computing for function main7_signed_upcast <- main. + Called from tests/value/downcast.i:162. +[eva] Recording results for main7_signed_upcast +[eva] Done for function main7_signed_upcast +[eva] computing for function main8_bitfields <- main. + Called from tests/value/downcast.i:163. +[eva] Recording results for main8_bitfields +[eva] Done for function main8_bitfields +[eva] computing for function main9_bitfield <- main. + Called from tests/value/downcast.i:164. +[eva] tests/value/downcast.i:138: assertion got status valid. +[eva] Recording results for main9_bitfield +[eva] Done for function main9_bitfield +[eva] computing for function main10_loop <- main. + Called from tests/value/downcast.i:165. +[eva] tests/value/downcast.i:149: starting to merge loop iterations +[eva] Recording results for main10_loop +[eva] Done for function main10_loop +[eva] Recording results for main +[eva] done for function main +[eva] ====== VALUES COMPUTED ====== +[eva:final-states] Values at end of function main1: + sz ∈ [--..--] + uc ∈ [--..--] + x ∈ [--..--] + ux ∈ [--..--] + s ∈ [--..--] +[eva:final-states] Values at end of function main10_loop: + c ∈ [--..--] or UNINITIALIZED + bf.b ∈ [--..--] or UNINITIALIZED + .[bits 10 to 31] ∈ UNINITIALIZED + k ∈ {10} +[eva:final-states] Values at end of function main2_bitfield: + i ∈ {117} + j ∈ {254} + ss.i ∈ {-11} or UNINITIALIZED + .j ∈ {30} or UNINITIALIZED + .[bits 10 to 31] ∈ UNINITIALIZED +[eva:final-states] Values at end of function main3_reduction: + x_0 ∈ [--..--] + c ∈ [--..--] + y ∈ [--..--] + d ∈ [--..--] +[eva:final-states] Values at end of function main4_pointer: + p ∈ {{ &x_0 + {100} }} + q ∈ {{ &x_0 + {100} }} + r ∈ {{ &x_0 + {100} }} +[eva:final-states] Values at end of function main5_wrap_signed: + x_0 ∈ [100000..2147483647] + y ∈ [100145..2147483792] + z ∈ [--..--] +[eva:final-states] Values at end of function main6_val_warn_converted_signed: + +[eva:final-states] Values at end of function main7_signed_upcast: + c ∈ {240} + i ∈ {240} +[eva:final-states] Values at end of function main8_bitfields: + S.i1 ∈ {65} + .i2 ∈ {-1; 1} or UNINITIALIZED + .[bits 24 to 31] ∈ UNINITIALIZED + c ∈ {-1; 1; 65} or UNINITIALIZED +[eva:final-states] Values at end of function main9_bitfield: + bf.a ∈ {1648} + .[bits 11 to 31] ∈ UNINITIALIZED + c ∈ {112} or UNINITIALIZED +[eva:final-states] Values at end of function main: + sz ∈ [--..--] + uc ∈ [--..--] + x ∈ [--..--] + ux ∈ [--..--] + s ∈ [--..--] +[from] Computing for function main1 +[from] Done for function main1 +[from] Computing for function main10_loop +[from] Done for function main10_loop +[from] Computing for function main2_bitfield +[from] Done for function main2_bitfield +[from] Computing for function main3_reduction +[from] Done for function main3_reduction +[from] Computing for function main4_pointer +[from] Done for function main4_pointer +[from] Computing for function main5_wrap_signed +[from] Done for function main5_wrap_signed +[from] Computing for function main6_val_warn_converted_signed +[from] Done for function main6_val_warn_converted_signed +[from] Computing for function main7_signed_upcast +[from] Done for function main7_signed_upcast +[from] Computing for function main8_bitfields +[from] Done for function main8_bitfields +[from] Computing for function main9_bitfield +[from] Done for function main9_bitfield +[from] Computing for function main +[from] Done for function main +[from] ====== DEPENDENCIES COMPUTED ====== + These dependencies hold at termination for the executions that terminate: +[from] Function main1: + sz FROM sx; sy + uc FROM x + x FROM uy; uz + ux FROM uy; uz + s FROM uy; uz +[from] Function main10_loop: + NO EFFECTS +[from] Function main2_bitfield: + NO EFFECTS +[from] Function main3_reduction: + NO EFFECTS +[from] Function main4_pointer: + NO EFFECTS +[from] Function main5_wrap_signed: + NO EFFECTS +[from] Function main6_val_warn_converted_signed: + NO EFFECTS +[from] Function main7_signed_upcast: + NO EFFECTS +[from] Function main8_bitfields: + NO EFFECTS +[from] Function main9_bitfield: + NO EFFECTS +[from] Function main: + sz FROM sx; sy + uc FROM x + x FROM uy; uz + ux FROM uy; uz + s FROM uy; uz +[from] ====== END OF DEPENDENCIES ====== +[inout] Out (internal) for function main1: + sz; uc; x; ux; s +[inout] Inputs for function main1: + sx; sy; x; uy; uz +[inout] Out (internal) for function main10_loop: + c; bf.b; k +[inout] Inputs for function main10_loop: + v +[inout] Out (internal) for function main2_bitfield: + i; j; ss{.i; .j} +[inout] Inputs for function main2_bitfield: + v +[inout] Out (internal) for function main3_reduction: + x_0; c; y; d +[inout] Inputs for function main3_reduction: + v +[inout] Out (internal) for function main4_pointer: + p; q; r +[inout] Inputs for function main4_pointer: + \nothing +[inout] Out (internal) for function main5_wrap_signed: + x_0; y; z +[inout] Inputs for function main5_wrap_signed: + v +[inout] Out (internal) for function main6_val_warn_converted_signed: + s_0; u; e; b; e_0; b_0; e_1; b_1; p; x_0; y; z +[inout] Inputs for function main6_val_warn_converted_signed: + v +[inout] Out (internal) for function main7_signed_upcast: + c; i +[inout] Inputs for function main7_signed_upcast: + \nothing +[inout] Out (internal) for function main8_bitfields: + S{.i1; .i2}; c +[inout] Inputs for function main8_bitfields: + v +[inout] Out (internal) for function main9_bitfield: + bf.a; signed_a; c +[inout] Inputs for function main9_bitfield: + v +[inout] Out (internal) for function main: + sz; uc; x; ux; s +[inout] Inputs for function main: + sx; sy; x; uy; uz; v diff --git a/tests/value/oracle/downcast.1.res.oracle b/tests/value/oracle/downcast.1.res.oracle new file mode 100644 index 00000000000..4430fdae775 --- /dev/null +++ b/tests/value/oracle/downcast.1.res.oracle @@ -0,0 +1,286 @@ +[kernel] Parsing tests/value/downcast.i (no preprocessing) +[eva] Analyzing an incomplete application starting at main +[eva] Computing initial state +[eva] Initial state computed +[eva:initial-state] Values of globals at initialization + sx ∈ [--..--] + sy ∈ [--..--] + sz ∈ [--..--] + uc ∈ [--..--] + x ∈ [--..--] + ux ∈ [--..--] + uy ∈ [--..--] + uz ∈ [--..--] + s ∈ [--..--] + v ∈ [--..--] +[eva] computing for function main1 <- main. + Called from tests/value/downcast.i:156. +[eva:alarm] tests/value/downcast.i:23: Warning: + signed downcast. assert -128 ≤ (int)((int)sx + (int)sy); +[eva:alarm] tests/value/downcast.i:23: Warning: + signed downcast. assert (int)((int)sx + (int)sy) ≤ 127; +[eva:alarm] tests/value/downcast.i:26: Warning: + signed downcast. assert (unsigned int)(uy + uz) ≤ 2147483647; +[eva] Recording results for main1 +[eva] Done for function main1 +[eva] computing for function main2_bitfield <- main. + Called from tests/value/downcast.i:157. +[eva:alarm] tests/value/downcast.i:36: Warning: + signed downcast. assert i ≤ 15; +[eva] Recording results for main2_bitfield +[eva] Done for function main2_bitfield +[eva] computing for function main3_reduction <- main. + Called from tests/value/downcast.i:158. +[eva:alarm] tests/value/downcast.i:42: Warning: + signed downcast. assert -128 ≤ x_0; +[eva:alarm] tests/value/downcast.i:42: Warning: + signed downcast. assert x_0 ≤ 127; +[eva] Recording results for main3_reduction +[eva] Done for function main3_reduction +[eva] computing for function main4_pointer <- main. + Called from tests/value/downcast.i:159. +[eva:alarm] tests/value/downcast.i:54: Warning: + signed overflow. assert -9223372036854775808 ≤ p + (long long)100; +[eva:alarm] tests/value/downcast.i:54: Warning: + signed overflow. assert p + (long long)100 ≤ 9223372036854775807; +[eva:alarm] tests/value/downcast.i:56: Warning: + signed downcast. assert -2147483648 ≤ p; +[eva:alarm] tests/value/downcast.i:56: Warning: + signed downcast. assert p ≤ 2147483647; +[eva] Recording results for main4_pointer +[eva] Done for function main4_pointer +[eva] computing for function main5_wrap_signed <- main. + Called from tests/value/downcast.i:160. +[eva:alarm] tests/value/downcast.i:62: Warning: + assertion 'ASSUME' got status unknown. +[eva] tests/value/downcast.i:63: assertion got status valid. +[eva:alarm] tests/value/downcast.i:66: Warning: + signed downcast. assert y ≤ 2147483647; +[eva] tests/value/downcast.i:67: + Frama_C_show_each: + [100000..2147483647], [100145..2147483647], [100145..2147483647] +[eva] tests/value/downcast.i:68: assertion got status valid. +[eva] Recording results for main5_wrap_signed +[eva] Done for function main5_wrap_signed +[eva] computing for function main6_val_warn_converted_signed <- main. + Called from tests/value/downcast.i:161. +[eva:alarm] tests/value/downcast.i:75: Warning: + signed downcast. assert 65300u ≤ 32767; +[eva:alarm] tests/value/downcast.i:86: Warning: + signed downcast. assert e_0 ≤ 32767; +[eva:alarm] tests/value/downcast.i:91: Warning: + signed downcast. assert e_1 ≤ 32767; +[eva:alarm] tests/value/downcast.i:95: Warning: + pointer downcast. assert (unsigned int)p ≤ 2147483647; +[eva:alarm] tests/value/downcast.i:96: Warning: + pointer downcast. assert (unsigned int)p ≤ 32767; +[eva:alarm] tests/value/downcast.i:97: Warning: + pointer downcast. assert (unsigned int)p ≤ 65535; +[eva] Recording results for main6_val_warn_converted_signed +[eva] Done for function main6_val_warn_converted_signed +[eva] computing for function main7_signed_upcast <- main. + Called from tests/value/downcast.i:162. +[eva] Recording results for main7_signed_upcast +[eva] Done for function main7_signed_upcast +[eva] computing for function main8_bitfields <- main. + Called from tests/value/downcast.i:163. +[eva:alarm] tests/value/downcast.i:118: Warning: + signed downcast. assert S.i1 ≤ 31; +[eva:alarm] tests/value/downcast.i:119: Warning: + signed downcast. assert S.i1 ≤ 127; +[eva:alarm] tests/value/downcast.i:123: Warning: + signed downcast. assert S.i1 ≤ 31; +[eva:alarm] tests/value/downcast.i:124: Warning: + signed downcast. assert S.i1 ≤ 127; +[eva:alarm] tests/value/downcast.i:128: Warning: + signed downcast. assert S.i1 ≤ 31; +[eva] Recording results for main8_bitfields +[eva] Done for function main8_bitfields +[eva] computing for function main9_bitfield <- main. + Called from tests/value/downcast.i:164. +[eva:alarm] tests/value/downcast.i:137: Warning: + signed downcast. assert bf.a ≤ 1023; +[eva:alarm] tests/value/downcast.i:141: Warning: + signed downcast. assert bf.a ≤ 127; +[eva] Recording results for main9_bitfield +[eva] Done for function main9_bitfield +[eva] computing for function main10_loop <- main. + Called from tests/value/downcast.i:165. +[eva:alarm] tests/value/downcast.i:151: Warning: + signed downcast. assert bf.b ≤ 127; +[eva] tests/value/downcast.i:149: starting to merge loop iterations +[eva] Recording results for main10_loop +[eva] Done for function main10_loop +[eva] Recording results for main +[eva] done for function main +[eva] tests/value/downcast.i:36: + assertion 'Eva,signed_downcast' got final status invalid. +[eva] tests/value/downcast.i:75: + assertion 'Eva,signed_downcast' got final status invalid. +[eva] tests/value/downcast.i:86: + assertion 'Eva,signed_downcast' got final status invalid. +[eva] tests/value/downcast.i:91: + assertion 'Eva,signed_downcast' got final status invalid. +[eva] tests/value/downcast.i:118: + assertion 'Eva,signed_downcast' got final status invalid. +[eva] tests/value/downcast.i:119: + assertion 'Eva,signed_downcast' got final status invalid. +[eva] tests/value/downcast.i:123: + assertion 'Eva,signed_downcast' got final status invalid. +[eva] tests/value/downcast.i:124: + assertion 'Eva,signed_downcast' got final status invalid. +[eva] tests/value/downcast.i:128: + assertion 'Eva,signed_downcast' got final status invalid. +[eva] tests/value/downcast.i:137: + assertion 'Eva,signed_downcast' got final status invalid. +[eva] tests/value/downcast.i:141: + assertion 'Eva,signed_downcast' got final status invalid. +[eva] ====== VALUES COMPUTED ====== +[eva:final-states] Values at end of function main1: + sz ∈ [--..--] + uc ∈ [--..--] + x ∈ [0..2147483647] + ux ∈ [--..--] + s ∈ [--..--] +[eva:final-states] Values at end of function main10_loop: + c ∈ [0..127] or UNINITIALIZED + bf.b ∈ [--..--] or UNINITIALIZED + .[bits 10 to 31] ∈ UNINITIALIZED + k ∈ {10} +[eva:final-states] Values at end of function main2_bitfield: + i ∈ {117} + j ∈ {254} + ss.i ∈ UNINITIALIZED + .j ∈ {30} or UNINITIALIZED + .[bits 10 to 31] ∈ UNINITIALIZED +[eva:final-states] Values at end of function main3_reduction: + x_0 ∈ [-128..127] + c ∈ [--..--] + y ∈ [--..--] + d ∈ [--..--] +[eva:final-states] Values at end of function main4_pointer: + p ∈ {{ &x_0 + {100} }} + q ∈ {{ &x_0 + {100} }} + r ∈ {{ &x_0 + {100} }} +[eva:final-states] Values at end of function main5_wrap_signed: + x_0 ∈ [100000..2147483647] + y ∈ [100145..2147483647] + z ∈ [100145..2147483647] +[eva:final-states] Values at end of function main6_val_warn_converted_signed: + +[eva:final-states] Values at end of function main7_signed_upcast: + c ∈ {240} + i ∈ {240} +[eva:final-states] Values at end of function main8_bitfields: + S.i1 ∈ {65} + {.i2; .[bits 24 to 31]} ∈ UNINITIALIZED + c ∈ {65} or UNINITIALIZED +[eva:final-states] Values at end of function main9_bitfield: + bf.a ∈ {1648} + .[bits 11 to 31] ∈ UNINITIALIZED + c ∈ UNINITIALIZED +[eva:final-states] Values at end of function main: + sz ∈ [--..--] + uc ∈ [--..--] + x ∈ [0..2147483647] + ux ∈ [--..--] + s ∈ [--..--] +[from] Computing for function main1 +[from] Done for function main1 +[from] Computing for function main10_loop +[from] Done for function main10_loop +[from] Computing for function main2_bitfield +[from] Done for function main2_bitfield +[from] Computing for function main3_reduction +[from] Done for function main3_reduction +[from] Computing for function main4_pointer +[from] Done for function main4_pointer +[from] Computing for function main5_wrap_signed +[from] Done for function main5_wrap_signed +[from] Computing for function main6_val_warn_converted_signed +[from] Done for function main6_val_warn_converted_signed +[from] Computing for function main7_signed_upcast +[from] Done for function main7_signed_upcast +[from] Computing for function main8_bitfields +[from] Done for function main8_bitfields +[from] Computing for function main9_bitfield +[from] Done for function main9_bitfield +[from] Computing for function main +[from] Done for function main +[from] ====== DEPENDENCIES COMPUTED ====== + These dependencies hold at termination for the executions that terminate: +[from] Function main1: + sz FROM sx; sy + uc FROM x + x FROM uy; uz + ux FROM uy; uz + s FROM uy; uz +[from] Function main10_loop: + NO EFFECTS +[from] Function main2_bitfield: + NO EFFECTS +[from] Function main3_reduction: + NO EFFECTS +[from] Function main4_pointer: + NO EFFECTS +[from] Function main5_wrap_signed: + NO EFFECTS +[from] Function main6_val_warn_converted_signed: + NO EFFECTS +[from] Function main7_signed_upcast: + NO EFFECTS +[from] Function main8_bitfields: + NO EFFECTS +[from] Function main9_bitfield: + NO EFFECTS +[from] Function main: + sz FROM sx; sy + uc FROM x + x FROM uy; uz + ux FROM uy; uz + s FROM uy; uz +[from] ====== END OF DEPENDENCIES ====== +[inout] Out (internal) for function main1: + sz; uc; x; ux; s +[inout] Inputs for function main1: + sx; sy; x; uy; uz +[inout] Out (internal) for function main10_loop: + c; bf.b; k +[inout] Inputs for function main10_loop: + v +[inout] Out (internal) for function main2_bitfield: + i; j; ss{.i; .j} +[inout] Inputs for function main2_bitfield: + v +[inout] Out (internal) for function main3_reduction: + x_0; c; y; d +[inout] Inputs for function main3_reduction: + v +[inout] Out (internal) for function main4_pointer: + p; q; r +[inout] Inputs for function main4_pointer: + \nothing +[inout] Out (internal) for function main5_wrap_signed: + x_0; y; z +[inout] Inputs for function main5_wrap_signed: + v +[inout] Out (internal) for function main6_val_warn_converted_signed: + s_0; u; e; b; e_0; b_0; e_1; b_1; p; x_0; y; z +[inout] Inputs for function main6_val_warn_converted_signed: + v +[inout] Out (internal) for function main7_signed_upcast: + c; i +[inout] Inputs for function main7_signed_upcast: + \nothing +[inout] Out (internal) for function main8_bitfields: + S{.i1; .i2}; c +[inout] Inputs for function main8_bitfields: + v +[inout] Out (internal) for function main9_bitfield: + bf.a; signed_a; c +[inout] Inputs for function main9_bitfield: + v +[inout] Out (internal) for function main: + sz; uc; x; ux; s +[inout] Inputs for function main: + sx; sy; x; uy; uz; v diff --git a/tests/value/oracle/downcast.2.res.oracle b/tests/value/oracle/downcast.2.res.oracle new file mode 100644 index 00000000000..0c43f9fb2f7 --- /dev/null +++ b/tests/value/oracle/downcast.2.res.oracle @@ -0,0 +1,257 @@ +[kernel] Parsing tests/value/downcast.i (no preprocessing) +[eva] Analyzing an incomplete application starting at main +[eva] Computing initial state +[eva] Initial state computed +[eva:initial-state] Values of globals at initialization + sx ∈ [--..--] + sy ∈ [--..--] + sz ∈ [--..--] + uc ∈ [--..--] + x ∈ [--..--] + ux ∈ [--..--] + uy ∈ [--..--] + uz ∈ [--..--] + s ∈ [--..--] + v ∈ [--..--] +[eva] computing for function main1 <- main. + Called from tests/value/downcast.i:156. +[eva:alarm] tests/value/downcast.i:24: Warning: + unsigned downcast. assert 0 ≤ (int)((int)sx + (int)sy); +[eva:alarm] tests/value/downcast.i:25: Warning: + unsigned downcast. assert 0 ≤ x; +[eva:alarm] tests/value/downcast.i:25: Warning: + unsigned downcast. assert x ≤ 255; +[eva:alarm] tests/value/downcast.i:28: Warning: + unsigned downcast. assert (unsigned int)(uy + uz) ≤ 65535; +[eva] Recording results for main1 +[eva] Done for function main1 +[eva] computing for function main2_bitfield <- main. + Called from tests/value/downcast.i:157. +[eva:alarm] tests/value/downcast.i:37: Warning: + unsigned downcast. assert j ≤ 31; +[eva] Recording results for main2_bitfield +[eva] Done for function main2_bitfield +[eva] computing for function main3_reduction <- main. + Called from tests/value/downcast.i:158. +[eva:alarm] tests/value/downcast.i:44: Warning: + unsigned downcast. assert 0 ≤ v; +[eva:alarm] tests/value/downcast.i:45: Warning: + unsigned downcast. assert y ≤ 255; +[eva] Recording results for main3_reduction +[eva] Done for function main3_reduction +[eva] computing for function main4_pointer <- main. + Called from tests/value/downcast.i:159. +[eva:alarm] tests/value/downcast.i:54: Warning: + signed overflow. assert -9223372036854775808 ≤ p + (long long)100; +[eva:alarm] tests/value/downcast.i:54: Warning: + signed overflow. assert p + (long long)100 ≤ 9223372036854775807; +[eva:alarm] tests/value/downcast.i:55: Warning: + unsigned downcast. assert 0 ≤ p; +[eva:alarm] tests/value/downcast.i:55: Warning: + unsigned downcast. assert p ≤ 4294967295; +[eva] Recording results for main4_pointer +[eva] Done for function main4_pointer +[eva] computing for function main5_wrap_signed <- main. + Called from tests/value/downcast.i:160. +[eva:alarm] tests/value/downcast.i:62: Warning: + assertion 'ASSUME' got status unknown. +[eva] tests/value/downcast.i:63: assertion got status valid. +[eva] tests/value/downcast.i:67: + Frama_C_show_each: + [100000..2147483647], [100145..2147483792], [-2147483648..2147483647] +[eva:alarm] tests/value/downcast.i:68: Warning: assertion got status unknown. +[eva] Recording results for main5_wrap_signed +[eva] Done for function main5_wrap_signed +[eva] computing for function main6_val_warn_converted_signed <- main. + Called from tests/value/downcast.i:161. +[eva:alarm] tests/value/downcast.i:85: Warning: + unsigned downcast. assert 0 ≤ (int)(-12); +[eva:alarm] tests/value/downcast.i:90: Warning: + unsigned downcast. assert 0 ≤ (int)(-64000); +[eva:alarm] tests/value/downcast.i:95: Warning: + pointer downcast. assert (unsigned int)p ≤ 2147483647; +[eva:alarm] tests/value/downcast.i:96: Warning: + pointer downcast. assert (unsigned int)p ≤ 32767; +[eva:alarm] tests/value/downcast.i:97: Warning: + pointer downcast. assert (unsigned int)p ≤ 65535; +[eva] Recording results for main6_val_warn_converted_signed +[eva] Done for function main6_val_warn_converted_signed +[eva] computing for function main7_signed_upcast <- main. + Called from tests/value/downcast.i:162. +[eva] Recording results for main7_signed_upcast +[eva] Done for function main7_signed_upcast +[eva] computing for function main8_bitfields <- main. + Called from tests/value/downcast.i:163. +[eva] Recording results for main8_bitfields +[eva] Done for function main8_bitfields +[eva] computing for function main9_bitfield <- main. + Called from tests/value/downcast.i:164. +[eva] tests/value/downcast.i:138: assertion got status valid. +[eva] Recording results for main9_bitfield +[eva] Done for function main9_bitfield +[eva] computing for function main10_loop <- main. + Called from tests/value/downcast.i:165. +[eva:alarm] tests/value/downcast.i:150: Warning: + unsigned downcast. assert 0 ≤ v; +[eva:alarm] tests/value/downcast.i:150: Warning: + unsigned downcast. assert v ≤ 1023; +[eva] tests/value/downcast.i:149: starting to merge loop iterations +[eva] Recording results for main10_loop +[eva] Done for function main10_loop +[eva] Recording results for main +[eva] done for function main +[eva] tests/value/downcast.i:37: + assertion 'Eva,unsigned_downcast' got final status invalid. +[eva] tests/value/downcast.i:85: + assertion 'Eva,unsigned_downcast' got final status invalid. +[eva] tests/value/downcast.i:90: + assertion 'Eva,unsigned_downcast' got final status invalid. +[eva] ====== VALUES COMPUTED ====== +[eva:final-states] Values at end of function main1: + sz ∈ [--..--] + uc ∈ [--..--] + x ∈ [--..--] + ux ∈ [--..--] + s ∈ [--..--] +[eva:final-states] Values at end of function main10_loop: + c ∈ [--..--] or UNINITIALIZED + bf.b ∈ [--..--] or UNINITIALIZED + .[bits 10 to 31] ∈ UNINITIALIZED + k ∈ {10} +[eva:final-states] Values at end of function main2_bitfield: + i ∈ {117} + j ∈ {254} + ss.i ∈ {-11} or UNINITIALIZED + {.j; .[bits 10 to 31]} ∈ UNINITIALIZED +[eva:final-states] Values at end of function main3_reduction: + x_0 ∈ [--..--] + c ∈ [--..--] + y ∈ [0..255] + d ∈ [--..--] +[eva:final-states] Values at end of function main4_pointer: + p ∈ {{ &x_0 + {100} }} + q ∈ {{ &x_0 + {100} }} + r ∈ {{ &x_0 + {100} }} +[eva:final-states] Values at end of function main5_wrap_signed: + x_0 ∈ [100000..2147483647] + y ∈ [100145..2147483792] + z ∈ [--..--] +[eva:final-states] Values at end of function main6_val_warn_converted_signed: + +[eva:final-states] Values at end of function main7_signed_upcast: + c ∈ {240} + i ∈ {240} +[eva:final-states] Values at end of function main8_bitfields: + S.i1 ∈ {65} + .i2 ∈ {-1; 1} or UNINITIALIZED + .[bits 24 to 31] ∈ UNINITIALIZED + c ∈ {-1; 1; 65} or UNINITIALIZED +[eva:final-states] Values at end of function main9_bitfield: + bf.a ∈ {1648} + .[bits 11 to 31] ∈ UNINITIALIZED + c ∈ {112} or UNINITIALIZED +[eva:final-states] Values at end of function main: + sz ∈ [--..--] + uc ∈ [--..--] + x ∈ [--..--] + ux ∈ [--..--] + s ∈ [--..--] +[from] Computing for function main1 +[from] Done for function main1 +[from] Computing for function main10_loop +[from] Done for function main10_loop +[from] Computing for function main2_bitfield +[from] Done for function main2_bitfield +[from] Computing for function main3_reduction +[from] Done for function main3_reduction +[from] Computing for function main4_pointer +[from] Done for function main4_pointer +[from] Computing for function main5_wrap_signed +[from] Done for function main5_wrap_signed +[from] Computing for function main6_val_warn_converted_signed +[from] Done for function main6_val_warn_converted_signed +[from] Computing for function main7_signed_upcast +[from] Done for function main7_signed_upcast +[from] Computing for function main8_bitfields +[from] Done for function main8_bitfields +[from] Computing for function main9_bitfield +[from] Done for function main9_bitfield +[from] Computing for function main +[from] Done for function main +[from] ====== DEPENDENCIES COMPUTED ====== + These dependencies hold at termination for the executions that terminate: +[from] Function main1: + sz FROM sx; sy + uc FROM x + x FROM uy; uz + ux FROM uy; uz + s FROM uy; uz +[from] Function main10_loop: + NO EFFECTS +[from] Function main2_bitfield: + NO EFFECTS +[from] Function main3_reduction: + NO EFFECTS +[from] Function main4_pointer: + NO EFFECTS +[from] Function main5_wrap_signed: + NO EFFECTS +[from] Function main6_val_warn_converted_signed: + NO EFFECTS +[from] Function main7_signed_upcast: + NO EFFECTS +[from] Function main8_bitfields: + NO EFFECTS +[from] Function main9_bitfield: + NO EFFECTS +[from] Function main: + sz FROM sx; sy + uc FROM x + x FROM uy; uz + ux FROM uy; uz + s FROM uy; uz +[from] ====== END OF DEPENDENCIES ====== +[inout] Out (internal) for function main1: + sz; uc; x; ux; s +[inout] Inputs for function main1: + sx; sy; x; uy; uz +[inout] Out (internal) for function main10_loop: + c; bf.b; k +[inout] Inputs for function main10_loop: + v +[inout] Out (internal) for function main2_bitfield: + i; j; ss{.i; .j} +[inout] Inputs for function main2_bitfield: + v +[inout] Out (internal) for function main3_reduction: + x_0; c; y; d +[inout] Inputs for function main3_reduction: + v +[inout] Out (internal) for function main4_pointer: + p; q; r +[inout] Inputs for function main4_pointer: + \nothing +[inout] Out (internal) for function main5_wrap_signed: + x_0; y; z +[inout] Inputs for function main5_wrap_signed: + v +[inout] Out (internal) for function main6_val_warn_converted_signed: + s_0; u; e; b; e_0; e_1; p; x_0; y; z +[inout] Inputs for function main6_val_warn_converted_signed: + v +[inout] Out (internal) for function main7_signed_upcast: + c; i +[inout] Inputs for function main7_signed_upcast: + \nothing +[inout] Out (internal) for function main8_bitfields: + S{.i1; .i2}; c +[inout] Inputs for function main8_bitfields: + v +[inout] Out (internal) for function main9_bitfield: + bf.a; signed_a; c +[inout] Inputs for function main9_bitfield: + v +[inout] Out (internal) for function main: + sz; uc; x; ux; s +[inout] Inputs for function main: + sx; sy; x; uy; uz; v diff --git a/tests/value/oracle/downcast.3.res.oracle b/tests/value/oracle/downcast.3.res.oracle new file mode 100644 index 00000000000..d25d52f4759 --- /dev/null +++ b/tests/value/oracle/downcast.3.res.oracle @@ -0,0 +1,270 @@ +[kernel] Parsing tests/value/downcast.i (no preprocessing) +[eva] Analyzing an incomplete application starting at main +[eva] Computing initial state +[eva] Initial state computed +[eva:initial-state] Values of globals at initialization + sx ∈ [--..--] + sy ∈ [--..--] + sz ∈ [--..--] + uc ∈ [--..--] + x ∈ [--..--] + ux ∈ [--..--] + uy ∈ [--..--] + uz ∈ [--..--] + s ∈ [--..--] + v ∈ [--..--] +[eva] computing for function main1 <- main. + Called from tests/value/downcast.i:156. +[eva:alarm] tests/value/downcast.i:23: Warning: + signed downcast. assert -128 ≤ (int)((int)sx + (int)sy); +[eva:alarm] tests/value/downcast.i:23: Warning: + signed downcast. assert (int)((int)sx + (int)sy) ≤ 127; +[eva] Recording results for main1 +[eva] Done for function main1 +[eva] computing for function main2_bitfield <- main. + Called from tests/value/downcast.i:157. +[eva:alarm] tests/value/downcast.i:36: Warning: + signed downcast. assert i ≤ 15; +[eva] Recording results for main2_bitfield +[eva] Done for function main2_bitfield +[eva] computing for function main3_reduction <- main. + Called from tests/value/downcast.i:158. +[eva:alarm] tests/value/downcast.i:42: Warning: + signed downcast. assert -128 ≤ x_0; +[eva:alarm] tests/value/downcast.i:42: Warning: + signed downcast. assert x_0 ≤ 127; +[eva] Recording results for main3_reduction +[eva] Done for function main3_reduction +[eva] computing for function main4_pointer <- main. + Called from tests/value/downcast.i:159. +[eva:alarm] tests/value/downcast.i:54: Warning: + signed overflow. assert -9223372036854775808 ≤ p + (long long)100; +[eva:alarm] tests/value/downcast.i:54: Warning: + signed overflow. assert p + (long long)100 ≤ 9223372036854775807; +[eva:alarm] tests/value/downcast.i:56: Warning: + signed downcast. assert -2147483648 ≤ p; +[eva:alarm] tests/value/downcast.i:56: Warning: + signed downcast. assert p ≤ 2147483647; +[eva] Recording results for main4_pointer +[eva] Done for function main4_pointer +[eva] computing for function main5_wrap_signed <- main. + Called from tests/value/downcast.i:160. +[eva:alarm] tests/value/downcast.i:62: Warning: + assertion 'ASSUME' got status unknown. +[eva] tests/value/downcast.i:63: assertion got status valid. +[eva] tests/value/downcast.i:67: + Frama_C_show_each: + [100000..2147483647], [100145..2147483792], [-2147483648..2147483647] +[eva:alarm] tests/value/downcast.i:68: Warning: assertion got status unknown. +[eva] Recording results for main5_wrap_signed +[eva] Done for function main5_wrap_signed +[eva] computing for function main6_val_warn_converted_signed <- main. + Called from tests/value/downcast.i:161. +[eva:alarm] tests/value/downcast.i:75: Warning: + signed downcast. assert (int)65300u ≤ 32767; +[eva:alarm] tests/value/downcast.i:91: Warning: + signed downcast. assert -32768 ≤ (int)e_1; +[eva:alarm] tests/value/downcast.i:95: Warning: + pointer downcast. assert (unsigned int)p ≤ 2147483647; +[eva:alarm] tests/value/downcast.i:96: Warning: + pointer downcast. assert (unsigned int)p ≤ 32767; +[eva:alarm] tests/value/downcast.i:97: Warning: + pointer downcast. assert (unsigned int)p ≤ 65535; +[eva] Recording results for main6_val_warn_converted_signed +[eva] Done for function main6_val_warn_converted_signed +[eva] computing for function main7_signed_upcast <- main. + Called from tests/value/downcast.i:162. +[eva] Recording results for main7_signed_upcast +[eva] Done for function main7_signed_upcast +[eva] computing for function main8_bitfields <- main. + Called from tests/value/downcast.i:163. +[eva:alarm] tests/value/downcast.i:123: Warning: + signed downcast. assert (int)S.i1 ≤ 31; +[eva:alarm] tests/value/downcast.i:124: Warning: + signed downcast. assert (int)S.i1 ≤ 127; +[eva:alarm] tests/value/downcast.i:128: Warning: + signed downcast. assert (int)S.i1 ≤ 31; +[eva] Recording results for main8_bitfields +[eva] Done for function main8_bitfields +[eva] computing for function main9_bitfield <- main. + Called from tests/value/downcast.i:164. +[eva] tests/value/downcast.i:138: assertion got status valid. +[eva:alarm] tests/value/downcast.i:141: Warning: + signed downcast. assert -128 ≤ (int)bf.a; +[eva] Recording results for main9_bitfield +[eva] Done for function main9_bitfield +[eva] computing for function main10_loop <- main. + Called from tests/value/downcast.i:165. +[eva:alarm] tests/value/downcast.i:151: Warning: + signed downcast. assert -128 ≤ (int)bf.b; +[eva:alarm] tests/value/downcast.i:151: Warning: + signed downcast. assert (int)bf.b ≤ 127; +[eva] tests/value/downcast.i:149: starting to merge loop iterations +[eva] Recording results for main10_loop +[eva] Done for function main10_loop +[eva] Recording results for main +[eva] done for function main +[eva] tests/value/downcast.i:36: + assertion 'Eva,signed_downcast' got final status invalid. +[eva] tests/value/downcast.i:75: + assertion 'Eva,signed_downcast' got final status invalid. +[eva] tests/value/downcast.i:91: + assertion 'Eva,signed_downcast' got final status invalid. +[eva] tests/value/downcast.i:123: + assertion 'Eva,signed_downcast' got final status invalid. +[eva] tests/value/downcast.i:124: + assertion 'Eva,signed_downcast' got final status invalid. +[eva] tests/value/downcast.i:128: + assertion 'Eva,signed_downcast' got final status invalid. +[eva] tests/value/downcast.i:141: + assertion 'Eva,signed_downcast' got final status invalid. +[eva] ====== VALUES COMPUTED ====== +[eva:final-states] Values at end of function main1: + sz ∈ [--..--] + uc ∈ [--..--] + x ∈ [--..--] + ux ∈ [--..--] + s ∈ [--..--] +[eva:final-states] Values at end of function main10_loop: + c ∈ [--..--] or UNINITIALIZED + bf.b ∈ [--..--] or UNINITIALIZED + .[bits 10 to 31] ∈ UNINITIALIZED + k ∈ {10} +[eva:final-states] Values at end of function main2_bitfield: + i ∈ {117} + j ∈ {254} + ss.i ∈ UNINITIALIZED + .j ∈ {30} or UNINITIALIZED + .[bits 10 to 31] ∈ UNINITIALIZED +[eva:final-states] Values at end of function main3_reduction: + x_0 ∈ [-128..127] + c ∈ [--..--] + y ∈ [--..--] + d ∈ [--..--] +[eva:final-states] Values at end of function main4_pointer: + p ∈ {{ &x_0 + {100} }} + q ∈ {{ &x_0 + {100} }} + r ∈ {{ &x_0 + {100} }} +[eva:final-states] Values at end of function main5_wrap_signed: + x_0 ∈ [100000..2147483647] + y ∈ [100145..2147483792] + z ∈ [--..--] +[eva:final-states] Values at end of function main6_val_warn_converted_signed: + +[eva:final-states] Values at end of function main7_signed_upcast: + c ∈ {240} + i ∈ {240} +[eva:final-states] Values at end of function main8_bitfields: + S.i1 ∈ {65} + .i2 ∈ {-1} or UNINITIALIZED + .[bits 24 to 31] ∈ UNINITIALIZED + c ∈ {-1; 65} or UNINITIALIZED +[eva:final-states] Values at end of function main9_bitfield: + bf.a ∈ {1648} + .[bits 11 to 31] ∈ UNINITIALIZED + c ∈ UNINITIALIZED +[eva:final-states] Values at end of function main: + sz ∈ [--..--] + uc ∈ [--..--] + x ∈ [--..--] + ux ∈ [--..--] + s ∈ [--..--] +[from] Computing for function main1 +[from] Done for function main1 +[from] Computing for function main10_loop +[from] Done for function main10_loop +[from] Computing for function main2_bitfield +[from] Done for function main2_bitfield +[from] Computing for function main3_reduction +[from] Done for function main3_reduction +[from] Computing for function main4_pointer +[from] Done for function main4_pointer +[from] Computing for function main5_wrap_signed +[from] Done for function main5_wrap_signed +[from] Computing for function main6_val_warn_converted_signed +[from] Done for function main6_val_warn_converted_signed +[from] Computing for function main7_signed_upcast +[from] Done for function main7_signed_upcast +[from] Computing for function main8_bitfields +[from] Done for function main8_bitfields +[from] Computing for function main9_bitfield +[from] Done for function main9_bitfield +[from] Computing for function main +[from] Done for function main +[from] ====== DEPENDENCIES COMPUTED ====== + These dependencies hold at termination for the executions that terminate: +[from] Function main1: + sz FROM sx; sy + uc FROM x + x FROM uy; uz + ux FROM uy; uz + s FROM uy; uz +[from] Function main10_loop: + NO EFFECTS +[from] Function main2_bitfield: + NO EFFECTS +[from] Function main3_reduction: + NO EFFECTS +[from] Function main4_pointer: + NO EFFECTS +[from] Function main5_wrap_signed: + NO EFFECTS +[from] Function main6_val_warn_converted_signed: + NO EFFECTS +[from] Function main7_signed_upcast: + NO EFFECTS +[from] Function main8_bitfields: + NO EFFECTS +[from] Function main9_bitfield: + NO EFFECTS +[from] Function main: + sz FROM sx; sy + uc FROM x + x FROM uy; uz + ux FROM uy; uz + s FROM uy; uz +[from] ====== END OF DEPENDENCIES ====== +[inout] Out (internal) for function main1: + sz; uc; x; ux; s +[inout] Inputs for function main1: + sx; sy; x; uy; uz +[inout] Out (internal) for function main10_loop: + c; bf.b; k +[inout] Inputs for function main10_loop: + v +[inout] Out (internal) for function main2_bitfield: + i; j; ss{.i; .j} +[inout] Inputs for function main2_bitfield: + v +[inout] Out (internal) for function main3_reduction: + x_0; c; y; d +[inout] Inputs for function main3_reduction: + v +[inout] Out (internal) for function main4_pointer: + p; q; r +[inout] Inputs for function main4_pointer: + \nothing +[inout] Out (internal) for function main5_wrap_signed: + x_0; y; z +[inout] Inputs for function main5_wrap_signed: + v +[inout] Out (internal) for function main6_val_warn_converted_signed: + s_0; u; e; b; e_0; b_0; e_1; b_1; p; x_0; y; z +[inout] Inputs for function main6_val_warn_converted_signed: + v +[inout] Out (internal) for function main7_signed_upcast: + c; i +[inout] Inputs for function main7_signed_upcast: + \nothing +[inout] Out (internal) for function main8_bitfields: + S{.i1; .i2}; c +[inout] Inputs for function main8_bitfields: + v +[inout] Out (internal) for function main9_bitfield: + bf.a; signed_a; c +[inout] Inputs for function main9_bitfield: + v +[inout] Out (internal) for function main: + sz; uc; x; ux; s +[inout] Inputs for function main: + sx; sy; x; uy; uz; v diff --git a/tests/value/oracle/downcast.4.res.oracle b/tests/value/oracle/downcast.4.res.oracle new file mode 100644 index 00000000000..d691ffe3fe1 --- /dev/null +++ b/tests/value/oracle/downcast.4.res.oracle @@ -0,0 +1,226 @@ +[kernel] Parsing tests/value/downcast.i (no preprocessing) +[eva] Analyzing an incomplete application starting at main +[eva] Computing initial state +[eva] Initial state computed +[eva:initial-state] Values of globals at initialization + sx ∈ [--..--] + sy ∈ [--..--] + sz ∈ [--..--] + uc ∈ [--..--] + x ∈ [--..--] + ux ∈ [--..--] + uy ∈ [--..--] + uz ∈ [--..--] + s ∈ [--..--] + v ∈ [--..--] +[eva] computing for function main1 <- main. + Called from tests/value/downcast.i:156. +[eva] Recording results for main1 +[eva] Done for function main1 +[eva] computing for function main2_bitfield <- main. + Called from tests/value/downcast.i:157. +[eva] Recording results for main2_bitfield +[eva] Done for function main2_bitfield +[eva] computing for function main3_reduction <- main. + Called from tests/value/downcast.i:158. +[eva] Recording results for main3_reduction +[eva] Done for function main3_reduction +[eva] computing for function main4_pointer <- main. + Called from tests/value/downcast.i:159. +[eva:alarm] tests/value/downcast.i:54: Warning: + signed overflow. assert -9223372036854775808 ≤ p + (long long)100; +[eva:alarm] tests/value/downcast.i:54: Warning: + signed overflow. assert p + (long long)100 ≤ 9223372036854775807; +[eva] Recording results for main4_pointer +[eva] Done for function main4_pointer +[eva] computing for function main5_wrap_signed <- main. + Called from tests/value/downcast.i:160. +[eva:alarm] tests/value/downcast.i:62: Warning: + assertion 'ASSUME' got status unknown. +[eva] tests/value/downcast.i:63: assertion got status valid. +[eva] tests/value/downcast.i:67: + Frama_C_show_each: + [100000..2147483647], [100145..2147483792], [-2147483648..2147483647] +[eva:alarm] tests/value/downcast.i:68: Warning: assertion got status unknown. +[eva] Recording results for main5_wrap_signed +[eva] Done for function main5_wrap_signed +[eva] computing for function main6_val_warn_converted_signed <- main. + Called from tests/value/downcast.i:161. +[eva] tests/value/downcast.i:96: + Assigning imprecise value to y. + The imprecision originates from Arithmetic {tests/value/downcast.i:96} +[eva] tests/value/downcast.i:97: + Assigning imprecise value to z. + The imprecision originates from Arithmetic {tests/value/downcast.i:97} +[eva] Recording results for main6_val_warn_converted_signed +[eva] Done for function main6_val_warn_converted_signed +[eva] computing for function main7_signed_upcast <- main. + Called from tests/value/downcast.i:162. +[eva] Recording results for main7_signed_upcast +[eva] Done for function main7_signed_upcast +[eva] computing for function main8_bitfields <- main. + Called from tests/value/downcast.i:163. +[eva] Recording results for main8_bitfields +[eva] Done for function main8_bitfields +[eva] computing for function main9_bitfield <- main. + Called from tests/value/downcast.i:164. +[eva] tests/value/downcast.i:138: assertion got status valid. +[eva] Recording results for main9_bitfield +[eva] Done for function main9_bitfield +[eva] computing for function main10_loop <- main. + Called from tests/value/downcast.i:165. +[eva] tests/value/downcast.i:149: starting to merge loop iterations +[eva] Recording results for main10_loop +[eva] Done for function main10_loop +[eva] Recording results for main +[eva] done for function main +[eva] ====== VALUES COMPUTED ====== +[eva:final-states] Values at end of function main1: + sz ∈ [--..--] + uc ∈ [--..--] + x ∈ [--..--] + ux ∈ [--..--] + s ∈ [--..--] +[eva:final-states] Values at end of function main10_loop: + c ∈ [--..--] or UNINITIALIZED + bf.b ∈ [--..--] or UNINITIALIZED + .[bits 10 to 31] ∈ UNINITIALIZED + k ∈ {10} +[eva:final-states] Values at end of function main2_bitfield: + i ∈ {117} + j ∈ {254} + ss.i ∈ {-11} or UNINITIALIZED + .j ∈ {30} or UNINITIALIZED + .[bits 10 to 31] ∈ UNINITIALIZED +[eva:final-states] Values at end of function main3_reduction: + x_0 ∈ [--..--] + c ∈ [--..--] + y ∈ [--..--] + d ∈ [--..--] +[eva:final-states] Values at end of function main4_pointer: + p ∈ {{ &x_0 + {100} }} + q ∈ {{ &x_0 + {100} }} + r ∈ {{ &x_0 + {100} }} +[eva:final-states] Values at end of function main5_wrap_signed: + x_0 ∈ [100000..2147483647] + y ∈ [100145..2147483792] + z ∈ [--..--] +[eva:final-states] Values at end of function main6_val_warn_converted_signed: + +[eva:final-states] Values at end of function main7_signed_upcast: + c ∈ {240} + i ∈ {240} +[eva:final-states] Values at end of function main8_bitfields: + S.i1 ∈ {65} + .i2 ∈ {-1; 1} or UNINITIALIZED + .[bits 24 to 31] ∈ UNINITIALIZED + c ∈ {-1; 1; 65} or UNINITIALIZED +[eva:final-states] Values at end of function main9_bitfield: + bf.a ∈ {1648} + .[bits 11 to 31] ∈ UNINITIALIZED + c ∈ {112} or UNINITIALIZED +[eva:final-states] Values at end of function main: + sz ∈ [--..--] + uc ∈ [--..--] + x ∈ [--..--] + ux ∈ [--..--] + s ∈ [--..--] +[from] Computing for function main1 +[from] Done for function main1 +[from] Computing for function main10_loop +[from] Done for function main10_loop +[from] Computing for function main2_bitfield +[from] Done for function main2_bitfield +[from] Computing for function main3_reduction +[from] Done for function main3_reduction +[from] Computing for function main4_pointer +[from] Done for function main4_pointer +[from] Computing for function main5_wrap_signed +[from] Done for function main5_wrap_signed +[from] Computing for function main6_val_warn_converted_signed +[from] Done for function main6_val_warn_converted_signed +[from] Computing for function main7_signed_upcast +[from] Done for function main7_signed_upcast +[from] Computing for function main8_bitfields +[from] Done for function main8_bitfields +[from] Computing for function main9_bitfield +[from] Done for function main9_bitfield +[from] Computing for function main +[from] Done for function main +[from] ====== DEPENDENCIES COMPUTED ====== + These dependencies hold at termination for the executions that terminate: +[from] Function main1: + sz FROM sx; sy + uc FROM x + x FROM uy; uz + ux FROM uy; uz + s FROM uy; uz +[from] Function main10_loop: + NO EFFECTS +[from] Function main2_bitfield: + NO EFFECTS +[from] Function main3_reduction: + NO EFFECTS +[from] Function main4_pointer: + NO EFFECTS +[from] Function main5_wrap_signed: + NO EFFECTS +[from] Function main6_val_warn_converted_signed: + NO EFFECTS +[from] Function main7_signed_upcast: + NO EFFECTS +[from] Function main8_bitfields: + NO EFFECTS +[from] Function main9_bitfield: + NO EFFECTS +[from] Function main: + sz FROM sx; sy + uc FROM x + x FROM uy; uz + ux FROM uy; uz + s FROM uy; uz +[from] ====== END OF DEPENDENCIES ====== +[inout] Out (internal) for function main1: + sz; uc; x; ux; s +[inout] Inputs for function main1: + sx; sy; x; uy; uz +[inout] Out (internal) for function main10_loop: + c; bf.b; k +[inout] Inputs for function main10_loop: + v +[inout] Out (internal) for function main2_bitfield: + i; j; ss{.i; .j} +[inout] Inputs for function main2_bitfield: + v +[inout] Out (internal) for function main3_reduction: + x_0; c; y; d +[inout] Inputs for function main3_reduction: + v +[inout] Out (internal) for function main4_pointer: + p; q; r +[inout] Inputs for function main4_pointer: + \nothing +[inout] Out (internal) for function main5_wrap_signed: + x_0; y; z +[inout] Inputs for function main5_wrap_signed: + v +[inout] Out (internal) for function main6_val_warn_converted_signed: + s_0; u; e; b; e_0; b_0; e_1; b_1; p; x_0; y; z +[inout] Inputs for function main6_val_warn_converted_signed: + v +[inout] Out (internal) for function main7_signed_upcast: + c; i +[inout] Inputs for function main7_signed_upcast: + \nothing +[inout] Out (internal) for function main8_bitfields: + S{.i1; .i2}; c +[inout] Inputs for function main8_bitfields: + v +[inout] Out (internal) for function main9_bitfield: + bf.a; signed_a; c +[inout] Inputs for function main9_bitfield: + v +[inout] Out (internal) for function main: + sz; uc; x; ux; s +[inout] Inputs for function main: + sx; sy; x; uy; uz; v diff --git a/tests/value/oracle/downcast.res.oracle b/tests/value/oracle/downcast.res.oracle deleted file mode 100644 index 7a4b220648e..00000000000 --- a/tests/value/oracle/downcast.res.oracle +++ /dev/null @@ -1,827 +0,0 @@ -[kernel] Parsing tests/value/downcast.i (no preprocessing) -[eva] Analyzing an incomplete application starting at main -[eva] Computing initial state -[eva] Initial state computed -[eva:initial-state] Values of globals at initialization - sx ∈ [--..--] - sy ∈ [--..--] - sz ∈ [--..--] - uc ∈ [--..--] - x ∈ [--..--] - ux ∈ [--..--] - uy ∈ [--..--] - uz ∈ [--..--] - s ∈ [--..--] - v ∈ [--..--] -[eva] computing for function main1 <- main. - Called from tests/value/downcast.i:152. -[eva:alarm] tests/value/downcast.i:19: Warning: - signed downcast. assert -128 ≤ (int)((int)sx + (int)sy); -[eva:alarm] tests/value/downcast.i:19: Warning: - signed downcast. assert (int)((int)sx + (int)sy) ≤ 127; -[eva:alarm] tests/value/downcast.i:22: Warning: - signed downcast. assert (unsigned int)(uy + uz) ≤ 2147483647; -[eva] Recording results for main1 -[eva] Done for function main1 -[eva] computing for function main2_bitfield <- main. - Called from tests/value/downcast.i:153. -[eva:alarm] tests/value/downcast.i:32: Warning: - signed downcast. assert i ≤ 15; -[eva] Recording results for main2_bitfield -[eva] Done for function main2_bitfield -[eva] computing for function main3_reduction <- main. - Called from tests/value/downcast.i:154. -[eva:alarm] tests/value/downcast.i:38: Warning: - signed downcast. assert -128 ≤ x_0; -[eva:alarm] tests/value/downcast.i:38: Warning: - signed downcast. assert x_0 ≤ 127; -[eva] Recording results for main3_reduction -[eva] Done for function main3_reduction -[eva] computing for function main4_pointer <- main. - Called from tests/value/downcast.i:155. -[eva:alarm] tests/value/downcast.i:50: Warning: - signed overflow. assert -9223372036854775808 ≤ p + (long long)100; -[eva:alarm] tests/value/downcast.i:50: Warning: - signed overflow. assert p + (long long)100 ≤ 9223372036854775807; -[eva:alarm] tests/value/downcast.i:52: Warning: - signed downcast. assert -2147483648 ≤ p; -[eva:alarm] tests/value/downcast.i:52: Warning: - signed downcast. assert p ≤ 2147483647; -[eva] Recording results for main4_pointer -[eva] Done for function main4_pointer -[eva] computing for function main5_wrap_signed <- main. - Called from tests/value/downcast.i:156. -[eva:alarm] tests/value/downcast.i:58: Warning: - assertion 'ASSUME' got status unknown. -[eva] tests/value/downcast.i:59: assertion got status valid. -[eva:alarm] tests/value/downcast.i:62: Warning: - signed downcast. assert y ≤ 2147483647; -[eva] tests/value/downcast.i:63: - Frama_C_show_each: - [100000..2147483647], [100145..2147483647], [100145..2147483647] -[eva] tests/value/downcast.i:64: assertion got status valid. -[eva] Recording results for main5_wrap_signed -[eva] Done for function main5_wrap_signed -[eva] computing for function main6_val_warn_converted_signed <- main. - Called from tests/value/downcast.i:157. -[eva:alarm] tests/value/downcast.i:71: Warning: - signed downcast. assert 65300u ≤ 32767; -[eva:alarm] tests/value/downcast.i:82: Warning: - signed downcast. assert e_0 ≤ 32767; -[eva:alarm] tests/value/downcast.i:87: Warning: - signed downcast. assert e_1 ≤ 32767; -[eva:alarm] tests/value/downcast.i:91: Warning: - pointer downcast. assert (unsigned int)p ≤ 2147483647; -[eva:alarm] tests/value/downcast.i:92: Warning: - pointer downcast. assert (unsigned int)p ≤ 32767; -[eva:alarm] tests/value/downcast.i:93: Warning: - pointer downcast. assert (unsigned int)p ≤ 65535; -[eva] Recording results for main6_val_warn_converted_signed -[eva] Done for function main6_val_warn_converted_signed -[eva] computing for function main7_signed_upcast <- main. - Called from tests/value/downcast.i:158. -[eva] Recording results for main7_signed_upcast -[eva] Done for function main7_signed_upcast -[eva] computing for function main8_bitfields <- main. - Called from tests/value/downcast.i:159. -[eva:alarm] tests/value/downcast.i:114: Warning: - signed downcast. assert S.i1 ≤ 31; -[eva:alarm] tests/value/downcast.i:115: Warning: - signed downcast. assert S.i1 ≤ 127; -[eva:alarm] tests/value/downcast.i:119: Warning: - signed downcast. assert S.i1 ≤ 31; -[eva:alarm] tests/value/downcast.i:120: Warning: - signed downcast. assert S.i1 ≤ 127; -[eva:alarm] tests/value/downcast.i:124: Warning: - signed downcast. assert S.i1 ≤ 31; -[eva] Recording results for main8_bitfields -[eva] Done for function main8_bitfields -[eva] computing for function main9_bitfield <- main. - Called from tests/value/downcast.i:160. -[eva:alarm] tests/value/downcast.i:133: Warning: - signed downcast. assert bf.a ≤ 1023; -[eva:alarm] tests/value/downcast.i:137: Warning: - signed downcast. assert bf.a ≤ 127; -[eva] Recording results for main9_bitfield -[eva] Done for function main9_bitfield -[eva] computing for function main10_loop <- main. - Called from tests/value/downcast.i:161. -[eva:alarm] tests/value/downcast.i:147: Warning: - signed downcast. assert bf.b ≤ 127; -[eva] tests/value/downcast.i:145: starting to merge loop iterations -[eva] Recording results for main10_loop -[eva] Done for function main10_loop -[eva] Recording results for main -[eva] done for function main -[eva] tests/value/downcast.i:32: - assertion 'Eva,signed_downcast' got final status invalid. -[eva] tests/value/downcast.i:71: - assertion 'Eva,signed_downcast' got final status invalid. -[eva] tests/value/downcast.i:82: - assertion 'Eva,signed_downcast' got final status invalid. -[eva] tests/value/downcast.i:87: - assertion 'Eva,signed_downcast' got final status invalid. -[eva] tests/value/downcast.i:114: - assertion 'Eva,signed_downcast' got final status invalid. -[eva] tests/value/downcast.i:115: - assertion 'Eva,signed_downcast' got final status invalid. -[eva] tests/value/downcast.i:119: - assertion 'Eva,signed_downcast' got final status invalid. -[eva] tests/value/downcast.i:120: - assertion 'Eva,signed_downcast' got final status invalid. -[eva] tests/value/downcast.i:124: - assertion 'Eva,signed_downcast' got final status invalid. -[eva] tests/value/downcast.i:133: - assertion 'Eva,signed_downcast' got final status invalid. -[eva] tests/value/downcast.i:137: - assertion 'Eva,signed_downcast' got final status invalid. -[eva] ====== VALUES COMPUTED ====== -[eva:final-states] Values at end of function main1: - sz ∈ [--..--] - uc ∈ [--..--] - x ∈ [0..2147483647] - ux ∈ [--..--] - s ∈ [--..--] -[eva:final-states] Values at end of function main10_loop: - c ∈ [0..127] or UNINITIALIZED - bf.b ∈ [--..--] or UNINITIALIZED - .[bits 10 to 31] ∈ UNINITIALIZED - k ∈ {10} -[eva:final-states] Values at end of function main2_bitfield: - i ∈ {117} - j ∈ {254} - ss.i ∈ UNINITIALIZED - .j ∈ {30} or UNINITIALIZED - .[bits 10 to 31] ∈ UNINITIALIZED -[eva:final-states] Values at end of function main3_reduction: - x_0 ∈ [-128..127] - c ∈ [--..--] - y ∈ [--..--] - d ∈ [--..--] -[eva:final-states] Values at end of function main4_pointer: - p ∈ {{ &x_0 + {100} }} - q ∈ {{ &x_0 + {100} }} - r ∈ {{ &x_0 + {100} }} -[eva:final-states] Values at end of function main5_wrap_signed: - x_0 ∈ [100000..2147483647] - y ∈ [100145..2147483647] - z ∈ [100145..2147483647] -[eva:final-states] Values at end of function main6_val_warn_converted_signed: - -[eva:final-states] Values at end of function main7_signed_upcast: - c ∈ {240} - i ∈ {240} -[eva:final-states] Values at end of function main8_bitfields: - S.i1 ∈ {65} - {.i2; .[bits 24 to 31]} ∈ UNINITIALIZED - c ∈ {65} or UNINITIALIZED -[eva:final-states] Values at end of function main9_bitfield: - bf.a ∈ {1648} - .[bits 11 to 31] ∈ UNINITIALIZED - c ∈ UNINITIALIZED -[eva:final-states] Values at end of function main: - sz ∈ [--..--] - uc ∈ [--..--] - x ∈ [0..2147483647] - ux ∈ [--..--] - s ∈ [--..--] -[from] Computing for function main1 -[from] Done for function main1 -[from] Computing for function main10_loop -[from] Done for function main10_loop -[from] Computing for function main2_bitfield -[from] Done for function main2_bitfield -[from] Computing for function main3_reduction -[from] Done for function main3_reduction -[from] Computing for function main4_pointer -[from] Done for function main4_pointer -[from] Computing for function main5_wrap_signed -[from] Done for function main5_wrap_signed -[from] Computing for function main6_val_warn_converted_signed -[from] Done for function main6_val_warn_converted_signed -[from] Computing for function main7_signed_upcast -[from] Done for function main7_signed_upcast -[from] Computing for function main8_bitfields -[from] Done for function main8_bitfields -[from] Computing for function main9_bitfield -[from] Done for function main9_bitfield -[from] Computing for function main -[from] Done for function main -[from] ====== DEPENDENCIES COMPUTED ====== - These dependencies hold at termination for the executions that terminate: -[from] Function main1: - sz FROM sx; sy - uc FROM x - x FROM uy; uz - ux FROM uy; uz - s FROM uy; uz -[from] Function main10_loop: - NO EFFECTS -[from] Function main2_bitfield: - NO EFFECTS -[from] Function main3_reduction: - NO EFFECTS -[from] Function main4_pointer: - NO EFFECTS -[from] Function main5_wrap_signed: - NO EFFECTS -[from] Function main6_val_warn_converted_signed: - NO EFFECTS -[from] Function main7_signed_upcast: - NO EFFECTS -[from] Function main8_bitfields: - NO EFFECTS -[from] Function main9_bitfield: - NO EFFECTS -[from] Function main: - sz FROM sx; sy - uc FROM x - x FROM uy; uz - ux FROM uy; uz - s FROM uy; uz -[from] ====== END OF DEPENDENCIES ====== -[inout] Out (internal) for function main1: - sz; uc; x; ux; s -[inout] Inputs for function main1: - sx; sy; x; uy; uz -[inout] Out (internal) for function main10_loop: - c; bf.b; k -[inout] Inputs for function main10_loop: - v -[inout] Out (internal) for function main2_bitfield: - i; j; ss{.i; .j} -[inout] Inputs for function main2_bitfield: - v -[inout] Out (internal) for function main3_reduction: - x_0; c; y; d -[inout] Inputs for function main3_reduction: - v -[inout] Out (internal) for function main4_pointer: - p; q; r -[inout] Inputs for function main4_pointer: - \nothing -[inout] Out (internal) for function main5_wrap_signed: - x_0; y; z -[inout] Inputs for function main5_wrap_signed: - v -[inout] Out (internal) for function main6_val_warn_converted_signed: - s_0; u; e; b; e_0; b_0; e_1; b_1; p; x_0; y; z -[inout] Inputs for function main6_val_warn_converted_signed: - v -[inout] Out (internal) for function main7_signed_upcast: - c; i -[inout] Inputs for function main7_signed_upcast: - \nothing -[inout] Out (internal) for function main8_bitfields: - S{.i1; .i2}; c -[inout] Inputs for function main8_bitfields: - v -[inout] Out (internal) for function main9_bitfield: - bf.a; signed_a; c -[inout] Inputs for function main9_bitfield: - v -[inout] Out (internal) for function main: - sz; uc; x; ux; s -[inout] Inputs for function main: - sx; sy; x; uy; uz; v -[eva] Analyzing an incomplete application starting at main -[eva] Computing initial state -[eva] Initial state computed -[eva:initial-state] Values of globals at initialization - sx ∈ [--..--] - sy ∈ [--..--] - sz ∈ [--..--] - uc ∈ [--..--] - x ∈ [--..--] - ux ∈ [--..--] - uy ∈ [--..--] - uz ∈ [--..--] - s ∈ [--..--] - v ∈ [--..--] -[eva] computing for function main1 <- main. - Called from tests/value/downcast.i:152. -[eva:alarm] tests/value/downcast.i:20: Warning: - unsigned downcast. assert 0 ≤ (int)((int)sx + (int)sy); -[eva:alarm] tests/value/downcast.i:21: Warning: - unsigned downcast. assert 0 ≤ x; -[eva:alarm] tests/value/downcast.i:21: Warning: - unsigned downcast. assert x ≤ 255; -[eva:alarm] tests/value/downcast.i:24: Warning: - unsigned downcast. assert (unsigned int)(uy + uz) ≤ 65535; -[eva] Recording results for main1 -[eva] Done for function main1 -[eva] computing for function main2_bitfield <- main. - Called from tests/value/downcast.i:153. -[eva:alarm] tests/value/downcast.i:33: Warning: - unsigned downcast. assert j ≤ 31; -[eva] Recording results for main2_bitfield -[eva] Done for function main2_bitfield -[eva] computing for function main3_reduction <- main. - Called from tests/value/downcast.i:154. -[eva:alarm] tests/value/downcast.i:40: Warning: - unsigned downcast. assert 0 ≤ v; -[eva:alarm] tests/value/downcast.i:41: Warning: - unsigned downcast. assert y ≤ 255; -[eva] Recording results for main3_reduction -[eva] Done for function main3_reduction -[eva] computing for function main4_pointer <- main. - Called from tests/value/downcast.i:155. -[eva:alarm] tests/value/downcast.i:50: Warning: - signed overflow. assert -9223372036854775808 ≤ p + (long long)100; -[eva:alarm] tests/value/downcast.i:50: Warning: - signed overflow. assert p + (long long)100 ≤ 9223372036854775807; -[eva:alarm] tests/value/downcast.i:51: Warning: - unsigned downcast. assert 0 ≤ p; -[eva:alarm] tests/value/downcast.i:51: Warning: - unsigned downcast. assert p ≤ 4294967295; -[eva] Recording results for main4_pointer -[eva] Done for function main4_pointer -[eva] computing for function main5_wrap_signed <- main. - Called from tests/value/downcast.i:156. -[eva] tests/value/downcast.i:63: - Frama_C_show_each: - [100000..2147483647], [100145..2147483792], [-2147483648..2147483647] -[eva:alarm] tests/value/downcast.i:64: Warning: assertion got status unknown. -[eva] Recording results for main5_wrap_signed -[eva] Done for function main5_wrap_signed -[eva] computing for function main6_val_warn_converted_signed <- main. - Called from tests/value/downcast.i:157. -[eva:alarm] tests/value/downcast.i:81: Warning: - unsigned downcast. assert 0 ≤ (int)(-12); -[eva:alarm] tests/value/downcast.i:86: Warning: - unsigned downcast. assert 0 ≤ (int)(-64000); -[eva:alarm] tests/value/downcast.i:91: Warning: - pointer downcast. assert (unsigned int)p ≤ 2147483647; -[eva:alarm] tests/value/downcast.i:92: Warning: - pointer downcast. assert (unsigned int)p ≤ 32767; -[eva:alarm] tests/value/downcast.i:93: Warning: - pointer downcast. assert (unsigned int)p ≤ 65535; -[eva] Recording results for main6_val_warn_converted_signed -[eva] Done for function main6_val_warn_converted_signed -[eva] computing for function main7_signed_upcast <- main. - Called from tests/value/downcast.i:158. -[eva] Recording results for main7_signed_upcast -[eva] Done for function main7_signed_upcast -[eva] computing for function main8_bitfields <- main. - Called from tests/value/downcast.i:159. -[eva] Recording results for main8_bitfields -[eva] Done for function main8_bitfields -[eva] computing for function main9_bitfield <- main. - Called from tests/value/downcast.i:160. -[eva] tests/value/downcast.i:134: assertion got status valid. -[eva] Recording results for main9_bitfield -[eva] Done for function main9_bitfield -[eva] computing for function main10_loop <- main. - Called from tests/value/downcast.i:161. -[eva:alarm] tests/value/downcast.i:146: Warning: - unsigned downcast. assert 0 ≤ v; -[eva:alarm] tests/value/downcast.i:146: Warning: - unsigned downcast. assert v ≤ 1023; -[eva] Recording results for main10_loop -[eva] Done for function main10_loop -[eva] Recording results for main -[eva] done for function main -[eva] tests/value/downcast.i:33: - assertion 'Eva,unsigned_downcast' got final status invalid. -[eva] tests/value/downcast.i:81: - assertion 'Eva,unsigned_downcast' got final status invalid. -[eva] tests/value/downcast.i:86: - assertion 'Eva,unsigned_downcast' got final status invalid. -[eva] ====== VALUES COMPUTED ====== -[eva:final-states] Values at end of function main1: - sz ∈ [--..--] - uc ∈ [--..--] - x ∈ [--..--] - ux ∈ [--..--] - s ∈ [--..--] -[eva:final-states] Values at end of function main10_loop: - c ∈ [--..--] or UNINITIALIZED - bf.b ∈ [--..--] or UNINITIALIZED - .[bits 10 to 31] ∈ UNINITIALIZED - k ∈ {10} -[eva:final-states] Values at end of function main2_bitfield: - i ∈ {117} - j ∈ {254} - ss.i ∈ {-11} or UNINITIALIZED - {.j; .[bits 10 to 31]} ∈ UNINITIALIZED -[eva:final-states] Values at end of function main3_reduction: - x_0 ∈ [--..--] - c ∈ [--..--] - y ∈ [0..255] - d ∈ [--..--] -[eva:final-states] Values at end of function main4_pointer: - p ∈ {{ &x_0 + {100} }} - q ∈ {{ &x_0 + {100} }} - r ∈ {{ &x_0 + {100} }} -[eva:final-states] Values at end of function main5_wrap_signed: - x_0 ∈ [100000..2147483647] - y ∈ [100145..2147483792] - z ∈ [--..--] -[eva:final-states] Values at end of function main6_val_warn_converted_signed: - -[eva:final-states] Values at end of function main7_signed_upcast: - c ∈ {240} - i ∈ {240} -[eva:final-states] Values at end of function main8_bitfields: - S.i1 ∈ {65} - .i2 ∈ {-1; 1} or UNINITIALIZED - .[bits 24 to 31] ∈ UNINITIALIZED - c ∈ {-1; 1; 65} or UNINITIALIZED -[eva:final-states] Values at end of function main9_bitfield: - bf.a ∈ {1648} - .[bits 11 to 31] ∈ UNINITIALIZED - c ∈ {112} or UNINITIALIZED -[eva:final-states] Values at end of function main: - sz ∈ [--..--] - uc ∈ [--..--] - x ∈ [--..--] - ux ∈ [--..--] - s ∈ [--..--] -[from] Computing for function main1 -[from] Done for function main1 -[from] Computing for function main10_loop -[from] Done for function main10_loop -[from] Computing for function main2_bitfield -[from] Done for function main2_bitfield -[from] Computing for function main3_reduction -[from] Done for function main3_reduction -[from] Computing for function main4_pointer -[from] Done for function main4_pointer -[from] Computing for function main5_wrap_signed -[from] Done for function main5_wrap_signed -[from] Computing for function main6_val_warn_converted_signed -[from] Done for function main6_val_warn_converted_signed -[from] Computing for function main7_signed_upcast -[from] Done for function main7_signed_upcast -[from] Computing for function main8_bitfields -[from] Done for function main8_bitfields -[from] Computing for function main9_bitfield -[from] Done for function main9_bitfield -[from] Computing for function main -[from] Done for function main -[from] ====== DEPENDENCIES COMPUTED ====== - These dependencies hold at termination for the executions that terminate: -[from] Function main1: - sz FROM sx; sy - uc FROM x - x FROM uy; uz - ux FROM uy; uz - s FROM uy; uz -[from] Function main10_loop: - NO EFFECTS -[from] Function main2_bitfield: - NO EFFECTS -[from] Function main3_reduction: - NO EFFECTS -[from] Function main4_pointer: - NO EFFECTS -[from] Function main5_wrap_signed: - NO EFFECTS -[from] Function main6_val_warn_converted_signed: - NO EFFECTS -[from] Function main7_signed_upcast: - NO EFFECTS -[from] Function main8_bitfields: - NO EFFECTS -[from] Function main9_bitfield: - NO EFFECTS -[from] Function main: - sz FROM sx; sy - uc FROM x - x FROM uy; uz - ux FROM uy; uz - s FROM uy; uz -[from] ====== END OF DEPENDENCIES ====== -[inout] Out (internal) for function main1: - sz; uc; x; ux; s -[inout] Inputs for function main1: - sx; sy; x; uy; uz -[inout] Out (internal) for function main10_loop: - c; bf.b; k -[inout] Inputs for function main10_loop: - v -[inout] Out (internal) for function main2_bitfield: - i; j; ss{.i; .j} -[inout] Inputs for function main2_bitfield: - v -[inout] Out (internal) for function main3_reduction: - x_0; c; y; d -[inout] Inputs for function main3_reduction: - v -[inout] Out (internal) for function main4_pointer: - p; q; r -[inout] Inputs for function main4_pointer: - \nothing -[inout] Out (internal) for function main5_wrap_signed: - x_0; y; z -[inout] Inputs for function main5_wrap_signed: - v -[inout] Out (internal) for function main6_val_warn_converted_signed: - s_0; u; e; b; e_0; e_1; p; x_0; y; z -[inout] Inputs for function main6_val_warn_converted_signed: - v -[inout] Out (internal) for function main7_signed_upcast: - c; i -[inout] Inputs for function main7_signed_upcast: - \nothing -[inout] Out (internal) for function main8_bitfields: - S{.i1; .i2}; c -[inout] Inputs for function main8_bitfields: - v -[inout] Out (internal) for function main9_bitfield: - bf.a; signed_a; c -[inout] Inputs for function main9_bitfield: - v -[inout] Out (internal) for function main: - sz; uc; x; ux; s -[inout] Inputs for function main: - sx; sy; x; uy; uz; v -[eva] Analyzing an incomplete application starting at main -[eva] Computing initial state -[eva] Initial state computed -[eva:initial-state] Values of globals at initialization - sx ∈ [--..--] - sy ∈ [--..--] - sz ∈ [--..--] - uc ∈ [--..--] - x ∈ [--..--] - ux ∈ [--..--] - uy ∈ [--..--] - uz ∈ [--..--] - s ∈ [--..--] - v ∈ [--..--] -[eva] computing for function main1 <- main. - Called from tests/value/downcast.i:152. -[eva:alarm] tests/value/downcast.i:19: Warning: - signed downcast. assert -128 ≤ (int)((int)sx + (int)sy); -[eva:alarm] tests/value/downcast.i:19: Warning: - signed downcast. assert (int)((int)sx + (int)sy) ≤ 127; -[eva] Recording results for main1 -[eva] Done for function main1 -[eva] computing for function main2_bitfield <- main. - Called from tests/value/downcast.i:153. -[eva:alarm] tests/value/downcast.i:32: Warning: - signed downcast. assert i ≤ 15; -[eva] Recording results for main2_bitfield -[eva] Done for function main2_bitfield -[eva] computing for function main3_reduction <- main. - Called from tests/value/downcast.i:154. -[eva:alarm] tests/value/downcast.i:38: Warning: - signed downcast. assert -128 ≤ x_0; -[eva:alarm] tests/value/downcast.i:38: Warning: - signed downcast. assert x_0 ≤ 127; -[eva] Recording results for main3_reduction -[eva] Done for function main3_reduction -[eva] computing for function main4_pointer <- main. - Called from tests/value/downcast.i:155. -[eva:alarm] tests/value/downcast.i:50: Warning: - signed overflow. assert -9223372036854775808 ≤ p + (long long)100; -[eva:alarm] tests/value/downcast.i:50: Warning: - signed overflow. assert p + (long long)100 ≤ 9223372036854775807; -[eva:alarm] tests/value/downcast.i:52: Warning: - signed downcast. assert -2147483648 ≤ p; -[eva:alarm] tests/value/downcast.i:52: Warning: - signed downcast. assert p ≤ 2147483647; -[eva] Recording results for main4_pointer -[eva] Done for function main4_pointer -[eva] computing for function main5_wrap_signed <- main. - Called from tests/value/downcast.i:156. -[eva] tests/value/downcast.i:63: - Frama_C_show_each: - [100000..2147483647], [100145..2147483792], [-2147483648..2147483647] -[eva] Recording results for main5_wrap_signed -[eva] Done for function main5_wrap_signed -[eva] computing for function main6_val_warn_converted_signed <- main. - Called from tests/value/downcast.i:157. -[eva:alarm] tests/value/downcast.i:71: Warning: - signed downcast. assert (int)65300u ≤ 32767; -[eva:alarm] tests/value/downcast.i:87: Warning: - signed downcast. assert -32768 ≤ (int)e_1; -[eva:alarm] tests/value/downcast.i:91: Warning: - pointer downcast. assert (unsigned int)p ≤ 2147483647; -[eva:alarm] tests/value/downcast.i:92: Warning: - pointer downcast. assert (unsigned int)p ≤ 32767; -[eva:alarm] tests/value/downcast.i:93: Warning: - pointer downcast. assert (unsigned int)p ≤ 65535; -[eva] Recording results for main6_val_warn_converted_signed -[eva] Done for function main6_val_warn_converted_signed -[eva] computing for function main7_signed_upcast <- main. - Called from tests/value/downcast.i:158. -[eva] Recording results for main7_signed_upcast -[eva] Done for function main7_signed_upcast -[eva] computing for function main8_bitfields <- main. - Called from tests/value/downcast.i:159. -[eva:alarm] tests/value/downcast.i:119: Warning: - signed downcast. assert (int)S.i1 ≤ 31; -[eva:alarm] tests/value/downcast.i:120: Warning: - signed downcast. assert (int)S.i1 ≤ 127; -[eva:alarm] tests/value/downcast.i:124: Warning: - signed downcast. assert (int)S.i1 ≤ 31; -[eva] Recording results for main8_bitfields -[eva] Done for function main8_bitfields -[eva] computing for function main9_bitfield <- main. - Called from tests/value/downcast.i:160. -[eva:alarm] tests/value/downcast.i:137: Warning: - signed downcast. assert -128 ≤ (int)bf.a; -[eva] Recording results for main9_bitfield -[eva] Done for function main9_bitfield -[eva] computing for function main10_loop <- main. - Called from tests/value/downcast.i:161. -[eva:alarm] tests/value/downcast.i:147: Warning: - signed downcast. assert -128 ≤ (int)bf.b; -[eva:alarm] tests/value/downcast.i:147: Warning: - signed downcast. assert (int)bf.b ≤ 127; -[eva] Recording results for main10_loop -[eva] Done for function main10_loop -[eva] Recording results for main -[eva] done for function main -[eva] ====== VALUES COMPUTED ====== -[eva:final-states] Values at end of function main1: - sz ∈ [--..--] - uc ∈ [--..--] - x ∈ [--..--] - ux ∈ [--..--] - s ∈ [--..--] -[eva:final-states] Values at end of function main10_loop: - c ∈ [--..--] or UNINITIALIZED - bf.b ∈ [--..--] or UNINITIALIZED - .[bits 10 to 31] ∈ UNINITIALIZED - k ∈ {10} -[eva:final-states] Values at end of function main2_bitfield: - i ∈ {117} - j ∈ {254} - ss.i ∈ UNINITIALIZED - .j ∈ {30} or UNINITIALIZED - .[bits 10 to 31] ∈ UNINITIALIZED -[eva:final-states] Values at end of function main3_reduction: - x_0 ∈ [-128..127] - c ∈ [--..--] - y ∈ [--..--] - d ∈ [--..--] -[eva:final-states] Values at end of function main4_pointer: - p ∈ {{ &x_0 + {100} }} - q ∈ {{ &x_0 + {100} }} - r ∈ {{ &x_0 + {100} }} -[eva:final-states] Values at end of function main5_wrap_signed: - x_0 ∈ [100000..2147483647] - y ∈ [100145..2147483792] - z ∈ [--..--] -[eva:final-states] Values at end of function main6_val_warn_converted_signed: - -[eva:final-states] Values at end of function main7_signed_upcast: - c ∈ {240} - i ∈ {240} -[eva:final-states] Values at end of function main8_bitfields: - S.i1 ∈ {65} - .i2 ∈ {-1} or UNINITIALIZED - .[bits 24 to 31] ∈ UNINITIALIZED - c ∈ {-1; 65} or UNINITIALIZED -[eva:final-states] Values at end of function main9_bitfield: - bf.a ∈ {1648} - .[bits 11 to 31] ∈ UNINITIALIZED - c ∈ UNINITIALIZED -[eva:final-states] Values at end of function main: - sz ∈ [--..--] - uc ∈ [--..--] - x ∈ [--..--] - ux ∈ [--..--] - s ∈ [--..--] -[from] Computing for function main1 -[from] Done for function main1 -[from] Computing for function main10_loop -[from] Done for function main10_loop -[from] Computing for function main2_bitfield -[from] Done for function main2_bitfield -[from] Computing for function main3_reduction -[from] Done for function main3_reduction -[from] Computing for function main4_pointer -[from] Done for function main4_pointer -[from] Computing for function main5_wrap_signed -[from] Done for function main5_wrap_signed -[from] Computing for function main6_val_warn_converted_signed -[from] Done for function main6_val_warn_converted_signed -[from] Computing for function main7_signed_upcast -[from] Done for function main7_signed_upcast -[from] Computing for function main8_bitfields -[from] Done for function main8_bitfields -[from] Computing for function main9_bitfield -[from] Done for function main9_bitfield -[from] Computing for function main -[from] Done for function main -[from] ====== DEPENDENCIES COMPUTED ====== - These dependencies hold at termination for the executions that terminate: -[from] Function main1: - sz FROM sx; sy - uc FROM x - x FROM uy; uz - ux FROM uy; uz - s FROM uy; uz -[from] Function main10_loop: - NO EFFECTS -[from] Function main2_bitfield: - NO EFFECTS -[from] Function main3_reduction: - NO EFFECTS -[from] Function main4_pointer: - NO EFFECTS -[from] Function main5_wrap_signed: - NO EFFECTS -[from] Function main6_val_warn_converted_signed: - NO EFFECTS -[from] Function main7_signed_upcast: - NO EFFECTS -[from] Function main8_bitfields: - NO EFFECTS -[from] Function main9_bitfield: - NO EFFECTS -[from] Function main: - sz FROM sx; sy - uc FROM x - x FROM uy; uz - ux FROM uy; uz - s FROM uy; uz -[from] ====== END OF DEPENDENCIES ====== -[inout] Out (internal) for function main1: - sz; uc; x; ux; s -[inout] Inputs for function main1: - sx; sy; x; uy; uz -[inout] Out (internal) for function main10_loop: - c; bf.b; k -[inout] Inputs for function main10_loop: - v -[inout] Out (internal) for function main2_bitfield: - i; j; ss{.i; .j} -[inout] Inputs for function main2_bitfield: - v -[inout] Out (internal) for function main3_reduction: - x_0; c; y; d -[inout] Inputs for function main3_reduction: - v -[inout] Out (internal) for function main4_pointer: - p; q; r -[inout] Inputs for function main4_pointer: - \nothing -[inout] Out (internal) for function main5_wrap_signed: - x_0; y; z -[inout] Inputs for function main5_wrap_signed: - v -[inout] Out (internal) for function main6_val_warn_converted_signed: - s_0; u; e; b; e_0; b_0; e_1; b_1; p; x_0; y; z -[inout] Inputs for function main6_val_warn_converted_signed: - v -[inout] Out (internal) for function main7_signed_upcast: - c; i -[inout] Inputs for function main7_signed_upcast: - \nothing -[inout] Out (internal) for function main8_bitfields: - S{.i1; .i2}; c -[inout] Inputs for function main8_bitfields: - v -[inout] Out (internal) for function main9_bitfield: - bf.a; signed_a; c -[inout] Inputs for function main9_bitfield: - v -[inout] Out (internal) for function main: - sz; uc; x; ux; s -[inout] Inputs for function main: - sx; sy; x; uy; uz; v -[eva] Analyzing an incomplete application starting at main5_wrap_signed -[eva] Computing initial state -[eva] Initial state computed -[eva:initial-state] Values of globals at initialization - sx ∈ [--..--] - sy ∈ [--..--] - sz ∈ [--..--] - uc ∈ [--..--] - x ∈ [--..--] - ux ∈ [--..--] - uy ∈ [--..--] - uz ∈ [--..--] - s ∈ [--..--] - v ∈ [--..--] -[eva] tests/value/downcast.i:63: - Frama_C_show_each: - [2147483503..2147483647], - [2147483648..2147483792], - [-2147483648..-2147483504] -[eva] tests/value/downcast.i:63: - Frama_C_show_each: - [100000..2147483502], [100145..2147483647], [100145..2147483647] -[eva] Recording results for main5_wrap_signed -[eva] done for function main5_wrap_signed -[eva] ====== VALUES COMPUTED ====== -[eva:final-states] Values at end of function main5_wrap_signed: - x_0 ∈ [100000..2147483647] - y ∈ [100145..2147483792] - z ∈ [--..--] -[from] Computing for function main5_wrap_signed -[from] Done for function main5_wrap_signed -[from] ====== DEPENDENCIES COMPUTED ====== - These dependencies hold at termination for the executions that terminate: -[from] Function main5_wrap_signed: - NO EFFECTS -[from] ====== END OF DEPENDENCIES ====== -[inout] Out (internal) for function main5_wrap_signed: - x_0; y; z -[inout] Inputs for function main5_wrap_signed: - v -- GitLab From 77e14a4e98d0c76ac7bb4dcca8843eebd29bf518 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20B=C3=BChler?= <david.buhler@cea.fr> Date: Thu, 26 Mar 2020 13:48:19 +0100 Subject: [PATCH 029/218] [rte] Rewrites the emission of downcast alarms into one function. --- src/plugins/rte/rte.ml | 114 +++++++++++---------------------------- src/plugins/rte/rte.mli | 3 +- src/plugins/rte/visit.ml | 14 +++-- 3 files changed, 39 insertions(+), 92 deletions(-) diff --git a/src/plugins/rte/rte.ml b/src/plugins/rte/rte.ml index ad09f17f553..4d77766b988 100644 --- a/src/plugins/rte/rte.ml +++ b/src/plugins/rte/rte.ml @@ -357,88 +357,38 @@ let shift_overflow_assertion ~signed ~remove_trivial ~on_alarm (exp, op, lexp, r end else overflow_alarm () -(* assertion for downcasting an integer to an unsigned integer type - without requiring modification of value to reach target domain - (well-defined behavior though) *) -let unsigned_downcast_assertion ~remove_trivial ~on_alarm (ty, exp) = - let e_typ = Cil.unrollType (Cil.typeOf exp) in - match e_typ with - | TInt (kind,_) -> - let szTo = Cil.bitsSizeOfBitfield ty in - let szFrom = Cil.bitsSizeOf e_typ in - (if szTo < szFrom || Cil.isSigned kind then - (* case signed to unsigned: - requires signed to be >= 0 and also <= max of unsigned size *) - (* cast unsigned to unsigned: - ok is same bit size ; - if target is <, requires <= max target *) - let max_ty = Cil.max_unsigned_number szTo in - let alarm ?(invalid=false) bk = - let b = match bk with - | Lower_bound -> Integer.zero - | Upper_bound -> max_ty - in - let a = Alarms.Overflow (Alarms.Unsigned_downcast, exp, b, bk) in - on_alarm ~invalid a; - in - let alarms () = - if Cil.isSigned kind then begin (* signed to unsigned *) - alarm Upper_bound; - alarm Lower_bound; - end else (* unsigned to unsigned; cannot overflow in the negative *) - alarm Upper_bound; - in - if remove_trivial then begin - match get_expr_val exp with - | None -> alarms () - | Some a64 -> - if Integer.lt a64 Integer.zero then - alarm ~invalid:true Lower_bound - else if Integer.gt a64 max_ty then - alarm ~invalid:true Upper_bound - end - else alarms ()) - | _ -> () - -(* assertion for downcasting an integer to a signed integer type - which can raise an implementation defined behavior *) -let signed_downcast_assertion ~remove_trivial ~on_alarm (ty, exp) = - let e_typ = Cil.unrollType (Cil.typeOf exp) in - match e_typ with - | TInt (kind,_) -> - (let szTo = Cil.bitsSizeOfBitfield ty in - let szFrom = Cil.bitsSizeOf e_typ in - if szTo < szFrom || (szTo == szFrom && not (Cil.isSigned kind)) then - (* downcast: the expression result should fit on szTo bits *) - let min_ty = Cil.min_signed_number szTo in - let max_ty = Cil.max_signed_number szTo in - let alarm ?(invalid=false) bk = - let b = match bk with - | Lower_bound -> min_ty - | Upper_bound -> max_ty - in - let a = Alarms.Overflow (Alarms.Signed_downcast, exp, b, bk) in - on_alarm ~invalid a; - in - let alarms () = - if Cil.isSigned kind then begin - (* signed to signed *) - alarm Upper_bound; - alarm Lower_bound - end else (* (unsigned to signed; cannot overflow in the negative *) - alarm Upper_bound - in - if remove_trivial then begin - match get_expr_val exp with - | None -> alarms () - | Some a64 -> - (if Integer.lt a64 min_ty then - alarm ~invalid:true Lower_bound - else if Integer.gt a64 max_ty then - alarm ~invalid:true Upper_bound) - end - else alarms ()) - | _ -> () +(* Assertion for downcasts. *) +let downcast_assertion ~remove_trivial ~on_alarm (dst_type, exp) = + let src_type = Cil.typeOf exp in + let src_signed = Cil.isSignedInteger src_type in + let dst_signed = Cil.isSignedInteger dst_type in + let src_size = Cil.bitsSizeOf src_type in + let dst_size = Cil.bitsSizeOfBitfield dst_type in + if dst_size < src_size || dst_size == src_size && dst_signed <> src_signed + then + let dst_min, dst_max = + if dst_signed + then Cil.min_signed_number dst_size, Cil.max_signed_number dst_size + else Integer.zero, Cil.max_unsigned_number dst_size + in + let overflow_kind = + if dst_signed then Alarms.Signed_downcast else Alarms.Unsigned_downcast + in + let alarm ?(invalid=false) bound bound_kind = + let a = Alarms.Overflow (overflow_kind, exp, bound, bound_kind) in + on_alarm ~invalid a; + in + let alarms () = + alarm dst_max Upper_bound; + (* unsigned values cannot overflow in the negative *) + if src_signed then alarm dst_min Lower_bound; + in + match remove_trivial, get_expr_val exp with + | true, Some a64 -> + let invalid = true in + if Integer.lt a64 dst_min then alarm ~invalid dst_min Lower_bound + else if Integer.gt a64 dst_max then alarm ~invalid dst_max Upper_bound + | _ -> alarms () (* assertion for casting a floating-point value to an integer *) let float_to_int_assertion ~remove_trivial ~on_alarm (ty, exp) = diff --git a/src/plugins/rte/rte.mli b/src/plugins/rte/rte.mli index 766fa82c856..7c787c279a8 100644 --- a/src/plugins/rte/rte.mli +++ b/src/plugins/rte/rte.mli @@ -40,8 +40,7 @@ val shift_negative_assertion: exp alarm_gen val shift_overflow_assertion: signed:bool -> (exp * binop * exp * exp) alarm_gen val mult_sub_add_assertion: signed:bool -> (exp * binop * exp * exp) alarm_gen val uminus_assertion: exp alarm_gen -val signed_downcast_assertion: (typ * exp) alarm_gen -val unsigned_downcast_assertion: (typ * exp) alarm_gen +val downcast_assertion: (typ * exp) alarm_gen val float_to_int_assertion: (typ * exp) alarm_gen val finite_float_assertion: (fkind * exp) alarm_gen val pointer_call: (exp * exp list) alarm_gen diff --git a/src/plugins/rte/visit.ml b/src/plugins/rte/visit.ml index 2592651085e..4919cfdef81 100644 --- a/src/plugins/rte/visit.ml +++ b/src/plugins/rte/visit.ml @@ -308,14 +308,12 @@ class annot_visitor kf flags on_alarm = object (self) (match Cil.unrollType ty, Cil.unrollType (Cil.typeOf e) with (* to , from *) | TInt(kind,_), TInt (_, _) -> - if Cil.isSigned kind then begin - if self#do_signed_downcast () then begin - self#generate_assertion Rte.signed_downcast_assertion (ty, e); - self#mark_to_skip e; - end - end - else if self#do_unsigned_downcast () then - self#generate_assertion Rte.unsigned_downcast_assertion (ty, e) + let signed = Cil.isSigned kind in + if signed && self#do_signed_downcast () + || not signed && self#do_unsigned_downcast () + then self#generate_assertion Rte.downcast_assertion (ty, e); + if signed && self#do_signed_downcast () + then self#mark_to_skip e; | TInt _, TFloat _ -> if self#do_float_to_int () then -- GitLab From 91b6a4d9772d0d67daad3a28ec56987f1930b5ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20B=C3=BChler?= <david.buhler@cea.fr> Date: Wed, 25 Mar 2020 14:49:02 +0100 Subject: [PATCH 030/218] [rte] Generates alarms on pointer downcasts, according to -warn-pointer-downcast. --- src/kernel_services/plugin_entry_points/db.ml | 1 + src/kernel_services/plugin_entry_points/db.mli | 1 + src/plugins/rte/flags.ml | 5 +++++ src/plugins/rte/flags.mli | 2 ++ src/plugins/rte/generator.ml | 8 ++++++++ src/plugins/rte/generator.mli | 1 + src/plugins/rte/register.ml | 1 + src/plugins/rte/rte.ml | 6 +++++- src/plugins/rte/visit.ml | 8 ++++++++ tests/rte/oracle/castoncall.0.res.oracle | 2 ++ tests/rte/oracle/castoncall.1.res.oracle | 2 ++ tests/rte/oracle/twofunc.res.oracle | 4 ++++ tests/value/oracle/div.1.res.oracle | 10 ++++++++++ 13 files changed, 50 insertions(+), 1 deletion(-) diff --git a/src/kernel_services/plugin_entry_points/db.ml b/src/kernel_services/plugin_entry_points/db.ml index e5ea4748e6b..2453bded636 100644 --- a/src/kernel_services/plugin_entry_points/db.ml +++ b/src/kernel_services/plugin_entry_points/db.ml @@ -1018,6 +1018,7 @@ module RteGen = struct let get_pointerCall_status = mk_fun "RteGen.get_pointerCall_status" let get_unsignedOv_status = mk_fun "RteGen.get_unsignedOv_status" let get_unsignedDownCast_status = mk_fun "RteGen.get_unsignedDownCast_status" + let get_pointer_downcast_status = mk_fun "RteGen.get_pointer_downcast_status" let get_float_to_int_status = mk_fun "RteGen.get_float_to_int_status" let get_finite_float_status = mk_fun "RteGen.get_finite_float_status" let get_bool_value_status = mk_fun "RteGen.get_bool_value_status" diff --git a/src/kernel_services/plugin_entry_points/db.mli b/src/kernel_services/plugin_entry_points/db.mli index 565c20806a0..a54ae74932d 100644 --- a/src/kernel_services/plugin_entry_points/db.mli +++ b/src/kernel_services/plugin_entry_points/db.mli @@ -900,6 +900,7 @@ module RteGen : sig val get_signed_downCast_status : (unit -> status_accessor) ref val get_unsignedOv_status : (unit -> status_accessor) ref val get_unsignedDownCast_status : (unit -> status_accessor) ref + val get_pointer_downcast_status : (unit -> status_accessor) ref val get_float_to_int_status : (unit -> status_accessor) ref val get_finite_float_status : (unit -> status_accessor) ref val get_bool_value_status : (unit -> status_accessor) ref diff --git a/src/plugins/rte/flags.ml b/src/plugins/rte/flags.ml index 5a5efb9c60c..7d17b15a3a9 100644 --- a/src/plugins/rte/flags.ml +++ b/src/plugins/rte/flags.ml @@ -36,6 +36,7 @@ type t = { unsigned_overflow: bool; signed_downcast: bool; unsigned_downcast: bool; + pointer_downcast: bool; float_to_int: bool; finite_float: bool; pointer_call: bool; @@ -54,6 +55,7 @@ let all = { unsigned_overflow = true; signed_downcast = true; unsigned_downcast = true; + pointer_downcast = true; float_to_int = true; finite_float = true; pointer_call = true; @@ -72,6 +74,7 @@ let none = { unsigned_overflow = false; signed_downcast = false; unsigned_downcast = false; + pointer_downcast = false; float_to_int = false; finite_float = false; pointer_call = false; @@ -95,6 +98,7 @@ let default ?unsigned_overflow ?signed_downcast ?unsigned_downcast + ?pointer_downcast ?float_to_int ?finite_float ?pointer_call @@ -112,6 +116,7 @@ let default unsigned_overflow = option Kernel.UnsignedOverflow.get unsigned_overflow ; signed_downcast = option Kernel.SignedDowncast.get signed_downcast ; unsigned_downcast = option Kernel.UnsignedDowncast.get unsigned_downcast ; + pointer_downcast = option Kernel.PointerDowncast.get pointer_downcast ; float_to_int = option Options.DoFloatToInt.get float_to_int ; finite_float = option (fun () -> Kernel.SpecialFloat.get () <> "none") finite_float ; pointer_call = option Options.DoPointerCall.get pointer_call ; diff --git a/src/plugins/rte/flags.mli b/src/plugins/rte/flags.mli index f90a63a3afa..3ea19d53f36 100644 --- a/src/plugins/rte/flags.mli +++ b/src/plugins/rte/flags.mli @@ -38,6 +38,7 @@ type t = { unsigned_overflow: bool; signed_downcast: bool; unsigned_downcast: bool; + pointer_downcast: bool; float_to_int: bool; finite_float: bool; pointer_call: bool; @@ -57,6 +58,7 @@ val default : ?unsigned_overflow:bool -> ?signed_downcast:bool -> ?unsigned_downcast:bool -> + ?pointer_downcast:bool -> ?float_to_int:bool -> ?finite_float:bool -> ?pointer_call:bool -> diff --git a/src/plugins/rte/generator.ml b/src/plugins/rte/generator.ml index 67214fae804..8c8e697d4dc 100644 --- a/src/plugins/rte/generator.ml +++ b/src/plugins/rte/generator.ml @@ -155,6 +155,14 @@ module Unsigned_downcast = let additional_parameters = [] end) +module Pointer_downcast = + Make + (struct + let name = "pointer_downcast" + let parameter = Kernel.PointerDowncast.parameter + let additional_parameters = [] + end) + module Float_to_int = Make (struct diff --git a/src/plugins/rte/generator.mli b/src/plugins/rte/generator.mli index 1e1c61ccd3a..1518a0acc67 100644 --- a/src/plugins/rte/generator.mli +++ b/src/plugins/rte/generator.mli @@ -39,6 +39,7 @@ module Signed_overflow: S module Signed_downcast: S module Unsigned_overflow: S module Unsigned_downcast: S +module Pointer_downcast: S module Float_to_int: S module Finite_float: S module Bool_value: S diff --git a/src/plugins/rte/register.ml b/src/plugins/rte/register.ml index ed9296659ab..8b5afe27c05 100644 --- a/src/plugins/rte/register.ml +++ b/src/plugins/rte/register.ml @@ -93,6 +93,7 @@ let () = nojournal_register get_pointerCall_status Pointer_call.accessor; nojournal_register get_unsignedOv_status Unsigned_overflow.accessor; nojournal_register get_unsignedDownCast_status Unsigned_downcast.accessor; + nojournal_register get_pointer_downcast_status Pointer_downcast.accessor; nojournal_register get_float_to_int_status Float_to_int.accessor; nojournal_register get_finite_float_status Finite_float.accessor; nojournal_register get_bool_value_status Bool_value.accessor ; diff --git a/src/plugins/rte/rte.ml b/src/plugins/rte/rte.ml index 4d77766b988..467d65f1ffd 100644 --- a/src/plugins/rte/rte.ml +++ b/src/plugins/rte/rte.ml @@ -372,7 +372,11 @@ let downcast_assertion ~remove_trivial ~on_alarm (dst_type, exp) = else Integer.zero, Cil.max_unsigned_number dst_size in let overflow_kind = - if dst_signed then Alarms.Signed_downcast else Alarms.Unsigned_downcast + if Cil.isPointerType src_type + then Alarms.Pointer_downcast + else if dst_signed + then Alarms.Signed_downcast + else Alarms.Unsigned_downcast in let alarm ?(invalid=false) bound bound_kind = let a = Alarms.Overflow (overflow_kind, exp, bound, bound_kind) in diff --git a/src/plugins/rte/visit.ml b/src/plugins/rte/visit.ml index 4919cfdef81..61dafe98471 100644 --- a/src/plugins/rte/visit.ml +++ b/src/plugins/rte/visit.ml @@ -86,6 +86,10 @@ class annot_visitor kf flags on_alarm = object (self) flags.Flags.unsigned_downcast && not (Generator.Unsigned_downcast.is_computed kf) + method private do_pointer_downcast () = + flags.Flags.pointer_downcast + && not (Generator.Pointer_downcast.is_computed kf) + method private do_float_to_int () = flags.Flags.float_to_int && not (Generator.Float_to_int.is_computed kf) @@ -307,6 +311,9 @@ class annot_visitor kf flags on_alarm = object (self) | CastE (ty, e) -> (match Cil.unrollType ty, Cil.unrollType (Cil.typeOf e) with (* to , from *) + | TInt _, TPtr _ when self#do_pointer_downcast () -> + self#generate_assertion Rte.downcast_assertion (ty, e) + | TInt(kind,_), TInt (_, _) -> let signed = Cil.isSigned kind in if signed && self#do_signed_downcast () @@ -453,6 +460,7 @@ let annotate ?flags kf = comp Signed_downcast.accessor flags.signed_downcast ||| comp Unsigned_overflow.accessor flags.unsigned_overflow ||| comp Unsigned_downcast.accessor flags.unsigned_downcast ||| + comp Pointer_downcast.accessor flags.pointer_downcast ||| comp Float_to_int.accessor flags.float_to_int ||| comp Finite_float.accessor flags.finite_float ||| comp Bool_value.accessor flags.bool_value diff --git a/tests/rte/oracle/castoncall.0.res.oracle b/tests/rte/oracle/castoncall.0.res.oracle index 430827699b3..5bee127b54a 100644 --- a/tests/rte/oracle/castoncall.0.res.oracle +++ b/tests/rte/oracle/castoncall.0.res.oracle @@ -16,6 +16,8 @@ void *nondet_ptr(void *a, void *b) { void *__retres; int tmp; + /*@ assert rte: pointer_downcast: (unsigned int)a ≤ 2147483647; */ + /*@ assert rte: pointer_downcast: (unsigned int)b ≤ 2147483647; */ tmp = nondet((int)a,(int)b); __retres = (void *)tmp; return __retres; diff --git a/tests/rte/oracle/castoncall.1.res.oracle b/tests/rte/oracle/castoncall.1.res.oracle index 430827699b3..5bee127b54a 100644 --- a/tests/rte/oracle/castoncall.1.res.oracle +++ b/tests/rte/oracle/castoncall.1.res.oracle @@ -16,6 +16,8 @@ void *nondet_ptr(void *a, void *b) { void *__retres; int tmp; + /*@ assert rte: pointer_downcast: (unsigned int)a ≤ 2147483647; */ + /*@ assert rte: pointer_downcast: (unsigned int)b ≤ 2147483647; */ tmp = nondet((int)a,(int)b); __retres = (void *)tmp; return __retres; diff --git a/tests/rte/oracle/twofunc.res.oracle b/tests/rte/oracle/twofunc.res.oracle index 58f6280ce2a..5d0a80d5f38 100644 --- a/tests/rte/oracle/twofunc.res.oracle +++ b/tests/rte/oracle/twofunc.res.oracle @@ -133,6 +133,7 @@ int main(void) [kernel] - bool_value = true [kernel] - finite_float = true [kernel] - float_to_int = true +[kernel] - pointer_downcast = true [kernel] - unsigned_downcast = false [kernel] - unsigned_overflow = false [kernel] - downcast = true @@ -148,6 +149,7 @@ int main(void) [kernel] - bool_value = true [kernel] - finite_float = true [kernel] - float_to_int = true +[kernel] - pointer_downcast = true [kernel] - unsigned_downcast = false [kernel] - unsigned_overflow = false [kernel] - downcast = true @@ -225,6 +227,7 @@ int main(void) [kernel] - bool_value = true [kernel] - finite_float = true [kernel] - float_to_int = true +[kernel] - pointer_downcast = true [kernel] - unsigned_downcast = false [kernel] - unsigned_overflow = false [kernel] - downcast = true @@ -240,6 +243,7 @@ int main(void) [kernel] - bool_value = true [kernel] - finite_float = true [kernel] - float_to_int = true +[kernel] - pointer_downcast = true [kernel] - unsigned_downcast = false [kernel] - unsigned_overflow = false [kernel] - downcast = true diff --git a/tests/value/oracle/div.1.res.oracle b/tests/value/oracle/div.1.res.oracle index 02145cd0576..d052fa034e4 100644 --- a/tests/value/oracle/div.1.res.oracle +++ b/tests/value/oracle/div.1.res.oracle @@ -50,6 +50,8 @@ [eva:alarm] tests/value/div.i:32: Warning: assertion 'rte,division_by_zero' got status unknown. [eva:alarm] tests/value/div.i:32: Warning: division by zero. assert Z2 ≢ 0; +[eva:alarm] tests/value/div.i:33: Warning: + assertion 'rte,pointer_downcast' got status unknown. [eva:alarm] tests/value/div.i:33: Warning: assertion 'rte,division_by_zero' got status unknown. [eva:alarm] tests/value/div.i:33: Warning: @@ -64,6 +66,8 @@ [eva] tests/value/div.i:33: Assigning imprecise value to b. The imprecision originates from Arithmetic {tests/value/div.i:33} +[eva:alarm] tests/value/div.i:34: Warning: + assertion 'rte,pointer_downcast' got status unknown. [eva:alarm] tests/value/div.i:34: Warning: assertion 'rte,division_by_zero' got status unknown. [eva:alarm] tests/value/div.i:34: Warning: @@ -77,6 +81,8 @@ [eva] tests/value/div.i:34: Assigning imprecise value to d2. The imprecision originates from Arithmetic {tests/value/div.i:34} +[eva:alarm] tests/value/div.i:35: Warning: + assertion 'rte,pointer_downcast' got status unknown. [eva] tests/value/div.i:35: assertion 'rte,division_by_zero' got status valid. [eva:alarm] tests/value/div.i:35: Warning: pointer downcast. assert (unsigned int)&X + 1 ≤ 2147483647; @@ -87,6 +93,8 @@ [eva] tests/value/div.i:35: Assigning imprecise value to d1. The imprecision originates from Arithmetic {tests/value/div.i:35} +[eva:alarm] tests/value/div.i:36: Warning: + assertion 'rte,pointer_downcast' got status unknown. [eva] tests/value/div.i:36: assertion 'rte,division_by_zero' got status valid. [eva:alarm] tests/value/div.i:36: Warning: pointer downcast. assert (unsigned int)&X ≤ 2147483647; @@ -97,6 +105,8 @@ [eva] tests/value/div.i:36: Assigning imprecise value to d0. The imprecision originates from Arithmetic {tests/value/div.i:36} +[eva:alarm] tests/value/div.i:37: Warning: + assertion 'rte,pointer_downcast' got status unknown. [eva:alarm] tests/value/div.i:37: Warning: assertion 'rte,signed_overflow' got status unknown. [eva:alarm] tests/value/div.i:37: Warning: -- GitLab From 48f0beafe945e70c035a739dbb879c282f78602f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20B=C3=BChler?= <david.buhler@cea.fr> Date: Thu, 26 Mar 2020 19:24:13 +0100 Subject: [PATCH 031/218] [Kernel] Fixes alarm: uses TCastE instead of TLogic_coerce. New smart constructor for TCastE in logic_const. --- src/kernel_services/ast_data/alarms.ml | 3 +- .../ast_queries/logic_const.ml | 3 + .../ast_queries/logic_const.mli | 3 + .../oracle/imprecise-malloc-free.res.oracle | 12 ++-- tests/builtins/oracle/imprecise.res.oracle | 8 +-- tests/builtins/oracle/memchr.res.oracle | 2 +- tests/builtins/oracle/memcpy.res.oracle | 8 +-- tests/builtins/oracle/memset.res.oracle | 4 +- tests/builtins/oracle/strchr.res.oracle | 4 +- tests/builtins/oracle/strlen.res.oracle | 2 +- tests/builtins/oracle/strnlen2.res.oracle | 2 +- tests/builtins/oracle/wcslen.res.oracle | 8 +-- tests/float/oracle/builtins.res.oracle | 2 +- tests/float/oracle/nonlin.0.res.oracle | 4 +- tests/float/oracle/nonlin.1.res.oracle | 4 +- tests/float/oracle/nonlin.2.res.oracle | 4 +- tests/float/oracle/nonlin.3.res.oracle | 4 +- tests/float/oracle/nonlin.4.res.oracle | 4 +- tests/float/oracle/nonlin.5.res.oracle | 4 +- tests/value/oracle/addition.res.oracle | 68 ++++++++++--------- .../value/oracle/align_char_array.res.oracle | 16 ++--- tests/value/oracle/arith_pointer.res.oracle | 4 +- tests/value/oracle/array_ptr.res.oracle | 2 +- tests/value/oracle/assigns.res.oracle | 8 +-- tests/value/oracle/bitfield.res.oracle | 12 ++-- tests/value/oracle/bitwise_pointer.res.oracle | 4 +- tests/value/oracle/cmp_ptr.0.res.oracle | 2 +- tests/value/oracle/cmp_ptr.1.res.oracle | 2 +- tests/value/oracle/context_free.res.oracle | 2 +- tests/value/oracle/conversion.res.oracle | 4 +- tests/value/oracle/deps_addr.res.oracle | 2 +- tests/value/oracle/deps_mixed.res.oracle | 2 +- tests/value/oracle/div.0.res.oracle | 10 +-- tests/value/oracle/div.1.res.oracle | 10 +-- tests/value/oracle/eval_separated.res.oracle | 4 +- tests/value/oracle/from_call.0.res.oracle | 4 +- tests/value/oracle/from_call.1.res.oracle | 4 +- tests/value/oracle/from_ptr.0.res.oracle | 4 +- tests/value/oracle/from_ptr.1.res.oracle | 4 +- tests/value/oracle/fun_ptr.1.res.oracle | 4 +- .../oracle/imprecise_invalid_write.res.oracle | 2 +- tests/value/oracle/initialized.res.oracle | 2 +- tests/value/oracle/join_misaligned.res.oracle | 4 +- tests/value/oracle/label.res.oracle | 2 +- tests/value/oracle/leaf2.res.oracle | 2 +- tests/value/oracle/mini_pointrer.res.oracle | 2 +- tests/value/oracle/nonlin.res.oracle | 2 +- .../value/oracle/not_ct_array_arg.res.oracle | 2 +- tests/value/oracle/offset_top.res.oracle | 2 +- tests/value/oracle/offsetmap.0.res.oracle | 2 +- tests/value/oracle/offsetmap.1.res.oracle | 2 +- tests/value/oracle/origin.0.res.oracle | 22 +++--- tests/value/oracle/origin.1.res.oracle | 2 +- tests/value/oracle/period.res.oracle | 6 +- .../oracle/pointer_comparison.0.res.oracle | 12 ++-- .../oracle/pointer_comparison.1.res.oracle | 12 ++-- .../value/oracle/pointer_int_cast.res.oracle | 2 +- tests/value/oracle/shift.0.res.oracle | 2 +- tests/value/oracle/shift.1.res.oracle | 2 +- tests/value/oracle/sizeof.res.oracle | 4 +- tests/value/oracle/struct3.res.oracle | 2 +- tests/value/oracle/struct_array.res.oracle | 12 ++-- tests/value/oracle/struct_incl.res.oracle | 6 +- tests/value/oracle/symbolic_locs.res.oracle | 2 +- tests/value/oracle/volatile.res.oracle | 2 +- 65 files changed, 189 insertions(+), 180 deletions(-) diff --git a/src/kernel_services/ast_data/alarms.ml b/src/kernel_services/ast_data/alarms.ml index 445efc3204d..2faab4979f1 100644 --- a/src/kernel_services/ast_data/alarms.ml +++ b/src/kernel_services/ast_data/alarms.ml @@ -553,8 +553,7 @@ let create_predicate ?(loc=Location.unknown) alarm = let t = match kind with | Pointer_downcast -> let t = Logic_utils.expr_to_term ~cast:true e in - let typ = Cil.theMachine.upointType in - Logic_const.tlogic_coerce ~loc t (Ctype typ) + Logic_const.tcast ~loc t Cil.theMachine.upointType | Signed_downcast | Unsigned_downcast -> Logic_utils.expr_to_term ~cast:true e | _ -> diff --git a/src/kernel_services/ast_queries/logic_const.ml b/src/kernel_services/ast_queries/logic_const.ml index 8da10c3cf69..e9417dd0256 100644 --- a/src/kernel_services/ast_queries/logic_const.ml +++ b/src/kernel_services/ast_queries/logic_const.ml @@ -305,6 +305,9 @@ let tat ?(loc=Cil_datatype.Location.unknown) (t,label) = let told ?(loc=Cil_datatype.Location.unknown) t = tat ~loc (t,old_label) +let tcast ?(loc=Cil_datatype.Location.unknown) t ct = + term ~loc (TCastE (ct, t)) (Ctype ct) + let tlogic_coerce ?(loc=Cil_datatype.Location.unknown) t lt = term ~loc (TLogic_coerce (lt, t)) lt diff --git a/src/kernel_services/ast_queries/logic_const.mli b/src/kernel_services/ast_queries/logic_const.mli index c3be4194f94..280661c522f 100644 --- a/src/kernel_services/ast_queries/logic_const.mli +++ b/src/kernel_services/ast_queries/logic_const.mli @@ -321,6 +321,9 @@ val tvar: ?loc:Location.t -> logic_var -> term (** \result *) val tresult: ?loc:Location.t -> typ -> term +(** cast to the given C type *) +val tcast: ?loc:Location.t -> term -> typ -> term + (** coercion to the given logic type *) val tlogic_coerce: ?loc:Location.t -> term -> logic_type -> term diff --git a/tests/builtins/oracle/imprecise-malloc-free.res.oracle b/tests/builtins/oracle/imprecise-malloc-free.res.oracle index c748e18da98..4d7ac635f76 100644 --- a/tests/builtins/oracle/imprecise-malloc-free.res.oracle +++ b/tests/builtins/oracle/imprecise-malloc-free.res.oracle @@ -5,9 +5,9 @@ [eva:initial-state] Values of globals at initialization i ∈ [--..--] [eva:alarm] tests/builtins/imprecise-malloc-free.c:12: Warning: - pointer downcast. assert (unsigned int)&size1 + i ≤ 2147483647; + pointer downcast. assert (unsigned int)(&size1 + i) ≤ 2147483647; [eva:alarm] tests/builtins/imprecise-malloc-free.c:13: Warning: - pointer downcast. assert (unsigned int)&size2 ≤ 2147483647; + pointer downcast. assert (unsigned int)(&size2) ≤ 2147483647; [eva:alarm] tests/builtins/imprecise-malloc-free.c:13: Warning: signed overflow. assert -2147483648 ≤ i + (int)((int)(&size2) >> 1); [eva:alarm] tests/builtins/imprecise-malloc-free.c:13: Warning: @@ -17,7 +17,7 @@ The imprecision originates from Arithmetic {tests/builtins/imprecise-malloc-free.c:13} [eva:alarm] tests/builtins/imprecise-malloc-free.c:14: Warning: - pointer downcast. assert (unsigned int)&i ≤ 2147483647; + pointer downcast. assert (unsigned int)(&i) ≤ 2147483647; [eva] tests/builtins/imprecise-malloc-free.c:14: Call to builtin malloc [eva] tests/builtins/imprecise-malloc-free.c:14: allocating variable __malloc_main_l14 @@ -37,15 +37,15 @@ [eva:alarm] tests/builtins/imprecise-malloc-free.c:21: Warning: out of bounds write. assert \valid(p); [eva:alarm] tests/builtins/imprecise-malloc-free.c:21: Warning: - pointer downcast. assert (unsigned int)p + 1 ≤ 2147483647; + pointer downcast. assert (unsigned int)(p + 1) ≤ 2147483647; [eva:alarm] tests/builtins/imprecise-malloc-free.c:22: Warning: out of bounds write. assert \valid(q); [eva:alarm] tests/builtins/imprecise-malloc-free.c:22: Warning: - pointer downcast. assert (unsigned int)q + 2 ≤ 2147483647; + pointer downcast. assert (unsigned int)(q + 2) ≤ 2147483647; [eva:alarm] tests/builtins/imprecise-malloc-free.c:23: Warning: out of bounds write. assert \valid(r); [eva:alarm] tests/builtins/imprecise-malloc-free.c:23: Warning: - pointer downcast. assert (unsigned int)r + 3 ≤ 2147483647; + pointer downcast. assert (unsigned int)(r + 3) ≤ 2147483647; [eva:alarm] tests/builtins/imprecise-malloc-free.c:25: Warning: pointer downcast. assert (unsigned int)p ≤ 2147483647; [eva] tests/builtins/imprecise-malloc-free.c:25: Call to builtin free diff --git a/tests/builtins/oracle/imprecise.res.oracle b/tests/builtins/oracle/imprecise.res.oracle index 240ad0e4b03..f93b938207e 100644 --- a/tests/builtins/oracle/imprecise.res.oracle +++ b/tests/builtins/oracle/imprecise.res.oracle @@ -49,7 +49,7 @@ [eva] computing for function write_garbled <- main. Called from tests/builtins/imprecise.c:145. [eva:alarm] tests/builtins/imprecise.c:19: Warning: - pointer downcast. assert (unsigned int)&k ≤ 2147483647; + pointer downcast. assert (unsigned int)(&k) ≤ 2147483647; [eva] tests/builtins/imprecise.c:19: Assigning imprecise value to p. The imprecision originates from Arithmetic {tests/builtins/imprecise.c:19} @@ -110,7 +110,7 @@ [eva:alarm] tests/builtins/imprecise.c:53: Warning: out of bounds write. assert \valid(p2); [eva:alarm] tests/builtins/imprecise.c:53: Warning: - pointer downcast. assert (unsigned int)&addr ≤ 2147483647; + pointer downcast. assert (unsigned int)(&addr) ≤ 2147483647; [eva:alarm] tests/builtins/imprecise.c:56: Warning: out of bounds write. assert \valid(p4); [eva:alarm] tests/builtins/imprecise.c:58: Warning: @@ -625,7 +625,7 @@ [eva] computing for function write_garbled <- main. Called from tests/builtins/imprecise.c:145. [eva:alarm] tests/builtins/imprecise.c:19: Warning: - pointer downcast. assert (unsigned int)&k ≤ 2147483647; + pointer downcast. assert (unsigned int)(&k) ≤ 2147483647; [eva:alarm] tests/builtins/imprecise.c:20: Warning: out of bounds write. assert \valid(p); [eva] tests/builtins/imprecise.c:21: @@ -686,7 +686,7 @@ [eva:alarm] tests/builtins/imprecise.c:53: Warning: out of bounds write. assert \valid(p2); [eva:alarm] tests/builtins/imprecise.c:53: Warning: - pointer downcast. assert (unsigned int)&addr ≤ 2147483647; + pointer downcast. assert (unsigned int)(&addr) ≤ 2147483647; [eva:alarm] tests/builtins/imprecise.c:56: Warning: out of bounds write. assert \valid(p4); [eva:alarm] tests/builtins/imprecise.c:58: Warning: diff --git a/tests/builtins/oracle/memchr.res.oracle b/tests/builtins/oracle/memchr.res.oracle index 452e93e5b6d..4fbe20f941e 100644 --- a/tests/builtins/oracle/memchr.res.oracle +++ b/tests/builtins/oracle/memchr.res.oracle @@ -478,7 +478,7 @@ [eva] computing for function memchr_escaping <- main. Called from tests/builtins/memchr.c:662. [eva:alarm] tests/builtins/memchr.c:264: Warning: - pointer downcast. assert (unsigned int)&x ≤ 2147483647; + pointer downcast. assert (unsigned int)(&x) ≤ 2147483647; [eva:locals-escaping] tests/builtins/memchr.c:264: Warning: locals {x} escaping the scope of a block of memchr_escaping through s [eva] tests/builtins/memchr.c:267: Call to builtin memchr diff --git a/tests/builtins/oracle/memcpy.res.oracle b/tests/builtins/oracle/memcpy.res.oracle index b6358392e62..68da1692272 100644 --- a/tests/builtins/oracle/memcpy.res.oracle +++ b/tests/builtins/oracle/memcpy.res.oracle @@ -129,7 +129,7 @@ [eva] tests/builtins/memcpy.c:85: function memcpy: precondition 'separation' got status valid. [eva:alarm] tests/builtins/memcpy.c:87: Warning: - pointer downcast. assert (unsigned int)(struct t1 *)t ≤ 2147483647; + pointer downcast. assert (unsigned int)((struct t1 *)t) ≤ 2147483647; [eva] tests/builtins/memcpy.c:87: Call to builtin memcpy [eva] tests/builtins/memcpy.c:87: function memcpy: precondition 'valid_dest' got status valid. @@ -138,7 +138,7 @@ [eva] tests/builtins/memcpy.c:87: function memcpy: precondition 'separation' got status valid. [eva:alarm] tests/builtins/memcpy.c:89: Warning: - pointer downcast. assert (unsigned int)&v4 ≤ 2147483647; + pointer downcast. assert (unsigned int)(&v4) ≤ 2147483647; [eva] tests/builtins/memcpy.c:89: Call to builtin memcpy [eva:alarm] tests/builtins/memcpy.c:89: Warning: function memcpy: precondition 'valid_dest' got status unknown. @@ -150,9 +150,9 @@ writing somewhere in {NULL; v4} because of Arithmetic {tests/builtins/memcpy.c:89}. [eva:alarm] tests/builtins/memcpy.c:90: Warning: - pointer downcast. assert (unsigned int)(struct t1 *)t ≤ 2147483647; + pointer downcast. assert (unsigned int)((struct t1 *)t) ≤ 2147483647; [eva:alarm] tests/builtins/memcpy.c:91: Warning: - pointer downcast. assert (unsigned int)&v5 ≤ 2147483647; + pointer downcast. assert (unsigned int)(&v5) ≤ 2147483647; [eva] tests/builtins/memcpy.c:91: Call to builtin memcpy [eva:alarm] tests/builtins/memcpy.c:91: Warning: function memcpy: precondition 'valid_dest' got status unknown. diff --git a/tests/builtins/oracle/memset.res.oracle b/tests/builtins/oracle/memset.res.oracle index 11215767505..e2c14678865 100644 --- a/tests/builtins/oracle/memset.res.oracle +++ b/tests/builtins/oracle/memset.res.oracle @@ -26,7 +26,7 @@ [eva] share/libc/string.h:118: cannot evaluate ACSL term, unsupported ACSL construct: logic function memset [eva:alarm] tests/builtins/memset.c:34: Warning: - pointer downcast. assert (unsigned int)(int *)t2 ≤ 2147483647; + pointer downcast. assert (unsigned int)((int *)t2) ≤ 2147483647; [eva] tests/builtins/memset.c:34: Call to builtin memset [eva:alarm] tests/builtins/memset.c:34: Warning: function memset: precondition 'valid_s' got status unknown. @@ -45,7 +45,7 @@ [eva:alarm] tests/builtins/memset.c:38: Warning: function memset: precondition 'valid_s' got status invalid. [eva:alarm] tests/builtins/memset.c:41: Warning: - pointer downcast. assert (unsigned int)(int *)t1 ≤ 2147483647; + pointer downcast. assert (unsigned int)((int *)t1) ≤ 2147483647; [eva] tests/builtins/memset.c:41: Call to builtin memset [eva] tests/builtins/memset.c:41: function memset: precondition 'valid_s' got status valid. diff --git a/tests/builtins/oracle/strchr.res.oracle b/tests/builtins/oracle/strchr.res.oracle index 6139567781a..21fd920919a 100644 --- a/tests/builtins/oracle/strchr.res.oracle +++ b/tests/builtins/oracle/strchr.res.oracle @@ -317,7 +317,7 @@ [eva] computing for function strchr_escaping <- main. Called from tests/builtins/strchr.c:556. [eva:alarm] tests/builtins/strchr.c:258: Warning: - pointer downcast. assert (unsigned int)&x ≤ 2147483647; + pointer downcast. assert (unsigned int)(&x) ≤ 2147483647; [eva:locals-escaping] tests/builtins/strchr.c:258: Warning: locals {x} escaping the scope of a block of strchr_escaping through s [eva] tests/builtins/strchr.c:261: Call to builtin strchr @@ -672,7 +672,7 @@ [eva] computing for function strchr_garbled_mix_in_char <- main. Called from tests/builtins/strchr.c:562. [eva:alarm] tests/builtins/strchr.c:541: Warning: - pointer downcast. assert (unsigned int)&x ≤ 2147483647; + pointer downcast. assert (unsigned int)(&x) ≤ 2147483647; [eva] tests/builtins/strchr.c:541: Assigning imprecise value to garbled. The imprecision originates from Arithmetic {tests/builtins/strchr.c:541} diff --git a/tests/builtins/oracle/strlen.res.oracle b/tests/builtins/oracle/strlen.res.oracle index 900d168bdba..dcc09a3de5d 100644 --- a/tests/builtins/oracle/strlen.res.oracle +++ b/tests/builtins/oracle/strlen.res.oracle @@ -262,7 +262,7 @@ [eva] computing for function escaping <- main. Called from tests/builtins/strlen.c:342. [eva:alarm] tests/builtins/strlen.c:222: Warning: - pointer downcast. assert (unsigned int)&x ≤ 2147483647; + pointer downcast. assert (unsigned int)(&x) ≤ 2147483647; [eva:locals-escaping] tests/builtins/strlen.c:222: Warning: locals {x} escaping the scope of a block of escaping through s [eva] tests/builtins/strlen.c:225: Call to builtin strlen diff --git a/tests/builtins/oracle/strnlen2.res.oracle b/tests/builtins/oracle/strnlen2.res.oracle index b04e6e5abe4..392940b6cb6 100644 --- a/tests/builtins/oracle/strnlen2.res.oracle +++ b/tests/builtins/oracle/strnlen2.res.oracle @@ -262,7 +262,7 @@ [eva] computing for function escaping <- main. Called from tests/builtins/strnlen2.c:522. [eva:alarm] tests/builtins/strnlen2.c:196: Warning: - pointer downcast. assert (unsigned int)&x ≤ 2147483647; + pointer downcast. assert (unsigned int)(&x) ≤ 2147483647; [eva:locals-escaping] tests/builtins/strnlen2.c:196: Warning: locals {x} escaping the scope of a block of escaping through s [eva] tests/builtins/strnlen2.c:199: Call to builtin strnlen diff --git a/tests/builtins/oracle/wcslen.res.oracle b/tests/builtins/oracle/wcslen.res.oracle index 0c9295b364c..784bf02c5cf 100644 --- a/tests/builtins/oracle/wcslen.res.oracle +++ b/tests/builtins/oracle/wcslen.res.oracle @@ -262,13 +262,13 @@ [eva] computing for function escaping <- main. Called from tests/builtins/wcslen.c:347. [eva:alarm] tests/builtins/wcslen.c:222: Warning: - pointer downcast. assert (unsigned int)&x ≤ 2147483647; + pointer downcast. assert (unsigned int)(&x) ≤ 2147483647; [eva:alarm] tests/builtins/wcslen.c:222: Warning: - pointer downcast. assert (unsigned int)&x ≤ 2147483647; + pointer downcast. assert (unsigned int)(&x) ≤ 2147483647; [eva:alarm] tests/builtins/wcslen.c:222: Warning: - pointer downcast. assert (unsigned int)&x ≤ 2147483647; + pointer downcast. assert (unsigned int)(&x) ≤ 2147483647; [eva:alarm] tests/builtins/wcslen.c:222: Warning: - pointer downcast. assert (unsigned int)&x ≤ 2147483647; + pointer downcast. assert (unsigned int)(&x) ≤ 2147483647; [eva:locals-escaping] tests/builtins/wcslen.c:222: Warning: locals {x} escaping the scope of a block of escaping through s [eva] tests/builtins/wcslen.c:225: Call to builtin wcslen diff --git a/tests/float/oracle/builtins.res.oracle b/tests/float/oracle/builtins.res.oracle index 00d692def3c..66f30707d32 100644 --- a/tests/float/oracle/builtins.res.oracle +++ b/tests/float/oracle/builtins.res.oracle @@ -135,7 +135,7 @@ [eva] tests/float/builtins.c:104: function exp: precondition 'finite_domain' got status valid. [eva:alarm] tests/float/builtins.c:107: Warning: - pointer downcast. assert (unsigned int)&d ≤ 2147483647; + pointer downcast. assert (unsigned int)(&d) ≤ 2147483647; [eva:alarm] tests/float/builtins.c:107: Warning: non-finite double value. assert \is_finite((double)((int)(&d))); [eva] tests/float/builtins.c:107: Call to builtin log diff --git a/tests/float/oracle/nonlin.0.res.oracle b/tests/float/oracle/nonlin.0.res.oracle index 6324ceb920c..5e60b7a32e5 100644 --- a/tests/float/oracle/nonlin.0.res.oracle +++ b/tests/float/oracle/nonlin.0.res.oracle @@ -231,9 +231,9 @@ [eva] computing for function garbled <- main. Called from tests/float/nonlin.c:148. [eva:alarm] tests/float/nonlin.c:98: Warning: - pointer downcast. assert (unsigned int)&x_0 ≤ 2147483647; + pointer downcast. assert (unsigned int)(&x_0) ≤ 2147483647; [eva:alarm] tests/float/nonlin.c:98: Warning: - pointer downcast. assert (unsigned int)&x_0 + (int)(&x_0) ≤ 2147483647; + pointer downcast. assert (unsigned int)(&x_0 + (int)(&x_0)) ≤ 2147483647; [eva:alarm] tests/float/nonlin.c:98: Warning: non-finite float value. assert \is_finite((float)((int)(&x_0 + (int)(&x_0)))); diff --git a/tests/float/oracle/nonlin.1.res.oracle b/tests/float/oracle/nonlin.1.res.oracle index 9f4864b2625..036f8d26e43 100644 --- a/tests/float/oracle/nonlin.1.res.oracle +++ b/tests/float/oracle/nonlin.1.res.oracle @@ -254,9 +254,9 @@ [eva] computing for function garbled <- main. Called from tests/float/nonlin.c:148. [eva:alarm] tests/float/nonlin.c:98: Warning: - pointer downcast. assert (unsigned int)&x_0 ≤ 2147483647; + pointer downcast. assert (unsigned int)(&x_0) ≤ 2147483647; [eva:alarm] tests/float/nonlin.c:98: Warning: - pointer downcast. assert (unsigned int)&x_0 + (int)(&x_0) ≤ 2147483647; + pointer downcast. assert (unsigned int)(&x_0 + (int)(&x_0)) ≤ 2147483647; [eva:alarm] tests/float/nonlin.c:98: Warning: non-finite float value. assert \is_finite((float)((int)(&x_0 + (int)(&x_0)))); diff --git a/tests/float/oracle/nonlin.2.res.oracle b/tests/float/oracle/nonlin.2.res.oracle index a0b3a97b62f..112f643e881 100644 --- a/tests/float/oracle/nonlin.2.res.oracle +++ b/tests/float/oracle/nonlin.2.res.oracle @@ -241,9 +241,9 @@ [eva] computing for function garbled <- main. Called from tests/float/nonlin.c:148. [eva:alarm] tests/float/nonlin.c:98: Warning: - pointer downcast. assert (unsigned int)&x_0 ≤ 2147483647; + pointer downcast. assert (unsigned int)(&x_0) ≤ 2147483647; [eva:alarm] tests/float/nonlin.c:98: Warning: - pointer downcast. assert (unsigned int)&x_0 + (int)(&x_0) ≤ 2147483647; + pointer downcast. assert (unsigned int)(&x_0 + (int)(&x_0)) ≤ 2147483647; [eva] tests/float/nonlin.c:98: Assigning imprecise value to a_0. The imprecision originates from Arithmetic {tests/float/nonlin.c:98} diff --git a/tests/float/oracle/nonlin.3.res.oracle b/tests/float/oracle/nonlin.3.res.oracle index 52fc170f4f8..f791b980831 100644 --- a/tests/float/oracle/nonlin.3.res.oracle +++ b/tests/float/oracle/nonlin.3.res.oracle @@ -231,9 +231,9 @@ [eva] computing for function garbled <- main. Called from tests/float/nonlin.c:148. [eva:alarm] tests/float/nonlin.c:98: Warning: - pointer downcast. assert (unsigned int)&x_0 ≤ 2147483647; + pointer downcast. assert (unsigned int)(&x_0) ≤ 2147483647; [eva:alarm] tests/float/nonlin.c:98: Warning: - pointer downcast. assert (unsigned int)&x_0 + (int)(&x_0) ≤ 2147483647; + pointer downcast. assert (unsigned int)(&x_0 + (int)(&x_0)) ≤ 2147483647; [eva:alarm] tests/float/nonlin.c:98: Warning: non-finite float value. assert \is_finite((float)((int)(&x_0 + (int)(&x_0)))); diff --git a/tests/float/oracle/nonlin.4.res.oracle b/tests/float/oracle/nonlin.4.res.oracle index 2d45c975ffb..ba58150afaf 100644 --- a/tests/float/oracle/nonlin.4.res.oracle +++ b/tests/float/oracle/nonlin.4.res.oracle @@ -254,9 +254,9 @@ [eva] computing for function garbled <- main. Called from tests/float/nonlin.c:148. [eva:alarm] tests/float/nonlin.c:98: Warning: - pointer downcast. assert (unsigned int)&x_0 ≤ 2147483647; + pointer downcast. assert (unsigned int)(&x_0) ≤ 2147483647; [eva:alarm] tests/float/nonlin.c:98: Warning: - pointer downcast. assert (unsigned int)&x_0 + (int)(&x_0) ≤ 2147483647; + pointer downcast. assert (unsigned int)(&x_0 + (int)(&x_0)) ≤ 2147483647; [eva:alarm] tests/float/nonlin.c:98: Warning: non-finite float value. assert \is_finite((float)((int)(&x_0 + (int)(&x_0)))); diff --git a/tests/float/oracle/nonlin.5.res.oracle b/tests/float/oracle/nonlin.5.res.oracle index 667b1228b96..36e1a671ef6 100644 --- a/tests/float/oracle/nonlin.5.res.oracle +++ b/tests/float/oracle/nonlin.5.res.oracle @@ -241,9 +241,9 @@ [eva] computing for function garbled <- main. Called from tests/float/nonlin.c:148. [eva:alarm] tests/float/nonlin.c:98: Warning: - pointer downcast. assert (unsigned int)&x_0 ≤ 2147483647; + pointer downcast. assert (unsigned int)(&x_0) ≤ 2147483647; [eva:alarm] tests/float/nonlin.c:98: Warning: - pointer downcast. assert (unsigned int)&x_0 + (int)(&x_0) ≤ 2147483647; + pointer downcast. assert (unsigned int)(&x_0 + (int)(&x_0)) ≤ 2147483647; [eva] tests/float/nonlin.c:98: Assigning imprecise value to a_0. The imprecision originates from Arithmetic {tests/float/nonlin.c:98} diff --git a/tests/value/oracle/addition.res.oracle b/tests/value/oracle/addition.res.oracle index 81d6deca427..1fe41a6755a 100644 --- a/tests/value/oracle/addition.res.oracle +++ b/tests/value/oracle/addition.res.oracle @@ -60,45 +60,47 @@ Assigning imprecise value to p1. The imprecision originates from Arithmetic {tests/value/addition.i:34} [eva:alarm] tests/value/addition.i:36: Warning: - pointer downcast. assert (unsigned int)&p1 ≤ 2147483647; + pointer downcast. assert (unsigned int)(&p1) ≤ 2147483647; [eva] tests/value/addition.i:36: Assigning imprecise value to p2. The imprecision originates from Arithmetic {tests/value/addition.i:36} [eva:alarm] tests/value/addition.i:38: Warning: - pointer downcast. assert (unsigned int)&p1 ≤ 127; + pointer downcast. assert (unsigned int)(&p1) ≤ 127; [eva:alarm] tests/value/addition.i:38: Warning: - pointer downcast. assert (unsigned int)&t[(char)(&p1)] ≤ 2147483647; + pointer downcast. assert (unsigned int)(&t[(char)(&p1)]) ≤ 2147483647; [eva] tests/value/addition.i:38: Assigning imprecise value to p3. The imprecision originates from Arithmetic {tests/value/addition.i:38} [eva:alarm] tests/value/addition.i:40: Warning: - pointer downcast. assert (unsigned int)&p1 ≤ 127; + pointer downcast. assert (unsigned int)(&p1) ≤ 127; [eva:alarm] tests/value/addition.i:40: Warning: - pointer downcast. assert (unsigned int)&tt[(char)(&p1)].a ≤ 2147483647; + pointer downcast. assert (unsigned int)(&tt[(char)(&p1)].a) ≤ 2147483647; [eva] tests/value/addition.i:40: Assigning imprecise value to p4. The imprecision originates from Arithmetic {tests/value/addition.i:40} [eva:alarm] tests/value/addition.i:42: Warning: - pointer downcast. assert (unsigned int)&p1 ≤ 127; + pointer downcast. assert (unsigned int)(&p1) ≤ 127; [eva:alarm] tests/value/addition.i:42: Warning: - pointer downcast. assert (unsigned int)&p2 ≤ 127; + pointer downcast. assert (unsigned int)(&p2) ≤ 127; [eva:alarm] tests/value/addition.i:42: Warning: pointer downcast. - assert (unsigned int)&ttt[(char)(&p1)][(char)(&p2)] ≤ 2147483647; + assert (unsigned int)(&ttt[(char)(&p1)][(char)(&p2)]) ≤ 2147483647; [eva] tests/value/addition.i:42: Assigning imprecise value to p5. The imprecision originates from Arithmetic {tests/value/addition.i:42} [eva:alarm] tests/value/addition.i:44: Warning: - pointer downcast. assert (unsigned int)&p1 ≤ 127; + pointer downcast. assert (unsigned int)(&p1) ≤ 127; [eva:alarm] tests/value/addition.i:44: Warning: - pointer downcast. assert (unsigned int)&ttt[(char)(&p1)][u2] ≤ 2147483647; + pointer downcast. + assert (unsigned int)(&ttt[(char)(&p1)][u2]) ≤ 2147483647; [eva] tests/value/addition.i:44: Assigning imprecise value to p6. The imprecision originates from Arithmetic {tests/value/addition.i:44} [eva:alarm] tests/value/addition.i:46: Warning: - pointer downcast. assert (unsigned int)&p2 ≤ 127; + pointer downcast. assert (unsigned int)(&p2) ≤ 127; [eva:alarm] tests/value/addition.i:46: Warning: - pointer downcast. assert (unsigned int)&ttt[u2][(char)(&p2)] ≤ 2147483647; + pointer downcast. + assert (unsigned int)(&ttt[u2][(char)(&p2)]) ≤ 2147483647; [eva] tests/value/addition.i:46: Assigning imprecise value to p7. The imprecision originates from Arithmetic {tests/value/addition.i:46} @@ -106,7 +108,7 @@ pointer comparison. assert \pointer_comparable((void *)(&p1 + 1), (void *)(&p2)); [eva:alarm] tests/value/addition.i:50: Warning: - pointer downcast. assert (unsigned int)&p1 ≤ 2147483647; + pointer downcast. assert (unsigned int)(&p1) ≤ 2147483647; [eva:alarm] tests/value/addition.i:50: Warning: signed overflow. assert -2147483648 ≤ (int)(&p1) / 2; [eva:alarm] tests/value/addition.i:50: Warning: @@ -115,14 +117,14 @@ Assigning imprecise value to p9. The imprecision originates from Arithmetic {tests/value/addition.i:50} [eva:alarm] tests/value/addition.i:52: Warning: - pointer downcast. assert (unsigned int)&p1 ≤ 2147483647; + pointer downcast. assert (unsigned int)(&p1) ≤ 2147483647; [eva] tests/value/addition.i:52: Assigning imprecise value to p10. The imprecision originates from Arithmetic {tests/value/addition.i:52} [eva:alarm] tests/value/addition.i:56: Warning: - pointer downcast. assert (unsigned int)&p1 ≤ 2147483647; + pointer downcast. assert (unsigned int)(&p1) ≤ 2147483647; [eva:alarm] tests/value/addition.i:56: Warning: - pointer downcast. assert (unsigned int)&p2 ≤ 2147483647; + pointer downcast. assert (unsigned int)(&p2) ≤ 2147483647; [eva] tests/value/addition.i:56: Assigning imprecise value to p12. The imprecision originates from Arithmetic {tests/value/addition.i:56} @@ -357,45 +359,47 @@ [eva:alarm] tests/value/addition.i:34: Warning: signed overflow. assert &p2 - &p3 ≤ 2147483647; [eva:alarm] tests/value/addition.i:36: Warning: - pointer downcast. assert (unsigned int)&p1 ≤ 2147483647; + pointer downcast. assert (unsigned int)(&p1) ≤ 2147483647; [eva:alarm] tests/value/addition.i:38: Warning: - pointer downcast. assert (unsigned int)&p1 ≤ 127; + pointer downcast. assert (unsigned int)(&p1) ≤ 127; [eva:alarm] tests/value/addition.i:38: Warning: - pointer downcast. assert (unsigned int)&t[(char)(&p1)] ≤ 2147483647; + pointer downcast. assert (unsigned int)(&t[(char)(&p1)]) ≤ 2147483647; [eva:alarm] tests/value/addition.i:40: Warning: - pointer downcast. assert (unsigned int)&p1 ≤ 127; + pointer downcast. assert (unsigned int)(&p1) ≤ 127; [eva:alarm] tests/value/addition.i:40: Warning: - pointer downcast. assert (unsigned int)&tt[(char)(&p1)].a ≤ 2147483647; + pointer downcast. assert (unsigned int)(&tt[(char)(&p1)].a) ≤ 2147483647; [eva:alarm] tests/value/addition.i:42: Warning: - pointer downcast. assert (unsigned int)&p1 ≤ 127; + pointer downcast. assert (unsigned int)(&p1) ≤ 127; [eva:alarm] tests/value/addition.i:42: Warning: - pointer downcast. assert (unsigned int)&p2 ≤ 127; + pointer downcast. assert (unsigned int)(&p2) ≤ 127; [eva:alarm] tests/value/addition.i:42: Warning: pointer downcast. - assert (unsigned int)&ttt[(char)(&p1)][(char)(&p2)] ≤ 2147483647; + assert (unsigned int)(&ttt[(char)(&p1)][(char)(&p2)]) ≤ 2147483647; [eva:alarm] tests/value/addition.i:44: Warning: - pointer downcast. assert (unsigned int)&p1 ≤ 127; + pointer downcast. assert (unsigned int)(&p1) ≤ 127; [eva:alarm] tests/value/addition.i:44: Warning: - pointer downcast. assert (unsigned int)&ttt[(char)(&p1)][u2] ≤ 2147483647; + pointer downcast. + assert (unsigned int)(&ttt[(char)(&p1)][u2]) ≤ 2147483647; [eva:alarm] tests/value/addition.i:46: Warning: - pointer downcast. assert (unsigned int)&p2 ≤ 127; + pointer downcast. assert (unsigned int)(&p2) ≤ 127; [eva:alarm] tests/value/addition.i:46: Warning: - pointer downcast. assert (unsigned int)&ttt[u2][(char)(&p2)] ≤ 2147483647; + pointer downcast. + assert (unsigned int)(&ttt[u2][(char)(&p2)]) ≤ 2147483647; [eva:alarm] tests/value/addition.i:48: Warning: pointer comparison. assert \pointer_comparable((void *)(&p1 + 1), (void *)(&p2)); [eva:alarm] tests/value/addition.i:50: Warning: - pointer downcast. assert (unsigned int)&p1 ≤ 2147483647; + pointer downcast. assert (unsigned int)(&p1) ≤ 2147483647; [eva:alarm] tests/value/addition.i:50: Warning: signed overflow. assert -2147483648 ≤ (int)(&p1) / 2; [eva:alarm] tests/value/addition.i:50: Warning: signed overflow. assert (int)(&p1) / 2 ≤ 2147483647; [eva:alarm] tests/value/addition.i:52: Warning: - pointer downcast. assert (unsigned int)&p1 ≤ 2147483647; + pointer downcast. assert (unsigned int)(&p1) ≤ 2147483647; [eva:alarm] tests/value/addition.i:56: Warning: - pointer downcast. assert (unsigned int)&p1 ≤ 2147483647; + pointer downcast. assert (unsigned int)(&p1) ≤ 2147483647; [eva:alarm] tests/value/addition.i:56: Warning: - pointer downcast. assert (unsigned int)&p2 ≤ 2147483647; + pointer downcast. assert (unsigned int)(&p2) ≤ 2147483647; [eva:alarm] tests/value/addition.i:59: Warning: signed overflow. assert -2147483648 ≤ (int)*((char *)(&q1)) + 2; [eva:alarm] tests/value/addition.i:59: Warning: diff --git a/tests/value/oracle/align_char_array.res.oracle b/tests/value/oracle/align_char_array.res.oracle index c84e281414a..3383a7f5af1 100644 --- a/tests/value/oracle/align_char_array.res.oracle +++ b/tests/value/oracle/align_char_array.res.oracle @@ -16,33 +16,33 @@ overlapread3 ∈ {0} overlapread4 ∈ {0} [eva:alarm] tests/value/align_char_array.c:21: Warning: - pointer downcast. assert (unsigned int)&S.a ≤ 2147483647; + pointer downcast. assert (unsigned int)(&S.a) ≤ 2147483647; [eva:alarm] tests/value/align_char_array.c:21: Warning: - pointer downcast. assert (unsigned int)&S.c ≤ 2147483647; + pointer downcast. assert (unsigned int)(&S.c) ≤ 2147483647; [eva:alarm] tests/value/align_char_array.c:23: Warning: - pointer downcast. assert (unsigned int)&t[2][2] ≤ 2147483647; + pointer downcast. assert (unsigned int)(&t[2][2]) ≤ 2147483647; [eva:alarm] tests/value/align_char_array.c:23: Warning: - pointer downcast. assert (unsigned int)&t[0][0] ≤ 2147483647; + pointer downcast. assert (unsigned int)(&t[0][0]) ≤ 2147483647; [eva:alarm] tests/value/align_char_array.c:25: Warning: - pointer downcast. assert (unsigned int)(char (*)[10])t ≤ 2147483647; + pointer downcast. assert (unsigned int)((char (*)[10])t) ≤ 2147483647; [eva:alarm] tests/value/align_char_array.c:25: Warning: signed overflow. assert -2147483648 ≤ (int)((char (*)[10])t) + 3; [eva:alarm] tests/value/align_char_array.c:25: Warning: signed overflow. assert (int)((char (*)[10])t) + 3 ≤ 2147483647; [eva:alarm] tests/value/align_char_array.c:26: Warning: - pointer downcast. assert (unsigned int)(char (*)[10])t ≤ 2147483647; + pointer downcast. assert (unsigned int)((char (*)[10])t) ≤ 2147483647; [eva:alarm] tests/value/align_char_array.c:26: Warning: signed overflow. assert -2147483648 ≤ (int)((char (*)[10])t) + 3; [eva:alarm] tests/value/align_char_array.c:26: Warning: signed overflow. assert (int)((char (*)[10])t) + 3 ≤ 2147483647; [eva:alarm] tests/value/align_char_array.c:27: Warning: - pointer downcast. assert (unsigned int)(char (*)[10])t ≤ 2147483647; + pointer downcast. assert (unsigned int)((char (*)[10])t) ≤ 2147483647; [eva:alarm] tests/value/align_char_array.c:27: Warning: signed overflow. assert -2147483648 ≤ (int)((char (*)[10])t) + 2; [eva:alarm] tests/value/align_char_array.c:27: Warning: signed overflow. assert (int)((char (*)[10])t) + 2 ≤ 2147483647; [eva:alarm] tests/value/align_char_array.c:28: Warning: - pointer downcast. assert (unsigned int)(char (*)[10])t ≤ 2147483647; + pointer downcast. assert (unsigned int)((char (*)[10])t) ≤ 2147483647; [eva:alarm] tests/value/align_char_array.c:28: Warning: signed overflow. assert -2147483648 ≤ (int)((char (*)[10])t) + 2; [eva:alarm] tests/value/align_char_array.c:28: Warning: diff --git a/tests/value/oracle/arith_pointer.res.oracle b/tests/value/oracle/arith_pointer.res.oracle index b8a89b48a6c..a09c922b6d3 100644 --- a/tests/value/oracle/arith_pointer.res.oracle +++ b/tests/value/oracle/arith_pointer.res.oracle @@ -23,7 +23,7 @@ pointer subtraction. assert \base_addr(p2) ≡ \base_addr(p2); [eva] tests/value/arith_pointer.c:52: Frama_C_show_each: {0} [eva:alarm] tests/value/arith_pointer.c:54: Warning: - pointer downcast. assert (unsigned int)&x ≤ 2147483647; + pointer downcast. assert (unsigned int)(&x) ≤ 2147483647; [eva] tests/value/arith_pointer.c:54: Assigning imprecise value to p1. The imprecision originates from Arithmetic {tests/value/arith_pointer.c:54} @@ -151,7 +151,7 @@ {{ garbled mix of &{x; y} (origin: Arithmetic {tests/value/arith_pointer.c:51}) }} [eva:alarm] tests/value/arith_pointer.c:54: Warning: - pointer downcast. assert (unsigned int)&x ≤ 2147483647; + pointer downcast. assert (unsigned int)(&x) ≤ 2147483647; [eva:alarm] tests/value/arith_pointer.c:56: Warning: signed overflow. assert -2147483648 ≤ p2 - p1; [eva:alarm] tests/value/arith_pointer.c:56: Warning: diff --git a/tests/value/oracle/array_ptr.res.oracle b/tests/value/oracle/array_ptr.res.oracle index 2d14be30289..8599de4e4af 100644 --- a/tests/value/oracle/array_ptr.res.oracle +++ b/tests/value/oracle/array_ptr.res.oracle @@ -7,7 +7,7 @@ l[0] ∈ {1} [1..19] ∈ {0} [eva:alarm] tests/value/array_ptr.i:14: Warning: - pointer downcast. assert (unsigned int)&l ≤ 2147483647; + pointer downcast. assert (unsigned int)(&l) ≤ 2147483647; [eva] computing for function f <- main. Called from tests/value/array_ptr.i:15. [eva] Recording results for f diff --git a/tests/value/oracle/assigns.res.oracle b/tests/value/oracle/assigns.res.oracle index 40501b7b144..4cfd1aeca7a 100644 --- a/tests/value/oracle/assigns.res.oracle +++ b/tests/value/oracle/assigns.res.oracle @@ -45,7 +45,7 @@ Called from tests/value/assigns.i:49. [eva] Done for function f [eva:alarm] tests/value/assigns.i:51: Warning: - pointer downcast. assert (unsigned int)&T ≤ 2147483647; + pointer downcast. assert (unsigned int)(&T) ≤ 2147483647; [eva:alarm] tests/value/assigns.i:51: Warning: signed overflow. assert -2147483648 ≤ 2 * (int)(&T); [eva:alarm] tests/value/assigns.i:51: Warning: @@ -55,7 +55,7 @@ [eva] using specification for function g [eva] Done for function g [eva:alarm] tests/value/assigns.i:52: Warning: - pointer downcast. assert (unsigned int)&t3 ≤ 2147483647; + pointer downcast. assert (unsigned int)(&t3) ≤ 2147483647; [eva:alarm] tests/value/assigns.i:52: Warning: signed overflow. assert -2147483648 ≤ 2 * (int)(&t3); [eva:alarm] tests/value/assigns.i:52: Warning: @@ -935,11 +935,11 @@ void main1(void) i ++; } } - /*@ assert Eva: pointer_downcast: (unsigned int)&T ≤ 2147483647; */ + /*@ assert Eva: pointer_downcast: (unsigned int)(&T) ≤ 2147483647; */ /*@ assert Eva: signed_overflow: -2147483648 ≤ 2 * (int)(&T); */ /*@ assert Eva: signed_overflow: 2 * (int)(&T) ≤ 2147483647; */ g(2 * (int)(& T)); - /*@ assert Eva: pointer_downcast: (unsigned int)&t3 ≤ 2147483647; */ + /*@ assert Eva: pointer_downcast: (unsigned int)(&t3) ≤ 2147483647; */ /*@ assert Eva: signed_overflow: -2147483648 ≤ 2 * (int)(&t3); */ /*@ assert Eva: signed_overflow: 2 * (int)(&t3) ≤ 2147483647; */ h((int *)(2 * (int)(& t3))); diff --git a/tests/value/oracle/bitfield.res.oracle b/tests/value/oracle/bitfield.res.oracle index 54cf0bfdba6..0ae5f039460 100644 --- a/tests/value/oracle/bitfield.res.oracle +++ b/tests/value/oracle/bitfield.res.oracle @@ -29,12 +29,12 @@ [eva] tests/value/bitfield.i:113: Frama_C_show_each: {1} [eva] tests/value/bitfield.i:117: Frama_C_show_each: {3} [eva:alarm] tests/value/bitfield.i:123: Warning: - pointer downcast. assert (unsigned int)&v ≤ 2147483647; + pointer downcast. assert (unsigned int)(&v) ≤ 2147483647; [eva] tests/value/bitfield.i:123: Assigning imprecise value to v.c. The imprecision originates from Arithmetic {tests/value/bitfield.i:123} [eva:alarm] tests/value/bitfield.i:124: Warning: - pointer downcast. assert (unsigned int)&v + 1 ≤ 2147483647; + pointer downcast. assert (unsigned int)(&v + 1) ≤ 2147483647; [eva:alarm] tests/value/bitfield.i:125: Warning: signed overflow. assert -2147483648 ≤ (int)v.d + 1; [eva:alarm] tests/value/bitfield.i:125: Warning: @@ -82,7 +82,7 @@ [eva:alarm] tests/value/bitfield.i:129: Warning: signed overflow. assert foo + foo ≤ 2147483647; [eva:alarm] tests/value/bitfield.i:130: Warning: - pointer downcast. assert (unsigned int)&v + 1 ≤ 2147483647; + pointer downcast. assert (unsigned int)(&v + 1) ≤ 2147483647; [eva] tests/value/bitfield.i:130: Assigning imprecise value to h.c. The imprecision originates from Arithmetic {tests/value/bitfield.i:130} @@ -557,9 +557,9 @@ void main_old(void) else Frama_C_show_each(3); VV = (unsigned int)h.a; h.a = (unsigned int __attribute__((__FRAMA_C_BITFIELD_SIZE__(2))))VV; - /*@ assert Eva: pointer_downcast: (unsigned int)&v ≤ 2147483647; */ + /*@ assert Eva: pointer_downcast: (unsigned int)(&v) ≤ 2147483647; */ v.c = (int __attribute__((__FRAMA_C_BITFIELD_SIZE__(22))))((int)(& v)); - /*@ assert Eva: pointer_downcast: (unsigned int)&v + 1 ≤ 2147483647; */ + /*@ assert Eva: pointer_downcast: (unsigned int)(&v + 1) ≤ 2147483647; */ v.d = (int __attribute__((__FRAMA_C_BITFIELD_SIZE__(32))))((int)(& v + 1)); /*@ assert Eva: signed_overflow: -2147483648 ≤ (int)v.d + 1; */ /*@ assert Eva: signed_overflow: (int)v.d + 1 ≤ 2147483647; */ @@ -570,7 +570,7 @@ void main_old(void) /*@ assert Eva: signed_overflow: -2147483648 ≤ foo + foo; */ /*@ assert Eva: signed_overflow: foo + foo ≤ 2147483647; */ h.b = (int __attribute__((__FRAMA_C_BITFIELD_SIZE__(4))))(((foo + foo) + (int)h.a) + (int)h.b); - /*@ assert Eva: pointer_downcast: (unsigned int)&v + 1 ≤ 2147483647; */ + /*@ assert Eva: pointer_downcast: (unsigned int)(&v + 1) ≤ 2147483647; */ h.c = (int __attribute__((__FRAMA_C_BITFIELD_SIZE__(22))))((int)(& v + 1)); k8.b = (int __attribute__((__FRAMA_C_BITFIELD_SIZE__(4))))8; tmp = return_8(); diff --git a/tests/value/oracle/bitwise_pointer.res.oracle b/tests/value/oracle/bitwise_pointer.res.oracle index a0538f60c8e..878fa04174a 100644 --- a/tests/value/oracle/bitwise_pointer.res.oracle +++ b/tests/value/oracle/bitwise_pointer.res.oracle @@ -30,14 +30,14 @@ p1 ∈ {0} x1 ∈ {0} [eva:alarm] tests/value/bitwise_pointer.i:18: Warning: - pointer downcast. assert (unsigned int)&t[7] ≤ 2147483647; + pointer downcast. assert (unsigned int)(&t[7]) ≤ 2147483647; [eva] tests/value/bitwise_pointer.i:18: Assigning imprecise value to p. The imprecision originates from Arithmetic {tests/value/bitwise_pointer.i:18} [eva:alarm] tests/value/bitwise_pointer.i:19: Warning: out of bounds write. assert \valid(p); [eva:alarm] tests/value/bitwise_pointer.i:22: Warning: - pointer downcast. assert (unsigned int)&t1[mask] ≤ 2147483647; + pointer downcast. assert (unsigned int)(&t1[mask]) ≤ 2147483647; [eva] tests/value/bitwise_pointer.i:22: Assigning imprecise value to p1. The imprecision originates from Arithmetic {tests/value/bitwise_pointer.i:22} diff --git a/tests/value/oracle/cmp_ptr.0.res.oracle b/tests/value/oracle/cmp_ptr.0.res.oracle index 08d4b95eafc..47a1035cc56 100644 --- a/tests/value/oracle/cmp_ptr.0.res.oracle +++ b/tests/value/oracle/cmp_ptr.0.res.oracle @@ -46,7 +46,7 @@ [eva:alarm] tests/value/cmp_ptr.i:22: Warning: pointer comparison. assert \pointer_comparable((void *)0, (void *)(&y + 2)); [eva:alarm] tests/value/cmp_ptr.i:23: Warning: - pointer downcast. assert (unsigned int)&y + 2 ≤ 2147483647; + pointer downcast. assert (unsigned int)(&y + 2) ≤ 2147483647; [eva:pointer-comparison] tests/value/cmp_ptr.i:24: invalid pointer comparison: invalid pointer(s) [eva:alarm] tests/value/cmp_ptr.i:24: Warning: diff --git a/tests/value/oracle/cmp_ptr.1.res.oracle b/tests/value/oracle/cmp_ptr.1.res.oracle index ea6793941d4..182c5433339 100644 --- a/tests/value/oracle/cmp_ptr.1.res.oracle +++ b/tests/value/oracle/cmp_ptr.1.res.oracle @@ -60,7 +60,7 @@ [eva:alarm] tests/value/cmp_ptr.i:22: Warning: pointer comparison. assert \pointer_comparable((void *)0, (void *)(&y + 2)); [eva:alarm] tests/value/cmp_ptr.i:23: Warning: - pointer downcast. assert (unsigned int)&y + 2 ≤ 2147483647; + pointer downcast. assert (unsigned int)(&y + 2) ≤ 2147483647; [eva:pointer-comparison] tests/value/cmp_ptr.i:24: invalid pointer comparison: invalid pointer(s) [eva:alarm] tests/value/cmp_ptr.i:24: Warning: diff --git a/tests/value/oracle/context_free.res.oracle b/tests/value/oracle/context_free.res.oracle index f8869049442..f1220992e0b 100644 --- a/tests/value/oracle/context_free.res.oracle +++ b/tests/value/oracle/context_free.res.oracle @@ -102,7 +102,7 @@ [eva:alarm] tests/value/context_free.i:61: Warning: out of bounds write. assert \valid(pvoid); [eva:alarm] tests/value/context_free.i:61: Warning: - pointer downcast. assert (unsigned int)&pvoid ≤ 127; + pointer downcast. assert (unsigned int)(&pvoid) ≤ 127; [eva:alarm] tests/value/context_free.i:62: Warning: pointer to function with incompatible type. assert \valid_function(g); [eva] Recording results for f diff --git a/tests/value/oracle/conversion.res.oracle b/tests/value/oracle/conversion.res.oracle index 26374aad66f..954fdab07b4 100644 --- a/tests/value/oracle/conversion.res.oracle +++ b/tests/value/oracle/conversion.res.oracle @@ -58,7 +58,7 @@ l ∈ UNINITIALIZED ==END OF DUMP== [eva:alarm] tests/value/conversion.i:38: Warning: - pointer downcast. assert (unsigned int)&x ≤ 2147483647; + pointer downcast. assert (unsigned int)(&x) ≤ 2147483647; [eva] tests/value/conversion.i:40: Frama_C_dump_each: # Cvalue domain: @@ -164,7 +164,7 @@ l ∈ UNINITIALIZED ==END OF DUMP== [eva:alarm] tests/value/conversion.i:38: Warning: - pointer downcast. assert (unsigned int)&x ≤ 2147483647; + pointer downcast. assert (unsigned int)(&x) ≤ 2147483647; [eva:alarm] tests/value/conversion.i:39: Warning: non-finite float value. assert \is_finite(*((float *)(&x))); [eva] tests/value/conversion.i:39: diff --git a/tests/value/oracle/deps_addr.res.oracle b/tests/value/oracle/deps_addr.res.oracle index 0c2afa4364c..59f4ac5f0f9 100644 --- a/tests/value/oracle/deps_addr.res.oracle +++ b/tests/value/oracle/deps_addr.res.oracle @@ -7,7 +7,7 @@ a ∈ {0} tt[0..4][0..4] ∈ {0} [eva:alarm] tests/value/deps_addr.i:6: Warning: - pointer downcast. assert (unsigned int)&a ≤ 2147483647; + pointer downcast. assert (unsigned int)(&a) ≤ 2147483647; [eva:alarm] tests/value/deps_addr.i:6: Warning: out of bounds read. assert \valid_read(t + (int)(&a)); [eva] Recording results for main diff --git a/tests/value/oracle/deps_mixed.res.oracle b/tests/value/oracle/deps_mixed.res.oracle index e7af15348e5..6631dfe4e46 100644 --- a/tests/value/oracle/deps_mixed.res.oracle +++ b/tests/value/oracle/deps_mixed.res.oracle @@ -31,7 +31,7 @@ [eva:alarm] tests/value/deps_mixed.i:24: Warning: pointer downcast. assert (unsigned int)q ≤ 2147483647; [eva:alarm] tests/value/deps_mixed.i:24: Warning: - pointer downcast. assert (unsigned int)p + (int)q ≤ 2147483647; + pointer downcast. assert (unsigned int)(p + (int)q) ≤ 2147483647; [eva] tests/value/deps_mixed.i:24: Assigning imprecise value to __retres. The imprecision originates from Arithmetic {tests/value/deps_mixed.i:24} diff --git a/tests/value/oracle/div.0.res.oracle b/tests/value/oracle/div.0.res.oracle index 4f8b786e02d..2f95483430e 100644 --- a/tests/value/oracle/div.0.res.oracle +++ b/tests/value/oracle/div.0.res.oracle @@ -36,7 +36,7 @@ [eva:alarm] tests/value/div.i:32: Warning: division by zero. assert Z2 ≢ 0; [eva:alarm] tests/value/div.i:33: Warning: division by zero. assert Z2 ≢ 0; [eva:alarm] tests/value/div.i:33: Warning: - pointer downcast. assert (unsigned int)&Z2 ≤ 2147483647; + pointer downcast. assert (unsigned int)(&Z2) ≤ 2147483647; [eva:alarm] tests/value/div.i:33: Warning: signed overflow. assert -2147483648 ≤ (int)(&Z2) / Z2; [eva:alarm] tests/value/div.i:33: Warning: @@ -45,7 +45,7 @@ Assigning imprecise value to b. The imprecision originates from Arithmetic {tests/value/div.i:33} [eva:alarm] tests/value/div.i:34: Warning: - pointer downcast. assert (unsigned int)&X + 2 ≤ 2147483647; + pointer downcast. assert (unsigned int)(&X + 2) ≤ 2147483647; [eva:alarm] tests/value/div.i:34: Warning: division by zero. assert (int)(&X + 2) ≢ 0; [eva:alarm] tests/value/div.i:34: Warning: @@ -56,7 +56,7 @@ Assigning imprecise value to d2. The imprecision originates from Arithmetic {tests/value/div.i:34} [eva:alarm] tests/value/div.i:35: Warning: - pointer downcast. assert (unsigned int)&X + 1 ≤ 2147483647; + pointer downcast. assert (unsigned int)(&X + 1) ≤ 2147483647; [eva:alarm] tests/value/div.i:35: Warning: signed overflow. assert -2147483648 ≤ 100 / (int)(&X + 1); [eva:alarm] tests/value/div.i:35: Warning: @@ -65,7 +65,7 @@ Assigning imprecise value to d1. The imprecision originates from Arithmetic {tests/value/div.i:35} [eva:alarm] tests/value/div.i:36: Warning: - pointer downcast. assert (unsigned int)&X ≤ 2147483647; + pointer downcast. assert (unsigned int)(&X) ≤ 2147483647; [eva:alarm] tests/value/div.i:36: Warning: signed overflow. assert -2147483648 ≤ 100 / (int)(&X); [eva:alarm] tests/value/div.i:36: Warning: @@ -74,7 +74,7 @@ Assigning imprecise value to d0. The imprecision originates from Arithmetic {tests/value/div.i:36} [eva:alarm] tests/value/div.i:37: Warning: - pointer downcast. assert (unsigned int)&X ≤ 2147483647; + pointer downcast. assert (unsigned int)(&X) ≤ 2147483647; [eva:alarm] tests/value/div.i:37: Warning: signed overflow. assert -2147483648 ≤ -((int)(&X)); [eva:alarm] tests/value/div.i:37: Warning: diff --git a/tests/value/oracle/div.1.res.oracle b/tests/value/oracle/div.1.res.oracle index d052fa034e4..bb2cbef1753 100644 --- a/tests/value/oracle/div.1.res.oracle +++ b/tests/value/oracle/div.1.res.oracle @@ -58,7 +58,7 @@ assertion 'rte,signed_overflow' got status unknown. [eva:alarm] tests/value/div.i:33: Warning: division by zero. assert Z2 ≢ 0; [eva:alarm] tests/value/div.i:33: Warning: - pointer downcast. assert (unsigned int)&Z2 ≤ 2147483647; + pointer downcast. assert (unsigned int)(&Z2) ≤ 2147483647; [eva:alarm] tests/value/div.i:33: Warning: signed overflow. assert -2147483648 ≤ (int)(&Z2) / Z2; [eva:alarm] tests/value/div.i:33: Warning: @@ -71,7 +71,7 @@ [eva:alarm] tests/value/div.i:34: Warning: assertion 'rte,division_by_zero' got status unknown. [eva:alarm] tests/value/div.i:34: Warning: - pointer downcast. assert (unsigned int)&X + 2 ≤ 2147483647; + pointer downcast. assert (unsigned int)(&X + 2) ≤ 2147483647; [eva:alarm] tests/value/div.i:34: Warning: division by zero. assert (int)(&X + 2) ≢ 0; [eva:alarm] tests/value/div.i:34: Warning: @@ -85,7 +85,7 @@ assertion 'rte,pointer_downcast' got status unknown. [eva] tests/value/div.i:35: assertion 'rte,division_by_zero' got status valid. [eva:alarm] tests/value/div.i:35: Warning: - pointer downcast. assert (unsigned int)&X + 1 ≤ 2147483647; + pointer downcast. assert (unsigned int)(&X + 1) ≤ 2147483647; [eva:alarm] tests/value/div.i:35: Warning: signed overflow. assert -2147483648 ≤ 100 / (int)(&X + 1); [eva:alarm] tests/value/div.i:35: Warning: @@ -97,7 +97,7 @@ assertion 'rte,pointer_downcast' got status unknown. [eva] tests/value/div.i:36: assertion 'rte,division_by_zero' got status valid. [eva:alarm] tests/value/div.i:36: Warning: - pointer downcast. assert (unsigned int)&X ≤ 2147483647; + pointer downcast. assert (unsigned int)(&X) ≤ 2147483647; [eva:alarm] tests/value/div.i:36: Warning: signed overflow. assert -2147483648 ≤ 100 / (int)(&X); [eva:alarm] tests/value/div.i:36: Warning: @@ -110,7 +110,7 @@ [eva:alarm] tests/value/div.i:37: Warning: assertion 'rte,signed_overflow' got status unknown. [eva:alarm] tests/value/div.i:37: Warning: - pointer downcast. assert (unsigned int)&X ≤ 2147483647; + pointer downcast. assert (unsigned int)(&X) ≤ 2147483647; [eva:alarm] tests/value/div.i:37: Warning: signed overflow. assert -2147483648 ≤ -((int)(&X)); [eva:alarm] tests/value/div.i:37: Warning: diff --git a/tests/value/oracle/eval_separated.res.oracle b/tests/value/oracle/eval_separated.res.oracle index 60f0db91f1e..ba49fd5aff7 100644 --- a/tests/value/oracle/eval_separated.res.oracle +++ b/tests/value/oracle/eval_separated.res.oracle @@ -12,7 +12,7 @@ [eva] tests/value/eval_separated.c:8: assertion got status valid. [eva] tests/value/eval_separated.c:9: assertion got status valid. [eva:alarm] tests/value/eval_separated.c:11: Warning: - pointer downcast. assert (unsigned int)&q ≤ 2147483647; + pointer downcast. assert (unsigned int)(&q) ≤ 2147483647; [eva:alarm] tests/value/eval_separated.c:11: Warning: signed overflow. assert -2147483648 ≤ (int)(&q) + (int)(&q); [eva:alarm] tests/value/eval_separated.c:11: Warning: @@ -21,7 +21,7 @@ Assigning imprecise value to q. The imprecision originates from Arithmetic {tests/value/eval_separated.c:11} [eva:alarm] tests/value/eval_separated.c:12: Warning: - pointer downcast. assert (unsigned int)&r ≤ 2147483647; + pointer downcast. assert (unsigned int)(&r) ≤ 2147483647; [eva:alarm] tests/value/eval_separated.c:12: Warning: signed overflow. assert -2147483648 ≤ (int)(&r) + (int)(&r); [eva:alarm] tests/value/eval_separated.c:12: Warning: diff --git a/tests/value/oracle/from_call.0.res.oracle b/tests/value/oracle/from_call.0.res.oracle index f06f8231e21..90af155562b 100644 --- a/tests/value/oracle/from_call.0.res.oracle +++ b/tests/value/oracle/from_call.0.res.oracle @@ -2,9 +2,9 @@ [eva] Analyzing a complete application starting at main [eva] Computing initial state [eva:alarm] tests/value/from_call.i:70: Warning: - pointer downcast. assert (unsigned int)&AA ≤ 2147483647; + pointer downcast. assert (unsigned int)(&AA) ≤ 2147483647; [eva:alarm] tests/value/from_call.i:71: Warning: - pointer downcast. assert (unsigned int)&AA ≤ 2147483647; + pointer downcast. assert (unsigned int)(&AA) ≤ 2147483647; [eva] Initial state computed [eva:initial-state] Values of globals at initialization a ∈ {0} diff --git a/tests/value/oracle/from_call.1.res.oracle b/tests/value/oracle/from_call.1.res.oracle index a11fbdf9fa2..eb4493ddfd3 100644 --- a/tests/value/oracle/from_call.1.res.oracle +++ b/tests/value/oracle/from_call.1.res.oracle @@ -2,9 +2,9 @@ [eva] Analyzing a complete application starting at main [eva] Computing initial state [eva:alarm] tests/value/from_call.i:70: Warning: - pointer downcast. assert (unsigned int)&AA ≤ 2147483647; + pointer downcast. assert (unsigned int)(&AA) ≤ 2147483647; [eva:alarm] tests/value/from_call.i:71: Warning: - pointer downcast. assert (unsigned int)&AA ≤ 2147483647; + pointer downcast. assert (unsigned int)(&AA) ≤ 2147483647; [eva] Initial state computed [eva:initial-state] Values of globals at initialization a ∈ {0} diff --git a/tests/value/oracle/from_ptr.0.res.oracle b/tests/value/oracle/from_ptr.0.res.oracle index f58c5770d44..7261a1cb811 100644 --- a/tests/value/oracle/from_ptr.0.res.oracle +++ b/tests/value/oracle/from_ptr.0.res.oracle @@ -16,9 +16,9 @@ p[0..9][0..9][0..9] ∈ {0} q ∈ {0} [eva:alarm] tests/value/from_ptr.i:12: Warning: - pointer downcast. assert (unsigned int)&p[11] ≤ 2147483647; + pointer downcast. assert (unsigned int)(&p[11]) ≤ 2147483647; [eva:alarm] tests/value/from_ptr.i:13: Warning: - pointer downcast. assert (unsigned int)&p[10] ≤ 2147483647; + pointer downcast. assert (unsigned int)(&p[10]) ≤ 2147483647; [eva:alarm] tests/value/from_ptr.i:17: Warning: out of bounds write. assert \valid((int *)i); [kernel] tests/value/from_ptr.i:17: Warning: diff --git a/tests/value/oracle/from_ptr.1.res.oracle b/tests/value/oracle/from_ptr.1.res.oracle index d1824131817..1cde862a4b6 100644 --- a/tests/value/oracle/from_ptr.1.res.oracle +++ b/tests/value/oracle/from_ptr.1.res.oracle @@ -16,9 +16,9 @@ p[0..9][0..9][0..9] ∈ {0} q ∈ {0} [eva:alarm] tests/value/from_ptr.i:24: Warning: - pointer downcast. assert (unsigned int)&p[1] ≤ 2147483647; + pointer downcast. assert (unsigned int)(&p[1]) ≤ 2147483647; [eva:alarm] tests/value/from_ptr.i:25: Warning: - pointer downcast. assert (unsigned int)(int (*)[10][10])p ≤ 2147483647; + pointer downcast. assert (unsigned int)((int (*)[10][10])p) ≤ 2147483647; [eva] Recording results for main1 [eva] done for function main1 [eva] ====== VALUES COMPUTED ====== diff --git a/tests/value/oracle/fun_ptr.1.res.oracle b/tests/value/oracle/fun_ptr.1.res.oracle index f99360712b5..3e7b008426e 100644 --- a/tests/value/oracle/fun_ptr.1.res.oracle +++ b/tests/value/oracle/fun_ptr.1.res.oracle @@ -9,9 +9,9 @@ [eva] Analyzing a complete application starting at main [eva] Computing initial state [eva:alarm] tests/value/fun_ptr.i:21: Warning: - pointer downcast. assert (unsigned __int64)&f ≤ 9223372036854775807; + pointer downcast. assert (unsigned __int64)(&f) ≤ 9223372036854775807; [eva:alarm] tests/value/fun_ptr.i:21: Warning: - pointer downcast. assert (unsigned __int64)&g ≤ 9223372036854775807; + pointer downcast. assert (unsigned __int64)(&g) ≤ 9223372036854775807; [eva] Initial state computed [eva:initial-state] Values of globals at initialization t[0] ∈ {{ (__int64)&f }} diff --git a/tests/value/oracle/imprecise_invalid_write.res.oracle b/tests/value/oracle/imprecise_invalid_write.res.oracle index 611d2093add..338f79ddc5e 100644 --- a/tests/value/oracle/imprecise_invalid_write.res.oracle +++ b/tests/value/oracle/imprecise_invalid_write.res.oracle @@ -22,7 +22,7 @@ [eva] computing for function main2 <- main. Called from tests/value/imprecise_invalid_write.i:25. [eva:alarm] tests/value/imprecise_invalid_write.i:9: Warning: - pointer downcast. assert (unsigned int)&main1 ≤ 2147483647; + pointer downcast. assert (unsigned int)(&main1) ≤ 2147483647; [eva] tests/value/imprecise_invalid_write.i:9: Assigning imprecise value to p. The imprecision originates from Arithmetic diff --git a/tests/value/oracle/initialized.res.oracle b/tests/value/oracle/initialized.res.oracle index 8ca94ab19cf..b57ddb23b52 100644 --- a/tests/value/oracle/initialized.res.oracle +++ b/tests/value/oracle/initialized.res.oracle @@ -67,7 +67,7 @@ [eva] computing for function g2 <- main. Called from tests/value/initialized.c:194. [eva:alarm] tests/value/initialized.c:50: Warning: - pointer downcast. assert (unsigned int)&b4 ≤ 2147483647; + pointer downcast. assert (unsigned int)(&b4) ≤ 2147483647; [eva:alarm] tests/value/initialized.c:50: Warning: signed overflow. assert -2147483648 ≤ (int)(&b4) + (int)(&b4); [eva:alarm] tests/value/initialized.c:50: Warning: diff --git a/tests/value/oracle/join_misaligned.res.oracle b/tests/value/oracle/join_misaligned.res.oracle index 2194180b285..111aa1c6f07 100644 --- a/tests/value/oracle/join_misaligned.res.oracle +++ b/tests/value/oracle/join_misaligned.res.oracle @@ -15,9 +15,9 @@ a ∈ {0} va ∈ [--..--] [eva:alarm] tests/value/join_misaligned.i:23: Warning: - pointer downcast. assert (unsigned int)&t ≤ 2147483647; + pointer downcast. assert (unsigned int)(&t) ≤ 2147483647; [eva:alarm] tests/value/join_misaligned.i:37: Warning: - pointer downcast. assert (unsigned int)&u ≤ 2147483647; + pointer downcast. assert (unsigned int)(&u) ≤ 2147483647; [eva] Recording results for main [eva] done for function main [eva:garbled-mix] Warning: diff --git a/tests/value/oracle/label.res.oracle b/tests/value/oracle/label.res.oracle index 3c3c61be0c2..a87f0773b6e 100644 --- a/tests/value/oracle/label.res.oracle +++ b/tests/value/oracle/label.res.oracle @@ -11,7 +11,7 @@ p ∈ {0} q ∈ {0} [eva:alarm] tests/value/label.i:14: Warning: - pointer downcast. assert (unsigned int)&d + 1 ≤ 2147483647; + pointer downcast. assert (unsigned int)(&d + 1) ≤ 2147483647; [eva] tests/value/label.i:18: Assigning imprecise value to *((char *)(& p) + i) (pointing to p with offsets {0}). diff --git a/tests/value/oracle/leaf2.res.oracle b/tests/value/oracle/leaf2.res.oracle index 41082946d0a..96ab8ffd9b4 100644 --- a/tests/value/oracle/leaf2.res.oracle +++ b/tests/value/oracle/leaf2.res.oracle @@ -7,7 +7,7 @@ H ∈ {0} I ∈ {0} [eva:alarm] tests/value/leaf2.i:6: Warning: - pointer downcast. assert (unsigned int)&I ≤ 2147483647; + pointer downcast. assert (unsigned int)(&I) ≤ 2147483647; [eva] computing for function f <- main. Called from tests/value/leaf2.i:6. [kernel:annot:missing-spec] tests/value/leaf2.i:6: Warning: diff --git a/tests/value/oracle/mini_pointrer.res.oracle b/tests/value/oracle/mini_pointrer.res.oracle index 65092ae89c4..0cc72335a3a 100644 --- a/tests/value/oracle/mini_pointrer.res.oracle +++ b/tests/value/oracle/mini_pointrer.res.oracle @@ -12,7 +12,7 @@ [eva:alarm] tests/value/mini_pointrer.i:6: Warning: accessing out of bounds index. assert c1 < 2; [eva:alarm] tests/value/mini_pointrer.i:6: Warning: - pointer downcast. assert (unsigned int)&T[c1] ≤ 2147483647; + pointer downcast. assert (unsigned int)(&T[c1]) ≤ 2147483647; [eva:alarm] tests/value/mini_pointrer.i:8: Warning: out of bounds read. assert \valid_read(ppp); [eva:alarm] tests/value/mini_pointrer.i:8: Warning: diff --git a/tests/value/oracle/nonlin.res.oracle b/tests/value/oracle/nonlin.res.oracle index b5be0d8bcaa..433ce49eaa0 100644 --- a/tests/value/oracle/nonlin.res.oracle +++ b/tests/value/oracle/nonlin.res.oracle @@ -64,7 +64,7 @@ [eva:alarm] tests/value/nonlin.c:21: Warning: out of bounds read. assert \valid_read((p + i) - i); [eva:alarm] tests/value/nonlin.c:23: Warning: - pointer downcast. assert (unsigned int)&x ≤ 2147483647; + pointer downcast. assert (unsigned int)(&x) ≤ 2147483647; [eva:alarm] tests/value/nonlin.c:24: Warning: out of bounds read. assert \valid_read((p + i) - i); [eva] Recording results for subdivide_pointer diff --git a/tests/value/oracle/not_ct_array_arg.res.oracle b/tests/value/oracle/not_ct_array_arg.res.oracle index 776fa403f15..8be78fd49c0 100644 --- a/tests/value/oracle/not_ct_array_arg.res.oracle +++ b/tests/value/oracle/not_ct_array_arg.res.oracle @@ -25,7 +25,7 @@ [eva:alarm] tests/value/not_ct_array_arg.i:12: Warning: out of bounds write. assert \valid(&(*(tb + 9))[100]); [eva:alarm] tests/value/not_ct_array_arg.i:12: Warning: - pointer downcast. assert (unsigned int)&tb ≤ 2147483647; + pointer downcast. assert (unsigned int)(&tb) ≤ 2147483647; [eva] tests/value/not_ct_array_arg.i:13: Frama_C_dump_each: # Cvalue domain: diff --git a/tests/value/oracle/offset_top.res.oracle b/tests/value/oracle/offset_top.res.oracle index 6c6287b4bff..8dbc430d5ee 100644 --- a/tests/value/oracle/offset_top.res.oracle +++ b/tests/value/oracle/offset_top.res.oracle @@ -7,7 +7,7 @@ T ∈ {0} TAB[0..9] ∈ {0} [eva:alarm] tests/value/offset_top.i:10: Warning: - pointer downcast. assert (unsigned int)&TAB[*T] ≤ 2147483647; + pointer downcast. assert (unsigned int)(&TAB[*T]) ≤ 2147483647; [eva] Recording results for main [eva] done for function main [eva] ====== VALUES COMPUTED ====== diff --git a/tests/value/oracle/offsetmap.0.res.oracle b/tests/value/oracle/offsetmap.0.res.oracle index 2a076ba31dc..572459f644a 100644 --- a/tests/value/oracle/offsetmap.0.res.oracle +++ b/tests/value/oracle/offsetmap.0.res.oracle @@ -28,7 +28,7 @@ [eva] tests/value/offsetmap.i:19: starting to merge loop iterations [eva] tests/value/offsetmap.i:29: starting to merge loop iterations [eva:alarm] tests/value/offsetmap.i:51: Warning: - pointer downcast. assert (unsigned int)&x2 ≤ 2147483647; + pointer downcast. assert (unsigned int)(&x2) ≤ 2147483647; [eva] Recording results for f [eva] Done for function f [eva] computing for function g <- main. diff --git a/tests/value/oracle/offsetmap.1.res.oracle b/tests/value/oracle/offsetmap.1.res.oracle index 115819f9674..d4ac4533187 100644 --- a/tests/value/oracle/offsetmap.1.res.oracle +++ b/tests/value/oracle/offsetmap.1.res.oracle @@ -28,7 +28,7 @@ [eva] tests/value/offsetmap.i:19: starting to merge loop iterations [eva] tests/value/offsetmap.i:29: starting to merge loop iterations [eva:alarm] tests/value/offsetmap.i:51: Warning: - pointer downcast. assert (unsigned int)&x2 ≤ 2147483647; + pointer downcast. assert (unsigned int)(&x2) ≤ 2147483647; [eva] Recording results for f [eva] Done for function f [eva] computing for function g <- main. diff --git a/tests/value/oracle/origin.0.res.oracle b/tests/value/oracle/origin.0.res.oracle index cd433bd1e2f..2bdd5becc39 100644 --- a/tests/value/oracle/origin.0.res.oracle +++ b/tests/value/oracle/origin.0.res.oracle @@ -55,7 +55,7 @@ [eva] computing for function origin_arithmetic_1 <- main. Called from tests/value/origin.i:94. [eva:alarm] tests/value/origin.i:14: Warning: - pointer downcast. assert (unsigned int)(int *)ta1 ≤ 2147483647; + pointer downcast. assert (unsigned int)((int *)ta1) ≤ 2147483647; [eva:alarm] tests/value/origin.i:14: Warning: signed overflow. assert -2147483648 ≤ -((int)((int *)ta1)); [eva:alarm] tests/value/origin.i:14: Warning: @@ -70,7 +70,7 @@ [eva] computing for function origin_arithmetic_2 <- main. Called from tests/value/origin.i:95. [eva:alarm] tests/value/origin.i:19: Warning: - pointer downcast. assert (unsigned int)(int *)ta2 ≤ 2147483647; + pointer downcast. assert (unsigned int)((int *)ta2) ≤ 2147483647; [eva:alarm] tests/value/origin.i:19: Warning: signed overflow. assert -2147483648 ≤ -((int)((int *)ta2)); [eva:alarm] tests/value/origin.i:19: Warning: @@ -82,7 +82,7 @@ Assigning imprecise value to qa2. The imprecision originates from Arithmetic {tests/value/origin.i:19} [eva:alarm] tests/value/origin.i:20: Warning: - pointer downcast. assert (unsigned int)(int *)tta2 ≤ 2147483647; + pointer downcast. assert (unsigned int)((int *)tta2) ≤ 2147483647; [eva:alarm] tests/value/origin.i:20: Warning: signed overflow. assert -2147483648 ≤ -((int)((int *)tta2)); [eva:alarm] tests/value/origin.i:20: Warning: @@ -93,13 +93,13 @@ [eva:alarm] tests/value/origin.i:21: Warning: out of bounds write. assert \valid(qa2); [eva:alarm] tests/value/origin.i:21: Warning: - pointer downcast. assert (unsigned int)&aa2 ≤ 2147483647; + pointer downcast. assert (unsigned int)(&aa2) ≤ 2147483647; [eva] Recording results for origin_arithmetic_2 [eva] Done for function origin_arithmetic_2 [eva] computing for function origin_arithmetic_3 <- main. Called from tests/value/origin.i:96. [eva:alarm] tests/value/origin.i:25: Warning: - pointer downcast. assert (unsigned int)(int *)ta3 ≤ 2147483647; + pointer downcast. assert (unsigned int)((int *)ta3) ≤ 2147483647; [eva:alarm] tests/value/origin.i:25: Warning: signed overflow. assert -2147483648 ≤ -((int)((int *)ta3)); [eva:alarm] tests/value/origin.i:25: Warning: @@ -159,7 +159,7 @@ [eva:alarm] tests/value/origin.i:56: Warning: out of bounds write. assert \valid(qm2); [eva:alarm] tests/value/origin.i:56: Warning: - pointer downcast. assert (unsigned int)&a ≤ 2147483647; + pointer downcast. assert (unsigned int)(&a) ≤ 2147483647; [eva] Recording results for origin_misalign_2 [eva] Done for function origin_misalign_2 [eva] computing for function origin_uninitialized_1 <- main. @@ -179,11 +179,11 @@ [eva] computing for function local_escape_1 <- main. Called from tests/value/origin.i:108. [eva:alarm] tests/value/origin.i:83: Warning: - pointer downcast. assert (unsigned int)&arg ≤ 2147483647; + pointer downcast. assert (unsigned int)(&arg) ≤ 2147483647; [eva:alarm] tests/value/origin.i:84: Warning: - pointer downcast. assert (unsigned int)&local1 ≤ 2147483647; + pointer downcast. assert (unsigned int)(&local1) ≤ 2147483647; [eva:alarm] tests/value/origin.i:85: Warning: - pointer downcast. assert (unsigned int)&arg ≤ 2147483647; + pointer downcast. assert (unsigned int)(&arg) ≤ 2147483647; [eva:alarm] tests/value/origin.i:85: Warning: signed overflow. assert -2147483648 ≤ -((int)(&arg)); [eva:alarm] tests/value/origin.i:85: Warning: @@ -192,9 +192,9 @@ Assigning imprecise value to esc3. The imprecision originates from Arithmetic {tests/value/origin.i:85} [eva:alarm] tests/value/origin.i:87: Warning: - pointer downcast. assert (unsigned int)&local1 ≤ 2147483647; + pointer downcast. assert (unsigned int)(&local1) ≤ 2147483647; [eva:alarm] tests/value/origin.i:88: Warning: - pointer downcast. assert (unsigned int)&esc1 ≤ 2147483647; + pointer downcast. assert (unsigned int)(&esc1) ≤ 2147483647; [eva] Recording results for local_escape_1 [eva] Done for function local_escape_1 [eva:locals-escaping] tests/value/origin.i:108: Warning: diff --git a/tests/value/oracle/origin.1.res.oracle b/tests/value/oracle/origin.1.res.oracle index 6e3283d9304..0b3195a5397 100644 --- a/tests/value/oracle/origin.1.res.oracle +++ b/tests/value/oracle/origin.1.res.oracle @@ -65,7 +65,7 @@ Assigning imprecise value to r.t[0]. The imprecision originates from Merge {tests/value/origin.i:129} [eva:alarm] tests/value/origin.i:130: Warning: - pointer downcast. assert (unsigned int)&x ≤ 2147483647; + pointer downcast. assert (unsigned int)(&x) ≤ 2147483647; [eva:alarm] tests/value/origin.i:130: Warning: signed overflow. assert -2147483648 ≤ -((int)(&x)); [eva:alarm] tests/value/origin.i:130: Warning: diff --git a/tests/value/oracle/period.res.oracle b/tests/value/oracle/period.res.oracle index 156c9148c10..2af9a46bd2a 100644 --- a/tests/value/oracle/period.res.oracle +++ b/tests/value/oracle/period.res.oracle @@ -79,21 +79,21 @@ Ht ∈ {1} ==END OF DUMP== [eva:alarm] tests/value/period.c:51: Warning: - pointer downcast. assert (unsigned int)&g ≤ 2147483647; + pointer downcast. assert (unsigned int)(&g) ≤ 2147483647; [eva] tests/value/period.c:51: Assigning imprecise value to p. The imprecision originates from Arithmetic {tests/value/period.c:51} [eva:alarm] tests/value/period.c:52: Warning: out of bounds write. assert \valid(p); [eva:alarm] tests/value/period.c:53: Warning: - pointer downcast. assert (unsigned int)&g ≤ 2147483647; + pointer downcast. assert (unsigned int)(&g) ≤ 2147483647; [eva] tests/value/period.c:53: Assigning imprecise value to p. The imprecision originates from Arithmetic {tests/value/period.c:53} [eva:alarm] tests/value/period.c:54: Warning: out of bounds read. assert \valid_read(p); [eva:alarm] tests/value/period.c:55: Warning: - pointer downcast. assert (unsigned int)&vg ≤ 2147483647; + pointer downcast. assert (unsigned int)(&vg) ≤ 2147483647; [eva] Recording results for main [eva] done for function main [scope:rm_asserts] removing 1 assertion(s) diff --git a/tests/value/oracle/pointer_comparison.0.res.oracle b/tests/value/oracle/pointer_comparison.0.res.oracle index fcd954b8df5..6ac5900dc2e 100644 --- a/tests/value/oracle/pointer_comparison.0.res.oracle +++ b/tests/value/oracle/pointer_comparison.0.res.oracle @@ -21,7 +21,7 @@ [eva:alarm] tests/value/pointer_comparison.c:16: Warning: pointer downcast. assert (unsigned int)p ≤ 2147483647; [eva:alarm] tests/value/pointer_comparison.c:16: Warning: - pointer downcast. assert (unsigned int)&y ≤ 2147483647; + pointer downcast. assert (unsigned int)(&y) ≤ 2147483647; [eva] tests/value/pointer_comparison.c:16: Frama_C_show_each_5: {{ &x + {16} }} [eva] tests/value/pointer_comparison.c:17: Frama_C_show_each_5e: {{ &x + {16} }} [eva:pointer-comparison] tests/value/pointer_comparison.c:18: @@ -61,7 +61,7 @@ assert Eva: pointer_downcast: (unsigned int)p ≤ 2147483647; tried with Eva. [ - ] Assertion 'Eva,pointer_downcast' (file tests/value/pointer_comparison.c, line 16) - assert Eva: pointer_downcast: (unsigned int)&y ≤ 2147483647; + assert Eva: pointer_downcast: (unsigned int)(&y) ≤ 2147483647; tried with Eva. -------------------------------------------------------------------------------- @@ -96,7 +96,7 @@ [eva:alarm] tests/value/pointer_comparison.c:16: Warning: pointer downcast. assert (unsigned int)p ≤ 2147483647; [eva:alarm] tests/value/pointer_comparison.c:16: Warning: - pointer downcast. assert (unsigned int)&y ≤ 2147483647; + pointer downcast. assert (unsigned int)(&y) ≤ 2147483647; [eva] tests/value/pointer_comparison.c:16: Frama_C_show_each_5: {{ &x + {16} }} [eva] tests/value/pointer_comparison.c:17: Frama_C_show_each_5e: {{ &x + {16} }} [eva:alarm] tests/value/pointer_comparison.c:18: Warning: @@ -152,7 +152,7 @@ assert Eva: pointer_downcast: (unsigned int)p ≤ 2147483647; tried with Eva. [ - ] Assertion 'Eva,pointer_downcast' (file tests/value/pointer_comparison.c, line 16) - assert Eva: pointer_downcast: (unsigned int)&y ≤ 2147483647; + assert Eva: pointer_downcast: (unsigned int)(&y) ≤ 2147483647; tried with Eva. [ - ] Assertion 'Eva,ptr_comparison' (file tests/value/pointer_comparison.c, line 18) assert @@ -192,7 +192,7 @@ [eva:alarm] tests/value/pointer_comparison.c:16: Warning: pointer downcast. assert (unsigned int)p ≤ 2147483647; [eva:alarm] tests/value/pointer_comparison.c:16: Warning: - pointer downcast. assert (unsigned int)&y ≤ 2147483647; + pointer downcast. assert (unsigned int)(&y) ≤ 2147483647; [eva:alarm] tests/value/pointer_comparison.c:16: Warning: pointer comparison. assert \pointer_comparable((void *)p, (void *)(&y)); [eva] tests/value/pointer_comparison.c:16: Frama_C_show_each_5: {{ &x + {16} }} @@ -250,7 +250,7 @@ assert Eva: pointer_downcast: (unsigned int)p ≤ 2147483647; tried with Eva. [ - ] Assertion 'Eva,pointer_downcast' (file tests/value/pointer_comparison.c, line 16) - assert Eva: pointer_downcast: (unsigned int)&y ≤ 2147483647; + assert Eva: pointer_downcast: (unsigned int)(&y) ≤ 2147483647; tried with Eva. [ - ] Assertion 'Eva,ptr_comparison' (file tests/value/pointer_comparison.c, line 16) assert diff --git a/tests/value/oracle/pointer_comparison.1.res.oracle b/tests/value/oracle/pointer_comparison.1.res.oracle index af00458ed51..cd63714dccc 100644 --- a/tests/value/oracle/pointer_comparison.1.res.oracle +++ b/tests/value/oracle/pointer_comparison.1.res.oracle @@ -36,7 +36,7 @@ [eva:alarm] tests/value/pointer_comparison.c:16: Warning: pointer downcast. assert (unsigned int)p ≤ 2147483647; [eva:alarm] tests/value/pointer_comparison.c:16: Warning: - pointer downcast. assert (unsigned int)&y ≤ 2147483647; + pointer downcast. assert (unsigned int)(&y) ≤ 2147483647; [eva] tests/value/pointer_comparison.c:16: Frama_C_show_each_5: {{ &x + {16} }} [eva] tests/value/pointer_comparison.c:17: Frama_C_show_each_5e: {{ &x + {16} }} [eva:pointer-comparison] tests/value/pointer_comparison.c:18: @@ -81,7 +81,7 @@ assert Eva: pointer_downcast: (unsigned int)p ≤ 2147483647; tried with Eva. [ - ] Assertion 'Eva,pointer_downcast' (file tests/value/pointer_comparison.c, line 16) - assert Eva: pointer_downcast: (unsigned int)&y ≤ 2147483647; + assert Eva: pointer_downcast: (unsigned int)(&y) ≤ 2147483647; tried with Eva. -------------------------------------------------------------------------------- @@ -119,7 +119,7 @@ [eva:alarm] tests/value/pointer_comparison.c:16: Warning: pointer downcast. assert (unsigned int)p ≤ 2147483647; [eva:alarm] tests/value/pointer_comparison.c:16: Warning: - pointer downcast. assert (unsigned int)&y ≤ 2147483647; + pointer downcast. assert (unsigned int)(&y) ≤ 2147483647; [eva] tests/value/pointer_comparison.c:16: Frama_C_show_each_5: {{ &x + {16} }} [eva] tests/value/pointer_comparison.c:17: Frama_C_show_each_5e: {{ &x + {16} }} [eva:alarm] tests/value/pointer_comparison.c:18: Warning: @@ -176,7 +176,7 @@ assert Eva: pointer_downcast: (unsigned int)p ≤ 2147483647; tried with Eva. [ - ] Assertion 'Eva,pointer_downcast' (file tests/value/pointer_comparison.c, line 16) - assert Eva: pointer_downcast: (unsigned int)&y ≤ 2147483647; + assert Eva: pointer_downcast: (unsigned int)(&y) ≤ 2147483647; tried with Eva. [ - ] Assertion 'Eva,ptr_comparison' (file tests/value/pointer_comparison.c, line 18) assert @@ -219,7 +219,7 @@ [eva:alarm] tests/value/pointer_comparison.c:16: Warning: pointer downcast. assert (unsigned int)p ≤ 2147483647; [eva:alarm] tests/value/pointer_comparison.c:16: Warning: - pointer downcast. assert (unsigned int)&y ≤ 2147483647; + pointer downcast. assert (unsigned int)(&y) ≤ 2147483647; [eva:alarm] tests/value/pointer_comparison.c:16: Warning: pointer comparison. assert \pointer_comparable((void *)p, (void *)(&y)); [eva] tests/value/pointer_comparison.c:16: Frama_C_show_each_5: {{ &x + {16} }} @@ -278,7 +278,7 @@ assert Eva: pointer_downcast: (unsigned int)p ≤ 2147483647; tried with Eva. [ - ] Assertion 'Eva,pointer_downcast' (file tests/value/pointer_comparison.c, line 16) - assert Eva: pointer_downcast: (unsigned int)&y ≤ 2147483647; + assert Eva: pointer_downcast: (unsigned int)(&y) ≤ 2147483647; tried with Eva. [ - ] Assertion 'Eva,ptr_comparison' (file tests/value/pointer_comparison.c, line 16) assert diff --git a/tests/value/oracle/pointer_int_cast.res.oracle b/tests/value/oracle/pointer_int_cast.res.oracle index 75c12b7d3ab..cad14cc1bd0 100644 --- a/tests/value/oracle/pointer_int_cast.res.oracle +++ b/tests/value/oracle/pointer_int_cast.res.oracle @@ -9,7 +9,7 @@ x ∈ {0} y ∈ {0} [eva:alarm] tests/value/pointer_int_cast.i:9: Warning: - pointer downcast. assert (unsigned int)&y ≤ 2147483647; + pointer downcast. assert (unsigned int)(&y) ≤ 2147483647; [eva] Recording results for g [eva] done for function g [eva] ====== VALUES COMPUTED ====== diff --git a/tests/value/oracle/shift.0.res.oracle b/tests/value/oracle/shift.0.res.oracle index 4e0d35dc30a..b2838250a6d 100644 --- a/tests/value/oracle/shift.0.res.oracle +++ b/tests/value/oracle/shift.0.res.oracle @@ -45,7 +45,7 @@ Assigning imprecise value to r. The imprecision originates from Arithmetic {tests/value/shift.i:52} [eva:alarm] tests/value/shift.i:53: Warning: - pointer downcast. assert (unsigned int)(char *)t ≤ 2147483647; + pointer downcast. assert (unsigned int)((char *)t) ≤ 2147483647; [eva:alarm] tests/value/shift.i:53: Warning: invalid LHS operand for left shift. assert 0 ≤ (long)((char *)t); [eva:alarm] tests/value/shift.i:53: Warning: diff --git a/tests/value/oracle/shift.1.res.oracle b/tests/value/oracle/shift.1.res.oracle index 46103bb62cc..9862244f180 100644 --- a/tests/value/oracle/shift.1.res.oracle +++ b/tests/value/oracle/shift.1.res.oracle @@ -39,7 +39,7 @@ Assigning imprecise value to r. The imprecision originates from Arithmetic {tests/value/shift.i:52} [eva:alarm] tests/value/shift.i:53: Warning: - pointer downcast. assert (unsigned int)(char *)t ≤ 2147483647; + pointer downcast. assert (unsigned int)((char *)t) ≤ 2147483647; [eva:alarm] tests/value/shift.i:53: Warning: signed overflow. assert -2147483648 ≤ (long)((char *)t) << 8; [eva:alarm] tests/value/shift.i:53: Warning: diff --git a/tests/value/oracle/sizeof.res.oracle b/tests/value/oracle/sizeof.res.oracle index 23b0674bd22..adc483ff665 100644 --- a/tests/value/oracle/sizeof.res.oracle +++ b/tests/value/oracle/sizeof.res.oracle @@ -19,7 +19,7 @@ [eva] computing for function main2 <- main. Called from tests/value/sizeof.i:41. [eva:alarm] tests/value/sizeof.i:32: Warning: - pointer downcast. assert (unsigned int)&s1 ≤ 2147483647; + pointer downcast. assert (unsigned int)(&s1) ≤ 2147483647; [eva] tests/value/sizeof.i:32: Assigning imprecise value to p. The imprecision originates from Arithmetic {tests/value/sizeof.i:32} @@ -126,7 +126,7 @@ struct s s1; int volatile i; void main2(void) { - /*@ assert Eva: pointer_downcast: (unsigned int)&s1 ≤ 2147483647; */ + /*@ assert Eva: pointer_downcast: (unsigned int)(&s1) ≤ 2147483647; */ struct s *p = (& s1 + (int)(& s1)) - (int)(& s1); /*@ assert Eva: index_bound: (unsigned int)(sizeof(s1.t) - (unsigned int)i) < 10; diff --git a/tests/value/oracle/struct3.res.oracle b/tests/value/oracle/struct3.res.oracle index 44c891f6674..4cbcaa45fec 100644 --- a/tests/value/oracle/struct3.res.oracle +++ b/tests/value/oracle/struct3.res.oracle @@ -22,7 +22,7 @@ [eva:alarm] tests/value/struct3.i:46: Warning: pointer downcast. assert (unsigned int)s2.c ≤ 2147483647; [eva:alarm] tests/value/struct3.i:46: Warning: - pointer downcast. assert (unsigned int)s2.c + (int)s2.c ≤ 2147483647; + pointer downcast. assert (unsigned int)(s2.c + (int)s2.c) ≤ 2147483647; [eva] tests/value/struct3.i:46: Assigning imprecise value to s2.a. The imprecision originates from Arithmetic {tests/value/struct3.i:46} diff --git a/tests/value/oracle/struct_array.res.oracle b/tests/value/oracle/struct_array.res.oracle index c0df48148db..05ac2f16880 100644 --- a/tests/value/oracle/struct_array.res.oracle +++ b/tests/value/oracle/struct_array.res.oracle @@ -2,11 +2,11 @@ [eva] Analyzing a complete application starting at main [eva] Computing initial state [eva:alarm] tests/value/struct_array.i:15: Warning: - pointer downcast. assert (unsigned int)&z1 ≤ 2147483647; + pointer downcast. assert (unsigned int)(&z1) ≤ 2147483647; [eva:alarm] tests/value/struct_array.i:15: Warning: - pointer downcast. assert (unsigned int)&z2 ≤ 2147483647; + pointer downcast. assert (unsigned int)(&z2) ≤ 2147483647; [eva:alarm] tests/value/struct_array.i:15: Warning: - pointer downcast. assert (unsigned int)&z4 ≤ 2147483647; + pointer downcast. assert (unsigned int)(&z4) ≤ 2147483647; [eva] Initial state computed [eva:initial-state] Values of globals at initialization v ∈ [--..--] @@ -241,11 +241,11 @@ [eva] Analyzing a complete application starting at main [eva] Computing initial state [eva:alarm] tests/value/struct_array.i:15: Warning: - pointer downcast. assert (unsigned int)&z1 ≤ 2147483647; + pointer downcast. assert (unsigned int)(&z1) ≤ 2147483647; [eva:alarm] tests/value/struct_array.i:15: Warning: - pointer downcast. assert (unsigned int)&z2 ≤ 2147483647; + pointer downcast. assert (unsigned int)(&z2) ≤ 2147483647; [eva:alarm] tests/value/struct_array.i:15: Warning: - pointer downcast. assert (unsigned int)&z4 ≤ 2147483647; + pointer downcast. assert (unsigned int)(&z4) ≤ 2147483647; [eva] Initial state computed [eva:initial-state] Values of globals at initialization v ∈ [--..--] diff --git a/tests/value/oracle/struct_incl.res.oracle b/tests/value/oracle/struct_incl.res.oracle index e8e83a5e446..3eb4f598ee5 100644 --- a/tests/value/oracle/struct_incl.res.oracle +++ b/tests/value/oracle/struct_incl.res.oracle @@ -23,11 +23,11 @@ t ∈ {0} v ∈ [--..--] [eva:alarm] tests/value/struct_incl.i:28: Warning: - pointer downcast. assert (unsigned int)&s1.d[9] ≤ 2147483647; + pointer downcast. assert (unsigned int)(&s1.d[9]) ≤ 2147483647; [eva:alarm] tests/value/struct_incl.i:29: Warning: - pointer downcast. assert (unsigned int)&s1.d[10] ≤ 2147483647; + pointer downcast. assert (unsigned int)(&s1.d[10]) ≤ 2147483647; [eva:alarm] tests/value/struct_incl.i:30: Warning: - pointer downcast. assert (unsigned int)&s1.b ≤ 2147483647; + pointer downcast. assert (unsigned int)(&s1.b) ≤ 2147483647; [eva:alarm] tests/value/struct_incl.i:48: Warning: accessing out of bounds index. assert 10 < 10; [kernel] tests/value/struct_incl.i:48: Warning: diff --git a/tests/value/oracle/symbolic_locs.res.oracle b/tests/value/oracle/symbolic_locs.res.oracle index 744e5e6a72f..eb325482dff 100644 --- a/tests/value/oracle/symbolic_locs.res.oracle +++ b/tests/value/oracle/symbolic_locs.res.oracle @@ -65,7 +65,7 @@ [eva:alarm] tests/value/symbolic_locs.i:51: Warning: assertion got status unknown. [eva:alarm] tests/value/symbolic_locs.i:54: Warning: - pointer downcast. assert (unsigned int)&x ≤ 2147483647; + pointer downcast. assert (unsigned int)(&x) ≤ 2147483647; [eva] tests/value/symbolic_locs.i:55: Frama_C_dump_each: # Cvalue domain: diff --git a/tests/value/oracle/volatile.res.oracle b/tests/value/oracle/volatile.res.oracle index 5298041bed3..8cfa94fed9d 100644 --- a/tests/value/oracle/volatile.res.oracle +++ b/tests/value/oracle/volatile.res.oracle @@ -91,7 +91,7 @@ [eva] computing for function main2 <- main. Called from tests/value/volatile.c:177. [eva:alarm] tests/value/volatile.c:83: Warning: - pointer downcast. assert (unsigned int)&X ≤ 2147483647; + pointer downcast. assert (unsigned int)(&X) ≤ 2147483647; [eva] Recording results for main2 [eva] Done for function main2 [eva] computing for function main3 <- main. -- GitLab From d8b06bb6d773705045a6e782aa1622007b4fd94d Mon Sep 17 00:00:00 2001 From: Virgile Prevosto <virgile.prevosto@cea.fr> Date: Fri, 27 Mar 2020 10:38:44 +0100 Subject: [PATCH 032/218] Update Changelog following MR !2557 --- Changelog | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Changelog b/Changelog index 13432e2d6da..d7a8acc7c53 100644 --- a/Changelog +++ b/Changelog @@ -17,7 +17,12 @@ Open Source Release <next-release> ################################## -- Kernel [2020/02/20] Add option -cpp-extra-args-per-file +- RTE [2020/03/27] Emits alarm on pointer downcast when option is on +- Eva [2020/03/27] Emits alarm on pointer downcast when option is on +- Kernel [2020/03/27] New option -warn-pointer-downcast (activated by + default), to warn when a conversion between pointer and integer + might provoke a loss of precision. +- Kernel [2020/03/20] Add option -cpp-extra-args-per-file -* Kernel [2020/03/18] Fixes #@823 (-load-module/-load-script now accept spaces in filename) -* Kernel [2020/03/18] Fixes #@818 (term generated for downcast alarms) -- GitLab From 5b4c1196aaf7e8d57498e57fe9bdef9762e712c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20B=C3=BChler?= <david.buhler@cea.fr> Date: Thu, 27 Feb 2020 11:09:33 +0100 Subject: [PATCH 033/218] [Logic] New predicate object_pointer. Not yet supported by the plugins. --- src/kernel_internals/parsing/logic_lexer.mll | 1 + src/kernel_internals/parsing/logic_parser.mly | 5 ++++- src/kernel_services/analysis/logic_interp.ml | 2 +- src/kernel_services/ast_data/cil_types.mli | 2 ++ src/kernel_services/ast_printing/cil_printer.ml | 5 +++++ src/kernel_services/ast_printing/cil_types_debug.ml | 2 ++ src/kernel_services/ast_printing/logic_print.ml | 10 +++++++--- src/kernel_services/ast_queries/cil.ml | 6 +++++- src/kernel_services/ast_queries/logic_const.ml | 1 + src/kernel_services/ast_queries/logic_const.mli | 3 +++ src/kernel_services/ast_queries/logic_typing.ml | 7 +++++-- src/kernel_services/ast_queries/logic_utils.ml | 12 ++++++++++-- src/kernel_services/parsetree/logic_ptree.mli | 1 + src/plugins/e-acsl/src/analyses/mmodel_analysis.ml | 3 ++- src/plugins/e-acsl/src/analyses/typing.ml | 1 + src/plugins/e-acsl/src/code_generator/translate.ml | 1 + src/plugins/value/legacy/eval_terms.ml | 6 +++++- src/plugins/wp/LogicSemantics.ml | 5 +++++ src/plugins/wp/RefUsage.ml | 3 ++- src/plugins/wp/RegionAccess.ml | 2 +- 20 files changed, 64 insertions(+), 14 deletions(-) diff --git a/src/kernel_internals/parsing/logic_lexer.mll b/src/kernel_internals/parsing/logic_lexer.mll index eb9fe4321f8..bc63b51001c 100644 --- a/src/kernel_internals/parsing/logic_lexer.mll +++ b/src/kernel_internals/parsing/logic_lexer.mll @@ -232,6 +232,7 @@ "\\typeof", TYPEOF; "\\unallocated", UNALLOCATED; "\\union", BSUNION; + "\\object_pointer", OBJECT_POINTER; "\\valid", VALID; "\\valid_read", VALID_READ; "\\valid_index", VALID_INDEX; diff --git a/src/kernel_internals/parsing/logic_parser.mly b/src/kernel_internals/parsing/logic_parser.mly index b19f7e478bd..9c25360b415 100644 --- a/src/kernel_internals/parsing/logic_parser.mly +++ b/src/kernel_internals/parsing/logic_parser.mly @@ -243,7 +243,8 @@ %token INT INTEGER REAL BOOLEAN BOOL FLOAT LT GT LE GE EQ NE COMMA ARROW EQUAL %token FORALL EXISTS IFF IMPLIES AND OR NOT SEPARATED %token TRUE FALSE OLD AT RESULT -%token BLOCK_LENGTH BASE_ADDR OFFSET VALID VALID_READ VALID_INDEX VALID_RANGE VALID_FUNCTION +%token BLOCK_LENGTH BASE_ADDR OFFSET VALID VALID_READ VALID_INDEX VALID_RANGE +%token OBJECT_POINTER VALID_FUNCTION %token ALLOCATION STATIC REGISTER AUTOMATIC DYNAMIC UNALLOCATED %token ALLOCABLE FREEABLE FRESH %token DOLLAR QUESTION MINUS PLUS STAR AMP SLASH PERCENT LSQUARE RSQUARE EOF @@ -456,6 +457,7 @@ lexpr_inner: | NOT lexpr_inner { info (PLnot $2) } | TRUE { info PLtrue } | FALSE { info PLfalse } +| OBJECT_POINTER opt_label_1 LPAR lexpr RPAR { info (PLobject_pointer ($2,$4)) } | VALID opt_label_1 LPAR lexpr RPAR { info (PLvalid ($2,$4)) } | VALID_READ opt_label_1 LPAR lexpr RPAR { info (PLvalid_read ($2,$4)) } | VALID_FUNCTION LPAR lexpr RPAR { info (PLvalid_function $3) } @@ -1932,6 +1934,7 @@ bs_keyword: | TYPEOF { () } | BSUNION { () } | UNALLOCATED { () } +| OBJECT_POINTER { () } | VALID { () } | VALID_INDEX { () } | VALID_RANGE { () } diff --git a/src/kernel_services/analysis/logic_interp.ml b/src/kernel_services/analysis/logic_interp.ml index 427467329aa..99fd4b2c8a7 100644 --- a/src/kernel_services/analysis/logic_interp.ml +++ b/src/kernel_services/analysis/logic_interp.ml @@ -800,7 +800,7 @@ to function contracts." taken into account by the functions [from_...] below *) DoChildren - | Pvalid_function _ -> + | Pobject_pointer _ | Pvalid_function _ -> DoChildren | Papp _ | Pallocable _ | Pfreeable _ | Pfresh _ diff --git a/src/kernel_services/ast_data/cil_types.mli b/src/kernel_services/ast_data/cil_types.mli index 49d3a0fecd3..66327ce7d8c 100644 --- a/src/kernel_services/ast_data/cil_types.mli +++ b/src/kernel_services/ast_data/cil_types.mli @@ -1569,6 +1569,8 @@ and predicate_node = | Pexists of quantifiers * predicate (** existential quantification. *) | Pat of predicate * logic_label (** predicate refers to a particular program point. *) + | Pobject_pointer of logic_label * term + (** the given locations can be pointed to. *) | Pvalid_read of logic_label * term (** the given locations are valid for reading. *) | Pvalid of logic_label * term (** the given locations are valid. *) | Pvalid_function of term diff --git a/src/kernel_services/ast_printing/cil_printer.ml b/src/kernel_services/ast_printing/cil_printer.ml index 2b8c620ea6b..aef50199843 100644 --- a/src/kernel_services/ast_printing/cil_printer.ml +++ b/src/kernel_services/ast_printing/cil_printer.ml @@ -231,6 +231,7 @@ module Precedence = struct | Pfreeable _ | Pvalid _ | Pvalid_read _ + | Pobject_pointer _ | Pvalid_function _ | Pinitialized _ | Pdangling _ @@ -2727,6 +2728,10 @@ class cil_printer () = object (self) fprintf fmt "@[%a%a(@[%a@])@]" self#pp_acsl_keyword "\\valid_read" self#labels [l] self#term p + | Pobject_pointer (l,p) -> + fprintf fmt "@[%a%a(@[%a@])@]" + self#pp_acsl_keyword "\\object_pointer" + self#labels [l] self#term p | Pvalid_function p -> fprintf fmt "@[%a(@[%a@])@]" self#pp_acsl_keyword "\\valid_function" diff --git a/src/kernel_services/ast_printing/cil_types_debug.ml b/src/kernel_services/ast_printing/cil_types_debug.ml index c059f8110e4..0b4be0a9ac9 100644 --- a/src/kernel_services/ast_printing/cil_types_debug.ml +++ b/src/kernel_services/ast_printing/cil_types_debug.ml @@ -859,6 +859,8 @@ and pp_predicate_node fmt = function Format.fprintf fmt "Pexists(%a,%a)" pp_quantifiers quantifiers pp_predicate predicate | Pat(predicate,logic_label) -> Format.fprintf fmt "Pat(%a,%a)" pp_predicate predicate pp_logic_label logic_label + | Pobject_pointer(logic_label,term) -> + Format.fprintf fmt "Pobject_pointer(%a,%a)" pp_logic_label logic_label pp_term term | Pvalid_read(logic_label,term) -> Format.fprintf fmt "Pvalid_read(%a,%a)" pp_logic_label logic_label pp_term term | Pvalid(logic_label,term) -> diff --git a/src/kernel_services/ast_printing/logic_print.ml b/src/kernel_services/ast_printing/logic_print.ml index 998b809f10e..fca0da49531 100644 --- a/src/kernel_services/ast_printing/logic_print.ml +++ b/src/kernel_services/ast_printing/logic_print.ml @@ -129,7 +129,7 @@ let getParenthLevel e = | PLapp _ | PLold _ | PLat _ | PLoffset _ | PLbase_addr _ | PLblock_length _ | PLupdate _ | PLinitField _ | PLinitIndex _ - | PLvalid _ | PLvalid_read _ | PLvalid_function _ + | PLvalid _ | PLvalid_read _ | PLobject_pointer _ | PLvalid_function _ | PLinitialized _ | PLdangling _ | PLallocable _ | PLfreeable _ | PLfresh _ | PLseparated _ | PLunion _ | PLinter _ -> 10 @@ -249,8 +249,12 @@ and print_lexpr_level n fmt e = | PLexists(q,e) -> fprintf fmt "@[\\exists@ @[%a@];@ %a@]" print_quantifiers q print_lexpr e - | PLvalid (l,e) -> fprintf fmt "\\valid%a(@;@[%a@]@;)" print_label_1 l print_lexpr_plain e - | PLvalid_read (l,e) -> fprintf fmt "\\valid_read%a(@;@[%a@]@;)" print_label_1 l print_lexpr_plain e + | PLvalid (l,e) -> + fprintf fmt "\\valid%a(@;@[%a@]@;)" print_label_1 l print_lexpr_plain e + | PLvalid_read (l,e) -> + fprintf fmt "\\valid_read%a(@;@[%a@]@;)" print_label_1 l print_lexpr_plain e + | PLobject_pointer (l,e) -> + fprintf fmt "\\object_pointer%a(@;@[%a@]@;)" print_label_1 l print_lexpr_plain e | PLvalid_function e -> fprintf fmt "\\valid_function(@;@[%a@]@;)" print_lexpr_plain e | PLinitialized (l,e) -> diff --git a/src/kernel_services/ast_queries/cil.ml b/src/kernel_services/ast_queries/cil.ml index 572e350a44a..459570e1be6 100644 --- a/src/kernel_services/ast_queries/cil.ml +++ b/src/kernel_services/ast_queries/cil.ml @@ -1868,6 +1868,10 @@ and childrenPredicateNode vis p = let s' = visitCilLogicLabel vis s in let t' = vTerm t in if t' != t || s != s' then Pvalid_read (s',t') else p + | Pobject_pointer (s,t) -> + let s' = visitCilLogicLabel vis s in + let t' = vTerm t in + if t' != t || s != s' then Pobject_pointer (s',t') else p | Pvalid_function t -> let t' = vTerm t in if t' != t then Pvalid_function t' else p @@ -6945,7 +6949,7 @@ and free_vars_predicate bound_vars p = match p.pred_content with Logic_var.Set.union (free_vars_term bound_vars t) acc) Logic_var.Set.empty tl | Pallocable (_,t) | Pfreeable (_,t) - | Pvalid (_,t) | Pvalid_read (_,t) | Pvalid_function t + | Pvalid (_,t) | Pvalid_read (_,t) | Pobject_pointer (_, t) | Pvalid_function t | Pinitialized (_,t) | Pdangling (_,t) -> free_vars_term bound_vars t | Pseparated seps -> diff --git a/src/kernel_services/ast_queries/logic_const.ml b/src/kernel_services/ast_queries/logic_const.ml index e9417dd0256..8ee64b0b366 100644 --- a/src/kernel_services/ast_queries/logic_const.ml +++ b/src/kernel_services/ast_queries/logic_const.ml @@ -425,6 +425,7 @@ let pallocable ?(loc=Cil_datatype.Location.unknown) (l,p) = unamed ~loc (Palloca let pfreeable ?(loc=Cil_datatype.Location.unknown) (l,p) = unamed ~loc (Pfreeable (l,p)) let pvalid ?(loc=Cil_datatype.Location.unknown) (l,p) = unamed ~loc (Pvalid (l,p)) let pvalid_read ?(loc=Cil_datatype.Location.unknown) (l,p) = unamed ~loc (Pvalid_read (l,p)) +let pobject_pointer ?(loc=Cil_datatype.Location.unknown) (l,p) = unamed ~loc (Pobject_pointer (l,p)) let pvalid_function ?(loc=Cil_datatype.Location.unknown) p = unamed ~loc (Pvalid_function p) (* the index should be an integer or a range of integers *) diff --git a/src/kernel_services/ast_queries/logic_const.mli b/src/kernel_services/ast_queries/logic_const.mli index 280661c522f..51759d05c13 100644 --- a/src/kernel_services/ast_queries/logic_const.mli +++ b/src/kernel_services/ast_queries/logic_const.mli @@ -170,6 +170,9 @@ val pvalid_read: ?loc:location -> logic_label * term -> predicate (** \valid *) val pvalid: ?loc:location -> logic_label * term -> predicate +(** \object_pointer *) +val pobject_pointer: ?loc:location -> logic_label * term -> predicate + (** \valid_function *) val pvalid_function: ?loc:location -> term -> predicate diff --git a/src/kernel_services/ast_queries/logic_typing.ml b/src/kernel_services/ast_queries/logic_typing.ml index 9cab004b334..f6a1c015fb9 100644 --- a/src/kernel_services/ast_queries/logic_typing.ml +++ b/src/kernel_services/ast_queries/logic_typing.ml @@ -1049,7 +1049,8 @@ struct | Pimplies(p1,p2) | Piff(p1,p2) -> needs_at_pred p1 || needs_at_pred p2 | Pnot p | Plet (_,p) | Pforall(_,p) | Pexists(_,p) -> needs_at_pred p | Pif(t,p1,p2) -> needs_at t || needs_at_pred p1 || needs_at_pred p2 - | Pvalid (_,t) | Pvalid_read (_,t) | Pvalid_function t + | Pvalid (_,t) | Pvalid_read (_,t) + | Pobject_pointer (_,t) | Pvalid_function t | Pinitialized (_,t) | Pdangling (_, t) | Pallocable(_,t) | Pfreeable(_,t)-> needs_at t | Pfresh (_,_,t,n) -> (needs_at t) && (needs_at n) @@ -3003,7 +3004,7 @@ struct let t2,ty2 = type_num_term_option ctxt env t2 in (Trange(t1,t2), Ltype(ctxt.find_logic_type "set", [arithmetic_conversion ty1 ty2])) - | PLvalid _ | PLvalid_read _ | PLvalid_function _ + | PLvalid _ | PLvalid_read _ | PLobject_pointer _ | PLvalid_function _ | PLfresh _ | PLallocable _ | PLfreeable _ | PLinitialized _ | PLdangling _ | PLexists _ | PLforall _ | PLimplies _ | PLiff _ @@ -3357,6 +3358,8 @@ struct predicate_label_ptr ~check_non_void:true pvalid_read l t | PLvalid (l,t) -> predicate_label_ptr ~check_non_void:true pvalid l t + | PLobject_pointer (l,t) -> + predicate_label_ptr ~check_non_void:false pobject_pointer l t | PLvalid_function t -> let t = term env t in if isLogicPointer t then begin diff --git a/src/kernel_services/ast_queries/logic_utils.ml b/src/kernel_services/ast_queries/logic_utils.ml index 41237fee587..ea652d98361 100644 --- a/src/kernel_services/ast_queries/logic_utils.ml +++ b/src/kernel_services/ast_queries/logic_utils.ml @@ -935,6 +935,7 @@ and is_same_predicate_node p1 p2 = | Pfreeable (l1,t1), Pfreeable (l2,t2) | Pvalid (l1,t1), Pvalid (l2,t2) | Pvalid_read (l1,t1), Pvalid_read (l2,t2) + | Pobject_pointer (l1,t1), Pobject_pointer (l2,t2) | Pinitialized (l1,t1), Pinitialized (l2,t2) -> is_same_logic_label l1 l2 && is_same_term t1 t2 | Pvalid_function t1, Pvalid_function t2 -> @@ -949,7 +950,7 @@ and is_same_predicate_node p1 p2 = with Invalid_argument _ -> false) | (Pfalse | Ptrue | Papp _ | Prel _ | Pand _ | Por _ | Pimplies _ | Piff _ | Pnot _ | Pif _ | Plet _ | Pforall _ | Pexists _ - | Pat _ | Pvalid _ | Pvalid_read _ | Pvalid_function _ + | Pat _ | Pvalid _ | Pvalid_read _ | Pobject_pointer _ | Pvalid_function _ | Pinitialized _ | Pdangling _ | Pfresh _ | Pallocable _ | Pfreeable _ | Pxor _ | Pseparated _ ), _ -> false @@ -1288,6 +1289,7 @@ and is_same_lexpr l1 l2 = | PLfreeable (l1,e1), PLfreeable (l2,e2) | PLvalid (l1,e1), PLvalid (l2,e2) | PLvalid_read (l1,e1), PLvalid_read (l2,e2) + | PLobject_pointer (l1,e1), PLobject_pointer (l2,e2) | PLbase_addr (l1,e1), PLbase_addr (l2,e2) | PLoffset (l1,e1), PLoffset (l2,e2) | PLblock_length (l1,e1), PLblock_length (l2,e2) @@ -1316,7 +1318,8 @@ and is_same_lexpr l1 l2 = | PLupdate _ | PLinitIndex _ | PLtype _ | PLfalse | PLtrue | PLinitField _ | PLrel _ | PLand _ | PLor _ | PLxor _ | PLimplies _ | PLiff _ | PLnot _ | PLif _ | PLforall _ - | PLexists _ | PLvalid _ | PLvalid_read _ | PLvalid_function _ + | PLexists _ | PLvalid _ | PLvalid_read _ + | PLobject_pointer _ | PLvalid_function _ | PLfreeable _ | PLallocable _ | PLinitialized _ | PLdangling _ | PLseparated _ | PLfresh _ | PLnamed _ | PLcomprehension _ | PLunion _ | PLinter _ @@ -1523,6 +1526,8 @@ and hash_predicate (acc,depth,tot) p = hash_predicate (acc + 173 + hash_label l, depth - 1, tot - 1) p | Pvalid_read (l, t) -> hash_term (acc + 187 + hash_label l, depth - 1, tot - 1) t + | Pobject_pointer (l, t) -> + hash_term (acc + 181 + hash_label l, depth - 1, tot - 1) t | Pvalid (l, t) -> hash_term (acc + 193 + hash_label l, depth - 1, tot - 1) t | Pvalid_function t -> hash_term (acc + 203, depth - 1, tot - 1) t @@ -1823,6 +1828,7 @@ and compare_predicate_node p1 p2 = | Pfreeable (l1,t1), Pfreeable (l2,t2) | Pvalid (l1,t1), Pvalid (l2,t2) | Pvalid_read (l1,t1), Pvalid_read (l2,t2) + | Pobject_pointer (l1,t1), Pobject_pointer (l2,t2) | Pinitialized (l1,t1), Pinitialized (l2,t2) | Pdangling (l1,t1), Pdangling (l2,t2) -> let res = compare_logic_label l1 l2 in @@ -1835,6 +1841,8 @@ and compare_predicate_node p1 p2 = | _, Pvalid _ -> -1 | Pvalid_read _, _ -> 1 | _, Pvalid_read _ -> -1 + | Pobject_pointer _, _ -> 1 + | _, Pobject_pointer _ -> -1 | Pinitialized _, _ -> 1 | _, Pinitialized _ -> -1 | Pdangling _, _ -> 1 diff --git a/src/kernel_services/parsetree/logic_ptree.mli b/src/kernel_services/parsetree/logic_ptree.mli index 30364e00fa1..adde2634144 100644 --- a/src/kernel_services/parsetree/logic_ptree.mli +++ b/src/kernel_services/parsetree/logic_ptree.mli @@ -132,6 +132,7 @@ and lexpr_node = expression. *) | PLvalid of string option * lexpr (** pointer is valid. *) | PLvalid_read of string option * lexpr (** pointer is valid for reading. *) + | PLobject_pointer of string option * lexpr (** object pointer can be created. *) | PLvalid_function of lexpr (** function pointer is compatible with pointed type. *) | PLallocable of string option * lexpr (** pointer is valid for malloc. *) | PLfreeable of string option * lexpr (** pointer is valid for free. *) diff --git a/src/plugins/e-acsl/src/analyses/mmodel_analysis.ml b/src/plugins/e-acsl/src/analyses/mmodel_analysis.ml index 36e0eab7721..3b655683995 100644 --- a/src/plugins/e-acsl/src/analyses/mmodel_analysis.ml +++ b/src/plugins/e-acsl/src/analyses/mmodel_analysis.ml @@ -359,7 +359,8 @@ module rec Transfer let register_object kf state_ref = object inherit Visitor.frama_c_inplace method !vpredicate_node = function - | Pvalid(_, t) | Pvalid_read(_, t) | Pvalid_function t + | Pvalid(_, t) | Pvalid_read(_, t) + | Pobject_pointer(_, t) | Pvalid_function t | Pinitialized(_, t) | Pfreeable(_, t) -> (* Options.feedback "REGISTER %a" Cil.d_term t;*) state_ref := register_term kf !state_ref t; diff --git a/src/plugins/e-acsl/src/analyses/typing.ml b/src/plugins/e-acsl/src/analyses/typing.ml index 91904e682a9..075d6bfa4a7 100644 --- a/src/plugins/e-acsl/src/analyses/typing.ml +++ b/src/plugins/e-acsl/src/analyses/typing.ml @@ -676,6 +676,7 @@ let rec type_predicate p = | Pallocable(_, t) | Pvalid(_, t) | Pvalid_read(_, t) + | Pobject_pointer(_,t) | Pvalid_function t -> ignore (type_term ~use_gmp_opt:false ~ctx:Nan t); c_int diff --git a/src/plugins/e-acsl/src/code_generator/translate.ml b/src/plugins/e-acsl/src/code_generator/translate.ml index e3d5580ba81..6a77b6530df 100644 --- a/src/plugins/e-acsl/src/code_generator/translate.ml +++ b/src/plugins/e-acsl/src/code_generator/translate.ml @@ -708,6 +708,7 @@ and named_predicate_content_to_exp ?name kf env p = e, env | Pseparated _ -> not_yet env "\\separated" | Pdangling _ -> not_yet env "\\dangling" + | Pobject_pointer _ -> not_yet env "\\object_pointer" | Pvalid_function _ -> not_yet env "\\valid_function" | Prel(rel, t1, t2) -> let ity = Typing.get_integer_op_of_predicate p in diff --git a/src/plugins/value/legacy/eval_terms.ml b/src/plugins/value/legacy/eval_terms.ml index cb9450bce91..968ec99416c 100644 --- a/src/plugins/value/legacy/eval_terms.ml +++ b/src/plugins/value/legacy/eval_terms.ml @@ -2144,6 +2144,7 @@ let rec reduce_by_predicate ~alarm_mode env positive p = | _,Pvalid_read (_label,tsets) -> reduce_by_valid env positive Read tsets + | _,Pobject_pointer (_label, _tsets) -> env (* TODO *) | _,Pvalid_function _tsets -> env (* TODO *) | _,(Pinitialized (lbl_initialized,tsets) @@ -2291,6 +2292,8 @@ and eval_predicate env pred = ignore (env_state env lbl); do_eval { env with e_cur = lbl } p + | Pobject_pointer (_label, _tsets) -> Unknown (* TODO *) + | Pvalid (_label, tsets) | Pvalid_read (_label, tsets) -> (* TODO: see same constructor in reduce_by_predicate *) let kind = match p.pred_content with Pvalid_read _ -> Read | _ -> Write in @@ -2579,7 +2582,8 @@ let predicate_deps env pred = | Pat (p, lbl) -> do_eval { env with e_cur = lbl } p - | Pvalid (_, tsets) | Pvalid_read (_, tsets) | Pvalid_function tsets-> + | Pvalid (_, tsets) | Pvalid_read (_, tsets) + | Pobject_pointer (_, tsets) | Pvalid_function tsets -> (eval_term_as_lval ~alarm_mode env tsets).ldeps | Pinitialized (lbl, tsets) | Pdangling (lbl, tsets) -> diff --git a/src/plugins/wp/LogicSemantics.ml b/src/plugins/wp/LogicSemantics.ml index d513d5172ba..825ace458d1 100644 --- a/src/plugins/wp/LogicSemantics.ml +++ b/src/plugins/wp/LogicSemantics.ml @@ -872,6 +872,11 @@ struct | Pvalid(label,t) -> valid env RW label t | Pvalid_read(label,t) -> valid env RD label t + | Pobject_pointer(_label,_t) -> + Warning.error + "\\object_pointer not yet implemented@\n\ + @[<hov 0>(%a)@]" Printer.pp_predicate p + | Pvalid_function _t -> Warning.error "\\valid_function not yet implemented@\n\ diff --git a/src/plugins/wp/RefUsage.ml b/src/plugins/wp/RefUsage.ml index 1841ce516fb..642686f8263 100644 --- a/src/plugins/wp/RefUsage.ml +++ b/src/plugins/wp/RefUsage.ml @@ -535,7 +535,8 @@ and pred (env:ctx) p : value = match p.pred_content with (* No escape *) | Pinitialized(_, t) | Pdangling(_,t) | Pallocable(_, t) | Pfreeable(_, t) - | Pvalid(_,t) | Pvalid_read (_,t) | Pvalid_function t -> + | Pvalid(_,t) | Pvalid_read (_,t) + | Pobject_pointer (_,t) | Pvalid_function t -> unescape ((term env) t) | Pseparated ts -> E.fcup (fun t -> unescape ((term env) t)) ts diff --git a/src/plugins/wp/RegionAccess.ml b/src/plugins/wp/RegionAccess.ml index 642f9c3fd9b..4f87b246b7f 100644 --- a/src/plugins/wp/RegionAccess.ml +++ b/src/plugins/wp/RegionAccess.ml @@ -369,7 +369,7 @@ and cc_pred (map:map) (p:predicate) = | Pforall(_,p) | Pexists(_,p) -> cc_pred map p | Pseparated ts -> List.iter (cc_term map) ts - | Pvalid(_,t) | Pvalid_read(_,t) | Pvalid_function t + | Pvalid(_,t) | Pvalid_read(_,t) | Pobject_pointer(_,t) | Pvalid_function t | Pinitialized(_,t) | Pdangling(_,t) | Pallocable(_,t) | Pfreeable(_,t) -> cc_term map t | Pfresh(_,_,ptr,n) -> cc_term map ptr ; cc_term map n -- GitLab From 0124c32181c27d8e5aa2ee5865f0cbe9f21da519 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20B=C3=BChler?= <david.buhler@cea.fr> Date: Thu, 27 Feb 2020 11:24:46 +0100 Subject: [PATCH 034/218] [Kernel] New invalid_pointer alarm, for the creation of invalid pointers. --- src/kernel_services/ast_data/alarms.ml | 49 +++++++++++++++++-------- src/kernel_services/ast_data/alarms.mli | 1 + src/plugins/value/alarmset.ml | 5 +++ 3 files changed, 39 insertions(+), 16 deletions(-) diff --git a/src/kernel_services/ast_data/alarms.ml b/src/kernel_services/ast_data/alarms.ml index 2faab4979f1..f251a750c84 100644 --- a/src/kernel_services/ast_data/alarms.ml +++ b/src/kernel_services/ast_data/alarms.ml @@ -41,6 +41,7 @@ type alarm = | Index_out_of_bound of exp (* index *) * exp option (* None = lower bound is zero; Some up = upper bound *) + | Invalid_pointer of exp | Invalid_shift of exp * int option (* strict upper bound, if any *) | Pointer_comparison of exp option (* [None] when implicit comparison to 0 *) @@ -67,7 +68,7 @@ type alarm = (* If you add one constructor to this type, make sure to add a dummy value in the 'reprs' value below, and increase 'nb_alarms' *) -let nb_alarm_constructors = 17 +let nb_alarm_constructors = 18 module D = Datatype.Make_with_collections @@ -82,6 +83,7 @@ module D = [ Division_by_zero e; Memory_access (lv, For_reading); Index_out_of_bound (e, None); + Invalid_pointer e; Invalid_shift (e, None); Pointer_comparison (None, e); Differing_blocks (e, e); @@ -102,20 +104,21 @@ module D = | Division_by_zero _ -> 0 | Memory_access _ -> 1 | Index_out_of_bound _ -> 2 - | Invalid_shift _ -> 3 - | Pointer_comparison _ -> 4 - | Overflow _ -> 5 - | Not_separated _ -> 6 - | Overlap _ -> 7 - | Uninitialized _ -> 8 - | Is_nan_or_infinite _ -> 9 - | Is_nan _ -> 10 - | Float_to_int _ -> 11 - | Differing_blocks _ -> 12 - | Dangling _ -> 13 - | Function_pointer _ -> 14 - | Uninitialized_union _ -> 15 - | Invalid_bool _ -> 16 + | Invalid_pointer _ -> 3 + | Invalid_shift _ -> 4 + | Pointer_comparison _ -> 5 + | Overflow _ -> 6 + | Not_separated _ -> 7 + | Overlap _ -> 8 + | Uninitialized _ -> 9 + | Is_nan_or_infinite _ -> 10 + | Is_nan _ -> 11 + | Float_to_int _ -> 12 + | Differing_blocks _ -> 13 + | Dangling _ -> 14 + | Function_pointer _ -> 15 + | Uninitialized_union _ -> 16 + | Invalid_bool _ -> 17 let () = (* Lightweight checks *) for i = 0 to nb_alarm_constructors - 1 do @@ -136,6 +139,7 @@ module D = | Index_out_of_bound(e11, e12), Index_out_of_bound(e21, e22) -> let n = Exp.compare e11 e21 in if n = 0 then Extlib.opt_compare Exp.compare e12 e22 else n + | Invalid_pointer e1, Invalid_pointer e2 -> Exp.compare e1 e2 | Invalid_shift(e1, n1), Invalid_shift(e2, n2) -> let n = Exp.compare e1 e2 in if n = 0 then Extlib.opt_compare Datatype.Int.compare n1 n2 else n @@ -187,7 +191,8 @@ module D = else Extlib.opt_compare (Extlib.list_compare Exp.compare) l1 l2 | Invalid_bool lv1, Invalid_bool lv2 -> Lval.compare lv1 lv2 | _, (Division_by_zero _ | Memory_access _ | - Index_out_of_bound _ | Invalid_shift _ | Pointer_comparison _ | + Index_out_of_bound _ | Invalid_pointer _ | + Invalid_shift _ | Pointer_comparison _ | Overflow _ | Not_separated _ | Overlap _ | Uninitialized _ | Dangling _ | Is_nan_or_infinite _ | Is_nan _ | Float_to_int _ | Differing_blocks _ | Function_pointer _ | @@ -211,6 +216,7 @@ module D = (nb a, Exp.hash e1, match e2 with None -> 0 | Some e -> 17 + Exp.hash e) + | Invalid_pointer e -> Hashtbl.hash (nb a, Exp.hash e) | Invalid_shift(e, n) -> Hashtbl.hash (nb a, Exp.hash e, n) | Pointer_comparison(e1, e2) -> Hashtbl.hash @@ -255,6 +261,8 @@ module D = (match e2 with None -> ">=" | Some _ -> "<") Printer.pp_exp (match e2 with None -> Cil.zero e1.eloc | Some e -> e) + | Invalid_pointer e -> + Format.fprintf fmt "Invalid_pointer(@[%a@])" Exp.pretty e | Invalid_shift(e, n) -> Format.fprintf fmt "Invalid_shift(@[%a@]@ %s)" Printer.pp_exp e @@ -393,6 +401,7 @@ let get_name = function | Division_by_zero _ -> "division_by_zero" | Memory_access _ -> "mem_access" | Index_out_of_bound _ -> "index_bound" + | Invalid_pointer _ -> "pointer_value" | Invalid_shift _ -> "shift" | Pointer_comparison _ -> "ptr_comparison" | Differing_blocks _ -> "differing_blocks" @@ -416,6 +425,7 @@ let get_description = function | Division_by_zero _ -> "Integer division by zero" | Memory_access _ -> "Invalid pointer dereferencing" | Index_out_of_bound _ -> "Array access out of bounds" + | Invalid_pointer _ -> "Invalid pointer computation" | Invalid_shift _ -> "Invalid shift" | Pointer_comparison _ -> "Invalid pointer comparison" | Differing_blocks _ -> "Operation on pointers within different blocks" @@ -503,6 +513,13 @@ let create_predicate ?(loc=Location.unknown) alarm = let t2 = Logic_utils.expr_to_term ~cast:true e2 in Logic_const.prel ~loc (Rlt, t1, t2)) + | Invalid_pointer e -> + let loc = best_loc ~loc e.eloc in + let t = Logic_utils.expr_to_term ~cast:true e in + if Cil.isFunPtrType (Cil.typeOf e) + then Logic_const.pvalid_function ~loc t + else Logic_const.pobject_pointer ~loc (Logic_const.here_label, t) + | Invalid_shift(e, n) -> (* 0 <= e < n *) let loc = best_loc ~loc e.eloc in diff --git a/src/kernel_services/ast_data/alarms.mli b/src/kernel_services/ast_data/alarms.mli index a369dc60f2b..bdbc4f9fa4d 100644 --- a/src/kernel_services/ast_data/alarms.mli +++ b/src/kernel_services/ast_data/alarms.mli @@ -40,6 +40,7 @@ type alarm = | Index_out_of_bound of exp (** index *) * exp option (** None = lower bound is zero; Some up = upper bound *) + | Invalid_pointer of exp | Invalid_shift of exp * int option (** strict upper bound, if any *) | Pointer_comparison of exp option (** [None] when implicit comparison to NULL pointer *) diff --git a/src/plugins/value/alarmset.ml b/src/plugins/value/alarmset.ml index 1738ac4a35a..222eed3099d 100644 --- a/src/plugins/value/alarmset.ml +++ b/src/plugins/value/alarmset.ml @@ -332,6 +332,9 @@ let emit_alarm kinstr alarm (status:status) = | Alarms.Index_out_of_bound _ -> register_alarm "accessing out of bounds index" + | Alarms.Invalid_pointer _ -> + register_alarm "invalid pointer creation" + | Alarms.Differing_blocks _ -> register_alarm "pointer subtraction" @@ -367,6 +370,7 @@ let emit_alarm kinstr alarm (status:status) = let height_alarm = let open Value_util in function | Alarms.Division_by_zero e | Alarms.Index_out_of_bound (e,_) + | Alarms.Invalid_pointer e | Alarms.Invalid_shift (e,_) | Alarms.Overflow (_,e,_,_) | Alarms.Float_to_int (e,_,_) @@ -426,6 +430,7 @@ let warn_alarm warn_mode = function | Alarms.Invalid_shift _ | Alarms.Memory_access _ | Alarms.Index_out_of_bound _ + | Alarms.Invalid_pointer _ | Alarms.Is_nan_or_infinite _ | Alarms.Is_nan _ | Alarms.Not_separated _ -- GitLab From 0284b45ea621f1a2fbb364bf1ffffbf9884c643e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20B=C3=BChler?= <david.buhler@cea.fr> Date: Thu, 27 Feb 2020 11:27:33 +0100 Subject: [PATCH 035/218] [Kernel] Adds the new option -warn-invalid-pointer. --- src/kernel_services/plugin_entry_points/kernel.ml | 9 +++++++++ src/kernel_services/plugin_entry_points/kernel.mli | 3 +++ 2 files changed, 12 insertions(+) diff --git a/src/kernel_services/plugin_entry_points/kernel.ml b/src/kernel_services/plugin_entry_points/kernel.ml index a7ffdfeb730..d437277a6da 100644 --- a/src/kernel_services/plugin_entry_points/kernel.ml +++ b/src/kernel_services/plugin_entry_points/kernel.ml @@ -1479,6 +1479,15 @@ module InvalidBool = _Bool lvalues." end) +let () = Parameter_customize.set_group analysis_options +let () = Parameter_customize.do_not_reset_on_copy () +module InvalidPointer = + False + (struct + let module_name = "InvalidPointer" + let option_name = "-warn-invalid-pointer" + let help = "generate alarms when invalid pointers are created." + end) (* ************************************************************************* *) (** {2 Sequencing options} *) diff --git a/src/kernel_services/plugin_entry_points/kernel.mli b/src/kernel_services/plugin_entry_points/kernel.mli index 04ef6317f0c..b641349af40 100644 --- a/src/kernel_services/plugin_entry_points/kernel.mli +++ b/src/kernel_services/plugin_entry_points/kernel.mli @@ -549,6 +549,9 @@ module SpecialFloat: Parameter_sig.String module InvalidBool: Parameter_sig.Bool (** Behavior of option "-warn-invalid-bool" *) +module InvalidPointer: Parameter_sig.Bool +(** Behavior of option "-warn-invalid-pointer" *) + module AbsoluteValidRange: Parameter_sig.String (** Behavior of option "-absolute-valid-range" *) -- GitLab From cde12158a17c120e4d9d965a11f006c078fb12c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20B=C3=BChler?= <david.buhler@cea.fr> Date: Thu, 27 Feb 2020 13:33:12 +0100 Subject: [PATCH 036/218] [Eva] Abstract values: new function assume_pointer. --- src/plugins/value/values/abstract_value.mli | 9 ++++++ src/plugins/value/values/cvalue_forward.ml | 29 +++++++++++++++++++ src/plugins/value/values/cvalue_forward.mli | 1 + src/plugins/value/values/main_values.ml | 2 ++ .../value/values/numerors/numerors_value.ml | 1 + src/plugins/value/values/offsm_value.ml | 1 + src/plugins/value/values/sign_value.ml | 1 + src/plugins/value/values/value_product.ml | 5 ++++ 8 files changed, 49 insertions(+) diff --git a/src/plugins/value/values/abstract_value.mli b/src/plugins/value/values/abstract_value.mli index 378c06407ac..bd42be08f83 100644 --- a/src/plugins/value/values/abstract_value.mli +++ b/src/plugins/value/values/abstract_value.mli @@ -92,6 +92,15 @@ module type S = sig floating-point values. *) val assume_not_nan: assume_finite:bool -> fkind -> t -> t truth + (** Assumes that the abstract value only represents well-formed pointer values: + pointers either to an element of an array object or one past the last + element of an array object. (A pointer to an object that is not an element + of an array is viewed as a pointer to the first element of an array of + length one with the type of the object as its element type.) + The NULL pointer is always a valid pointer value. Function pointers are + also considered as valid pointer values for now. *) + val assume_pointer: t -> t truth + (* [assume_comparable cmp v1 v2] assumes that the integer or pointer values [v1] and [v2] are comparable for [cmp]. Integers are always comparable. If one value is a pointer, then both values should be pointers, and: diff --git a/src/plugins/value/values/cvalue_forward.ml b/src/plugins/value/values/cvalue_forward.ml index ad45ab9ddb8..6822e5f5a5c 100644 --- a/src/plugins/value/values/cvalue_forward.ml +++ b/src/plugins/value/values/cvalue_forward.ml @@ -220,6 +220,35 @@ let assume_not_nan ~assume_finite fkind v = let res = Bottom.non_bottom (backward_propagate kind res) in `Unknown (V.inject_float res) +let nearly_valid_bits = function + | Base.Empty + | Base.Invalid -> Integer.zero, Integer.zero + | Base.Known (min, max) | Base.Unknown (min, _, max) -> min, Integer.succ max + | Base.Variable variable -> Integer.zero, Integer.succ variable.Base.max_alloc + +let nearly_valid_offset base = + let min, max = nearly_valid_bits base in + let to_byte bound = Some (Integer.e_div bound (Bit_utils.sizeofchar ())) in + Ival.inject_range (to_byte min) (to_byte max) + +let assume_pointer loc = + let aux base ival (acc_v, acc_ok) = + let validity = Base.validity base in + let nearly_valid_ival = nearly_valid_offset validity in + let new_ival = Ival.narrow ival nearly_valid_ival in + let ival, ok = + if Base.is_null base && Ival.contains_zero ival + then Ival.(join zero new_ival), acc_ok && Ival.is_zero ival + else new_ival, acc_ok && Ival.equal ival new_ival + in + Locations.Location_Bytes.add base ival acc_v, ok + in + try + let loc, ok = Cvalue.V.(fold_topset_ok aux loc (bottom, true)) in + if Cvalue.V.is_bottom loc then `False + else if ok then `True else `Unknown loc + with Abstract_interp.Error_Top -> `Unknown loc + (* -------------------------------------------------------------------------- Integer overflow -------------------------------------------------------------------------- *) diff --git a/src/plugins/value/values/cvalue_forward.mli b/src/plugins/value/values/cvalue_forward.mli index 77b587c28e4..07fb2ef7591 100644 --- a/src/plugins/value/values/cvalue_forward.mli +++ b/src/plugins/value/values/cvalue_forward.mli @@ -31,6 +31,7 @@ val are_comparable: Abstract_interp.Comp.t -> V.t -> V.t -> bool val assume_non_zero: V.t -> V.t truth val assume_bounded: bound_kind -> bound -> V.t -> V.t truth val assume_not_nan: assume_finite:bool -> fkind -> V.t -> V.t truth +val assume_pointer: V.t -> V.t truth val assume_comparable: pointer_comparison -> V.t -> V.t -> (V.t * V.t) truth val forward_binop_int: typ: typ -> V.t -> binop -> V.t -> V.t diff --git a/src/plugins/value/values/main_values.ml b/src/plugins/value/values/main_values.ml index ebd8d3b0989..9218b0a03a3 100644 --- a/src/plugins/value/values/main_values.ml +++ b/src/plugins/value/values/main_values.ml @@ -46,6 +46,7 @@ module CVal = struct let assume_non_zero = Cvalue_forward.assume_non_zero let assume_bounded = Cvalue_forward.assume_bounded let assume_not_nan = Cvalue_forward.assume_not_nan + let assume_pointer = Cvalue_forward.assume_pointer let assume_comparable = Cvalue_forward.assume_comparable let constant exp = function @@ -165,6 +166,7 @@ module Interval = struct let assume_non_zero v = `Unknown v let assume_bounded _ _ v = `Unknown v let assume_not_nan ~assume_finite:_ _ v = `Unknown v + let assume_pointer v = `Unknown v let assume_comparable _ v1 v2 = `Unknown (v1, v2) let constant _ _ = top diff --git a/src/plugins/value/values/numerors/numerors_value.ml b/src/plugins/value/values/numerors/numerors_value.ml index da6a115444b..443a2dd4434 100644 --- a/src/plugins/value/values/numerors/numerors_value.ml +++ b/src/plugins/value/values/numerors/numerors_value.ml @@ -312,6 +312,7 @@ let backward_binop ~input_type:_ ~resulting_type:_ op ~left ~right ~result = let assume_non_zero v = `Unknown v let assume_bounded _kind _bound v = `Unknown v let assume_not_nan ~assume_finite:_ _fkind v = `Unknown v +let assume_pointer v = `Unknown v let assume_comparable _cmp v1 v2 = `Unknown (v1, v2) let rewrap_integer _ _ = top diff --git a/src/plugins/value/values/offsm_value.ml b/src/plugins/value/values/offsm_value.ml index 672025219b7..d6d7995ae35 100644 --- a/src/plugins/value/values/offsm_value.ml +++ b/src/plugins/value/values/offsm_value.ml @@ -423,6 +423,7 @@ module Offsm : Abstract_value.Leaf with type t = offsm_or_top = struct let assume_non_zero v = `Unknown v let assume_bounded _ _ v = `Unknown v let assume_not_nan ~assume_finite:_ _ v = `Unknown v + let assume_pointer v = `Unknown v let assume_comparable _ v1 v2 = `Unknown (v1, v2) let constant e _c = diff --git a/src/plugins/value/values/sign_value.ml b/src/plugins/value/values/sign_value.ml index 58f961a324d..74c45a2c268 100644 --- a/src/plugins/value/values/sign_value.ml +++ b/src/plugins/value/values/sign_value.ml @@ -120,6 +120,7 @@ let assume_non_zero v = let assume_bounded _ _ v = `Unknown v let assume_not_nan ~assume_finite:_ _ v = `Unknown v +let assume_pointer v = `Unknown v let assume_comparable _ v1 v2 = `Unknown (v1, v2) (** {2 Forward transfer functions} *) diff --git a/src/plugins/value/values/value_product.ml b/src/plugins/value/values/value_product.ml index 5b612953614..99d6ff34751 100644 --- a/src/plugins/value/values/value_product.ml +++ b/src/plugins/value/values/value_product.ml @@ -81,6 +81,11 @@ module Make and right_truth = Right.assume_not_nan ~assume_finite fkind right in narrow_truth (left, left_truth) (right, right_truth) + let assume_pointer (left, right) = + let left_truth = Left.assume_pointer left + and right_truth = Right.assume_pointer right in + narrow_truth (left, left_truth) (right, right_truth) + let assume_comparable op (l1, r1) (l2, r2) = let left_truth = Left.assume_comparable op l1 l2 and right_truth = Right.assume_comparable op r1 r2 in -- GitLab From a779f5aedc21fa80e1f872e7a0b6a8d79bef4ab7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20B=C3=BChler?= <david.buhler@cea.fr> Date: Thu, 27 Feb 2020 17:43:27 +0100 Subject: [PATCH 037/218] [Eva] Refactors two functions in the evaluation engine. --- src/plugins/value/engine/evaluation.ml | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/src/plugins/value/engine/evaluation.ml b/src/plugins/value/engine/evaluation.ml index ab391eb3546..ff69569b645 100644 --- a/src/plugins/value/engine/evaluation.ml +++ b/src/plugins/value/engine/evaluation.ml @@ -492,28 +492,25 @@ module Make | Some (Eval_typ.TSPtr _) | None -> return value - (* Removes NaN and infinite floats from the value read from a lvalue. *) - let remove_special_float_lvalue typ lval res = + (* Assumes that [res] is a valid result for the lvalue [lval] of type [typ]. + Removes NaN and infinite floats and trap representations of bool values. *) + let assume_valid_value typ lval res = match typ with | TFloat (fkind, _) -> res >>= fun (value, origin) -> let expr = Value_util.lval_to_exp lval in remove_special_float expr fkind value >>=: fun new_value -> new_value, origin - | _ -> res - - (* Removes invalid bool values from a lvalue. *) - let assume_valid_bool typ lval res = - if not (Kernel.InvalidBool.get ()) then res else - match typ with - | TInt (IBool, _) -> + | TInt (IBool, _) -> + if Kernel.InvalidBool.get () then res >>= fun (value, origin) -> let one = Abstract_value.Int Integer.one in let truth = Value.assume_bounded Alarms.Upper_bound one value in let alarm () = Alarms.Invalid_bool lval in interpret_truth ~alarm value truth >>=: fun new_value -> new_value, origin - | _ -> res + else res + | _ -> res (* Reduce the rhs argument of a shift so that it fits inside [size] bits. *) let reduce_shift_rhs typ expr value = @@ -1068,8 +1065,7 @@ module Make let record, alarms = indeterminate_copy lval v alarms in `Value (record, Neither, volatile), alarms else - let v, alarms = remove_special_float_lvalue typ_lv lval (v, alarms) in - let v, alarms = assume_valid_bool typ_lv lval (v, alarms) in + let v, alarms = assume_valid_value typ_lv lval (v, alarms) in (v, alarms) >>=: fun (value, origin) -> let value = define_value value and origin = Some origin -- GitLab From a5a70d3ff6a5621c90155156571d0d7705a761c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20B=C3=BChler?= <david.buhler@cea.fr> Date: Thu, 27 Feb 2020 13:39:11 +0100 Subject: [PATCH 038/218] [Eva] Evaluation engine: emits alarms at the creation of invalid pointers. Complies with the kernel option -warn-invalid-pointers. --- src/plugins/value/engine/evaluation.ml | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/src/plugins/value/engine/evaluation.ml b/src/plugins/value/engine/evaluation.ml index ff69569b645..5e0445cf0ca 100644 --- a/src/plugins/value/engine/evaluation.ml +++ b/src/plugins/value/engine/evaluation.ml @@ -477,6 +477,14 @@ module Make | "non-finite" -> restrict_float ~assume_finite:true expr fk value | _ -> assert false + let assume_pointer expr value = + if Kernel.InvalidPointer.get () + then + let truth = Value.assume_pointer value in + let alarm () = Alarms.Invalid_pointer expr in + interpret_truth ~alarm value truth + else return value + let handle_overflow ~may_overflow expr typ value = match Eval_typ.classify_as_scalar typ with | Some (Eval_typ.TSInt range) -> @@ -489,7 +497,7 @@ module Make then fst (truncate_integer Alarms.Signed expr range value), Alarmset.none else handle_integer_overflow expr range value | Some (Eval_typ.TSFloat fk) -> remove_special_float expr fk value - | Some (Eval_typ.TSPtr _) + | Some (Eval_typ.TSPtr _) -> assume_pointer expr value | None -> return value (* Assumes that [res] is a valid result for the lvalue [lval] of type [typ]. @@ -510,6 +518,11 @@ module Make interpret_truth ~alarm value truth >>=: fun new_value -> new_value, origin else res + | TPtr _ -> + res >>= fun (value, origin) -> + let expr = Value_util.lval_to_exp lval in + assume_pointer expr value >>=: fun new_value -> + new_value, origin | _ -> res (* Reduce the rhs argument of a shift so that it fits inside [size] bits. *) @@ -871,8 +884,10 @@ module Make | AddrOf v | StartOf v -> lval_to_loc context ~for_writing:false ~reduction:false v - >>=: fun (loc, _, _) -> - Loc.to_value loc, Neither, false + >>= fun (loc, _, _) -> + let value = Loc.to_value loc in + let v = assume_pointer expr value in + compute_reduction v false | UnOp (op, e, typ) -> root_forward_eval context e >>= fun (v, volatile) -> @@ -894,6 +909,7 @@ module Make let v = forward_cast ~dst e value in let v = match Cil.unrollType dst with | TFloat (fkind, _) -> v >>= remove_special_float expr fkind + | TPtr _ -> v >>= assume_pointer expr | _ -> v in compute_reduction v volatile -- GitLab From 3a6f6364171270d58bd926c451604bbceccae857 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20B=C3=BChler?= <david.buhler@cea.fr> Date: Thu, 27 Feb 2020 14:03:08 +0100 Subject: [PATCH 039/218] [Eva] Do not emit redundant invalid_pointer and memory_access alarms. --- src/plugins/value/alarmset.ml | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/plugins/value/alarmset.ml b/src/plugins/value/alarmset.ml index 222eed3099d..21475b79a7a 100644 --- a/src/plugins/value/alarmset.ml +++ b/src/plugins/value/alarmset.ml @@ -399,7 +399,25 @@ let height_alarm = let open Value_util in function let cmp a1 a2 = Datatype.Int.compare (height_alarm (fst a1)) (height_alarm (fst a2)) +let remove_redundant_alarms map = + let filter alarm status = + match alarm with + | Alarms.Invalid_pointer expr -> + let lval = Mem expr, NoOffset in + let implies alarm s = + status = s && + match alarm with + | Alarms.Memory_access (lv, _access_kind) -> + Cil_datatype.LvalStructEq.equal lv lval + | _ -> false + in + not (M.exists implies map) + | _ -> true + in + M.filter filter map + let emit_alarms kinstr map = + let map = remove_redundant_alarms map in let list = M.bindings map in let sorted_list = List.sort cmp list in List.iter (fun (alarm, status) -> emit_alarm kinstr alarm status) sorted_list; -- GitLab From c2a24d6fba11c68cfad86fc1c61059917a0a25ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20B=C3=BChler?= <david.buhler@cea.fr> Date: Thu, 27 Feb 2020 14:11:47 +0100 Subject: [PATCH 040/218] [Eva] Supports \object_pointer predicate in eval_term. --- src/plugins/value/legacy/eval_terms.ml | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/plugins/value/legacy/eval_terms.ml b/src/plugins/value/legacy/eval_terms.ml index 968ec99416c..995160e3482 100644 --- a/src/plugins/value/legacy/eval_terms.ml +++ b/src/plugins/value/legacy/eval_terms.ml @@ -2143,8 +2143,9 @@ let rec reduce_by_predicate ~alarm_mode env positive p = reduce_by_valid env positive Write tsets | _,Pvalid_read (_label,tsets) -> reduce_by_valid env positive Read tsets + | _,Pobject_pointer (_label, tsets) -> + reduce_by_valid env positive No_access tsets - | _,Pobject_pointer (_label, _tsets) -> env (* TODO *) | _,Pvalid_function _tsets -> env (* TODO *) | _,(Pinitialized (lbl_initialized,tsets) @@ -2292,11 +2293,17 @@ and eval_predicate env pred = ignore (env_state env lbl); do_eval { env with e_cur = lbl } p - | Pobject_pointer (_label, _tsets) -> Unknown (* TODO *) - - | Pvalid (_label, tsets) | Pvalid_read (_label, tsets) -> + | Pvalid (_, tsets) + | Pvalid_read (_, tsets) + | Pobject_pointer (_, tsets) -> (* TODO: see same constructor in reduce_by_predicate *) - let kind = match p.pred_content with Pvalid_read _ -> Read | _ -> Write in + let kind = + match p.pred_content with + | Pvalid_read _ -> Read + | Pvalid _ -> Write + | Pobject_pointer _ -> No_access + | _ -> assert false + in let typ_pointed = Logic_typing.ctype_of_pointed tsets.term_type in (* Check if we are trying to write in a const l-value *) if kind = Write && Value_util.is_const_write_invalid typ_pointed -- GitLab From 72781a6353a89c02518480a395a71fac8612d1fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20B=C3=BChler?= <david.buhler@cea.fr> Date: Fri, 28 Feb 2020 16:11:58 +0100 Subject: [PATCH 041/218] [Eva] Base: fixes the possible offsets for the Null base without memory access. When -absolute-valid-range is enabled, the Null base has a Known validity, but a pointer can always points to Null+{0}. --- src/kernel_services/abstract_interp/base.ml | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/kernel_services/abstract_interp/base.ml b/src/kernel_services/abstract_interp/base.ml index e0ff1e50268..226eefc98e5 100644 --- a/src/kernel_services/abstract_interp/base.ml +++ b/src/kernel_services/abstract_interp/base.ml @@ -306,7 +306,14 @@ let offset_for_validity ~bitfield access base = let valid_offset ?(bitfield=true) access base = if for_writing access && is_read_only base then Ival.bottom - else offset_for_validity ~bitfield access base + else + let offset = offset_for_validity ~bitfield access base in + (* When -absolute-valid-range is enabled, the Null base has a Known validity + that does not include 0. In this case, adds 0 as possible offset for a + pointer without memory access. *) + if access = No_access && is_null base + then Ival.(join zero offset) + else offset let offset_is_in_validity access base ival = let is_valid_for_bounds min_bound max_bound = @@ -327,7 +334,8 @@ let offset_is_in_validity access base ival = let is_valid_offset access base offset = Ival.is_bottom offset || not (for_writing access && (is_read_only base)) - && offset_is_in_validity access base offset + && (offset_is_in_validity access base offset + || access = No_access && is_null base && Ival.(equal zero offset)) let is_function base = match base with -- GitLab From efe0045964be2d1ebe2e3f0a01a0bb2a64c019a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20B=C3=BChler?= <david.buhler@cea.fr> Date: Fri, 28 Feb 2020 14:38:10 +0100 Subject: [PATCH 042/218] [Eva] Adds a test for the alarm about the creation of invalid pointers. --- tests/value/invalid_pointer.c | 178 ++++++++ .../value/oracle/invalid_pointer.0.res.oracle | 409 ++++++++++++++++++ .../value/oracle/invalid_pointer.1.res.oracle | 337 +++++++++++++++ 3 files changed, 924 insertions(+) create mode 100644 tests/value/invalid_pointer.c create mode 100644 tests/value/oracle/invalid_pointer.0.res.oracle create mode 100644 tests/value/oracle/invalid_pointer.1.res.oracle diff --git a/tests/value/invalid_pointer.c b/tests/value/invalid_pointer.c new file mode 100644 index 00000000000..bde7ed009dc --- /dev/null +++ b/tests/value/invalid_pointer.c @@ -0,0 +1,178 @@ +/* run.config* + STDOPT: +"-warn-invalid-pointer -absolute-valid-range=10-30" + STDOPT: +"-no-warn-invalid-pointer -absolute-valid-range=10-30" +*/ + +#include <__fc_builtin.h> +#include <stdint.h> + +/* Tests the emission of \object_pointer alarms when -warn-invalid-pointer + is enabled. The second run should emit no alarm. */ + +volatile int undet; + +/* Simple pointer computations. */ +void pointer_computation () { + int x; + int *p = &x; + if (undet) + p--; // Red alarm. + p++; // No alarm. + if (undet) + p++; // Red alarm. + int i = undet; + p += i; // Unknown alarm. [i] should be reduced to {-1, 0}. + int j = undet; + p -= j; // Unknown alarm. [j] should be reduced to {-1, 0, 1}. + p --; // Unknown alarm. [p] should be exactly {&x}. + int array[25]; + int *q = undet ? &x : &array[0]; + int offset1 = Frama_C_interval(0, 10); + q += offset1; // Unknown alarm. [offset1] should not be reduced. + int offset2 = Frama_C_interval(0, 50); + q += offset2; // Unknown alarm. [offset2] should be reduced to [0..25]. + q += 0; // No alarm. +} + +/* Increment or decrement pointers in loops. */ +void pointer_in_loops () { + int t[128]; + int *p = &t[0]; + /*@ loop unroll 128; */ + for (int i = 0; i < 128; i++) { + *p = i; + p++; // No alarm. + } + if (undet) { + int *q = &t[127]; + /*@ loop unroll 128; */ + for (int i = 0; i < 128; i++) { + *q = i; + q--; // Alarm in the last iteration: q points to t[-1]. + } + Frama_C_show_each_bottom(q); // Should not be reached. + } +} + +/* Conversion integer -> pointer. */ +void int_conversion () { + int x, *p; + p = (int *)0; // NULL pointer: always ok. + p = (int *) 20; // Inside -absolute-valid-range: no alarms. + if (undet) { + p = (int *) 42; // Outside -absolute-valid-range: red alarm. + } + x = Frama_C_interval(15, 25); + p = (int *) x; // Inside -absolute-valid-range: no alarms. + x = Frama_C_interval(100, 500); + if (undet) { + p = (int *) x; // Outside -absolute-valid-range: red alarm. + } + x = Frama_C_interval(15, 100); + p = (int *) x; // Unknown alarm. [x] should be reduced to [15..31]. + p = (int *) undet; // Unknown alarm. [p] should be have value in [0..31]. +} + +void addrof () { + int a[10], *p; + p = &(a[0]); + p = &(a[10]); + if (undet) + p = &(a[11]); // Invalid alarm + if (undet) + p = &(a[-1]); // Invalid alarm + int offset = undet; + p = &(a[offset]); /* Unknown alarm. [offset] should be reduced to [0..10]. */ +} + +typedef union { + uintptr_t integer; + int *pointer; +} ptr_union; + +/* Creates invalid pointers through an union. */ +void union_pointer () { + int *p; + ptr_union u; + u.integer = 0; + p = u.pointer; // No alarm. + if (undet) { + u.integer = 42; + p = u.pointer; // Red alarm. + } + u.integer = undet; + p = u.pointer; // Unknown alarm. [u.integer] should be reduced to [0..31]. +} + +/* Creates invalid pointers through untyped writes. */ +void write_pointer () { + int x; + int *p = 0; + *((uintptr_t *) &p) = &x; + int *q = p; // No alarm. + *((uintptr_t *) &p) = (uintptr_t)p + undet; + q = p; // Unknown alarm. + *((uintptr_t *) &p) = 42; + if (undet) { + q = p; // Red alarm. + } +} + +/* Tests the evaluation of the logical predicate \object_pointer when + -warn-invalid-pointer is disabled. */ +void object_pointer_predicate () { + int x, array[64]; + int *p = &x; + /*@ assert \object_pointer(p); */ + if (undet) { + p--; + /*@ assert \object_pointer(p); */ + } + p++; + /*@ assert \object_pointer(p); */ + if (undet) { + p++; + /*@ assert \object_pointer(p); */ + } + p += undet; + /*@ assert \object_pointer(p); */ + /*@ assert \object_pointer(p); */ + Frama_C_show_each_object_pointer(p); + p = (int *)((uintptr_t)&x + undet); + /*@ assert \object_pointer(p); */ + /*@ assert \object_pointer(p); */ + Frama_C_show_each_object_pointer_char(p); + int i = Frama_C_interval(0, 20); + p = undet ? &x : &array[i]; + /*@ assert \object_pointer(p); */ + p += i; + /*@ assert \object_pointer(p); */ + p += undet; + /*@ assert \object_pointer(p); */ + Frama_C_show_each_object_pointer_array(p); + p = (int *) 0; + /*@ assert \object_pointer(p); */ + if (undet) + p = (int *) 20; + /*@ assert \object_pointer(p); */ + if (undet) + p = (int *) 50; + /*@ assert \object_pointer(p); */ + p = (int *) undet; + /*@ assert \object_pointer(p); */ + if (undet) { + p = (int *) 100; + /*@ assert \object_pointer(p); */ + } +} + + +void main () { + pointer_computation (); + pointer_in_loops (); + int_conversion (); + addrof (); + union_pointer (); + write_pointer (); + object_pointer_predicate (); +} diff --git a/tests/value/oracle/invalid_pointer.0.res.oracle b/tests/value/oracle/invalid_pointer.0.res.oracle new file mode 100644 index 00000000000..4f0f2133ff5 --- /dev/null +++ b/tests/value/oracle/invalid_pointer.0.res.oracle @@ -0,0 +1,409 @@ +[kernel] Parsing tests/value/invalid_pointer.c (with preprocessing) +[kernel:typing:int-conversion] tests/value/invalid_pointer.c:111: Warning: + Conversion from a pointer to an integer without an explicit cast +[eva] Analyzing a complete application starting at main +[eva] Computing initial state +[eva] Initial state computed +[eva:initial-state] Values of globals at initialization + NULL[rbits 80 to 247] ∈ [--..--] + undet ∈ [--..--] +[eva] computing for function pointer_computation <- main. + Called from tests/value/invalid_pointer.c:171. +[eva:alarm] tests/value/invalid_pointer.c:19: Warning: + invalid pointer creation. assert \object_pointer(p - 1); +[eva:alarm] tests/value/invalid_pointer.c:22: Warning: + invalid pointer creation. assert \object_pointer(p + 1); +[eva:alarm] tests/value/invalid_pointer.c:24: Warning: + invalid pointer creation. assert \object_pointer(p + i); +[eva:alarm] tests/value/invalid_pointer.c:26: Warning: + invalid pointer creation. assert \object_pointer(p - j); +[eva:alarm] tests/value/invalid_pointer.c:27: Warning: + invalid pointer creation. assert \object_pointer(p - 1); +[eva] computing for function Frama_C_interval <- pointer_computation <- main. + Called from tests/value/invalid_pointer.c:30. +[eva] using specification for function Frama_C_interval +[eva] tests/value/invalid_pointer.c:30: + function Frama_C_interval: precondition 'order' got status valid. +[eva] Done for function Frama_C_interval +[eva:alarm] tests/value/invalid_pointer.c:31: Warning: + invalid pointer creation. assert \object_pointer(q + offset1); +[eva] computing for function Frama_C_interval <- pointer_computation <- main. + Called from tests/value/invalid_pointer.c:32. +[eva] tests/value/invalid_pointer.c:32: + function Frama_C_interval: precondition 'order' got status valid. +[eva] Done for function Frama_C_interval +[eva:alarm] tests/value/invalid_pointer.c:33: Warning: + invalid pointer creation. assert \object_pointer(q + offset2); +[eva] Recording results for pointer_computation +[eva] Done for function pointer_computation +[eva] computing for function pointer_in_loops <- main. + Called from tests/value/invalid_pointer.c:172. +[eva] tests/value/invalid_pointer.c:42: + Trace partitioning superposing up to 100 states +[eva:alarm] tests/value/invalid_pointer.c:51: Warning: + invalid pointer creation. assert \object_pointer(q - 1); +[eva] Recording results for pointer_in_loops +[eva] Done for function pointer_in_loops +[eva] computing for function int_conversion <- main. + Called from tests/value/invalid_pointer.c:173. +[eva:alarm] tests/value/invalid_pointer.c:63: Warning: + invalid pointer creation. assert \object_pointer((int *)42); +[eva] computing for function Frama_C_interval <- int_conversion <- main. + Called from tests/value/invalid_pointer.c:65. +[eva] tests/value/invalid_pointer.c:65: + function Frama_C_interval: precondition 'order' got status valid. +[eva] Done for function Frama_C_interval +[eva] computing for function Frama_C_interval <- int_conversion <- main. + Called from tests/value/invalid_pointer.c:67. +[eva] tests/value/invalid_pointer.c:67: + function Frama_C_interval: precondition 'order' got status valid. +[eva] Done for function Frama_C_interval +[eva:alarm] tests/value/invalid_pointer.c:69: Warning: + invalid pointer creation. assert \object_pointer((int *)x); +[eva] computing for function Frama_C_interval <- int_conversion <- main. + Called from tests/value/invalid_pointer.c:71. +[eva] tests/value/invalid_pointer.c:71: + function Frama_C_interval: precondition 'order' got status valid. +[eva] Done for function Frama_C_interval +[eva:alarm] tests/value/invalid_pointer.c:72: Warning: + invalid pointer creation. assert \object_pointer((int *)x); +[eva:alarm] tests/value/invalid_pointer.c:73: Warning: + invalid pointer creation. assert \object_pointer((int *)undet); +[eva] Recording results for int_conversion +[eva] Done for function int_conversion +[eva] computing for function addrof <- main. + Called from tests/value/invalid_pointer.c:174. +[eva:alarm] tests/value/invalid_pointer.c:81: Warning: + invalid pointer creation. assert \object_pointer(&a[11]); +[eva:alarm] tests/value/invalid_pointer.c:83: Warning: + invalid pointer creation. assert \object_pointer(&a[(int)(-1)]); +[eva:alarm] tests/value/invalid_pointer.c:85: Warning: + invalid pointer creation. assert \object_pointer(&a[offset]); +[eva] Recording results for addrof +[eva] Done for function addrof +[eva] computing for function union_pointer <- main. + Called from tests/value/invalid_pointer.c:175. +[eva:alarm] tests/value/invalid_pointer.c:101: Warning: + invalid pointer creation. assert \object_pointer(u.pointer); +[eva:alarm] tests/value/invalid_pointer.c:104: Warning: + invalid pointer creation. assert \object_pointer(u.pointer); +[eva] Recording results for union_pointer +[eva] Done for function union_pointer +[eva] computing for function write_pointer <- main. + Called from tests/value/invalid_pointer.c:176. +[eva:alarm] tests/value/invalid_pointer.c:114: Warning: + invalid pointer creation. assert \object_pointer(p); +[eva:alarm] tests/value/invalid_pointer.c:117: Warning: + invalid pointer creation. assert \object_pointer(p); +[eva] Recording results for write_pointer +[eva] Done for function write_pointer +[eva] computing for function object_pointer_predicate <- main. + Called from tests/value/invalid_pointer.c:177. +[eva] tests/value/invalid_pointer.c:126: assertion got status valid. +[eva:alarm] tests/value/invalid_pointer.c:128: Warning: + invalid pointer creation. assert \object_pointer(p - 1); +[eva] tests/value/invalid_pointer.c:132: assertion got status valid. +[eva:alarm] tests/value/invalid_pointer.c:134: Warning: + invalid pointer creation. assert \object_pointer(p + 1); +[eva:alarm] tests/value/invalid_pointer.c:137: Warning: + invalid pointer creation. assert \object_pointer(p + undet); +[eva] tests/value/invalid_pointer.c:138: assertion got status valid. +[eva] tests/value/invalid_pointer.c:139: assertion got status valid. +[eva] tests/value/invalid_pointer.c:140: + Frama_C_show_each_object_pointer: {{ &x + {0; 4} }} +[eva:alarm] tests/value/invalid_pointer.c:141: Warning: + invalid pointer creation. + assert + \object_pointer((int *)((unsigned int)((unsigned int)(&x) + + (unsigned int)undet))); +[eva] tests/value/invalid_pointer.c:142: assertion got status valid. +[eva] tests/value/invalid_pointer.c:143: assertion got status valid. +[eva] tests/value/invalid_pointer.c:144: + Frama_C_show_each_object_pointer_char: {{ &x + {0; 1; 2; 3; 4} }} +[eva] computing for function Frama_C_interval <- object_pointer_predicate <- main. + Called from tests/value/invalid_pointer.c:145. +[eva] tests/value/invalid_pointer.c:145: + function Frama_C_interval: precondition 'order' got status valid. +[eva] Done for function Frama_C_interval +[eva] tests/value/invalid_pointer.c:147: assertion got status valid. +[eva:alarm] tests/value/invalid_pointer.c:148: Warning: + invalid pointer creation. assert \object_pointer(p + i); +[eva] tests/value/invalid_pointer.c:149: assertion got status valid. +[eva:alarm] tests/value/invalid_pointer.c:150: Warning: + invalid pointer creation. assert \object_pointer(p + undet); +[eva] tests/value/invalid_pointer.c:151: assertion got status valid. +[eva] tests/value/invalid_pointer.c:152: + Frama_C_show_each_object_pointer_array: + {{ &x + {0; 4} ; &array + [0..256],0%4 }} +[eva] tests/value/invalid_pointer.c:154: assertion got status valid. +[eva:alarm] tests/value/invalid_pointer.c:157: Warning: + assertion got status unknown. +[eva:alarm] tests/value/invalid_pointer.c:159: Warning: + invalid pointer creation. assert \object_pointer((int *)50); +[eva:alarm] tests/value/invalid_pointer.c:160: Warning: + assertion got status unknown. +[eva:alarm] tests/value/invalid_pointer.c:161: Warning: + invalid pointer creation. assert \object_pointer((int *)undet); +[eva:alarm] tests/value/invalid_pointer.c:162: Warning: + assertion got status unknown. +[eva:alarm] tests/value/invalid_pointer.c:164: Warning: + invalid pointer creation. assert \object_pointer((int *)100); +[eva] Recording results for object_pointer_predicate +[eva] Done for function object_pointer_predicate +[eva] Recording results for main +[eva] done for function main +[eva] tests/value/invalid_pointer.c:19: + assertion 'Eva,pointer_value' got final status invalid. +[eva] tests/value/invalid_pointer.c:22: + assertion 'Eva,pointer_value' got final status invalid. +[eva] tests/value/invalid_pointer.c:63: + assertion 'Eva,pointer_value' got final status invalid. +[eva] tests/value/invalid_pointer.c:69: + assertion 'Eva,pointer_value' got final status invalid. +[eva] tests/value/invalid_pointer.c:81: + assertion 'Eva,pointer_value' got final status invalid. +[eva] tests/value/invalid_pointer.c:83: + assertion 'Eva,pointer_value' got final status invalid. +[eva] tests/value/invalid_pointer.c:101: + assertion 'Eva,pointer_value' got final status invalid. +[eva] tests/value/invalid_pointer.c:117: + assertion 'Eva,pointer_value' got final status invalid. +[eva] tests/value/invalid_pointer.c:128: + assertion 'Eva,pointer_value' got final status invalid. +[eva] tests/value/invalid_pointer.c:134: + assertion 'Eva,pointer_value' got final status invalid. +[eva] tests/value/invalid_pointer.c:159: + assertion 'Eva,pointer_value' got final status invalid. +[eva] tests/value/invalid_pointer.c:164: + assertion 'Eva,pointer_value' got final status invalid. +[scope:rm_asserts] removing 2 assertion(s) +[eva] ====== VALUES COMPUTED ====== +[eva:final-states] Values at end of function addrof: + p ∈ {{ &a + [0..40],0%4 }} + offset ∈ [--..--] +[eva:final-states] Values at end of function int_conversion: + Frama_C_entropy_source ∈ [--..--] + x ∈ [15..31] + p ∈ [0..31] +[eva:final-states] Values at end of function object_pointer_predicate: + Frama_C_entropy_source ∈ [--..--] + p ∈ [0..31] + i ∈ [0..20] +[eva:final-states] Values at end of function pointer_computation: + Frama_C_entropy_source ∈ [--..--] + p ∈ {{ &x }} + i ∈ {-1; 0} + j ∈ {-1; 0; 1} + q ∈ {{ &x + {0; 4} ; &array + [0..100],0%4 }} + offset1 ∈ [0..10] + offset2 ∈ [0..25] +[eva:final-states] Values at end of function pointer_in_loops: + t[0] ∈ {0} + [1] ∈ {1} + [2] ∈ {2} + [3] ∈ {3} + [4] ∈ {4} + [5] ∈ {5} + [6] ∈ {6} + [7] ∈ {7} + [8] ∈ {8} + [9] ∈ {9} + [10] ∈ {10} + [11] ∈ {11} + [12] ∈ {12} + [13] ∈ {13} + [14] ∈ {14} + [15] ∈ {15} + [16] ∈ {16} + [17] ∈ {17} + [18] ∈ {18} + [19] ∈ {19} + [20] ∈ {20} + [21] ∈ {21} + [22] ∈ {22} + [23] ∈ {23} + [24] ∈ {24} + [25] ∈ {25} + [26] ∈ {26} + [27] ∈ {27} + [28] ∈ {28} + [29] ∈ {29} + [30] ∈ {30} + [31] ∈ {31} + [32] ∈ {32} + [33] ∈ {33} + [34] ∈ {34} + [35] ∈ {35} + [36] ∈ {36} + [37] ∈ {37} + [38] ∈ {38} + [39] ∈ {39} + [40] ∈ {40} + [41] ∈ {41} + [42] ∈ {42} + [43] ∈ {43} + [44] ∈ {44} + [45] ∈ {45} + [46] ∈ {46} + [47] ∈ {47} + [48] ∈ {48} + [49] ∈ {49} + [50] ∈ {50} + [51] ∈ {51} + [52] ∈ {52} + [53] ∈ {53} + [54] ∈ {54} + [55] ∈ {55} + [56] ∈ {56} + [57] ∈ {57} + [58] ∈ {58} + [59] ∈ {59} + [60] ∈ {60} + [61] ∈ {61} + [62] ∈ {62} + [63] ∈ {63} + [64] ∈ {64} + [65] ∈ {65} + [66] ∈ {66} + [67] ∈ {67} + [68] ∈ {68} + [69] ∈ {69} + [70] ∈ {70} + [71] ∈ {71} + [72] ∈ {72} + [73] ∈ {73} + [74] ∈ {74} + [75] ∈ {75} + [76] ∈ {76} + [77] ∈ {77} + [78] ∈ {78} + [79] ∈ {79} + [80] ∈ {80} + [81] ∈ {81} + [82] ∈ {82} + [83] ∈ {83} + [84] ∈ {84} + [85] ∈ {85} + [86] ∈ {86} + [87] ∈ {87} + [88] ∈ {88} + [89] ∈ {89} + [90] ∈ {90} + [91] ∈ {91} + [92] ∈ {92} + [93] ∈ {93} + [94] ∈ {94} + [95] ∈ {95} + [96] ∈ {96} + [97] ∈ {97} + [98] ∈ {98} + [99] ∈ {99} + [100] ∈ {100} + [101] ∈ {101} + [102] ∈ {102} + [103] ∈ {103} + [104] ∈ {104} + [105] ∈ {105} + [106] ∈ {106} + [107] ∈ {107} + [108] ∈ {108} + [109] ∈ {109} + [110] ∈ {110} + [111] ∈ {111} + [112] ∈ {112} + [113] ∈ {113} + [114] ∈ {114} + [115] ∈ {115} + [116] ∈ {116} + [117] ∈ {117} + [118] ∈ {118} + [119] ∈ {119} + [120] ∈ {120} + [121] ∈ {121} + [122] ∈ {122} + [123] ∈ {123} + [124] ∈ {124} + [125] ∈ {125} + [126] ∈ {126} + [127] ∈ {127} + p ∈ {{ &t[128] }} +[eva:final-states] Values at end of function union_pointer: + p ∈ [0..31] + u{.integer; .pointer} ∈ [0..31] +[eva:final-states] Values at end of function write_pointer: + p ∈ {42} + q ∈ {{ &x + {0; 1; 2; 3; 4} }} +[eva:final-states] Values at end of function main: + Frama_C_entropy_source ∈ [--..--] +[from] Computing for function addrof +[from] Done for function addrof +[from] Computing for function int_conversion +[from] Computing for function Frama_C_interval <-int_conversion +[from] Done for function Frama_C_interval +[from] Done for function int_conversion +[from] Computing for function object_pointer_predicate +[from] Done for function object_pointer_predicate +[from] Computing for function pointer_computation +[from] Done for function pointer_computation +[from] Computing for function pointer_in_loops +[from] Done for function pointer_in_loops +[from] Computing for function union_pointer +[from] Done for function union_pointer +[from] Computing for function write_pointer +[from] Done for function write_pointer +[from] Computing for function main +[from] Done for function main +[from] ====== DEPENDENCIES COMPUTED ====== + These dependencies hold at termination for the executions that terminate: +[from] Function Frama_C_interval: + Frama_C_entropy_source FROM Frama_C_entropy_source (and SELF) + \result FROM Frama_C_entropy_source; min; max +[from] Function addrof: + NO EFFECTS +[from] Function int_conversion: + Frama_C_entropy_source FROM Frama_C_entropy_source (and SELF) +[from] Function object_pointer_predicate: + Frama_C_entropy_source FROM Frama_C_entropy_source (and SELF) +[from] Function pointer_computation: + Frama_C_entropy_source FROM Frama_C_entropy_source (and SELF) +[from] Function pointer_in_loops: + NO EFFECTS +[from] Function union_pointer: + NO EFFECTS +[from] Function write_pointer: + NO EFFECTS +[from] Function main: + Frama_C_entropy_source FROM Frama_C_entropy_source (and SELF) +[from] ====== END OF DEPENDENCIES ====== +[inout] Out (internal) for function addrof: + p; offset +[inout] Inputs for function addrof: + undet +[inout] Out (internal) for function int_conversion: + Frama_C_entropy_source; x; p +[inout] Inputs for function int_conversion: + Frama_C_entropy_source; undet +[inout] Out (internal) for function object_pointer_predicate: + Frama_C_entropy_source; p; i +[inout] Inputs for function object_pointer_predicate: + Frama_C_entropy_source; undet +[inout] Out (internal) for function pointer_computation: + Frama_C_entropy_source; p; i; j; q; tmp; offset1; offset2 +[inout] Inputs for function pointer_computation: + Frama_C_entropy_source; undet +[inout] Out (internal) for function pointer_in_loops: + t[0..127]; p; i; q; i_0 +[inout] Inputs for function pointer_in_loops: + undet +[inout] Out (internal) for function union_pointer: + p; u +[inout] Inputs for function union_pointer: + undet +[inout] Out (internal) for function write_pointer: + p; q +[inout] Inputs for function write_pointer: + undet +[inout] Out (internal) for function main: + Frama_C_entropy_source +[inout] Inputs for function main: + Frama_C_entropy_source; undet diff --git a/tests/value/oracle/invalid_pointer.1.res.oracle b/tests/value/oracle/invalid_pointer.1.res.oracle new file mode 100644 index 00000000000..ccb4096a72d --- /dev/null +++ b/tests/value/oracle/invalid_pointer.1.res.oracle @@ -0,0 +1,337 @@ +[kernel] Parsing tests/value/invalid_pointer.c (with preprocessing) +[kernel:typing:int-conversion] tests/value/invalid_pointer.c:111: Warning: + Conversion from a pointer to an integer without an explicit cast +[eva] Analyzing a complete application starting at main +[eva] Computing initial state +[eva] Initial state computed +[eva:initial-state] Values of globals at initialization + NULL[rbits 80 to 247] ∈ [--..--] + undet ∈ [--..--] +[eva] computing for function pointer_computation <- main. + Called from tests/value/invalid_pointer.c:171. +[eva] computing for function Frama_C_interval <- pointer_computation <- main. + Called from tests/value/invalid_pointer.c:30. +[eva] using specification for function Frama_C_interval +[eva] tests/value/invalid_pointer.c:30: + function Frama_C_interval: precondition 'order' got status valid. +[eva] Done for function Frama_C_interval +[eva] computing for function Frama_C_interval <- pointer_computation <- main. + Called from tests/value/invalid_pointer.c:32. +[eva] tests/value/invalid_pointer.c:32: + function Frama_C_interval: precondition 'order' got status valid. +[eva] Done for function Frama_C_interval +[eva] Recording results for pointer_computation +[eva] Done for function pointer_computation +[eva] computing for function pointer_in_loops <- main. + Called from tests/value/invalid_pointer.c:172. +[eva] tests/value/invalid_pointer.c:42: + Trace partitioning superposing up to 100 states +[eva] tests/value/invalid_pointer.c:53: + Frama_C_show_each_bottom: {{ &t + {-4} }} +[eva] Recording results for pointer_in_loops +[eva] Done for function pointer_in_loops +[eva] computing for function int_conversion <- main. + Called from tests/value/invalid_pointer.c:173. +[eva] computing for function Frama_C_interval <- int_conversion <- main. + Called from tests/value/invalid_pointer.c:65. +[eva] tests/value/invalid_pointer.c:65: + function Frama_C_interval: precondition 'order' got status valid. +[eva] Done for function Frama_C_interval +[eva] computing for function Frama_C_interval <- int_conversion <- main. + Called from tests/value/invalid_pointer.c:67. +[eva] tests/value/invalid_pointer.c:67: + function Frama_C_interval: precondition 'order' got status valid. +[eva] Done for function Frama_C_interval +[eva] computing for function Frama_C_interval <- int_conversion <- main. + Called from tests/value/invalid_pointer.c:71. +[eva] tests/value/invalid_pointer.c:71: + function Frama_C_interval: precondition 'order' got status valid. +[eva] Done for function Frama_C_interval +[eva] Recording results for int_conversion +[eva] Done for function int_conversion +[eva] computing for function addrof <- main. + Called from tests/value/invalid_pointer.c:174. +[eva] Recording results for addrof +[eva] Done for function addrof +[eva] computing for function union_pointer <- main. + Called from tests/value/invalid_pointer.c:175. +[eva] Recording results for union_pointer +[eva] Done for function union_pointer +[eva] computing for function write_pointer <- main. + Called from tests/value/invalid_pointer.c:176. +[eva] Recording results for write_pointer +[eva] Done for function write_pointer +[eva] computing for function object_pointer_predicate <- main. + Called from tests/value/invalid_pointer.c:177. +[eva] tests/value/invalid_pointer.c:126: assertion got status valid. +[eva:alarm] tests/value/invalid_pointer.c:129: Warning: + assertion got status invalid (stopping propagation). +[eva] tests/value/invalid_pointer.c:132: assertion got status valid. +[eva:alarm] tests/value/invalid_pointer.c:135: Warning: + assertion got status invalid (stopping propagation). +[eva:alarm] tests/value/invalid_pointer.c:138: Warning: + assertion got status unknown. +[eva] tests/value/invalid_pointer.c:139: assertion got status valid. +[eva] tests/value/invalid_pointer.c:140: + Frama_C_show_each_object_pointer: {{ &x + {0; 4} }} +[eva:alarm] tests/value/invalid_pointer.c:142: Warning: + assertion got status unknown. +[eva] tests/value/invalid_pointer.c:143: assertion got status valid. +[eva] tests/value/invalid_pointer.c:144: + Frama_C_show_each_object_pointer_char: {{ &x + {0; 1; 2; 3; 4} }} +[eva] computing for function Frama_C_interval <- object_pointer_predicate <- main. + Called from tests/value/invalid_pointer.c:145. +[eva] tests/value/invalid_pointer.c:145: + function Frama_C_interval: precondition 'order' got status valid. +[eva] Done for function Frama_C_interval +[eva] tests/value/invalid_pointer.c:147: assertion got status valid. +[eva:alarm] tests/value/invalid_pointer.c:149: Warning: + assertion got status unknown. +[eva:alarm] tests/value/invalid_pointer.c:151: Warning: + assertion got status unknown. +[eva] tests/value/invalid_pointer.c:152: + Frama_C_show_each_object_pointer_array: + {{ &x + {0; 4} ; &array + [0..256],0%4 }} +[eva] tests/value/invalid_pointer.c:154: assertion got status valid. +[eva:alarm] tests/value/invalid_pointer.c:157: Warning: + assertion got status unknown. +[eva:alarm] tests/value/invalid_pointer.c:160: Warning: + assertion got status unknown. +[eva:alarm] tests/value/invalid_pointer.c:162: Warning: + assertion got status unknown. +[eva:alarm] tests/value/invalid_pointer.c:165: Warning: + assertion got status invalid (stopping propagation). +[eva] Recording results for object_pointer_predicate +[eva] Done for function object_pointer_predicate +[eva] Recording results for main +[eva] done for function main +[scope:rm_asserts] removing 2 assertion(s) +[eva] ====== VALUES COMPUTED ====== +[eva:final-states] Values at end of function addrof: + p ∈ {{ &a + [-8589934592..8589934588],0%4 }} + offset ∈ [--..--] +[eva:final-states] Values at end of function int_conversion: + Frama_C_entropy_source ∈ [--..--] + x ∈ [15..100] + p ∈ [--..--] +[eva:final-states] Values at end of function object_pointer_predicate: + Frama_C_entropy_source ∈ [--..--] + p ∈ [0..31] + i ∈ [0..20] +[eva:final-states] Values at end of function pointer_computation: + Frama_C_entropy_source ∈ [--..--] + p ∈ {{ &x + [-17179869184..17179869184],0%4 }} + i ∈ [--..--] + j ∈ [--..--] + q ∈ {{ &x + [0..240],0%4 ; &array + [0..240],0%4 }} + offset1 ∈ [0..10] + offset2 ∈ [0..50] +[eva:final-states] Values at end of function pointer_in_loops: + t[0] ∈ {0; 127} + [1] ∈ {1; 126} + [2] ∈ {2; 125} + [3] ∈ {3; 124} + [4] ∈ {4; 123} + [5] ∈ {5; 122} + [6] ∈ {6; 121} + [7] ∈ {7; 120} + [8] ∈ {8; 119} + [9] ∈ {9; 118} + [10] ∈ {10; 117} + [11] ∈ {11; 116} + [12] ∈ {12; 115} + [13] ∈ {13; 114} + [14] ∈ {14; 113} + [15] ∈ {15; 112} + [16] ∈ {16; 111} + [17] ∈ {17; 110} + [18] ∈ {18; 109} + [19] ∈ {19; 108} + [20] ∈ {20; 107} + [21] ∈ {21; 106} + [22] ∈ {22; 105} + [23] ∈ {23; 104} + [24] ∈ {24; 103} + [25] ∈ {25; 102} + [26] ∈ {26; 101} + [27] ∈ {27; 100} + [28] ∈ {28; 99} + [29] ∈ {29; 98} + [30] ∈ {30; 97} + [31] ∈ {31; 96} + [32] ∈ {32; 95} + [33] ∈ {33; 94} + [34] ∈ {34; 93} + [35] ∈ {35; 92} + [36] ∈ {36; 91} + [37] ∈ {37; 90} + [38] ∈ {38; 89} + [39] ∈ {39; 88} + [40] ∈ {40; 87} + [41] ∈ {41; 86} + [42] ∈ {42; 85} + [43] ∈ {43; 84} + [44] ∈ {44; 83} + [45] ∈ {45; 82} + [46] ∈ {46; 81} + [47] ∈ {47; 80} + [48] ∈ {48; 79} + [49] ∈ {49; 78} + [50] ∈ {50; 77} + [51] ∈ {51; 76} + [52] ∈ {52; 75} + [53] ∈ {53; 74} + [54] ∈ {54; 73} + [55] ∈ {55; 72} + [56] ∈ {56; 71} + [57] ∈ {57; 70} + [58] ∈ {58; 69} + [59] ∈ {59; 68} + [60] ∈ {60; 67} + [61] ∈ {61; 66} + [62] ∈ {62; 65} + [63..64] ∈ {63; 64} + [65] ∈ {62; 65} + [66] ∈ {61; 66} + [67] ∈ {60; 67} + [68] ∈ {59; 68} + [69] ∈ {58; 69} + [70] ∈ {57; 70} + [71] ∈ {56; 71} + [72] ∈ {55; 72} + [73] ∈ {54; 73} + [74] ∈ {53; 74} + [75] ∈ {52; 75} + [76] ∈ {51; 76} + [77] ∈ {50; 77} + [78] ∈ {49; 78} + [79] ∈ {48; 79} + [80] ∈ {47; 80} + [81] ∈ {46; 81} + [82] ∈ {45; 82} + [83] ∈ {44; 83} + [84] ∈ {43; 84} + [85] ∈ {42; 85} + [86] ∈ {41; 86} + [87] ∈ {40; 87} + [88] ∈ {39; 88} + [89] ∈ {38; 89} + [90] ∈ {37; 90} + [91] ∈ {36; 91} + [92] ∈ {35; 92} + [93] ∈ {34; 93} + [94] ∈ {33; 94} + [95] ∈ {32; 95} + [96] ∈ {31; 96} + [97] ∈ {30; 97} + [98] ∈ {29; 98} + [99] ∈ {28; 99} + [100] ∈ {27; 100} + [101] ∈ {26; 101} + [102] ∈ {25; 102} + [103] ∈ {24; 103} + [104] ∈ {23; 104} + [105] ∈ {22; 105} + [106] ∈ {21; 106} + [107] ∈ {20; 107} + [108] ∈ {19; 108} + [109] ∈ {18; 109} + [110] ∈ {17; 110} + [111] ∈ {16; 111} + [112] ∈ {15; 112} + [113] ∈ {14; 113} + [114] ∈ {13; 114} + [115] ∈ {12; 115} + [116] ∈ {11; 116} + [117] ∈ {10; 117} + [118] ∈ {9; 118} + [119] ∈ {8; 119} + [120] ∈ {7; 120} + [121] ∈ {6; 121} + [122] ∈ {5; 122} + [123] ∈ {4; 123} + [124] ∈ {3; 124} + [125] ∈ {2; 125} + [126] ∈ {1; 126} + [127] ∈ {0; 127} + p ∈ {{ &t[128] }} +[eva:final-states] Values at end of function union_pointer: + p ∈ [--..--] + u ∈ [--..--] +[eva:final-states] Values at end of function write_pointer: + p ∈ {42} + q ∈ {{ NULL + {42} ; &x + [0..4294967295] }} +[eva:final-states] Values at end of function main: + Frama_C_entropy_source ∈ [--..--] +[from] Computing for function addrof +[from] Done for function addrof +[from] Computing for function int_conversion +[from] Computing for function Frama_C_interval <-int_conversion +[from] Done for function Frama_C_interval +[from] Done for function int_conversion +[from] Computing for function object_pointer_predicate +[from] Done for function object_pointer_predicate +[from] Computing for function pointer_computation +[from] Done for function pointer_computation +[from] Computing for function pointer_in_loops +[from] Done for function pointer_in_loops +[from] Computing for function union_pointer +[from] Done for function union_pointer +[from] Computing for function write_pointer +[from] Done for function write_pointer +[from] Computing for function main +[from] Done for function main +[from] ====== DEPENDENCIES COMPUTED ====== + These dependencies hold at termination for the executions that terminate: +[from] Function Frama_C_interval: + Frama_C_entropy_source FROM Frama_C_entropy_source (and SELF) + \result FROM Frama_C_entropy_source; min; max +[from] Function addrof: + NO EFFECTS +[from] Function int_conversion: + Frama_C_entropy_source FROM Frama_C_entropy_source (and SELF) +[from] Function object_pointer_predicate: + Frama_C_entropy_source FROM Frama_C_entropy_source (and SELF) +[from] Function pointer_computation: + Frama_C_entropy_source FROM Frama_C_entropy_source (and SELF) +[from] Function pointer_in_loops: + NO EFFECTS +[from] Function union_pointer: + NO EFFECTS +[from] Function write_pointer: + NO EFFECTS +[from] Function main: + Frama_C_entropy_source FROM Frama_C_entropy_source (and SELF) +[from] ====== END OF DEPENDENCIES ====== +[inout] Out (internal) for function addrof: + p; offset +[inout] Inputs for function addrof: + undet +[inout] Out (internal) for function int_conversion: + Frama_C_entropy_source; x; p +[inout] Inputs for function int_conversion: + Frama_C_entropy_source; undet +[inout] Out (internal) for function object_pointer_predicate: + Frama_C_entropy_source; p; i +[inout] Inputs for function object_pointer_predicate: + Frama_C_entropy_source; undet +[inout] Out (internal) for function pointer_computation: + Frama_C_entropy_source; p; i; j; q; tmp; offset1; offset2 +[inout] Inputs for function pointer_computation: + Frama_C_entropy_source; undet +[inout] Out (internal) for function pointer_in_loops: + t[0..127]; p; i; q; i_0 +[inout] Inputs for function pointer_in_loops: + undet +[inout] Out (internal) for function union_pointer: + p; u +[inout] Inputs for function union_pointer: + undet +[inout] Out (internal) for function write_pointer: + p; q +[inout] Inputs for function write_pointer: + undet +[inout] Out (internal) for function main: + Frama_C_entropy_source +[inout] Inputs for function main: + Frama_C_entropy_source; undet -- GitLab From 8c94ad72e7479cb3d6ec36fddc7a70c56b1caf3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20B=C3=BChler?= <david.buhler@cea.fr> Date: Tue, 3 Mar 2020 18:05:43 +0100 Subject: [PATCH 043/218] [Kernel] Cabs2cil: inlines the C offsetof macro before the analyses. In order to avoid an undefined behavior in the C code generated for this macro (conversion from an absolute integer to a pointer). --- src/kernel_internals/parsing/cparser.mly | 9 +++++++- src/kernel_internals/typing/cabs2cil.ml | 22 +++++++++++++++++++ .../ast_printing/cil_printer.ml | 17 ++++++++++++++ src/kernel_services/ast_queries/cil.ml | 13 ----------- tests/misc/oracle/pragma-pack.0.res.oracle | 2 ++ tests/misc/oracle/pragma-pack.1.res.oracle | 2 ++ tests/misc/oracle/pragma-pack.2.res.oracle | 2 ++ .../misc/oracle/pragma_pack_zero.0.res.oracle | 2 ++ .../misc/oracle/pragma_pack_zero.1.res.oracle | 2 ++ tests/syntax/oracle/offsetof.res.oracle | 7 +++--- .../value/oracle/attribute-aligned.res.oracle | 2 ++ 11 files changed, 62 insertions(+), 18 deletions(-) diff --git a/src/kernel_internals/parsing/cparser.mly b/src/kernel_internals/parsing/cparser.mly index 666053a2830..fadfd5c5949 100644 --- a/src/kernel_internals/parsing/cparser.mly +++ b/src/kernel_internals/parsing/cparser.mly @@ -566,7 +566,14 @@ postfix_expression: /*(* 6.5.2 *)*/ { expr_loc = loc2; expr_node = TYPE_SIZEOF(b2,d2)}],[])) } | BUILTIN_OFFSETOF LPAREN type_name COMMA offsetof_member_designator RPAREN - { transformOffsetOf $3 $5 } + { + let loc_f = Cil_datatype.Location.of_lexing_loc (Parsing.rhs_start_pos 1, Parsing.rhs_end_pos 1) in + let arg = transformOffsetOf $3 $5 in + let builtin = { expr_loc = loc_f; + expr_node = VARIABLE "__builtin_offsetof" } + in + make_expr (CALL (builtin, [ arg ], [])) + } | postfix_expression DOT id_or_typename { make_expr (MEMBEROF ($1, $3))} | postfix_expression ARROW id_or_typename { make_expr (MEMBEROFPTR ($1, $3)) } | postfix_expression PLUS_PLUS { make_expr (UNARY (POSINCR, $1)) } diff --git a/src/kernel_internals/typing/cabs2cil.ml b/src/kernel_internals/typing/cabs2cil.ml index 42b88e95e86..39a07c2eb0e 100644 --- a/src/kernel_internals/typing/cabs2cil.ml +++ b/src/kernel_internals/typing/cabs2cil.ml @@ -7026,6 +7026,28 @@ and doExp local_env Kernel.warning ~current:true "Invalid call to builtin_constant_p") end + | "__builtin_offsetof" -> + begin + match !pargs with + | [{ enode = CastE (_, {enode = AddrOf (host, offset)}) } as e] -> + begin + piscall := false; + prestype := Cil.theMachine.Cil.typeOfSizeOf; + try + let typ = Cil.typeOfLhost host in + let start, _width = Cil.bitsOffset typ offset in + if start mod 8 <> 0 then + Kernel.error ~current:true "Using offset of bitfield"; + let kind = Cil.theMachine.kindOfSizeOf in + pres := Cil.kinteger ~loc:e.eloc kind (start / 8); + with SizeOfError _ -> + pres := e; + Kernel.warning ~once:true ~current:true + "Invalid call to builtin_offsetof"; + end + | _ -> + Kernel.abort ~current:true "Invalid call to builtin_offsetof"; + end | "__builtin_types_compatible_p" -> begin (* Constant-fold the argument and see if it is a constant *) diff --git a/src/kernel_services/ast_printing/cil_printer.ml b/src/kernel_services/ast_printing/cil_printer.ml index aef50199843..8bb7a5f20ef 100644 --- a/src/kernel_services/ast_printing/cil_printer.ml +++ b/src/kernel_services/ast_printing/cil_printer.ml @@ -1047,6 +1047,23 @@ class cil_printer () = object (self) "__builtin_types_compatible_p: cabs2cil should have added sizeof to \ the arguments." + | Call(dest, {enode = Lval (Var vi, NoOffset)}, [ arg ], (l, _)) + when vi.vname = "__builtin_offsetof" + && not state.print_cil_as_is -> + begin + match arg.enode with + | CastE (_, { enode = AddrOf (host, offset) }) -> + (* Print the destination *) + Extlib.may (fprintf fmt "%a = " self#lval) dest; + (* Now the call itself *) + fprintf fmt "%a(%a, %a)%s" + self#varname vi.vname + (self#typ None) (Cil.typeOfLhost host) + self#offset offset + instr_terminator + | _ -> Kernel.fatal ~source:l "__builtin_offsetof: invalid argument." + end + | Call(dest,e,args,_) -> pp_call dest e fmt args | Asm(attrs, tmpls, ext_asm, l) -> diff --git a/src/kernel_services/ast_queries/cil.ml b/src/kernel_services/ast_queries/cil.ml index 459570e1be6..91afc7abef7 100644 --- a/src/kernel_services/ast_queries/cil.ml +++ b/src/kernel_services/ast_queries/cil.ml @@ -4509,19 +4509,6 @@ and constFold (machdep: bool) (e: exp) : exp = | AlignOfE _ | AlignOf _ | SizeOfStr _ | SizeOfE _ | SizeOf _ -> e (* Depends on machdep. Do not evaluate in this case*) - (* Special case to handle the C macro 'offsetof' *) - | CastE(it, - { enode = AddrOf (Mem ({enode = CastE(TPtr(bt, _), z)}), off)}) - when machdep && isZero z -> begin - try - let start, _width = bitsOffset bt off in - if start mod 8 <> 0 then - Kernel.error ~current:true "Using offset of bitfield" ; - constFold machdep - (new_exp ~loc (CastE(it, (integer ~loc (start / 8))))) - with SizeOfError _ -> e - end - | CastE (t, e) -> begin Kernel.debug ~dkey "ConstFold CAST to %a@." !pp_typ_ref t ; let e = constFold machdep e in diff --git a/tests/misc/oracle/pragma-pack.0.res.oracle b/tests/misc/oracle/pragma-pack.0.res.oracle index 8688b345c3b..f3f41b911f7 100644 --- a/tests/misc/oracle/pragma-pack.0.res.oracle +++ b/tests/misc/oracle/pragma-pack.0.res.oracle @@ -87,6 +87,8 @@ adding aligned(1) attribute to field 'PACKOVERPOP.j' due to packing pragma [kernel:typing:pragma] tests/misc/pragma-pack.c:88: adding aligned(1) attribute to comp 'PACKOVERPOP' due to packing pragma +[kernel:typing:implicit-function-declaration] tests/misc/pragma-pack.c:104: Warning: + Calling undeclared function __builtin_offsetof. Old style K&R code? [kernel:typing:pragma] tests/misc/pragma-pack.c:133: packing pragma: restoring alignment to default (16) [kernel:typing:pragma] tests/misc/pragma-pack.c:135: diff --git a/tests/misc/oracle/pragma-pack.1.res.oracle b/tests/misc/oracle/pragma-pack.1.res.oracle index 559d8cfaacb..59c543748f2 100644 --- a/tests/misc/oracle/pragma-pack.1.res.oracle +++ b/tests/misc/oracle/pragma-pack.1.res.oracle @@ -1,6 +1,8 @@ [kernel] Parsing tests/misc/pragma-pack.c (with preprocessing) [kernel] tests/misc/pragma-pack.c:87: Warning: ignoring #pragma pack(pop) with empty stack +[kernel:typing:implicit-function-declaration] tests/misc/pragma-pack.c:104: Warning: + Calling undeclared function __builtin_offsetof. Old style K&R code? [eva] Analyzing a complete application starting at main [eva] Computing initial state [eva] Initial state computed diff --git a/tests/misc/oracle/pragma-pack.2.res.oracle b/tests/misc/oracle/pragma-pack.2.res.oracle index ae56a3d1f1a..c2534c76f82 100644 --- a/tests/misc/oracle/pragma-pack.2.res.oracle +++ b/tests/misc/oracle/pragma-pack.2.res.oracle @@ -1,6 +1,8 @@ [kernel] Parsing tests/misc/pragma-pack.c (with preprocessing) [kernel] tests/misc/pragma-pack.c:87: Warning: ignoring #pragma pack(pop) with empty stack +[kernel:typing:implicit-function-declaration] tests/misc/pragma-pack.c:104: Warning: + Calling undeclared function __builtin_offsetof. Old style K&R code? [eva] Analyzing a complete application starting at main [eva] Computing initial state [eva] Initial state computed diff --git a/tests/misc/oracle/pragma_pack_zero.0.res.oracle b/tests/misc/oracle/pragma_pack_zero.0.res.oracle index 6c491d9c591..0137611438a 100644 --- a/tests/misc/oracle/pragma_pack_zero.0.res.oracle +++ b/tests/misc/oracle/pragma_pack_zero.0.res.oracle @@ -1,6 +1,8 @@ [kernel] Parsing tests/misc/pragma_pack_zero.c (with preprocessing) [kernel] tests/misc/pragma_pack_zero.c:35: Warning: GCC accepts pack(0) but does not specify its behavior; considering it equivalent to pack() +[kernel:typing:implicit-function-declaration] tests/misc/pragma_pack_zero.c:47: Warning: + Calling undeclared function __builtin_offsetof. Old style K&R code? [eva] Analyzing a complete application starting at main [eva] Computing initial state [eva] Initial state computed diff --git a/tests/misc/oracle/pragma_pack_zero.1.res.oracle b/tests/misc/oracle/pragma_pack_zero.1.res.oracle index 69b3a971800..672ee382233 100644 --- a/tests/misc/oracle/pragma_pack_zero.1.res.oracle +++ b/tests/misc/oracle/pragma_pack_zero.1.res.oracle @@ -1,6 +1,8 @@ [kernel] Parsing tests/misc/pragma_pack_zero.c (with preprocessing) [kernel] tests/misc/pragma_pack_zero.c:35: Warning: ignoring invalid packing alignment (0) +[kernel:typing:implicit-function-declaration] tests/misc/pragma_pack_zero.c:47: Warning: + Calling undeclared function __builtin_offsetof. Old style K&R code? [eva] Analyzing a complete application starting at main [eva] Computing initial state [eva] Initial state computed diff --git a/tests/syntax/oracle/offsetof.res.oracle b/tests/syntax/oracle/offsetof.res.oracle index ac9886f97c2..0829a102008 100644 --- a/tests/syntax/oracle/offsetof.res.oracle +++ b/tests/syntax/oracle/offsetof.res.oracle @@ -1,13 +1,12 @@ [kernel] Parsing tests/syntax/offsetof.c (with preprocessing) +[kernel:typing:implicit-function-declaration] tests/syntax/offsetof.c:6: Warning: + Calling undeclared function __builtin_offsetof. Old style K&R code? /* Generated by Frama-C */ #include "stddef.h" -struct c { - char ca ; -}; void main(void) { size_t S; - S = (unsigned int)(& ((struct c *)0)->ca); + S = 0U; return; } diff --git a/tests/value/oracle/attribute-aligned.res.oracle b/tests/value/oracle/attribute-aligned.res.oracle index c451f494f10..160214c6a77 100644 --- a/tests/value/oracle/attribute-aligned.res.oracle +++ b/tests/value/oracle/attribute-aligned.res.oracle @@ -1,4 +1,6 @@ [kernel] Parsing tests/value/attribute-aligned.c (with preprocessing) +[kernel:typing:implicit-function-declaration] tests/value/attribute-aligned.c:17: Warning: + Calling undeclared function __builtin_offsetof. Old style K&R code? [eva] Analyzing a complete application starting at main [eva] Computing initial state [eva] Initial state computed -- GitLab From 1bc51471c48a2d4afb94bf1e2d123a11cd88095e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20B=C3=BChler?= <david.buhler@cea.fr> Date: Fri, 20 Mar 2020 17:45:47 +0100 Subject: [PATCH 044/218] [rte] Generates alarms on invalid pointer values. According to the kernel option -warn-invalid-pointer. --- src/kernel_services/plugin_entry_points/db.ml | 1 + src/kernel_services/plugin_entry_points/db.mli | 1 + src/plugins/rte/flags.ml | 5 +++++ src/plugins/rte/flags.mli | 2 ++ src/plugins/rte/generator.ml | 8 ++++++++ src/plugins/rte/generator.mli | 1 + src/plugins/rte/register.ml | 1 + src/plugins/rte/rte.ml | 18 ++++++++++++++++++ src/plugins/rte/rte.mli | 1 + src/plugins/rte/visit.ml | 16 ++++++++++++++-- tests/rte/oracle/twofunc.res.oracle | 4 ++++ 11 files changed, 56 insertions(+), 2 deletions(-) diff --git a/src/kernel_services/plugin_entry_points/db.ml b/src/kernel_services/plugin_entry_points/db.ml index 2453bded636..9d0a42e6ebd 100644 --- a/src/kernel_services/plugin_entry_points/db.ml +++ b/src/kernel_services/plugin_entry_points/db.ml @@ -1021,6 +1021,7 @@ module RteGen = struct let get_pointer_downcast_status = mk_fun "RteGen.get_pointer_downcast_status" let get_float_to_int_status = mk_fun "RteGen.get_float_to_int_status" let get_finite_float_status = mk_fun "RteGen.get_finite_float_status" + let get_pointer_value_status = mk_fun "RteGen.get_pointer_value_status" let get_bool_value_status = mk_fun "RteGen.get_bool_value_status" end diff --git a/src/kernel_services/plugin_entry_points/db.mli b/src/kernel_services/plugin_entry_points/db.mli index a54ae74932d..43b89f26ecf 100644 --- a/src/kernel_services/plugin_entry_points/db.mli +++ b/src/kernel_services/plugin_entry_points/db.mli @@ -903,6 +903,7 @@ module RteGen : sig val get_pointer_downcast_status : (unit -> status_accessor) ref val get_float_to_int_status : (unit -> status_accessor) ref val get_finite_float_status : (unit -> status_accessor) ref + val get_pointer_value_status : (unit -> status_accessor) ref val get_bool_value_status : (unit -> status_accessor) ref end diff --git a/src/plugins/rte/flags.ml b/src/plugins/rte/flags.ml index 7d17b15a3a9..fea846e8b19 100644 --- a/src/plugins/rte/flags.ml +++ b/src/plugins/rte/flags.ml @@ -40,6 +40,7 @@ type t = { float_to_int: bool; finite_float: bool; pointer_call: bool; + pointer_value: bool; bool_value: bool; } @@ -59,6 +60,7 @@ let all = { float_to_int = true; finite_float = true; pointer_call = true; + pointer_value = true; bool_value = true; } @@ -78,6 +80,7 @@ let none = { float_to_int = false; finite_float = false; pointer_call = false; + pointer_value = false; bool_value = false; } @@ -102,6 +105,7 @@ let default ?float_to_int ?finite_float ?pointer_call + ?pointer_value ?bool_value () = { @@ -120,6 +124,7 @@ let default float_to_int = option Options.DoFloatToInt.get float_to_int ; finite_float = option (fun () -> Kernel.SpecialFloat.get () <> "none") finite_float ; pointer_call = option Options.DoPointerCall.get pointer_call ; + pointer_value = option Kernel.InvalidPointer.get pointer_value; bool_value = option Kernel.InvalidBool.get bool_value ; } diff --git a/src/plugins/rte/flags.mli b/src/plugins/rte/flags.mli index 3ea19d53f36..fc1a7b6f4d7 100644 --- a/src/plugins/rte/flags.mli +++ b/src/plugins/rte/flags.mli @@ -42,6 +42,7 @@ type t = { float_to_int: bool; finite_float: bool; pointer_call: bool; + pointer_value: bool; bool_value: bool; } @@ -62,6 +63,7 @@ val default : ?float_to_int:bool -> ?finite_float:bool -> ?pointer_call:bool -> + ?pointer_value:bool -> ?bool_value:bool -> unit -> t diff --git a/src/plugins/rte/generator.ml b/src/plugins/rte/generator.ml index 8c8e697d4dc..4c84ce9c126 100644 --- a/src/plugins/rte/generator.ml +++ b/src/plugins/rte/generator.ml @@ -83,6 +83,14 @@ module Mem_access = let additional_parameters = [ Kernel.SafeArrays.parameter ] end) +module Pointer_value = + Make + (struct + let name = "pointer_value" + let parameter = Kernel.InvalidPointer.parameter + let additional_parameters = [] + end) + module Pointer_call = Make (struct diff --git a/src/plugins/rte/generator.mli b/src/plugins/rte/generator.mli index 1518a0acc67..0116b9d7698 100644 --- a/src/plugins/rte/generator.mli +++ b/src/plugins/rte/generator.mli @@ -30,6 +30,7 @@ end module Initialized: S module Mem_access: S +module Pointer_value: S module Pointer_call: S module Div_mod: S module Shift: S diff --git a/src/plugins/rte/register.ml b/src/plugins/rte/register.ml index 8b5afe27c05..a3f3df56f04 100644 --- a/src/plugins/rte/register.ml +++ b/src/plugins/rte/register.ml @@ -96,6 +96,7 @@ let () = nojournal_register get_pointer_downcast_status Pointer_downcast.accessor; nojournal_register get_float_to_int_status Float_to_int.accessor; nojournal_register get_finite_float_status Finite_float.accessor; + nojournal_register get_pointer_value_status Pointer_value.accessor; nojournal_register get_bool_value_status Bool_value.accessor ; nojournal_register get_all_status all_statuses; ;; diff --git a/src/plugins/rte/rte.ml b/src/plugins/rte/rte.ml index 467d65f1ffd..16845eed8d5 100644 --- a/src/plugins/rte/rte.ml +++ b/src/plugins/rte/rte.ml @@ -451,6 +451,24 @@ let finite_float_assertion ~remove_trivial:_ ~on_alarm (fkind, exp) = let pointer_call ~remove_trivial:_ ~on_alarm (e, args) = on_alarm ~invalid:false (Alarms.Function_pointer (e, Some args)) +let is_safe_pointer_value = function + | Lval (Var vi, offset) -> + (* Reading a pointer variable must emit an alarm if an invalid pointer value + could have been written without previous alarm, through: + - an union type, in which case [offset] is not NoOffset; + - an untyped write, in which case the address of [vi] is taken. *) + not vi.vaddrof && offset = NoOffset + | AddrOf (_, NoOffset) | StartOf (_, NoOffset) -> true + | CastE (_typ, e) -> + (* 0 can always be converted into a NULL pointer. *) + let v = get_expr_val e in + Extlib.may_map ~dft:false Integer.(equal zero) v + | _ -> false + +let pointer_value ~remove_trivial ~on_alarm expr = + if not (remove_trivial && is_safe_pointer_value expr.enode) + then on_alarm ~invalid:false (Alarms.Invalid_pointer expr) + let bool_value ~remove_trivial ~on_alarm lv = match remove_trivial, lv with | true, (Var vi, NoOffset) diff --git a/src/plugins/rte/rte.mli b/src/plugins/rte/rte.mli index 7c787c279a8..c7a292c92ca 100644 --- a/src/plugins/rte/rte.mli +++ b/src/plugins/rte/rte.mli @@ -44,6 +44,7 @@ val downcast_assertion: (typ * exp) alarm_gen val float_to_int_assertion: (typ * exp) alarm_gen val finite_float_assertion: (fkind * exp) alarm_gen val pointer_call: (exp * exp list) alarm_gen +val pointer_value: exp alarm_gen val bool_value: lval alarm_gen (* diff --git a/src/plugins/rte/visit.ml b/src/plugins/rte/visit.ml index 61dafe98471..36c092b8a7c 100644 --- a/src/plugins/rte/visit.ml +++ b/src/plugins/rte/visit.ml @@ -99,6 +99,9 @@ class annot_visitor kf flags on_alarm = object (self) method private do_pointer_call () = flags.Flags.pointer_call && not (Generator.Pointer_call.is_computed kf) + method private do_pointer_value () = + flags.Flags.pointer_value && not (Generator.Pointer_value.is_computed kf) + method private do_bool_value () = flags.Flags.bool_value && not (Generator.Bool_value.is_computed kf) @@ -275,6 +278,9 @@ class annot_visitor kf flags on_alarm = object (self) self#generate_assertion Rte.finite_float_assertion (fkind,exp) | _ -> ()) + | BinOp((PlusPI | MinusPI), _, _, _) when self#do_pointer_value () -> + self#generate_assertion Rte.pointer_value exp + | UnOp(Neg, exp, ty) -> (* Note: if unary minus on unsigned integer is to be understood as "subtracting the promoted value from the largest value @@ -290,6 +296,8 @@ class annot_visitor kf flags on_alarm = object (self) | Lval lval -> (match Cil.(unrollType (typeOfLval lval)) with + | TPtr _ when self#do_pointer_value () -> + self#generate_assertion Rte.pointer_value exp | TInt (IBool,_) when self#do_bool_value () -> self#generate_assertion Rte.bool_value lval | _ -> ()); @@ -313,6 +321,8 @@ class annot_visitor kf flags on_alarm = object (self) (* to , from *) | TInt _, TPtr _ when self#do_pointer_downcast () -> self#generate_assertion Rte.downcast_assertion (ty, e) + | TPtr _, TInt _ when self#do_pointer_value () -> + self#generate_assertion Rte.pointer_value exp | TInt(kind,_), TInt (_, _) -> let signed = Cil.isSigned kind in @@ -339,8 +349,9 @@ class annot_visitor kf flags on_alarm = object (self) | FP_nan -> self#generate_assertion Rte.finite_float_assertion (fkind,exp) end - | StartOf _ - | AddrOf _ + | StartOf _ | AddrOf _ -> + if self#do_pointer_value () + then self#generate_assertion Rte.pointer_value exp | Info _ | UnOp _ | Const _ @@ -451,6 +462,7 @@ let annotate ?flags kf = let open Flags in if comp Initialized.accessor flags.initialized ||| comp Mem_access.accessor flags.mem_access ||| + comp Pointer_value.accessor flags.pointer_value ||| comp Pointer_call.accessor flags.pointer_call ||| comp Div_mod.accessor flags.div_mod ||| comp Shift.accessor flags.shift ||| diff --git a/tests/rte/oracle/twofunc.res.oracle b/tests/rte/oracle/twofunc.res.oracle index 5d0a80d5f38..834e89b4e69 100644 --- a/tests/rte/oracle/twofunc.res.oracle +++ b/tests/rte/oracle/twofunc.res.oracle @@ -143,6 +143,7 @@ int main(void) [kernel] - shift_value_out_of_bounds = true [kernel] - division_by_zero = true [kernel] - pointer_call = true +[kernel] - pointer_value = false [kernel] - mem_access = true [kernel] - initialized = false [kernel] kf = main @@ -159,6 +160,7 @@ int main(void) [kernel] - shift_value_out_of_bounds = true [kernel] - division_by_zero = true [kernel] - pointer_call = true +[kernel] - pointer_value = false [kernel] - mem_access = true [kernel] - initialized = false [kernel] ================================ @@ -237,6 +239,7 @@ int main(void) [kernel] - shift_value_out_of_bounds = true [kernel] - division_by_zero = true [kernel] - pointer_call = true +[kernel] - pointer_value = false [kernel] - mem_access = true [kernel] - initialized = false [kernel] kf = main @@ -253,6 +256,7 @@ int main(void) [kernel] - shift_value_out_of_bounds = true [kernel] - division_by_zero = true [kernel] - pointer_call = true +[kernel] - pointer_value = false [kernel] - mem_access = true [kernel] - initialized = false [kernel] ================================ -- GitLab From 3bf9500a79b809c216bd871b839deda44829b6af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20B=C3=BChler?= <david.buhler@cea.fr> Date: Mon, 23 Mar 2020 16:31:11 +0100 Subject: [PATCH 045/218] [typing] properly register __builtin_offsetof as a builtin Avoid warning about missing proto during typechecking. Also changes a warning into an error, and improves the error message. --- src/kernel_internals/parsing/cparser.mly | 12 +- src/kernel_internals/typing/cabs2cil.ml | 10 +- .../ast_printing/cil_printer.ml | 2 +- src/kernel_services/ast_queries/cil.ml | 9 +- .../tests/arith/oracle_ci/gen_functions.c | 88 ++++++------ .../tests/arith/oracle_ci/gen_functions_rec.c | 128 +++++++++--------- .../tests/gmp-only/oracle_ci/gen_functions.c | 124 ++++++++--------- .../tests/batch/oracle/ast_services.out.json | 2 +- .../wp_acsl/oracle/funvar_inv.1.res.oracle | 36 ++--- .../oracle/init_value_mem.0.res.oracle | 4 +- .../wp/tests/wp_acsl/oracle/logic.res.oracle | 18 +-- .../tests/wp_acsl/oracle/pointer.res.oracle | 28 ++-- .../wp_acsl/oracle/post_result.res.oracle | 2 +- .../wp/tests/wp_bts/oracle/bts0843.res.oracle | 4 +- .../wp/tests/wp_bts/oracle/bts986.res.oracle | 2 +- .../tests/wp_bts/oracle/bts_1382.res.oracle | 4 +- .../tests/wp_bts/oracle/bts_1828.0.res.oracle | 2 +- .../tests/wp_bts/oracle/bts_1828.1.res.oracle | 2 +- .../wp_bts/oracle/issue_715_b.res.oracle | 2 +- .../tests/wp_hoare/oracle/logicarr.res.oracle | 6 +- .../oracle/logicref_simple.res.oracle | 2 +- .../tests/wp_plugin/oracle/dynamic.res.oracle | 10 +- .../tests/wp_plugin/oracle/flash.0.res.oracle | 20 +-- .../tests/wp_plugin/oracle/flash.1.res.oracle | 20 +-- .../tests/wp_plugin/oracle/frame.res.oracle | 2 +- .../oracle/init_const_guard.res.oracle | 6 +- .../tests/wp_plugin/oracle/initarr.res.oracle | 18 +-- .../wp_plugin/oracle/overassign.res.oracle | 16 +-- .../wp_plugin/oracle/subset_fopen.res.oracle | 2 +- .../tests/wp_store/oracle/struct.res.oracle | 4 +- .../oracle/array_initialized.0.res.oracle | 2 +- .../oracle/array_initialized.1.res.oracle | 10 +- .../tests/wp_typed/oracle/frame.0.res.oracle | 4 +- .../tests/wp_typed/oracle/frame.1.res.oracle | 4 +- .../wp_typed/oracle/unit_alloc.0.res.oracle | 10 +- .../wp_typed/oracle/unit_alloc.1.res.oracle | 10 +- .../wp_typed/oracle/unit_local.0.res.oracle | 2 +- .../wp_typed/oracle/unit_local.1.res.oracle | 6 +- .../wp_typed/oracle/user_init.0.res.oracle | 32 ++--- .../wp_typed/oracle/user_init.1.res.oracle | 32 ++--- .../tests/wp_usage/oracle/caveat.1.res.oracle | 2 +- .../tests/wp_usage/oracle/caveat2.res.oracle | 6 +- .../wp_usage/oracle/caveat_range.res.oracle | 10 +- .../tests/wp_usage/oracle/global.0.res.oracle | 6 +- .../oracle/issue-189-bis.0.res.oracle | 44 +++--- .../oracle/issue-189-bis.1.res.oracle | 16 +-- tests/misc/oracle/pragma-pack.0.res.oracle | 2 - tests/misc/oracle/pragma-pack.1.res.oracle | 2 - tests/misc/oracle/pragma-pack.2.res.oracle | 2 - .../misc/oracle/pragma_pack_zero.0.res.oracle | 2 - .../misc/oracle/pragma_pack_zero.1.res.oracle | 2 - tests/syntax/oracle/bts1553_2.res.oracle | 4 + .../oracle/check_builtin_bts1440.res.oracle | 2 + .../oracle/get_astinfo_bts1136.res.oracle | 24 ++-- tests/syntax/oracle/offsetof.res.oracle | 2 - tests/syntax/oracle/reorder.res.oracle | 4 +- .../syntax/oracle/static_formals_1.res.oracle | 24 ++-- tests/syntax/oracle/syntactic_hook.res.oracle | 12 +- .../value/oracle/attribute-aligned.res.oracle | 2 - 59 files changed, 433 insertions(+), 432 deletions(-) diff --git a/src/kernel_internals/parsing/cparser.mly b/src/kernel_internals/parsing/cparser.mly index fadfd5c5949..eaab7b61312 100644 --- a/src/kernel_internals/parsing/cparser.mly +++ b/src/kernel_internals/parsing/cparser.mly @@ -226,11 +226,6 @@ let trd3 (_, _, result) = result let fourth4 (_,_,_,result) = result -(* - transform: __builtin_offsetof(type, member) - into : (size_t) (&(type * ) 0)->member - *) - let sizeofType () = let findSpecifier name = let convert_one_specifier s = @@ -253,6 +248,11 @@ let sizeofType () = findSpecifier Cil.theMachine.Cil.theMachine.Cil_types.size_t +(* + transform: offsetof(type, member) + into : (size_t) (&(type * ) 0)->member + *) + let transformOffsetOf (speclist, dtype) member = let mk_expr e = { expr_loc = member.expr_loc; expr_node = e } in let rec addPointer = function @@ -280,7 +280,7 @@ let transformOffsetOf (speclist, dtype) member = | INDEX (base, index) -> INDEX (replaceBase base, index) | _ -> - Errorloc.parse_error "malformed offset expression in __builtin_offsetof" + Errorloc.parse_error "malformed offset expression in offsetof macro" in { e with expr_node = node } in let memberExpr = replaceBase member in diff --git a/src/kernel_internals/typing/cabs2cil.ml b/src/kernel_internals/typing/cabs2cil.ml index 39a07c2eb0e..57c91da7c3e 100644 --- a/src/kernel_internals/typing/cabs2cil.ml +++ b/src/kernel_internals/typing/cabs2cil.ml @@ -7033,8 +7033,8 @@ and doExp local_env begin piscall := false; prestype := Cil.theMachine.Cil.typeOfSizeOf; + let typ = Cil.typeOfLhost host in try - let typ = Cil.typeOfLhost host in let start, _width = Cil.bitsOffset typ offset in if start mod 8 <> 0 then Kernel.error ~current:true "Using offset of bitfield"; @@ -7042,11 +7042,13 @@ and doExp local_env pres := Cil.kinteger ~loc:e.eloc kind (start / 8); with SizeOfError _ -> pres := e; - Kernel.warning ~once:true ~current:true - "Invalid call to builtin_offsetof"; + Kernel.error ~once:true ~current:true + "Unable to compute offset %a in type %a" + Cil_datatype.Offset.pretty offset + Cil_datatype.Typ.pretty typ; end | _ -> - Kernel.abort ~current:true "Invalid call to builtin_offsetof"; + Kernel.abort ~current:true "Invalid call to builtin_offsetof" end | "__builtin_types_compatible_p" -> begin diff --git a/src/kernel_services/ast_printing/cil_printer.ml b/src/kernel_services/ast_printing/cil_printer.ml index 8bb7a5f20ef..37a6a46cd2c 100644 --- a/src/kernel_services/ast_printing/cil_printer.ml +++ b/src/kernel_services/ast_printing/cil_printer.ml @@ -1057,7 +1057,7 @@ class cil_printer () = object (self) Extlib.may (fprintf fmt "%a = " self#lval) dest; (* Now the call itself *) fprintf fmt "%a(%a, %a)%s" - self#varname vi.vname + self#varname "offsetof" (self#typ None) (Cil.typeOfLhost host) self#offset offset instr_terminator diff --git a/src/kernel_services/ast_queries/cil.ml b/src/kernel_services/ast_queries/cil.ml index 91afc7abef7..d9330b5ab30 100644 --- a/src/kernel_services/ast_queries/cil.ml +++ b/src/kernel_services/ast_queries/cil.ml @@ -5199,13 +5199,20 @@ let initVABuiltins () = let initMsvcBuiltins () : unit = (** Take a number of wide string literals *) Builtin_functions.add "__annotation" (voidType, [ ], true) -;; + +let init_common_builtins () = + add_builtin + "offsetof" + theMachine.typeOfSizeOf + [ theMachine.typeOfSizeOf ] + false let init_builtins () = if not (TheMachine.is_computed ()) then Kernel.fatal ~current:true "You must call initCIL before init_builtins" ; if Builtin_functions.length () <> 0 then Kernel.fatal ~current:true "Cil builtins already initialized." ; + init_common_builtins (); if msvcMode () then initMsvcBuiltins () else begin diff --git a/src/plugins/e-acsl/tests/arith/oracle_ci/gen_functions.c b/src/plugins/e-acsl/tests/arith/oracle_ci/gen_functions.c index f8431536df1..457ff5d2aa2 100644 --- a/src/plugins/e-acsl/tests/arith/oracle_ci/gen_functions.c +++ b/src/plugins/e-acsl/tests/arith/oracle_ci/gen_functions.c @@ -232,6 +232,50 @@ void __gen_e_acsl_k(int x) return; } +int __gen_e_acsl_g_hidden(int x) +{ + return x; +} + +double __gen_e_acsl_f2(double x) +{ + __e_acsl_mpq_t __gen_e_acsl__8; + __e_acsl_mpq_t __gen_e_acsl__9; + __e_acsl_mpq_t __gen_e_acsl_div; + double __gen_e_acsl__10; + __gmpq_init(__gen_e_acsl__8); + __gmpq_set_str(__gen_e_acsl__8,"1",10); + __gmpq_init(__gen_e_acsl__9); + __gmpq_set_d(__gen_e_acsl__9,x); + __gmpq_init(__gen_e_acsl_div); + __gmpq_div(__gen_e_acsl_div,(__e_acsl_mpq_struct const *)(__gen_e_acsl__8), + (__e_acsl_mpq_struct const *)(__gen_e_acsl__9)); + __gen_e_acsl__10 = __gmpq_get_d((__e_acsl_mpq_struct const *)(__gen_e_acsl_div)); + __gmpq_clear(__gen_e_acsl__8); + __gmpq_clear(__gen_e_acsl__9); + __gmpq_clear(__gen_e_acsl_div); + /*@ assert Eva: is_nan_or_infinite: \is_finite(__gen_e_acsl__10); */ + return __gen_e_acsl__10; +} + +int __gen_e_acsl_g(int x) +{ + int __gen_e_acsl_g_hidden_2; + __gen_e_acsl_g_hidden_2 = __gen_e_acsl_g_hidden(x); + return __gen_e_acsl_g_hidden_2; +} + +mystruct __gen_e_acsl_t1(mystruct m) +{ + return m; +} + +int __gen_e_acsl_p1(int x, int y) +{ + int __retres = x + (long)y > 0L; + return __retres; +} + long __gen_e_acsl_t2(mystruct m) { long __retres = m.k + (long)m.l; @@ -340,48 +384,4 @@ int __gen_e_acsl_h_short(int s) return s; } -int __gen_e_acsl_g_hidden(int x) -{ - return x; -} - -double __gen_e_acsl_f2(double x) -{ - __e_acsl_mpq_t __gen_e_acsl__8; - __e_acsl_mpq_t __gen_e_acsl__9; - __e_acsl_mpq_t __gen_e_acsl_div; - double __gen_e_acsl__10; - __gmpq_init(__gen_e_acsl__8); - __gmpq_set_str(__gen_e_acsl__8,"1",10); - __gmpq_init(__gen_e_acsl__9); - __gmpq_set_d(__gen_e_acsl__9,x); - __gmpq_init(__gen_e_acsl_div); - __gmpq_div(__gen_e_acsl_div,(__e_acsl_mpq_struct const *)(__gen_e_acsl__8), - (__e_acsl_mpq_struct const *)(__gen_e_acsl__9)); - __gen_e_acsl__10 = __gmpq_get_d((__e_acsl_mpq_struct const *)(__gen_e_acsl_div)); - __gmpq_clear(__gen_e_acsl__8); - __gmpq_clear(__gen_e_acsl__9); - __gmpq_clear(__gen_e_acsl_div); - /*@ assert Eva: is_nan_or_infinite: \is_finite(__gen_e_acsl__10); */ - return __gen_e_acsl__10; -} - -int __gen_e_acsl_g(int x) -{ - int __gen_e_acsl_g_hidden_2; - __gen_e_acsl_g_hidden_2 = __gen_e_acsl_g_hidden(x); - return __gen_e_acsl_g_hidden_2; -} - -mystruct __gen_e_acsl_t1(mystruct m) -{ - return m; -} - -int __gen_e_acsl_p1(int x, int y) -{ - int __retres = x + (long)y > 0L; - return __retres; -} - diff --git a/src/plugins/e-acsl/tests/arith/oracle_ci/gen_functions_rec.c b/src/plugins/e-acsl/tests/arith/oracle_ci/gen_functions_rec.c index 6b5f403f5a2..b9015c95933 100644 --- a/src/plugins/e-acsl/tests/arith/oracle_ci/gen_functions_rec.c +++ b/src/plugins/e-acsl/tests/arith/oracle_ci/gen_functions_rec.c @@ -105,6 +105,70 @@ int main(void) return __retres; } +void __gen_e_acsl_f1(__e_acsl_mpz_t *__retres_arg, int n) +{ + __e_acsl_mpz_t __gen_e_acsl_if_2; + if (n <= 0) { + __e_acsl_mpz_t __gen_e_acsl_; + __gmpz_init_set_si(__gen_e_acsl_,0L); + __gmpz_init_set(__gen_e_acsl_if_2, + (__e_acsl_mpz_struct const *)(__gen_e_acsl_)); + __gmpz_clear(__gen_e_acsl_); + } + else { + __e_acsl_mpz_t __gen_e_acsl_f1_5; + __e_acsl_mpz_t __gen_e_acsl_n_2; + __e_acsl_mpz_t __gen_e_acsl_add_2; + __gen_e_acsl_f1_2(& __gen_e_acsl_f1_5,n - 1L); + __gmpz_init_set_si(__gen_e_acsl_n_2,(long)n); + __gmpz_init(__gen_e_acsl_add_2); + __gmpz_add(__gen_e_acsl_add_2, + (__e_acsl_mpz_struct const *)(__gen_e_acsl_f1_5), + (__e_acsl_mpz_struct const *)(__gen_e_acsl_n_2)); + __gmpz_init_set(__gen_e_acsl_if_2, + (__e_acsl_mpz_struct const *)(__gen_e_acsl_add_2)); + __gmpz_clear(__gen_e_acsl_f1_5); + __gmpz_clear(__gen_e_acsl_n_2); + __gmpz_clear(__gen_e_acsl_add_2); + } + __gmpz_init_set(*__retres_arg, + (__e_acsl_mpz_struct const *)(__gen_e_acsl_if_2)); + __gmpz_clear(__gen_e_acsl_if_2); + return; +} + +void __gen_e_acsl_f1_2(__e_acsl_mpz_t *__retres_arg, long n) +{ + __e_acsl_mpz_t __gen_e_acsl_if; + if (n <= 0L) { + __e_acsl_mpz_t __gen_e_acsl__2; + __gmpz_init_set_si(__gen_e_acsl__2,0L); + __gmpz_init_set(__gen_e_acsl_if, + (__e_acsl_mpz_struct const *)(__gen_e_acsl__2)); + __gmpz_clear(__gen_e_acsl__2); + } + else { + __e_acsl_mpz_t __gen_e_acsl_f1_4; + __e_acsl_mpz_t __gen_e_acsl_n; + __e_acsl_mpz_t __gen_e_acsl_add; + __gen_e_acsl_f1_2(& __gen_e_acsl_f1_4,n - 1L); + __gmpz_init_set_si(__gen_e_acsl_n,n); + __gmpz_init(__gen_e_acsl_add); + __gmpz_add(__gen_e_acsl_add, + (__e_acsl_mpz_struct const *)(__gen_e_acsl_f1_4), + (__e_acsl_mpz_struct const *)(__gen_e_acsl_n)); + __gmpz_init_set(__gen_e_acsl_if, + (__e_acsl_mpz_struct const *)(__gen_e_acsl_add)); + __gmpz_clear(__gen_e_acsl_f1_4); + __gmpz_clear(__gen_e_acsl_n); + __gmpz_clear(__gen_e_acsl_add); + } + __gmpz_init_set(*__retres_arg, + (__e_acsl_mpz_struct const *)(__gen_e_acsl_if)); + __gmpz_clear(__gen_e_acsl_if); + return; +} + int __gen_e_acsl_f2(int n) { int __gen_e_acsl_if_4; @@ -253,68 +317,4 @@ unsigned long __gen_e_acsl_f4_2(long n) return __gen_e_acsl_if_8; } -void __gen_e_acsl_f1(__e_acsl_mpz_t *__retres_arg, int n) -{ - __e_acsl_mpz_t __gen_e_acsl_if_2; - if (n <= 0) { - __e_acsl_mpz_t __gen_e_acsl_; - __gmpz_init_set_si(__gen_e_acsl_,0L); - __gmpz_init_set(__gen_e_acsl_if_2, - (__e_acsl_mpz_struct const *)(__gen_e_acsl_)); - __gmpz_clear(__gen_e_acsl_); - } - else { - __e_acsl_mpz_t __gen_e_acsl_f1_5; - __e_acsl_mpz_t __gen_e_acsl_n_2; - __e_acsl_mpz_t __gen_e_acsl_add_2; - __gen_e_acsl_f1_2(& __gen_e_acsl_f1_5,n - 1L); - __gmpz_init_set_si(__gen_e_acsl_n_2,(long)n); - __gmpz_init(__gen_e_acsl_add_2); - __gmpz_add(__gen_e_acsl_add_2, - (__e_acsl_mpz_struct const *)(__gen_e_acsl_f1_5), - (__e_acsl_mpz_struct const *)(__gen_e_acsl_n_2)); - __gmpz_init_set(__gen_e_acsl_if_2, - (__e_acsl_mpz_struct const *)(__gen_e_acsl_add_2)); - __gmpz_clear(__gen_e_acsl_f1_5); - __gmpz_clear(__gen_e_acsl_n_2); - __gmpz_clear(__gen_e_acsl_add_2); - } - __gmpz_init_set(*__retres_arg, - (__e_acsl_mpz_struct const *)(__gen_e_acsl_if_2)); - __gmpz_clear(__gen_e_acsl_if_2); - return; -} - -void __gen_e_acsl_f1_2(__e_acsl_mpz_t *__retres_arg, long n) -{ - __e_acsl_mpz_t __gen_e_acsl_if; - if (n <= 0L) { - __e_acsl_mpz_t __gen_e_acsl__2; - __gmpz_init_set_si(__gen_e_acsl__2,0L); - __gmpz_init_set(__gen_e_acsl_if, - (__e_acsl_mpz_struct const *)(__gen_e_acsl__2)); - __gmpz_clear(__gen_e_acsl__2); - } - else { - __e_acsl_mpz_t __gen_e_acsl_f1_4; - __e_acsl_mpz_t __gen_e_acsl_n; - __e_acsl_mpz_t __gen_e_acsl_add; - __gen_e_acsl_f1_2(& __gen_e_acsl_f1_4,n - 1L); - __gmpz_init_set_si(__gen_e_acsl_n,n); - __gmpz_init(__gen_e_acsl_add); - __gmpz_add(__gen_e_acsl_add, - (__e_acsl_mpz_struct const *)(__gen_e_acsl_f1_4), - (__e_acsl_mpz_struct const *)(__gen_e_acsl_n)); - __gmpz_init_set(__gen_e_acsl_if, - (__e_acsl_mpz_struct const *)(__gen_e_acsl_add)); - __gmpz_clear(__gen_e_acsl_f1_4); - __gmpz_clear(__gen_e_acsl_n); - __gmpz_clear(__gen_e_acsl_add); - } - __gmpz_init_set(*__retres_arg, - (__e_acsl_mpz_struct const *)(__gen_e_acsl_if)); - __gmpz_clear(__gen_e_acsl_if); - return; -} - diff --git a/src/plugins/e-acsl/tests/gmp-only/oracle_ci/gen_functions.c b/src/plugins/e-acsl/tests/gmp-only/oracle_ci/gen_functions.c index 25a8fe98421..f7f9708c3cc 100644 --- a/src/plugins/e-acsl/tests/gmp-only/oracle_ci/gen_functions.c +++ b/src/plugins/e-acsl/tests/gmp-only/oracle_ci/gen_functions.c @@ -277,6 +277,68 @@ void __gen_e_acsl_k(int x) return; } +int __gen_e_acsl_g_hidden(int x) +{ + return x; +} + +double __gen_e_acsl_f2(double x) +{ + __e_acsl_mpq_t __gen_e_acsl__13; + __e_acsl_mpq_t __gen_e_acsl__14; + __e_acsl_mpq_t __gen_e_acsl_div; + double __gen_e_acsl__15; + __gmpq_init(__gen_e_acsl__13); + __gmpq_set_str(__gen_e_acsl__13,"1",10); + __gmpq_init(__gen_e_acsl__14); + __gmpq_set_d(__gen_e_acsl__14,x); + __gmpq_init(__gen_e_acsl_div); + __gmpq_div(__gen_e_acsl_div, + (__e_acsl_mpq_struct const *)(__gen_e_acsl__13), + (__e_acsl_mpq_struct const *)(__gen_e_acsl__14)); + __gen_e_acsl__15 = __gmpq_get_d((__e_acsl_mpq_struct const *)(__gen_e_acsl_div)); + __gmpq_clear(__gen_e_acsl__13); + __gmpq_clear(__gen_e_acsl__14); + __gmpq_clear(__gen_e_acsl_div); + /*@ assert Eva: is_nan_or_infinite: \is_finite(__gen_e_acsl__15); */ + return __gen_e_acsl__15; +} + +int __gen_e_acsl_g(int x) +{ + int __gen_e_acsl_g_hidden_2; + __gen_e_acsl_g_hidden_2 = __gen_e_acsl_g_hidden(x); + return __gen_e_acsl_g_hidden_2; +} + +mystruct __gen_e_acsl_t1(mystruct m) +{ + return m; +} + +int __gen_e_acsl_p1(int x, int y) +{ + __e_acsl_mpz_t __gen_e_acsl_x; + __e_acsl_mpz_t __gen_e_acsl_y; + __e_acsl_mpz_t __gen_e_acsl_add; + __e_acsl_mpz_t __gen_e_acsl_; + int __gen_e_acsl_gt; + __gmpz_init_set_si(__gen_e_acsl_x,(long)x); + __gmpz_init_set_si(__gen_e_acsl_y,(long)y); + __gmpz_init(__gen_e_acsl_add); + __gmpz_add(__gen_e_acsl_add,(__e_acsl_mpz_struct const *)(__gen_e_acsl_x), + (__e_acsl_mpz_struct const *)(__gen_e_acsl_y)); + __gmpz_init_set_si(__gen_e_acsl_,0L); + __gen_e_acsl_gt = __gmpz_cmp((__e_acsl_mpz_struct const *)(__gen_e_acsl_add), + (__e_acsl_mpz_struct const *)(__gen_e_acsl_)); + int __retres = __gen_e_acsl_gt > 0; + __gmpz_clear(__gen_e_acsl_x); + __gmpz_clear(__gen_e_acsl_y); + __gmpz_clear(__gen_e_acsl_add); + __gmpz_clear(__gen_e_acsl_); + return __retres; +} + void __gen_e_acsl_t2(__e_acsl_mpz_t *__retres_arg, mystruct m) { __e_acsl_mpz_t __gen_e_acsl__10; @@ -415,66 +477,4 @@ int __gen_e_acsl_h_short(int s) return s; } -int __gen_e_acsl_g_hidden(int x) -{ - return x; -} - -double __gen_e_acsl_f2(double x) -{ - __e_acsl_mpq_t __gen_e_acsl__13; - __e_acsl_mpq_t __gen_e_acsl__14; - __e_acsl_mpq_t __gen_e_acsl_div; - double __gen_e_acsl__15; - __gmpq_init(__gen_e_acsl__13); - __gmpq_set_str(__gen_e_acsl__13,"1",10); - __gmpq_init(__gen_e_acsl__14); - __gmpq_set_d(__gen_e_acsl__14,x); - __gmpq_init(__gen_e_acsl_div); - __gmpq_div(__gen_e_acsl_div, - (__e_acsl_mpq_struct const *)(__gen_e_acsl__13), - (__e_acsl_mpq_struct const *)(__gen_e_acsl__14)); - __gen_e_acsl__15 = __gmpq_get_d((__e_acsl_mpq_struct const *)(__gen_e_acsl_div)); - __gmpq_clear(__gen_e_acsl__13); - __gmpq_clear(__gen_e_acsl__14); - __gmpq_clear(__gen_e_acsl_div); - /*@ assert Eva: is_nan_or_infinite: \is_finite(__gen_e_acsl__15); */ - return __gen_e_acsl__15; -} - -int __gen_e_acsl_g(int x) -{ - int __gen_e_acsl_g_hidden_2; - __gen_e_acsl_g_hidden_2 = __gen_e_acsl_g_hidden(x); - return __gen_e_acsl_g_hidden_2; -} - -mystruct __gen_e_acsl_t1(mystruct m) -{ - return m; -} - -int __gen_e_acsl_p1(int x, int y) -{ - __e_acsl_mpz_t __gen_e_acsl_x; - __e_acsl_mpz_t __gen_e_acsl_y; - __e_acsl_mpz_t __gen_e_acsl_add; - __e_acsl_mpz_t __gen_e_acsl_; - int __gen_e_acsl_gt; - __gmpz_init_set_si(__gen_e_acsl_x,(long)x); - __gmpz_init_set_si(__gen_e_acsl_y,(long)y); - __gmpz_init(__gen_e_acsl_add); - __gmpz_add(__gen_e_acsl_add,(__e_acsl_mpz_struct const *)(__gen_e_acsl_x), - (__e_acsl_mpz_struct const *)(__gen_e_acsl_y)); - __gmpz_init_set_si(__gen_e_acsl_,0L); - __gen_e_acsl_gt = __gmpz_cmp((__e_acsl_mpz_struct const *)(__gen_e_acsl_add), - (__e_acsl_mpz_struct const *)(__gen_e_acsl_)); - int __retres = __gen_e_acsl_gt > 0; - __gmpz_clear(__gen_e_acsl_x); - __gmpz_clear(__gen_e_acsl_y); - __gmpz_clear(__gen_e_acsl_add); - __gmpz_clear(__gen_e_acsl_); - return __retres; -} - diff --git a/src/plugins/server/tests/batch/oracle/ast_services.out.json b/src/plugins/server/tests/batch/oracle/ast_services.out.json index 40a40546e0d..726bac4cc75 100644 --- a/src/plugins/server/tests/batch/oracle/ast_services.out.json +++ b/src/plugins/server/tests/batch/oracle/ast_services.out.json @@ -4,7 +4,7 @@ "id": "printFunction", "data": [ "", - [ "#v19", "void f(void)" ], + [ "#v21", "void f(void)" ], "\n{\n ", [ "#s7", [ "#k7", "return;" ] ], "\n}\n", diff --git a/src/plugins/wp/tests/wp_acsl/oracle/funvar_inv.1.res.oracle b/src/plugins/wp/tests/wp_acsl/oracle/funvar_inv.1.res.oracle index 8fbdbbc6383..1e8b67744c3 100644 --- a/src/plugins/wp/tests/wp_acsl/oracle/funvar_inv.1.res.oracle +++ b/src/plugins/wp/tests/wp_acsl/oracle/funvar_inv.1.res.oracle @@ -8,24 +8,24 @@ ------------------------------------------------------------ Goal Post-condition 'P_startof' in 'f': -Let a = global(G_G_18). +Let a = global(G_G_20). Let a_1 = shift_sint32(a, 0). Assume { Type: is_sint32(v) /\ is_sint32(Mint_0[shift_sint32(a, 1)]). (* Goal *) When: Mint_0[a_1] = 0. (* Initializer *) - Init: Mint_0[global(L_i_25)] = 0. + Init: Mint_0[global(L_i_27)] = 0. If v <= 3 Then { (* Else *) Have: Mint_0[f] = 0. Have: shift_sint32(a, v) = f. } - Else { Have: global(L_i_25) = f. } + Else { Have: global(L_i_27) = f. } } Prove: a_1 = f. ------------------------------------------------------------ Goal Post-condition 'P_addr' in 'f': -Let a = global(G_G_18). +Let a = global(G_G_20). Let x = Mint_0[shift_sint32(a, 0)]. Let a_1 = shift_sint32(a, 1). Assume { @@ -33,10 +33,10 @@ Assume { (* Goal *) When: (x != 0) /\ (Mint_0[a_1] = 0). (* Initializer *) - Init: Mint_0[global(L_i_25)] = 0. + Init: Mint_0[global(L_i_27)] = 0. If v <= 3 Then { (* Else *) Have: Mint_0[f] = 0. Have: shift_sint32(a, v) = f. } - Else { Have: global(L_i_25) = f. } + Else { Have: global(L_i_27) = f. } } Prove: a_1 = f. @@ -51,25 +51,25 @@ Prove: true. ------------------------------------------------------------ Goal Post-condition 'P_startof_shift' in 'f2': -Let a = global(G_G_18). +Let a = global(G_G_20). Let a_1 = shift_sint32(a, 0). Assume { Type: is_sint32(v) /\ is_sint32(Mint_0[shift_sint32(a, 1)]). (* Goal *) When: Mint_0[a_1] = 0. (* Initializer *) - Init: Mint_0[global(L_i_30)] = 0. + Init: Mint_0[global(L_i_32)] = 0. If v <= 3 Then { (* Else *) Have: Mint_0[f2_0] = 0. Have: shift_sint32(a, v) = f2_0. } - Else { Have: global(L_i_30) = f2_0. } + Else { Have: global(L_i_32) = f2_0. } } Prove: a_1 = f2_0. ------------------------------------------------------------ Goal Post-condition 'P_addr_shift' in 'f2': -Let a = global(G_G_18). +Let a = global(G_G_20). Let x = Mint_0[shift_sint32(a, 0)]. Let a_1 = shift_sint32(a, 1). Assume { @@ -77,11 +77,11 @@ Assume { (* Goal *) When: (x != 0) /\ (Mint_0[a_1] = 0). (* Initializer *) - Init: Mint_0[global(L_i_30)] = 0. + Init: Mint_0[global(L_i_32)] = 0. If v <= 3 Then { (* Else *) Have: Mint_0[f2_0] = 0. Have: shift_sint32(a, v) = f2_0. } - Else { Have: global(L_i_30) = f2_0. } + Else { Have: global(L_i_32) = f2_0. } } Prove: a_1 = f2_0. @@ -96,24 +96,24 @@ Prove: true. ------------------------------------------------------------ Goal Post-condition 'P_addr_startof_shift' in 'g': -Let a = global(G_G_18). +Let a = global(G_G_20). Let a_1 = shift_sint32(a, 0). Assume { Type: is_sint32(v) /\ is_sint32(Mint_0[shift_sint32(a, 1)]). (* Goal *) When: Mint_0[a_1] = 0. (* Initializer *) - Init: Mint_0[global(L_i_35)] = 0. + Init: Mint_0[global(L_i_37)] = 0. If v <= 3 Then { (* Else *) Have: Mint_0[g] = 0. Have: shift_sint32(a, v) = g. } - Else { Have: global(L_i_35) = g. } + Else { Have: global(L_i_37) = g. } } Prove: a_1 = g. ------------------------------------------------------------ Goal Post-condition 'P_addr_addr_shift' in 'g': -Let a = global(G_G_18). +Let a = global(G_G_20). Let x = Mint_0[shift_sint32(a, 0)]. Let a_1 = shift_sint32(a, 1). Assume { @@ -121,10 +121,10 @@ Assume { (* Goal *) When: (x != 0) /\ (Mint_0[a_1] = 0). (* Initializer *) - Init: Mint_0[global(L_i_35)] = 0. + Init: Mint_0[global(L_i_37)] = 0. If v <= 3 Then { (* Else *) Have: Mint_0[g] = 0. Have: shift_sint32(a, v) = g. } - Else { Have: global(L_i_35) = g. } + Else { Have: global(L_i_37) = g. } } Prove: a_1 = g. diff --git a/src/plugins/wp/tests/wp_acsl/oracle/init_value_mem.0.res.oracle b/src/plugins/wp/tests/wp_acsl/oracle/init_value_mem.0.res.oracle index 3092db73a21..2e42b9e3cb6 100644 --- a/src/plugins/wp/tests/wp_acsl/oracle/init_value_mem.0.res.oracle +++ b/src/plugins/wp/tests/wp_acsl/oracle/init_value_mem.0.res.oracle @@ -8,7 +8,7 @@ ------------------------------------------------------------ Goal Post-condition 'P' in 'main': -Let a = global(G_v_18). +Let a = global(G_v_20). Let a_1 = Load_S1_St(a, Mint_0). Assume { Type: IsS1_St(w) /\ IsS1_St(a_1). @@ -26,7 +26,7 @@ Prove: EqS1_St(a_1, w). ------------------------------------------------------------ Goal Post-condition 'Q' in 'main': -Let a = global(G_v_18). +Let a = global(G_v_20). Let a_1 = Load_S1_St(a, Mint_0). Assume { Type: IsS1_St(w) /\ IsS1_St(a_1). diff --git a/src/plugins/wp/tests/wp_acsl/oracle/logic.res.oracle b/src/plugins/wp/tests/wp_acsl/oracle/logic.res.oracle index 0f0ac33fa3f..e519f55833a 100644 --- a/src/plugins/wp/tests/wp_acsl/oracle/logic.res.oracle +++ b/src/plugins/wp/tests/wp_acsl/oracle/logic.res.oracle @@ -39,7 +39,7 @@ ------------------------------------------------------------ Goal Post-condition (file tests/wp_acsl/logic.i, line 21) in 'h': -Let a = global(G_t_27). +Let a = global(G_t_29). Let m = Array1_S1(shift___anonstruct_Point_1(a, 0), 3, Mint_0). Let m_1 = Array1_S1(a, 3, Mint_0). Assume { Type: IsArray1S1(m_1) /\ IsArray1S1(m). (* Call 'f' *) Have: P_P(m). @@ -67,11 +67,11 @@ Prove: true. ------------------------------------------------------------ Goal Pre-condition 'qed_ok' in 'main': -Let a = global(G_tr_33). +Let a = global(G_tr_35). Let a_1 = shift___anonstruct_Point_1(a, 2). Let a_2 = shift___anonstruct_Point_1(a, 1). Let a_3 = shift___anonstruct_Point_1(a, 0). -Let a_4 = shiftfield_F4_bytes(global(G_buint_39)). +Let a_4 = shiftfield_F4_bytes(global(G_buint_41)). Let m = Array1_S1(a, 3, Mint_0). Assume { Type: IsArray1S1(m) /\ IsArray1S1(Array1_S1(a_3, 3, Mint_0)). @@ -101,11 +101,11 @@ Prove: P_P(m). ------------------------------------------------------------ Goal Pre-condition 'qed_ok' in 'main': -Let a = global(G_tr_33). +Let a = global(G_tr_35). Let a_1 = shift___anonstruct_Point_1(a, 2). Let a_2 = shift___anonstruct_Point_1(a, 1). Let a_3 = shift___anonstruct_Point_1(a, 0). -Let a_4 = shiftfield_F4_bytes(global(G_buint_39)). +Let a_4 = shiftfield_F4_bytes(global(G_buint_41)). Let m = Array1_S1(a, 3, Mint_0). Assume { Type: IsArray1S1(m) /\ IsArray1S1(Array1_S1(a_3, 3, Mint_0)). @@ -135,11 +135,11 @@ Prove: P_P(m). ------------------------------------------------------------ Goal Pre-condition 'qed_ok' in 'main': -Let a = global(G_tr_33). +Let a = global(G_tr_35). Let a_1 = shift___anonstruct_Point_1(a, 2). Let a_2 = shift___anonstruct_Point_1(a, 1). Let a_3 = shift___anonstruct_Point_1(a, 0). -Let a_4 = shiftfield_F4_bytes(global(G_buint_39)). +Let a_4 = shiftfield_F4_bytes(global(G_buint_41)). Let m = Array1_S1(a_3, 3, Mint_0). Assume { Type: IsArray1S1(Array1_S1(a, 3, Mint_0)) /\ IsArray1S1(m). @@ -220,11 +220,11 @@ Goal Pre-condition 'qed_ok' in 'main': tests/wp_acsl/logic.i:55: warning from wp: - Warning: Hide sub-term definition Reason: Logic cast to struct (Buint) from (unsigned int) not implemented yet -Let a = global(G_tr_33). +Let a = global(G_tr_35). Let a_1 = shift___anonstruct_Point_1(a, 2). Let a_2 = shift___anonstruct_Point_1(a, 1). Let a_3 = shift___anonstruct_Point_1(a, 0). -Let a_4 = global(G_buint_39). +Let a_4 = global(G_buint_41). Let a_5 = shiftfield_F4_bytes(a_4). Let a_6 = Load_S4(a_4, Mint_0). Assume { diff --git a/src/plugins/wp/tests/wp_acsl/oracle/pointer.res.oracle b/src/plugins/wp/tests/wp_acsl/oracle/pointer.res.oracle index 8724a747b0a..1737e32302f 100644 --- a/src/plugins/wp/tests/wp_acsl/oracle/pointer.res.oracle +++ b/src/plugins/wp/tests/wp_acsl/oracle/pointer.res.oracle @@ -26,7 +26,7 @@ Assume { (* Goal *) When: q.offset < p.offset. (* Pre-condition *) - Have: p.base = G_t_19. + Have: p.base = G_t_21. } Prove: addr_lt(q, p). @@ -37,7 +37,7 @@ Assume { (* Goal *) When: i_1 <= i. (* Pre-condition *) - Have: p.base = G_t_19. + Have: p.base = G_t_21. } Prove: i <= i_1. @@ -116,8 +116,8 @@ Goal Post-condition 'qed_ok,Lt' in 'mixed_array_pointer': tests/wp_acsl/pointer.i:45: warning from Reference Variable Model: - Warning: Hide sub-term definition Reason: Uncomparable locations p_0 and mem:t.(0) -Assume { (* Goal *) When: 0 < w. (* Pre-condition *) Have: p.base = G_t_19. } -Prove: addr_lt(shift_sint32(global(G_t_19), 0), p). +Assume { (* Goal *) When: 0 < w. (* Pre-condition *) Have: p.base = G_t_21. } +Prove: addr_lt(shift_sint32(global(G_t_21), 0), p). ------------------------------------------------------------ @@ -125,9 +125,9 @@ Goal Post-condition 'qed_ok,Le' in 'mixed_array_pointer': tests/wp_acsl/pointer.i:46: warning from Reference Variable Model: - Warning: Hide sub-term definition Reason: Uncomparable locations p_0 and mem:t.(0) -Assume { (* Goal *) When: 0 <= w. (* Pre-condition *) Have: p.base = G_t_19. +Assume { (* Goal *) When: 0 <= w. (* Pre-condition *) Have: p.base = G_t_21. } -Prove: addr_le(shift_sint32(global(G_t_19), 0), p). +Prove: addr_le(shift_sint32(global(G_t_21), 0), p). ------------------------------------------------------------ @@ -135,8 +135,8 @@ Goal Post-condition 'qed_ok,Eq' in 'mixed_array_pointer': tests/wp_acsl/pointer.i:47: warning from Reference Variable Model: - Warning: Hide sub-term definition Reason: Uncomparable locations p_0 and mem:t.(0) -Assume { (* Pre-condition *) Have: p.base = G_t_19. } -Prove: shift_sint32(global(G_t_19), 0) = p. +Assume { (* Pre-condition *) Have: p.base = G_t_21. } +Prove: shift_sint32(global(G_t_21), 0) = p. ------------------------------------------------------------ @@ -144,9 +144,9 @@ Goal Post-condition 'qed_ok,Ne' in 'mixed_array_pointer': tests/wp_acsl/pointer.i:48: warning from Reference Variable Model: - Warning: Hide sub-term definition Reason: Uncomparable locations p_0 and mem:t.(0) -Assume { (* Goal *) When: w != 0. (* Pre-condition *) Have: p.base = G_t_19. +Assume { (* Goal *) When: w != 0. (* Pre-condition *) Have: p.base = G_t_21. } -Prove: shift_sint32(global(G_t_19), 0) != p. +Prove: shift_sint32(global(G_t_21), 0) != p. ------------------------------------------------------------ @@ -154,9 +154,9 @@ Goal Post-condition 'qed_ko,Le_oracle_ko' in 'mixed_array_pointer': tests/wp_acsl/pointer.i:49: warning from Reference Variable Model: - Warning: Hide sub-term definition Reason: Uncomparable locations p_0 and mem:t.(0) -Assume { (* Goal *) When: 0 <= w. (* Pre-condition *) Have: p.base = G_t_19. +Assume { (* Goal *) When: 0 <= w. (* Pre-condition *) Have: p.base = G_t_21. } -Prove: addr_lt(shift_sint32(global(G_t_19), 0), p). +Prove: addr_lt(shift_sint32(global(G_t_21), 0), p). ------------------------------------------------------------ @@ -164,8 +164,8 @@ Goal Post-condition 'qed_ko,Lt_oracle_ko' in 'mixed_array_pointer': tests/wp_acsl/pointer.i:50: warning from Reference Variable Model: - Warning: Hide sub-term definition Reason: Uncomparable locations p_0 and mem:t.(0) -Assume { (* Goal *) When: 0 < w. (* Pre-condition *) Have: p.base = G_t_19. } -Prove: addr_le(p, shift_sint32(global(G_t_19), 0)). +Assume { (* Goal *) When: 0 < w. (* Pre-condition *) Have: p.base = G_t_21. } +Prove: addr_le(p, shift_sint32(global(G_t_21), 0)). ------------------------------------------------------------ ------------------------------------------------------------ diff --git a/src/plugins/wp/tests/wp_acsl/oracle/post_result.res.oracle b/src/plugins/wp/tests/wp_acsl/oracle/post_result.res.oracle index 503527e1a7e..0f84cd85b5c 100644 --- a/src/plugins/wp/tests/wp_acsl/oracle/post_result.res.oracle +++ b/src/plugins/wp/tests/wp_acsl/oracle/post_result.res.oracle @@ -16,7 +16,7 @@ Prove: true. ------------------------------------------------------------ Goal Assertion 'KO' (file tests/wp_acsl/post_result.i, line 22): -Let a = shift_sint32(global(G_a_18), 1). +Let a = shift_sint32(global(G_a_20), 1). Let x = Mint_0[a]. Let x_1 = Mint_undef_0[a]. Assume { Type: is_sint32(x) /\ is_sint32(x_1). } diff --git a/src/plugins/wp/tests/wp_bts/oracle/bts0843.res.oracle b/src/plugins/wp/tests/wp_bts/oracle/bts0843.res.oracle index 127e971b35a..27c968f5192 100644 --- a/src/plugins/wp/tests/wp_bts/oracle/bts0843.res.oracle +++ b/src/plugins/wp/tests/wp_bts/oracle/bts0843.res.oracle @@ -18,7 +18,7 @@ Prove: true. Goal Assigns (file tests/wp_bts/bts0843.i, line 14) in 'g3': Call Effect at line 16 -Let a = Mptr_0[global(G_p_18)]. +Let a = Mptr_0[global(G_p_20)]. Let a_1 = shiftfield_F1_a(a). Assume { (* Heap *) @@ -34,7 +34,7 @@ Prove: a_1 = shiftfield_F1_a(Mptr_0[L_p_ref]). Goal Assigns (file tests/wp_bts/bts0843.i, line 14) in 'g3': Call Effect at line 16 -Let a = Mptr_0[global(G_p_18)]. +Let a = Mptr_0[global(G_p_20)]. Let a_1 = shiftfield_F1_a(a). Assume { (* Heap *) diff --git a/src/plugins/wp/tests/wp_bts/oracle/bts986.res.oracle b/src/plugins/wp/tests/wp_bts/oracle/bts986.res.oracle index ce79600349b..f0a8fc075ef 100644 --- a/src/plugins/wp/tests/wp_bts/oracle/bts986.res.oracle +++ b/src/plugins/wp/tests/wp_bts/oracle/bts986.res.oracle @@ -9,6 +9,6 @@ Goal Assertion 'A' (file tests/wp_bts/bts986.i, line 12): Assume { (* Heap *) Type: linked(Malloc_0). } -Prove: !valid_rw(Malloc_0[L_x_21 <- 0], global(L_x_21), 1). +Prove: !valid_rw(Malloc_0[L_x_23 <- 0], global(L_x_23), 1). ------------------------------------------------------------ diff --git a/src/plugins/wp/tests/wp_bts/oracle/bts_1382.res.oracle b/src/plugins/wp/tests/wp_bts/oracle/bts_1382.res.oracle index 06a8ba6dc04..07498d37853 100644 --- a/src/plugins/wp/tests/wp_bts/oracle/bts_1382.res.oracle +++ b/src/plugins/wp/tests/wp_bts/oracle/bts_1382.res.oracle @@ -41,7 +41,7 @@ Assume { (* Then *) Have: i <= 99. } -Prove: global(G_dest_43) = w. +Prove: global(G_dest_45) = w. ------------------------------------------------------------ @@ -66,6 +66,6 @@ Assume { (* Then *) Have: i <= 99. } -Prove: included(a, 4, global(G_dest_43), 1). +Prove: included(a, 4, global(G_dest_45), 1). ------------------------------------------------------------ diff --git a/src/plugins/wp/tests/wp_bts/oracle/bts_1828.0.res.oracle b/src/plugins/wp/tests/wp_bts/oracle/bts_1828.0.res.oracle index 811b400b32b..0054a9afc53 100644 --- a/src/plugins/wp/tests/wp_bts/oracle/bts_1828.0.res.oracle +++ b/src/plugins/wp/tests/wp_bts/oracle/bts_1828.0.res.oracle @@ -63,7 +63,7 @@ Assume { (* Pre-condition *) Have: valid_rw(Malloc_0, one_0, 1). } -Prove: global(L_two_22) != one_0. +Prove: global(L_two_24) != one_0. ------------------------------------------------------------ [wp] Warning: Memory model hypotheses for function 'global_frame': diff --git a/src/plugins/wp/tests/wp_bts/oracle/bts_1828.1.res.oracle b/src/plugins/wp/tests/wp_bts/oracle/bts_1828.1.res.oracle index 665539648c8..3949d8d5a74 100644 --- a/src/plugins/wp/tests/wp_bts/oracle/bts_1828.1.res.oracle +++ b/src/plugins/wp/tests/wp_bts/oracle/bts_1828.1.res.oracle @@ -42,7 +42,7 @@ Assume { (* Pre-condition *) Have: valid_rw(Malloc_0, one_0, 1). } -Prove: global(L_two_22) != one_0. +Prove: global(L_two_24) != one_0. ------------------------------------------------------------ [wp] Warning: Memory model hypotheses for function 'global_frame': diff --git a/src/plugins/wp/tests/wp_bts/oracle/issue_715_b.res.oracle b/src/plugins/wp/tests/wp_bts/oracle/issue_715_b.res.oracle index 433297728cb..06b261910a5 100644 --- a/src/plugins/wp/tests/wp_bts/oracle/issue_715_b.res.oracle +++ b/src/plugins/wp/tests/wp_bts/oracle/issue_715_b.res.oracle @@ -12,7 +12,7 @@ Goal Instance of 'Pre-condition (file tests/wp_bts/issue_715_b.i, line 4) in 'dummy'' in 'foo' at call 'dummy' (file tests/wp_bts/issue_715_b.i, line 11) : Assume { (* Heap *) Type: linked(Malloc_0). } -Prove: P_isValid(Malloc_0[L_p_28 <- 1], shift_sint32(global(L_p_28), 0)). +Prove: P_isValid(Malloc_0[L_p_30 <- 1], shift_sint32(global(L_p_30), 0)). ------------------------------------------------------------ diff --git a/src/plugins/wp/tests/wp_hoare/oracle/logicarr.res.oracle b/src/plugins/wp/tests/wp_hoare/oracle/logicarr.res.oracle index 5e73be63b7d..bfb7581b49d 100644 --- a/src/plugins/wp/tests/wp_hoare/oracle/logicarr.res.oracle +++ b/src/plugins/wp/tests/wp_hoare/oracle/logicarr.res.oracle @@ -8,7 +8,7 @@ ------------------------------------------------------------ Goal Post-condition 'PTR' in 'job': -Let a = global(G_arr_33). +Let a = global(G_arr_35). Let a_1 = shift_sint32(a, i). Let x = Mint_0[a_1]. Let a_2 = shift_sint32(a, j). @@ -25,7 +25,7 @@ Prove: P_p_pointer(m, Mint_0, shift_sint32(a, 0), i, j). ------------------------------------------------------------ Goal Post-condition 'ARR' in 'job': -Let a = global(G_arr_33). +Let a = global(G_arr_35). Let m = Array1_int(a, 10, Mint_0). Let a_1 = shift_sint32(a, i). Let x = Mint_0[a_1]. @@ -43,7 +43,7 @@ Prove: P_p_arrays(m, i, m_1, j). ------------------------------------------------------------ Goal Post-condition 'DUM' in 'job': -Let a = global(G_arr_33). +Let a = global(G_arr_35). Let a_1 = shift_sint32(a, i). Let x = Mint_0[a_1]. Let a_2 = shift_sint32(a, j). diff --git a/src/plugins/wp/tests/wp_hoare/oracle/logicref_simple.res.oracle b/src/plugins/wp/tests/wp_hoare/oracle/logicref_simple.res.oracle index cb5bbabf891..e789d39c37d 100644 --- a/src/plugins/wp/tests/wp_hoare/oracle/logicref_simple.res.oracle +++ b/src/plugins/wp/tests/wp_hoare/oracle/logicref_simple.res.oracle @@ -39,7 +39,7 @@ Prove: true. ------------------------------------------------------------ Goal Post-condition (file tests/wp_hoare/logicref_simple.i, line 19) in 'fsimple_array': -Let a = global(G_t_33). +Let a = global(G_t_35). Let x = Mint_0[shift_sint32(a, 3)]. Assume { Type: is_sint32(x) /\ is_sint32(1 + x). diff --git a/src/plugins/wp/tests/wp_plugin/oracle/dynamic.res.oracle b/src/plugins/wp/tests/wp_plugin/oracle/dynamic.res.oracle index 3caefec4a3e..f61e601b4d2 100644 --- a/src/plugins/wp/tests/wp_plugin/oracle/dynamic.res.oracle +++ b/src/plugins/wp/tests/wp_plugin/oracle/dynamic.res.oracle @@ -77,8 +77,8 @@ Prove: true. Goal Call point f1 f2 in 'call' at instruction (file tests/wp_plugin/dynamic.i, line 30): Let a = Mptr_0[shiftfield_F1_S_f(closure_0)]. -Let a_1 = global(G_f2_28). -Let a_2 = global(G_f1_20). +Let a_1 = global(G_f2_30). +Let a_2 = global(G_f1_22). Let x = Mint_0[shiftfield_F1_S_param(closure_0)]. Assume { Type: is_sint32(x). @@ -115,7 +115,7 @@ Assume { Have: abs_int(x) <= 5. (* Instance of 'f1' *) (* Call point f1 f2 *) - Have: Mptr_0[shiftfield_F1_S_f(closure_0)] = global(G_f1_20). + Have: Mptr_0[shiftfield_F1_S_f(closure_0)] = global(G_f1_22). } Prove: ((-10) <= x) /\ (x <= 10). @@ -137,7 +137,7 @@ Assume { (* Goal *) When: Mptr_0[shiftfield_F1_S_f(p)] = global(0). (* Else *) - Have: G_g_46 = 0. + Have: G_g_48 = 0. } Prove: X = 1. @@ -165,7 +165,7 @@ Prove: true. Goal Call point h1 in 'missing_context' at instruction (file tests/wp_plugin/dynamic.i, line 87): Assume { (* Heap *) Type: region(p.base) <= 0. } -Prove: global(G_h1_59) = p. +Prove: global(G_h1_61) = p. ------------------------------------------------------------ diff --git a/src/plugins/wp/tests/wp_plugin/oracle/flash.0.res.oracle b/src/plugins/wp/tests/wp_plugin/oracle/flash.0.res.oracle index db2c070f9c2..818a355e2d1 100644 --- a/src/plugins/wp/tests/wp_plugin/oracle/flash.0.res.oracle +++ b/src/plugins/wp/tests/wp_plugin/oracle/flash.0.res.oracle @@ -14,9 +14,9 @@ Prove: true. Goal Post-condition 'A_reads' in 'job': Let x = 1 + OBSERVER_time_0. -Let a = global(G_a_62). +Let a = global(G_a_64). Let a_1 = C_RdAt_int(a). -Let a_2 = global(G_b_63). +Let a_2 = global(G_b_65). Let a_3 = C_RdAt_int(a_2). Let a_4 = C_WrAt_int(a_2). Let a_5 = L_RD_update(L_INDEX_init, a). @@ -58,9 +58,9 @@ Prove: L_RD_access(a_7, a) = 2. Goal Post-condition 'B_reads' in 'job': Let x = 1 + OBSERVER_time_0. -Let a = global(G_a_62). +Let a = global(G_a_64). Let a_1 = C_RdAt_int(a). -Let a_2 = global(G_b_63). +Let a_2 = global(G_b_65). Let a_3 = C_RdAt_int(a_2). Let a_4 = C_WrAt_int(a_2). Let a_5 = L_RD_update(L_INDEX_init, a). @@ -102,9 +102,9 @@ Prove: L_RD_access(a_7, a_2) = 1. Goal Post-condition 'B_writes' in 'job': Let x = 1 + OBSERVER_time_0. -Let a = global(G_a_62). +Let a = global(G_a_64). Let a_1 = C_RdAt_int(a). -Let a_2 = global(G_b_63). +Let a_2 = global(G_b_65). Let a_3 = C_RdAt_int(a_2). Let a_4 = C_WrAt_int(a_2). Let a_5 = L_RD_update(L_INDEX_init, a). @@ -146,9 +146,9 @@ Prove: L_WR_access(a_7, a_2) = 1. Goal Post-condition 'ReadValues' in 'job': Let x = 1 + OBSERVER_time_0. -Let a = global(G_a_62). +Let a = global(G_a_64). Let a_1 = C_RdAt_int(a). -Let a_2 = global(G_b_63). +Let a_2 = global(G_b_65). Let a_3 = C_RdAt_int(a_2). Let a_4 = C_WrAt_int(a_2). Let a_5 = L_RD_update(L_INDEX_init, a). @@ -191,9 +191,9 @@ Prove: (x_6 + L_RD_value(a_2, L_RD_access(a_5, a_2)) Goal Post-condition 'WriteValues' in 'job': Let x = 1 + OBSERVER_time_0. -Let a = global(G_a_62). +Let a = global(G_a_64). Let a_1 = C_RdAt_int(a). -Let a_2 = global(G_b_63). +Let a_2 = global(G_b_65). Let a_3 = C_RdAt_int(a_2). Let a_4 = C_WrAt_int(a_2). Let a_5 = L_RD_update(L_INDEX_init, a). diff --git a/src/plugins/wp/tests/wp_plugin/oracle/flash.1.res.oracle b/src/plugins/wp/tests/wp_plugin/oracle/flash.1.res.oracle index ed8294e3ee5..312f0897fc5 100644 --- a/src/plugins/wp/tests/wp_plugin/oracle/flash.1.res.oracle +++ b/src/plugins/wp/tests/wp_plugin/oracle/flash.1.res.oracle @@ -16,9 +16,9 @@ Prove: true. Goal Post-condition 'A_reads' in 'job': Let x = 1 + OBSERVER_time_0. -Let a = global(G_a_62). +Let a = global(G_a_64). Let a_1 = C_RdAt_int(a). -Let a_2 = global(G_b_63). +Let a_2 = global(G_b_65). Let a_3 = C_RdAt_int(a_2). Let a_4 = C_WrAt_int(a_2). Let a_5 = ((const(0))[(a) <- (const(0))[a]+1]). @@ -59,9 +59,9 @@ Prove: (a_7)[a] = 2. Goal Post-condition 'B_reads' in 'job': Let x = 1 + OBSERVER_time_0. -Let a = global(G_a_62). +Let a = global(G_a_64). Let a_1 = C_RdAt_int(a). -Let a_2 = global(G_b_63). +Let a_2 = global(G_b_65). Let a_3 = C_RdAt_int(a_2). Let a_4 = C_WrAt_int(a_2). Let a_5 = ((const(0))[(a) <- (const(0))[a]+1]). @@ -102,9 +102,9 @@ Prove: (a_7)[a_2] = 1. Goal Post-condition 'B_writes' in 'job': Let x = 1 + OBSERVER_time_0. -Let a = global(G_a_62). +Let a = global(G_a_64). Let a_1 = C_RdAt_int(a). -Let a_2 = global(G_b_63). +Let a_2 = global(G_b_65). Let a_3 = C_RdAt_int(a_2). Let a_4 = C_WrAt_int(a_2). Let a_5 = ((const(0))[(a) <- (const(0))[a]+1]). @@ -145,9 +145,9 @@ Prove: (a_7)[a_2] = 1. Goal Post-condition 'ReadValues' in 'job': Let x = 1 + OBSERVER_time_0. -Let a = global(G_a_62). +Let a = global(G_a_64). Let a_1 = C_RdAt_int(a). -Let a_2 = global(G_b_63). +Let a_2 = global(G_b_65). Let a_3 = C_RdAt_int(a_2). Let a_4 = C_WrAt_int(a_2). Let a_5 = ((const(0))[(a) <- (const(0))[a]+1]). @@ -188,9 +188,9 @@ Prove: (x_6 + L_RD_value(a_2, (a_5)[a_2]) + L_RD_value(a, (a_6)[a])) Goal Post-condition 'WriteValues' in 'job': Let x = 1 + OBSERVER_time_0. -Let a = global(G_a_62). +Let a = global(G_a_64). Let a_1 = C_RdAt_int(a). -Let a_2 = global(G_b_63). +Let a_2 = global(G_b_65). Let a_3 = C_RdAt_int(a_2). Let a_4 = C_WrAt_int(a_2). Let a_5 = ((const(0))[(a) <- (const(0))[a]+1]). diff --git a/src/plugins/wp/tests/wp_plugin/oracle/frame.res.oracle b/src/plugins/wp/tests/wp_plugin/oracle/frame.res.oracle index a4a77a805e6..3ef9251b463 100644 --- a/src/plugins/wp/tests/wp_plugin/oracle/frame.res.oracle +++ b/src/plugins/wp/tests/wp_plugin/oracle/frame.res.oracle @@ -8,7 +8,7 @@ ------------------------------------------------------------ Goal Post-condition 'KO' in 'alias': -Let a = global(P_r_39). +Let a = global(P_r_41). Let x = Mint_1[a]. Let x_1 = Mint_0[a]. Assume { Type: is_sint32(x) /\ is_sint32(x_1). } diff --git a/src/plugins/wp/tests/wp_plugin/oracle/init_const_guard.res.oracle b/src/plugins/wp/tests/wp_plugin/oracle/init_const_guard.res.oracle index a055c763f22..3fcaa7780cb 100644 --- a/src/plugins/wp/tests/wp_plugin/oracle/init_const_guard.res.oracle +++ b/src/plugins/wp/tests/wp_plugin/oracle/init_const_guard.res.oracle @@ -14,7 +14,7 @@ Prove: true. Goal Post-condition 'Pointed_Valid' in 'f': Assume { (* Heap *) Type: linked(Malloc_0). } -Prove: valid_rw(Malloc_0, global(G_x_18), 1). +Prove: valid_rw(Malloc_0, global(G_x_20), 1). ------------------------------------------------------------ @@ -38,12 +38,12 @@ Prove: true. Goal Assertion 'Read' (file tests/wp_plugin/init_const_guard.i, line 31): Assume { (* Heap *) Type: linked(Malloc_0). } -Prove: valid_rd(Malloc_0, global(G_x_18), 1). +Prove: valid_rd(Malloc_0, global(G_x_20), 1). ------------------------------------------------------------ Goal Assertion 'Guard_against_Const' (file tests/wp_plugin/init_const_guard.i, line 32): -Let a = global(G_x_18). +Let a = global(G_x_20). Assume { (* Heap *) Type: linked(Malloc_0). diff --git a/src/plugins/wp/tests/wp_plugin/oracle/initarr.res.oracle b/src/plugins/wp/tests/wp_plugin/oracle/initarr.res.oracle index 59ec8e29771..402be8d8ac5 100644 --- a/src/plugins/wp/tests/wp_plugin/oracle/initarr.res.oracle +++ b/src/plugins/wp/tests/wp_plugin/oracle/initarr.res.oracle @@ -18,17 +18,17 @@ Assume { Type: forall i_1 : Z. let a_4 = A[i_1] in (region(a_4.F1_f.base) <= 0) /\ (region(a_4.F1_g.base) <= 0). (* Initializer *) - Init: (a_2.F1_f) = global(G_a_18). + Init: (a_2.F1_f) = global(G_a_20). (* Initializer *) - Init: (a_2.F1_g) = global(G_b_19). + Init: (a_2.F1_g) = global(G_b_21). (* Initializer *) - Init: (a_1.F1_f) = global(G_c_20). + Init: (a_1.F1_f) = global(G_c_22). (* Initializer *) - Init: (a_1.F1_g) = global(G_d_21). + Init: (a_1.F1_g) = global(G_d_23). (* Initializer *) - Init: (a.F1_f) = global(G_e_22). + Init: (a.F1_f) = global(G_e_24). (* Initializer *) - Init: (a.F1_g) = global(G_f_23). + Init: (a.F1_g) = global(G_f_25). (* Pre-condition *) Have: (0 <= i) /\ (i <= 2). } @@ -37,9 +37,9 @@ Prove: (a_3.F1_g) != (a_3.F1_f). ------------------------------------------------------------ Goal Post-condition 'ALT' in 'job': -Let a = global(G_e_22). -Let a_1 = global(G_c_20). -Let a_2 = global(G_a_18). +Let a = global(G_e_24). +Let a_1 = global(G_c_22). +Let a_2 = global(G_a_20). Let a_3 = A[i].F1_f. Assume { Type: is_sint32(i). diff --git a/src/plugins/wp/tests/wp_plugin/oracle/overassign.res.oracle b/src/plugins/wp/tests/wp_plugin/oracle/overassign.res.oracle index 67cb9a837b5..53a71fb06d7 100644 --- a/src/plugins/wp/tests/wp_plugin/oracle/overassign.res.oracle +++ b/src/plugins/wp/tests/wp_plugin/oracle/overassign.res.oracle @@ -40,14 +40,14 @@ Prove: true. Goal Assigns nothing in 'f3_ok': Call Effect at line 20 Assume { (* Heap *) Type: linked(Malloc_0). } -Prove: invalid(Malloc_0, shift_sint32(global(G_A_30), 20), 10). +Prove: invalid(Malloc_0, shift_sint32(global(G_A_32), 20), 10). ------------------------------------------------------------ Goal Assigns nothing in 'f3_ok': Call Effect at line 20 Assume { (* Heap *) Type: linked(Malloc_0). } -Prove: invalid(Malloc_0, shift_sint32(global(G_A_30), 20), 10). +Prove: invalid(Malloc_0, shift_sint32(global(G_A_32), 20), 10). ------------------------------------------------------------ ------------------------------------------------------------ @@ -57,14 +57,14 @@ Prove: invalid(Malloc_0, shift_sint32(global(G_A_30), 20), 10). Goal Assigns nothing in 'f4_ok': Call Effect at line 23 Assume { (* Heap *) Type: linked(Malloc_0). } -Prove: invalid(Malloc_0, shift_sint32(global(G_A_30), -10), 10). +Prove: invalid(Malloc_0, shift_sint32(global(G_A_32), -10), 10). ------------------------------------------------------------ Goal Assigns nothing in 'f4_ok': Call Effect at line 23 Assume { (* Heap *) Type: linked(Malloc_0). } -Prove: invalid(Malloc_0, shift_sint32(global(G_A_30), -10), 10). +Prove: invalid(Malloc_0, shift_sint32(global(G_A_32), -10), 10). ------------------------------------------------------------ ------------------------------------------------------------ @@ -74,14 +74,14 @@ Prove: invalid(Malloc_0, shift_sint32(global(G_A_30), -10), 10). Goal Assigns nothing in 'f5_ko': Call Effect at line 26 Assume { (* Heap *) Type: linked(Malloc_0). } -Prove: invalid(Malloc_0, shift_sint32(global(G_A_30), 15), 10). +Prove: invalid(Malloc_0, shift_sint32(global(G_A_32), 15), 10). ------------------------------------------------------------ Goal Assigns nothing in 'f5_ko': Call Effect at line 26 Assume { (* Heap *) Type: linked(Malloc_0). } -Prove: invalid(Malloc_0, shift_sint32(global(G_A_30), 15), 10). +Prove: invalid(Malloc_0, shift_sint32(global(G_A_32), 15), 10). ------------------------------------------------------------ ------------------------------------------------------------ @@ -91,13 +91,13 @@ Prove: invalid(Malloc_0, shift_sint32(global(G_A_30), 15), 10). Goal Assigns nothing in 'f6_ko': Call Effect at line 29 Assume { (* Heap *) Type: linked(Malloc_0). } -Prove: invalid(Malloc_0, shift_sint32(global(G_A_30), -5), 10). +Prove: invalid(Malloc_0, shift_sint32(global(G_A_32), -5), 10). ------------------------------------------------------------ Goal Assigns nothing in 'f6_ko': Call Effect at line 29 Assume { (* Heap *) Type: linked(Malloc_0). } -Prove: invalid(Malloc_0, shift_sint32(global(G_A_30), -5), 10). +Prove: invalid(Malloc_0, shift_sint32(global(G_A_32), -5), 10). ------------------------------------------------------------ diff --git a/src/plugins/wp/tests/wp_plugin/oracle/subset_fopen.res.oracle b/src/plugins/wp/tests/wp_plugin/oracle/subset_fopen.res.oracle index eec7909c061..d18122a712f 100644 --- a/src/plugins/wp/tests/wp_plugin/oracle/subset_fopen.res.oracle +++ b/src/plugins/wp/tests/wp_plugin/oracle/subset_fopen.res.oracle @@ -38,7 +38,7 @@ Assume { (* Assertion 'Ok_A' *) Have: (0 <= i) /\ (i <= 9). (* Call 'fopen' *) - Have: included(p, 2, shift___fc_FILE(global(G___fc_fopen_19), 0), 1024). + Have: included(p, 2, shift___fc_FILE(global(G___fc_fopen_21), 0), 1024). } Prove: valid_rw(Malloc_0, p, 2). diff --git a/src/plugins/wp/tests/wp_store/oracle/struct.res.oracle b/src/plugins/wp/tests/wp_store/oracle/struct.res.oracle index 730ef7717db..5b15a883bf9 100644 --- a/src/plugins/wp/tests/wp_store/oracle/struct.res.oracle +++ b/src/plugins/wp/tests/wp_store/oracle/struct.res.oracle @@ -43,7 +43,7 @@ Prove: true. ------------------------------------------------------------ Goal Post-condition 'P,qed_ok' in 'main': -Let a = global(G_v_28). +Let a = global(G_v_30). Let a_1 = Load_S2_St(a, Mint_0). Assume { Type: IsS2_St(w) /\ IsS2_St(a_1). @@ -61,7 +61,7 @@ Prove: EqS2_St(a_1, w). ------------------------------------------------------------ Goal Post-condition 'Q,qed_ok' in 'main': -Let a = global(G_v_28). +Let a = global(G_v_30). Let a_1 = Load_S2_St(a, Mint_0). Assume { Type: IsS2_St(w) /\ IsS2_St(a_1). diff --git a/src/plugins/wp/tests/wp_typed/oracle/array_initialized.0.res.oracle b/src/plugins/wp/tests/wp_typed/oracle/array_initialized.0.res.oracle index dcd53447520..b461930a19a 100644 --- a/src/plugins/wp/tests/wp_typed/oracle/array_initialized.0.res.oracle +++ b/src/plugins/wp/tests/wp_typed/oracle/array_initialized.0.res.oracle @@ -259,7 +259,7 @@ Assume { When: (0 <= i) /\ (i <= 499). (* Initializer *) Init: forall i_1 : Z. ((0 <= i_1) -> ((i_1 <= 499) -> - (p[i_1] = global(G_p0_28)))). + (p[i_1] = global(G_p0_30)))). } Prove: valid_rw(Malloc_0, p[i], 1). diff --git a/src/plugins/wp/tests/wp_typed/oracle/array_initialized.1.res.oracle b/src/plugins/wp/tests/wp_typed/oracle/array_initialized.1.res.oracle index 2831cde85ee..a4351662142 100644 --- a/src/plugins/wp/tests/wp_typed/oracle/array_initialized.1.res.oracle +++ b/src/plugins/wp/tests/wp_typed/oracle/array_initialized.1.res.oracle @@ -10,7 +10,7 @@ ------------------------------------------------------------ Goal Assertion (file tests/wp_typed/array_initialized.c, line 71): -Let a = global(K_g_18). +Let a = global(K_g_20). Assume { (* Goal *) When: (0 <= i) /\ (i <= 499). @@ -26,8 +26,8 @@ Prove: Mint_0[shift_sint32(a, i)] = 0. ------------------------------------------------------------ Goal Assertion (file tests/wp_typed/array_initialized.c, line 185): -Let a = global(K_h1_24). -Let a_1 = global(K_h2_25). +Let a = global(K_h1_26). +Let a_1 = global(K_h2_27). Assume { (* Goal *) When: (0 <= i) /\ (i <= 499). @@ -254,7 +254,7 @@ Prove: true. ------------------------------------------------------------ Goal Assertion (file tests/wp_typed/array_initialized.c, line 283): -Let a = global(K_p_32). +Let a = global(K_p_34). Assume { (* Heap *) Type: framed(Mptr_0) /\ linked(Malloc_0). @@ -262,7 +262,7 @@ Assume { When: (0 <= i) /\ (i <= 499). (* Initializer *) Init: forall i_1 : Z. ((0 <= i_1) -> ((i_1 <= 499) -> - (Mptr_0[shift_PTR(a, i_1)] = global(G_p0_31)))). + (Mptr_0[shift_PTR(a, i_1)] = global(G_p0_33)))). } Prove: valid_rw(Malloc_0, Mptr_0[shift_PTR(a, i)], 1). diff --git a/src/plugins/wp/tests/wp_typed/oracle/frame.0.res.oracle b/src/plugins/wp/tests/wp_typed/oracle/frame.0.res.oracle index 2407c64b95d..1e91b9fe01b 100644 --- a/src/plugins/wp/tests/wp_typed/oracle/frame.0.res.oracle +++ b/src/plugins/wp/tests/wp_typed/oracle/frame.0.res.oracle @@ -16,13 +16,13 @@ Assume { (* Pre-condition *) Have: (0 <= k) /\ (k <= 19). } -Prove: (comp_0[k].F1_ptr) != global(L_m_26). +Prove: (comp_0[k].F1_ptr) != global(L_m_28). ------------------------------------------------------------ Goal Assertion 'RES' (file tests/wp_typed/frame.i, line 11): Let a = comp_0[k].F1_ptr. -Let a_1 = global(L_m_26). +Let a_1 = global(L_m_28). Let x = Mint_0[a <- 4][a_1]. Assume { Type: is_sint32(k) /\ is_sint32(x). diff --git a/src/plugins/wp/tests/wp_typed/oracle/frame.1.res.oracle b/src/plugins/wp/tests/wp_typed/oracle/frame.1.res.oracle index bb4a852b80b..3cc68cc1bef 100644 --- a/src/plugins/wp/tests/wp_typed/oracle/frame.1.res.oracle +++ b/src/plugins/wp/tests/wp_typed/oracle/frame.1.res.oracle @@ -16,13 +16,13 @@ Assume { (* Pre-condition *) Have: (0 <= k) /\ (k <= 19). } -Prove: (comp_0[k].F1_ptr) != global(L_m_26). +Prove: (comp_0[k].F1_ptr) != global(L_m_28). ------------------------------------------------------------ Goal Assertion 'RES' (file tests/wp_typed/frame.i, line 11): Let a = comp_0[k].F1_ptr. -Let a_1 = global(L_m_26). +Let a_1 = global(L_m_28). Let x = Mint_0[a <- 4][a_1]. Assume { Type: is_sint32(k) /\ is_sint32(x). diff --git a/src/plugins/wp/tests/wp_typed/oracle/unit_alloc.0.res.oracle b/src/plugins/wp/tests/wp_typed/oracle/unit_alloc.0.res.oracle index 190fb6be9db..dc5985c4828 100644 --- a/src/plugins/wp/tests/wp_typed/oracle/unit_alloc.0.res.oracle +++ b/src/plugins/wp/tests/wp_typed/oracle/unit_alloc.0.res.oracle @@ -26,7 +26,7 @@ Prove: true. Goal Post-condition (file tests/wp_typed/unit_alloc.i, line 33) in 'h': Assume { (* Heap *) Type: linked(Malloc_0). } -Prove: !valid_rw(Malloc_0[P_x_38 <- 0], global(P_x_38), 1). +Prove: !valid_rw(Malloc_0[P_x_40 <- 0], global(P_x_40), 1). ------------------------------------------------------------ ------------------------------------------------------------ @@ -40,7 +40,7 @@ Prove: true. Goal Assertion (file tests/wp_typed/unit_alloc.i, line 21): Assume { (* Heap *) Type: linked(Malloc_0). } -Prove: valid_rw(Malloc_0[L_y_23 <- 1], global(L_y_23), 1). +Prove: valid_rw(Malloc_0[L_y_25 <- 1], global(L_y_25), 1). ------------------------------------------------------------ @@ -50,13 +50,13 @@ Prove: true. ------------------------------------------------------------ Goal Assertion (file tests/wp_typed/unit_alloc.i, line 24): -Let a = global(L_y_23). +Let a = global(L_y_25). Assume { (* Heap *) Type: linked(Malloc_0). (* Assertion *) - Have: valid_rw(Malloc_0[L_y_23 <- 1], a, 1). + Have: valid_rw(Malloc_0[L_y_25 <- 1], a, 1). } -Prove: !valid_rw(Malloc_0[L_y_23 <- 0], a, 1). +Prove: !valid_rw(Malloc_0[L_y_25 <- 0], a, 1). ------------------------------------------------------------ diff --git a/src/plugins/wp/tests/wp_typed/oracle/unit_alloc.1.res.oracle b/src/plugins/wp/tests/wp_typed/oracle/unit_alloc.1.res.oracle index 38f2578d643..3716b8fceb3 100644 --- a/src/plugins/wp/tests/wp_typed/oracle/unit_alloc.1.res.oracle +++ b/src/plugins/wp/tests/wp_typed/oracle/unit_alloc.1.res.oracle @@ -26,7 +26,7 @@ Prove: true. Goal Post-condition (file tests/wp_typed/unit_alloc.i, line 33) in 'h': Assume { (* Heap *) Type: linked(Malloc_0). } -Prove: !valid_rw(Malloc_0[P_x_38 <- 0], global(P_x_38), 1). +Prove: !valid_rw(Malloc_0[P_x_40 <- 0], global(P_x_40), 1). ------------------------------------------------------------ ------------------------------------------------------------ @@ -40,7 +40,7 @@ Prove: true. Goal Assertion (file tests/wp_typed/unit_alloc.i, line 21): Assume { (* Heap *) Type: linked(Malloc_0). } -Prove: valid_rw(Malloc_0[L_y_23 <- 1], global(L_y_23), 1). +Prove: valid_rw(Malloc_0[L_y_25 <- 1], global(L_y_25), 1). ------------------------------------------------------------ @@ -50,13 +50,13 @@ Prove: true. ------------------------------------------------------------ Goal Assertion (file tests/wp_typed/unit_alloc.i, line 24): -Let a = global(L_y_23). +Let a = global(L_y_25). Assume { (* Heap *) Type: linked(Malloc_0). (* Assertion *) - Have: valid_rw(Malloc_0[L_y_23 <- 1], a, 1). + Have: valid_rw(Malloc_0[L_y_25 <- 1], a, 1). } -Prove: !valid_rw(Malloc_0[L_y_23 <- 0], a, 1). +Prove: !valid_rw(Malloc_0[L_y_25 <- 0], a, 1). ------------------------------------------------------------ diff --git a/src/plugins/wp/tests/wp_typed/oracle/unit_local.0.res.oracle b/src/plugins/wp/tests/wp_typed/oracle/unit_local.0.res.oracle index dfa5e2f13d2..e81bad545d0 100644 --- a/src/plugins/wp/tests/wp_typed/oracle/unit_local.0.res.oracle +++ b/src/plugins/wp/tests/wp_typed/oracle/unit_local.0.res.oracle @@ -25,6 +25,6 @@ Prove: true. Goal Assigns nothing in 'foo' (2/2): Effect at line 19 Assume { (* Heap *) Type: linked(Malloc_0). } -Prove: invalid(Malloc_0, global(L_a_21), 1). +Prove: invalid(Malloc_0, global(L_a_23), 1). ------------------------------------------------------------ diff --git a/src/plugins/wp/tests/wp_typed/oracle/unit_local.1.res.oracle b/src/plugins/wp/tests/wp_typed/oracle/unit_local.1.res.oracle index 106ea82cce5..ca652b49c38 100644 --- a/src/plugins/wp/tests/wp_typed/oracle/unit_local.1.res.oracle +++ b/src/plugins/wp/tests/wp_typed/oracle/unit_local.1.res.oracle @@ -10,7 +10,7 @@ Goal Assigns nothing in 'bar': Effect at line 28 Assume { (* Heap *) Type: linked(Malloc_0). } -Prove: invalid(Malloc_0, global(L_a_26), 1). +Prove: invalid(Malloc_0, global(L_a_28), 1). ------------------------------------------------------------ ------------------------------------------------------------ @@ -20,13 +20,13 @@ Prove: invalid(Malloc_0, global(L_a_26), 1). Goal Assigns nothing in 'foo' (1/2): Effect at line 18 Assume { (* Heap *) Type: linked(Malloc_0). } -Prove: invalid(Malloc_0, global(L_pa_22), 1). +Prove: invalid(Malloc_0, global(L_pa_24), 1). ------------------------------------------------------------ Goal Assigns nothing in 'foo' (2/2): Effect at line 19 Assume { (* Heap *) Type: linked(Malloc_0). } -Prove: invalid(Malloc_0, global(L_a_21), 1). +Prove: invalid(Malloc_0, global(L_a_23), 1). ------------------------------------------------------------ diff --git a/src/plugins/wp/tests/wp_typed/oracle/user_init.0.res.oracle b/src/plugins/wp/tests/wp_typed/oracle/user_init.0.res.oracle index 361403d8aa2..999fd9b7424 100644 --- a/src/plugins/wp/tests/wp_typed/oracle/user_init.0.res.oracle +++ b/src/plugins/wp/tests/wp_typed/oracle/user_init.0.res.oracle @@ -232,7 +232,7 @@ Prove: true. ------------------------------------------------------------ Goal Post-condition (file tests/wp_typed/user_init.i, line 127) in 'init_t2_bis_v1': -Let a = global(G_t2_50). +Let a = global(G_t2_52). Assume { Type: is_uint32(i_2) /\ is_sint32(v). (* Goal *) @@ -262,7 +262,7 @@ Prove: true. ------------------------------------------------------------ Goal Preservation of Invariant 'Partial' (file tests/wp_typed/user_init.i, line 136): -Let a = global(G_t2_50). +Let a = global(G_t2_52). Let a_1 = shift_A20_sint32(a, i). Let a_2 = shift_sint32(a_1, 0). Let a_3 = havoc(Mint_undef_0, Mint_0, a_2, 20). @@ -298,7 +298,7 @@ Prove: true. ------------------------------------------------------------ Goal Preservation of Invariant 'Range' (file tests/wp_typed/user_init.i, line 135): -Let a = global(G_t2_50). +Let a = global(G_t2_52). Let a_1 = shift_A20_sint32(a, i). Assume { Type: is_uint32(i) /\ is_sint32(v). @@ -342,7 +342,7 @@ Prove: true. Goal Loop assigns 'lack,Zone' (2/3): Effect at line 139 -Let a = global(G_t2_50). +Let a = global(G_t2_52). Let a_1 = shift_A20_sint32(a, i_2). Assume { Type: is_uint32(i_2) /\ is_sint32(v). @@ -376,7 +376,7 @@ Prove: exists i_8,i_7 : Z. (i_8 <= i) /\ (i_7 <= i_1) /\ (0 <= i_8) /\ Goal Loop assigns 'lack,Zone' (3/3): Call Effect at line 140 -Let a = global(G_t2_50). +Let a = global(G_t2_52). Let a_1 = shift_A20_sint32(a, i). Assume { Type: is_uint32(i) /\ is_sint32(v). @@ -425,7 +425,7 @@ Assume { Have: forall a : addr. ((forall i_5,i_4 : Z. ((0 <= i_5) -> ((0 <= i_4) -> ((i_5 <= 9) -> ((i_4 <= 19) -> - (shift_sint32(shift_A20_sint32(global(G_t2_50), i_5), i_4) != a)))))) -> + (shift_sint32(shift_A20_sint32(global(G_t2_52), i_5), i_4) != a)))))) -> (Mint_0[a] = Mint_1[a])). } Prove: exists i_5,i_4 : Z. (i_5 <= i) /\ (i_4 <= i_1) /\ (0 <= i_5) /\ @@ -460,7 +460,7 @@ Assume { Have: forall a : addr. ((forall i_5,i_4 : Z. ((0 <= i_5) -> ((0 <= i_4) -> ((i_5 <= 9) -> ((i_4 <= 19) -> - (shift_sint32(shift_A20_sint32(global(G_t2_50), i_5), i_4) != a)))))) -> + (shift_sint32(shift_A20_sint32(global(G_t2_52), i_5), i_4) != a)))))) -> (Mint_0[a] = Mint_1[a])). } Prove: exists i_5,i_4 : Z. (i_5 <= i) /\ (i_4 <= i_1) /\ (0 <= i_5) /\ @@ -469,7 +469,7 @@ Prove: exists i_5,i_4 : Z. (i_5 <= i) /\ (i_4 <= i_1) /\ (0 <= i_5) /\ ------------------------------------------------------------ Goal Decreasing of Loop variant at loop (file tests/wp_typed/user_init.i, line 139): -Let a = global(G_t2_50). +Let a = global(G_t2_52). Let a_1 = shift_A20_sint32(a, i). Assume { Type: is_uint32(i) /\ is_sint32(v). @@ -517,7 +517,7 @@ Prove: true. ------------------------------------------------------------ Goal Post-condition (file tests/wp_typed/user_init.i, line 145) in 'init_t2_bis_v2': -Let a = global(G_t2_50). +Let a = global(G_t2_52). Assume { Type: is_uint32(i_2) /\ is_sint32(v). (* Goal *) @@ -546,7 +546,7 @@ Prove: true. ------------------------------------------------------------ Goal Preservation of Invariant 'Partial' (file tests/wp_typed/user_init.i, line 154): -Let a = global(G_t2_50). +Let a = global(G_t2_52). Let a_1 = shift_A20_sint32(a, i). Let a_2 = shift_sint32(a_1, 0). Let a_3 = havoc(Mint_undef_0, Mint_0, a_2, 20). @@ -581,7 +581,7 @@ Prove: true. ------------------------------------------------------------ Goal Preservation of Invariant 'Range' (file tests/wp_typed/user_init.i, line 153): -Let a = global(G_t2_50). +Let a = global(G_t2_52). Let a_1 = shift_A20_sint32(a, i). Assume { Type: is_uint32(i) /\ is_sint32(v). @@ -624,7 +624,7 @@ Prove: true. Goal Loop assigns 'tactic,Zone' (2/3): Effect at line 157 -Let a = global(G_t2_50). +Let a = global(G_t2_52). Let a_1 = shift_A20_sint32(a, i_2). Assume { Type: is_uint32(i_2) /\ is_sint32(v). @@ -656,7 +656,7 @@ Prove: exists i_7,i_6 : Z. (i_7 <= i) /\ (i_6 <= i_1) /\ (0 <= i_7) /\ Goal Loop assigns 'tactic,Zone' (3/3): Call Effect at line 158 -Let a = global(G_t2_50). +Let a = global(G_t2_52). Let a_1 = shift_A20_sint32(a, i). Assume { Type: is_uint32(i) /\ is_sint32(v). @@ -701,7 +701,7 @@ Assume { (* Loop assigns 'tactic,Zone' *) Have: forall a : addr. ((forall i_5,i_4 : Z. ((0 <= i_5) -> ((i_5 <= 9) -> - (shift_sint32(shift_A20_sint32(global(G_t2_50), i_5), i_4) != a)))) -> + (shift_sint32(shift_A20_sint32(global(G_t2_52), i_5), i_4) != a)))) -> (Mint_0[a] = Mint_1[a])). } Prove: exists i_5,i_4 : Z. (i_5 <= i) /\ (i_4 <= i_1) /\ (0 <= i_5) /\ @@ -733,7 +733,7 @@ Assume { (* Loop assigns 'tactic,Zone' *) Have: forall a : addr. ((forall i_5,i_4 : Z. ((0 <= i_5) -> ((i_5 <= 9) -> - (shift_sint32(shift_A20_sint32(global(G_t2_50), i_5), i_4) != a)))) -> + (shift_sint32(shift_A20_sint32(global(G_t2_52), i_5), i_4) != a)))) -> (Mint_0[a] = Mint_1[a])). } Prove: exists i_5,i_4 : Z. (i_5 <= i) /\ (i_4 <= i_1) /\ (0 <= i_5) /\ @@ -742,7 +742,7 @@ Prove: exists i_5,i_4 : Z. (i_5 <= i) /\ (i_4 <= i_1) /\ (0 <= i_5) /\ ------------------------------------------------------------ Goal Decreasing of Loop variant at loop (file tests/wp_typed/user_init.i, line 157): -Let a = global(G_t2_50). +Let a = global(G_t2_52). Let a_1 = shift_A20_sint32(a, i). Assume { Type: is_uint32(i) /\ is_sint32(v). diff --git a/src/plugins/wp/tests/wp_typed/oracle/user_init.1.res.oracle b/src/plugins/wp/tests/wp_typed/oracle/user_init.1.res.oracle index 0247f47de97..e6996907f93 100644 --- a/src/plugins/wp/tests/wp_typed/oracle/user_init.1.res.oracle +++ b/src/plugins/wp/tests/wp_typed/oracle/user_init.1.res.oracle @@ -232,7 +232,7 @@ Prove: true. ------------------------------------------------------------ Goal Post-condition (file tests/wp_typed/user_init.i, line 127) in 'init_t2_bis_v1': -Let a = global(G_t2_50). +Let a = global(G_t2_52). Assume { Type: is_uint32(i_2) /\ is_sint32(v). (* Goal *) @@ -262,7 +262,7 @@ Prove: true. ------------------------------------------------------------ Goal Preservation of Invariant 'Partial' (file tests/wp_typed/user_init.i, line 136): -Let a = global(G_t2_50). +Let a = global(G_t2_52). Let a_1 = shift_A20_sint32(a, i). Let a_2 = shift_sint32(a_1, 0). Let a_3 = havoc(Mint_undef_0, Mint_0, a_2, 20). @@ -298,7 +298,7 @@ Prove: true. ------------------------------------------------------------ Goal Preservation of Invariant 'Range' (file tests/wp_typed/user_init.i, line 135): -Let a = global(G_t2_50). +Let a = global(G_t2_52). Let a_1 = shift_A20_sint32(a, i). Assume { Type: is_uint32(i) /\ is_sint32(v). @@ -342,7 +342,7 @@ Prove: true. Goal Loop assigns 'lack,Zone' (2/3): Effect at line 139 -Let a = global(G_t2_50). +Let a = global(G_t2_52). Let a_1 = shift_A20_sint32(a, i_2). Assume { Type: is_uint32(i_2) /\ is_sint32(v). @@ -376,7 +376,7 @@ Prove: exists i_8,i_7 : Z. (i_8 <= i) /\ (i_7 <= i_1) /\ (0 <= i_8) /\ Goal Loop assigns 'lack,Zone' (3/3): Call Effect at line 140 -Let a = global(G_t2_50). +Let a = global(G_t2_52). Let a_1 = shift_A20_sint32(a, i). Assume { Type: is_uint32(i) /\ is_sint32(v). @@ -425,7 +425,7 @@ Assume { Have: forall a : addr. ((forall i_5,i_4 : Z. ((0 <= i_5) -> ((0 <= i_4) -> ((i_5 <= 9) -> ((i_4 <= 19) -> - (shift_sint32(shift_A20_sint32(global(G_t2_50), i_5), i_4) != a)))))) -> + (shift_sint32(shift_A20_sint32(global(G_t2_52), i_5), i_4) != a)))))) -> (Mint_0[a] = Mint_1[a])). } Prove: exists i_5,i_4 : Z. (i_5 <= i) /\ (i_4 <= i_1) /\ (0 <= i_5) /\ @@ -460,7 +460,7 @@ Assume { Have: forall a : addr. ((forall i_5,i_4 : Z. ((0 <= i_5) -> ((0 <= i_4) -> ((i_5 <= 9) -> ((i_4 <= 19) -> - (shift_sint32(shift_A20_sint32(global(G_t2_50), i_5), i_4) != a)))))) -> + (shift_sint32(shift_A20_sint32(global(G_t2_52), i_5), i_4) != a)))))) -> (Mint_0[a] = Mint_1[a])). } Prove: exists i_5,i_4 : Z. (i_5 <= i) /\ (i_4 <= i_1) /\ (0 <= i_5) /\ @@ -469,7 +469,7 @@ Prove: exists i_5,i_4 : Z. (i_5 <= i) /\ (i_4 <= i_1) /\ (0 <= i_5) /\ ------------------------------------------------------------ Goal Decreasing of Loop variant at loop (file tests/wp_typed/user_init.i, line 139): -Let a = global(G_t2_50). +Let a = global(G_t2_52). Let a_1 = shift_A20_sint32(a, i). Assume { Type: is_uint32(i) /\ is_sint32(v). @@ -517,7 +517,7 @@ Prove: true. ------------------------------------------------------------ Goal Post-condition (file tests/wp_typed/user_init.i, line 145) in 'init_t2_bis_v2': -Let a = global(G_t2_50). +Let a = global(G_t2_52). Assume { Type: is_uint32(i_2) /\ is_sint32(v). (* Goal *) @@ -546,7 +546,7 @@ Prove: true. ------------------------------------------------------------ Goal Preservation of Invariant 'Partial' (file tests/wp_typed/user_init.i, line 154): -Let a = global(G_t2_50). +Let a = global(G_t2_52). Let a_1 = shift_A20_sint32(a, i). Let a_2 = shift_sint32(a_1, 0). Let a_3 = havoc(Mint_undef_0, Mint_0, a_2, 20). @@ -581,7 +581,7 @@ Prove: true. ------------------------------------------------------------ Goal Preservation of Invariant 'Range' (file tests/wp_typed/user_init.i, line 153): -Let a = global(G_t2_50). +Let a = global(G_t2_52). Let a_1 = shift_A20_sint32(a, i). Assume { Type: is_uint32(i) /\ is_sint32(v). @@ -624,7 +624,7 @@ Prove: true. Goal Loop assigns 'tactic,Zone' (2/3): Effect at line 157 -Let a = global(G_t2_50). +Let a = global(G_t2_52). Let a_1 = shift_A20_sint32(a, i_2). Assume { Type: is_uint32(i_2) /\ is_sint32(v). @@ -656,7 +656,7 @@ Prove: exists i_7,i_6 : Z. (i_7 <= i) /\ (i_6 <= i_1) /\ (0 <= i_7) /\ Goal Loop assigns 'tactic,Zone' (3/3): Call Effect at line 158 -Let a = global(G_t2_50). +Let a = global(G_t2_52). Let a_1 = shift_A20_sint32(a, i). Assume { Type: is_uint32(i) /\ is_sint32(v). @@ -701,7 +701,7 @@ Assume { (* Loop assigns 'tactic,Zone' *) Have: forall a : addr. ((forall i_5,i_4 : Z. ((0 <= i_5) -> ((i_5 <= 9) -> - (shift_sint32(shift_A20_sint32(global(G_t2_50), i_5), i_4) != a)))) -> + (shift_sint32(shift_A20_sint32(global(G_t2_52), i_5), i_4) != a)))) -> (Mint_0[a] = Mint_1[a])). } Prove: exists i_5,i_4 : Z. (i_5 <= i) /\ (i_4 <= i_1) /\ (0 <= i_5) /\ @@ -733,7 +733,7 @@ Assume { (* Loop assigns 'tactic,Zone' *) Have: forall a : addr. ((forall i_5,i_4 : Z. ((0 <= i_5) -> ((i_5 <= 9) -> - (shift_sint32(shift_A20_sint32(global(G_t2_50), i_5), i_4) != a)))) -> + (shift_sint32(shift_A20_sint32(global(G_t2_52), i_5), i_4) != a)))) -> (Mint_0[a] = Mint_1[a])). } Prove: exists i_5,i_4 : Z. (i_5 <= i) /\ (i_4 <= i_1) /\ (0 <= i_5) /\ @@ -742,7 +742,7 @@ Prove: exists i_5,i_4 : Z. (i_5 <= i) /\ (i_4 <= i_1) /\ (0 <= i_5) /\ ------------------------------------------------------------ Goal Decreasing of Loop variant at loop (file tests/wp_typed/user_init.i, line 157): -Let a = global(G_t2_50). +Let a = global(G_t2_52). Let a_1 = shift_A20_sint32(a, i). Assume { Type: is_uint32(i) /\ is_sint32(v). diff --git a/src/plugins/wp/tests/wp_usage/oracle/caveat.1.res.oracle b/src/plugins/wp/tests/wp_usage/oracle/caveat.1.res.oracle index 4d2f07be6ab..bf3ddd57997 100644 --- a/src/plugins/wp/tests/wp_usage/oracle/caveat.1.res.oracle +++ b/src/plugins/wp/tests/wp_usage/oracle/caveat.1.res.oracle @@ -54,7 +54,7 @@ Prove: true. ------------------------------------------------------------ Goal Post-condition 'KO' in 'observer': -Let a = global(G_a_43). +Let a = global(G_a_45). Let x = Mint_0[shiftfield_F1_S_f(a)]. Let x_1 = Mint_0[shiftfield_F1_S_g(a)]. Let x_2 = 1 + x. diff --git a/src/plugins/wp/tests/wp_usage/oracle/caveat2.res.oracle b/src/plugins/wp/tests/wp_usage/oracle/caveat2.res.oracle index 0ff6c92ce1f..e1c317646d5 100644 --- a/src/plugins/wp/tests/wp_usage/oracle/caveat2.res.oracle +++ b/src/plugins/wp/tests/wp_usage/oracle/caveat2.res.oracle @@ -14,7 +14,7 @@ Prove: true. ------------------------------------------------------------ Goal Post-condition 'A' in 'job': -Let a = global(G_b_24). +Let a = global(G_b_26). Assume { Type: is_sint32(i_1) /\ is_sint32(n). (* Goal *) @@ -40,7 +40,7 @@ Assume { Have: (0 <= n) /\ (n <= 3). (* Invariant *) Have: forall i_1 : Z. ((0 <= i_1) -> ((i_1 < i) -> - (Mint_0[shift_sint32(global(G_b_24), i_1)] = v[i_1]))). + (Mint_0[shift_sint32(global(G_b_26), i_1)] = v[i_1]))). (* Invariant *) Have: (0 <= i) /\ (i <= n). (* Then *) @@ -59,7 +59,7 @@ Goal Preservation of Invariant (file tests/wp_usage/caveat2.i, line 22): tests/wp_usage/caveat2.i:22: warning from Typed Model: - Warning: No allocation size for variable 'b' Reason: Undefined array-size (sint32[]) -Let a = global(G_b_24). +Let a = global(G_b_26). Assume { Type: is_sint32(i) /\ is_sint32(n) /\ is_sint32(1 + i). (* Goal *) diff --git a/src/plugins/wp/tests/wp_usage/oracle/caveat_range.res.oracle b/src/plugins/wp/tests/wp_usage/oracle/caveat_range.res.oracle index 6fb072eec83..514fab0cd9f 100644 --- a/src/plugins/wp/tests/wp_usage/oracle/caveat_range.res.oracle +++ b/src/plugins/wp/tests/wp_usage/oracle/caveat_range.res.oracle @@ -8,7 +8,7 @@ ------------------------------------------------------------ Goal Post-condition (file tests/wp_usage/caveat_range.i, line 12) in 'reset': -Let a = global(G_p_20). +Let a = global(G_p_22). Let a_1 = havoc(Mint_undef_0, Mint_0, shift_S(a, 0), 20). Assume { Type: is_sint32(i_1). @@ -30,7 +30,7 @@ Prove: a_1[shiftfield_F1_S_f(shift_S(a, i))] = 1. ------------------------------------------------------------ Goal Post-condition (file tests/wp_usage/caveat_range.i, line 13) in 'reset': -Let a = global(G_p_20). +Let a = global(G_p_22). Let a_1 = havoc(Mint_undef_0, Mint_0, shift_S(a, 0), 20). Assume { Type: is_sint32(i_1). @@ -52,7 +52,7 @@ Prove: a_1[shiftfield_F1_S_g(shift_S(a, i))] = 2. ------------------------------------------------------------ Goal Preservation of Invariant (file tests/wp_usage/caveat_range.i, line 19): -Let a = global(G_p_20). +Let a = global(G_p_22). Let a_1 = havoc(Mint_undef_0, Mint_0, shift_S(a, 0), 20). Assume { Type: is_sint32(i) /\ is_sint32(1 + i). @@ -77,7 +77,7 @@ Prove: true. ------------------------------------------------------------ Goal Preservation of Invariant (file tests/wp_usage/caveat_range.i, line 20): -Let a = global(G_p_20). +Let a = global(G_p_22). Let a_1 = havoc(Mint_undef_0, Mint_0, shift_S(a, 0), 20). Assume { Type: is_sint32(i) /\ is_sint32(1 + i). @@ -105,7 +105,7 @@ Prove: true. ------------------------------------------------------------ Goal Preservation of Invariant (file tests/wp_usage/caveat_range.i, line 21): -Let a = global(G_p_20). +Let a = global(G_p_22). Let a_1 = havoc(Mint_undef_0, Mint_0, shift_S(a, 0), 20). Let a_2 = shift_S(a, i). Assume { diff --git a/src/plugins/wp/tests/wp_usage/oracle/global.0.res.oracle b/src/plugins/wp/tests/wp_usage/oracle/global.0.res.oracle index 036b86a3fb4..4535eb5a131 100644 --- a/src/plugins/wp/tests/wp_usage/oracle/global.0.res.oracle +++ b/src/plugins/wp/tests/wp_usage/oracle/global.0.res.oracle @@ -8,14 +8,14 @@ ------------------------------------------------------------ Goal Assertion 'no_address_taken' (file tests/wp_usage/global.c, line 17): -Let a = Mptr_0[global(P_a_21)]. +Let a = Mptr_0[global(P_a_23)]. Assume { (* Heap *) Type: framed(Mptr_0) /\ linked(Malloc_0). (* Pre-condition *) Have: valid_rw(Malloc_0, a, 1). } -Prove: a != global(G_GLOBAL_18). +Prove: a != global(G_GLOBAL_20). ------------------------------------------------------------ ------------------------------------------------------------ @@ -25,6 +25,6 @@ Prove: a != global(G_GLOBAL_18). Goal Instance of 'Pre-condition (file tests/wp_usage/global.c, line 14) in 'foo'' in 'main' at call 'foo' (file tests/wp_usage/global.c, line 21) : Assume { (* Heap *) Type: linked(Malloc_0). } -Prove: valid_rw(Malloc_0[L___retres_24 <- 1], global(G_GLOBAL_18), 1). +Prove: valid_rw(Malloc_0[L___retres_26 <- 1], global(G_GLOBAL_20), 1). ------------------------------------------------------------ diff --git a/src/plugins/wp/tests/wp_usage/oracle/issue-189-bis.0.res.oracle b/src/plugins/wp/tests/wp_usage/oracle/issue-189-bis.0.res.oracle index 5b1f0e248c4..c089fb5d1fb 100644 --- a/src/plugins/wp/tests/wp_usage/oracle/issue-189-bis.0.res.oracle +++ b/src/plugins/wp/tests/wp_usage/oracle/issue-189-bis.0.res.oracle @@ -8,8 +8,8 @@ ------------------------------------------------------------ Goal Post-condition 'memcpy' in 'memcpy_alias_vars': -Let a = Mptr_0[global(P_src_22)]. -Let a_1 = Mptr_0[global(P_dst_23)]. +Let a = Mptr_0[global(P_src_24)]. +Let a_1 = Mptr_0[global(P_dst_25)]. Let a_2 = shift_uint8(a_1, 0). Let a_3 = havoc(Mint_undef_0, Mint_0, a_2, len_0). Let a_4 = shift_uint8(a, 0). @@ -39,8 +39,8 @@ Prove: a_3[shift_uint8(a_1, i)] = Mint_0[shift_uint8(a, i)]. ------------------------------------------------------------ Goal Post-condition 'unmodified' in 'memcpy_alias_vars': -Let a = Mptr_0[global(P_src_22)]. -Let a_1 = Mptr_0[global(P_dst_23)]. +Let a = Mptr_0[global(P_src_24)]. +Let a_1 = Mptr_0[global(P_dst_25)]. Let a_2 = shift_uint8(a_1, 0). Let a_3 = havoc(Mint_undef_0, Mint_0, a_2, len_0). Let a_4 = shift_uint8(a, 0). @@ -71,8 +71,8 @@ Prove: a_3[a_5] = Mint_0[a_5]. ------------------------------------------------------------ Goal Preservation of Invariant 'cpy' (file tests/wp_usage/issue-189-bis.i, line 27): -Let a = Mptr_0[global(P_src_22)]. -Let a_1 = Mptr_0[global(P_dst_23)]. +Let a = Mptr_0[global(P_src_24)]. +Let a_1 = Mptr_0[global(P_dst_25)]. Let a_2 = shift_uint8(a_1, 0). Let a_3 = havoc(Mint_undef_0, Mint_0, a_2, len_0). Let a_4 = shift_uint8(a, 0). @@ -118,8 +118,8 @@ Prove: true. ------------------------------------------------------------ Goal Preservation of Invariant 'len' (file tests/wp_usage/issue-189-bis.i, line 23): -Let a = Mptr_0[global(P_src_22)]. -Let a_1 = Mptr_0[global(P_dst_23)]. +Let a = Mptr_0[global(P_src_24)]. +Let a_1 = Mptr_0[global(P_dst_25)]. Let a_2 = shift_uint8(a_1, 0). Let a_3 = havoc(Mint_undef_0, Mint_0, a_2, len_1). Let a_4 = shift_uint8(a, 0). @@ -180,9 +180,9 @@ Prove: true. Goal Loop assigns (file tests/wp_usage/issue-189-bis.i, line 26) (4/4): Effect at line 32 -Let a = global(P_src_22). +Let a = global(P_src_24). Let a_1 = Mptr_0[a]. -Let a_2 = global(P_dst_23). +Let a_2 = global(P_dst_25). Let a_3 = Mptr_0[a_2]. Let a_4 = shift_uint8(a_3, 0). Let a_5 = havoc(Mint_undef_0, Mint_0, a_4, len_0). @@ -192,7 +192,7 @@ Assume { (* Heap *) Type: framed(Mptr_0) /\ linked(Malloc_0). (* Goal *) - When: !invalid(Malloc_0[P_src_22 <- 1][P_dst_23 <- 1], v, 1). + When: !invalid(Malloc_0[P_src_24 <- 1][P_dst_25 <- 1], v, 1). (* Pre-condition *) Have: valid_rd(Malloc_0, a_6, len_0) /\ valid_rw(Malloc_0, a_4, len_0) /\ separated(a_4, len_0, a_6, len_0). @@ -222,8 +222,8 @@ Prove: true. ------------------------------------------------------------ Goal Post-condition 'memcpy,ok' in 'memcpy_context_vars': -Let a = Mptr_0[global(P_src_45)]. -Let a_1 = Mptr_0[global(P_dst_46)]. +Let a = Mptr_0[global(P_src_47)]. +Let a_1 = Mptr_0[global(P_dst_48)]. Let a_2 = shift_uint8(a_1, 0). Let a_3 = havoc(Mint_undef_0, Mint_0, a_2, len_0). Let a_4 = shift_uint8(a, 0). @@ -253,8 +253,8 @@ Prove: a_3[shift_uint8(a_1, i)] = Mint_0[shift_uint8(a, i)]. ------------------------------------------------------------ Goal Post-condition 'unmodified,ok' in 'memcpy_context_vars': -Let a = Mptr_0[global(P_src_45)]. -Let a_1 = Mptr_0[global(P_dst_46)]. +Let a = Mptr_0[global(P_src_47)]. +Let a_1 = Mptr_0[global(P_dst_48)]. Let a_2 = shift_uint8(a_1, 0). Let a_3 = havoc(Mint_undef_0, Mint_0, a_2, len_0). Let a_4 = shift_uint8(a, 0). @@ -285,8 +285,8 @@ Prove: a_3[a_5] = Mint_0[a_5]. ------------------------------------------------------------ Goal Preservation of Invariant 'ok,cpy' (file tests/wp_usage/issue-189-bis.i, line 55): -Let a = Mptr_0[global(P_src_45)]. -Let a_1 = Mptr_0[global(P_dst_46)]. +Let a = Mptr_0[global(P_src_47)]. +Let a_1 = Mptr_0[global(P_dst_48)]. Let a_2 = shift_uint8(a_1, 0). Let a_3 = havoc(Mint_undef_0, Mint_0, a_2, len_0). Let a_4 = shift_uint8(a, 0). @@ -332,8 +332,8 @@ Prove: true. ------------------------------------------------------------ Goal Preservation of Invariant 'ok,len' (file tests/wp_usage/issue-189-bis.i, line 51): -Let a = Mptr_0[global(P_src_45)]. -Let a_1 = Mptr_0[global(P_dst_46)]. +Let a = Mptr_0[global(P_src_47)]. +Let a_1 = Mptr_0[global(P_dst_48)]. Let a_2 = shift_uint8(a_1, 0). Let a_3 = havoc(Mint_undef_0, Mint_0, a_2, len_1). Let a_4 = shift_uint8(a, 0). @@ -394,8 +394,8 @@ Prove: true. Goal Loop assigns (file tests/wp_usage/issue-189-bis.i, line 54) (4/4): Effect at line 60 -Let a = Mptr_0[global(P_src_45)]. -Let a_1 = Mptr_0[global(P_dst_46)]. +Let a = Mptr_0[global(P_src_47)]. +Let a_1 = Mptr_0[global(P_dst_48)]. Let a_2 = shift_uint8(a_1, 0). Let a_3 = havoc(Mint_undef_0, Mint_0, a_2, len_0). Let a_4 = shift_uint8(a, 0). @@ -404,7 +404,7 @@ Assume { (* Heap *) Type: framed(Mptr_0) /\ linked(Malloc_0). (* Goal *) - When: !invalid(Malloc_0[P_src_45 <- 1][P_dst_46 <- 1], tmp_0, 1). + When: !invalid(Malloc_0[P_src_47 <- 1][P_dst_48 <- 1], tmp_0, 1). (* Pre-condition *) Have: valid_rd(Malloc_0, a_4, len_0) /\ valid_rw(Malloc_0, a_2, len_0) /\ separated(a_2, len_0, a_4, len_0). diff --git a/src/plugins/wp/tests/wp_usage/oracle/issue-189-bis.1.res.oracle b/src/plugins/wp/tests/wp_usage/oracle/issue-189-bis.1.res.oracle index ded08a1708f..f3a2767ec5c 100644 --- a/src/plugins/wp/tests/wp_usage/oracle/issue-189-bis.1.res.oracle +++ b/src/plugins/wp/tests/wp_usage/oracle/issue-189-bis.1.res.oracle @@ -5,8 +5,8 @@ [wp] Warning: Missing RTE guards Goal Post-condition 'memcpy,ok' in 'memcpy_context_vars': -Let a = global(G_src_45). -Let a_1 = global(G_dst_46). +Let a = global(G_src_47). +Let a_1 = global(G_dst_48). Let a_2 = havoc(Mint_undef_0, Mint_0, shift_uint8(a_1, 0), len_0). Assume { Type: is_sint32(len_0) /\ is_sint32(len_1). @@ -36,8 +36,8 @@ Prove: true. ------------------------------------------------------------ Goal Preservation of Invariant 'ok,cpy' (file tests/wp_usage/issue-189-bis.i, line 55): -Let a = global(G_src_45). -Let a_1 = global(G_dst_46). +Let a = global(G_src_47). +Let a_1 = global(G_dst_48). Let a_2 = havoc(Mint_undef_0, Mint_0, shift_uint8(a_1, 0), len_0). Let a_3 = a_2[dst2_0 <- a_2[src2_0]]. Assume { @@ -78,8 +78,8 @@ Prove: true. ------------------------------------------------------------ Goal Preservation of Invariant 'ok,len' (file tests/wp_usage/issue-189-bis.i, line 51): -Let a = global(G_src_45). -Let a_1 = global(G_dst_46). +Let a = global(G_src_47). +Let a_1 = global(G_dst_48). Assume { Type: is_sint32(len_1) /\ is_sint32(len_0) /\ is_sint32(len_0 - 1). (* Pre-condition *) @@ -135,8 +135,8 @@ Prove: true. Goal Loop assigns (file tests/wp_usage/issue-189-bis.i, line 54) (4/4): Effect at line 60 -Let a = global(G_src_45). -Let a_1 = global(G_dst_46). +Let a = global(G_src_47). +Let a_1 = global(G_dst_48). Let a_2 = shift_uint8(a_1, 0). Assume { Type: is_sint32(len_0) /\ is_sint32(len_1). diff --git a/tests/misc/oracle/pragma-pack.0.res.oracle b/tests/misc/oracle/pragma-pack.0.res.oracle index f3f41b911f7..8688b345c3b 100644 --- a/tests/misc/oracle/pragma-pack.0.res.oracle +++ b/tests/misc/oracle/pragma-pack.0.res.oracle @@ -87,8 +87,6 @@ adding aligned(1) attribute to field 'PACKOVERPOP.j' due to packing pragma [kernel:typing:pragma] tests/misc/pragma-pack.c:88: adding aligned(1) attribute to comp 'PACKOVERPOP' due to packing pragma -[kernel:typing:implicit-function-declaration] tests/misc/pragma-pack.c:104: Warning: - Calling undeclared function __builtin_offsetof. Old style K&R code? [kernel:typing:pragma] tests/misc/pragma-pack.c:133: packing pragma: restoring alignment to default (16) [kernel:typing:pragma] tests/misc/pragma-pack.c:135: diff --git a/tests/misc/oracle/pragma-pack.1.res.oracle b/tests/misc/oracle/pragma-pack.1.res.oracle index 59c543748f2..559d8cfaacb 100644 --- a/tests/misc/oracle/pragma-pack.1.res.oracle +++ b/tests/misc/oracle/pragma-pack.1.res.oracle @@ -1,8 +1,6 @@ [kernel] Parsing tests/misc/pragma-pack.c (with preprocessing) [kernel] tests/misc/pragma-pack.c:87: Warning: ignoring #pragma pack(pop) with empty stack -[kernel:typing:implicit-function-declaration] tests/misc/pragma-pack.c:104: Warning: - Calling undeclared function __builtin_offsetof. Old style K&R code? [eva] Analyzing a complete application starting at main [eva] Computing initial state [eva] Initial state computed diff --git a/tests/misc/oracle/pragma-pack.2.res.oracle b/tests/misc/oracle/pragma-pack.2.res.oracle index c2534c76f82..ae56a3d1f1a 100644 --- a/tests/misc/oracle/pragma-pack.2.res.oracle +++ b/tests/misc/oracle/pragma-pack.2.res.oracle @@ -1,8 +1,6 @@ [kernel] Parsing tests/misc/pragma-pack.c (with preprocessing) [kernel] tests/misc/pragma-pack.c:87: Warning: ignoring #pragma pack(pop) with empty stack -[kernel:typing:implicit-function-declaration] tests/misc/pragma-pack.c:104: Warning: - Calling undeclared function __builtin_offsetof. Old style K&R code? [eva] Analyzing a complete application starting at main [eva] Computing initial state [eva] Initial state computed diff --git a/tests/misc/oracle/pragma_pack_zero.0.res.oracle b/tests/misc/oracle/pragma_pack_zero.0.res.oracle index 0137611438a..6c491d9c591 100644 --- a/tests/misc/oracle/pragma_pack_zero.0.res.oracle +++ b/tests/misc/oracle/pragma_pack_zero.0.res.oracle @@ -1,8 +1,6 @@ [kernel] Parsing tests/misc/pragma_pack_zero.c (with preprocessing) [kernel] tests/misc/pragma_pack_zero.c:35: Warning: GCC accepts pack(0) but does not specify its behavior; considering it equivalent to pack() -[kernel:typing:implicit-function-declaration] tests/misc/pragma_pack_zero.c:47: Warning: - Calling undeclared function __builtin_offsetof. Old style K&R code? [eva] Analyzing a complete application starting at main [eva] Computing initial state [eva] Initial state computed diff --git a/tests/misc/oracle/pragma_pack_zero.1.res.oracle b/tests/misc/oracle/pragma_pack_zero.1.res.oracle index 672ee382233..69b3a971800 100644 --- a/tests/misc/oracle/pragma_pack_zero.1.res.oracle +++ b/tests/misc/oracle/pragma_pack_zero.1.res.oracle @@ -1,8 +1,6 @@ [kernel] Parsing tests/misc/pragma_pack_zero.c (with preprocessing) [kernel] tests/misc/pragma_pack_zero.c:35: Warning: ignoring invalid packing alignment (0) -[kernel:typing:implicit-function-declaration] tests/misc/pragma_pack_zero.c:47: Warning: - Calling undeclared function __builtin_offsetof. Old style K&R code? [eva] Analyzing a complete application starting at main [eva] Computing initial state [eva] Initial state computed diff --git a/tests/syntax/oracle/bts1553_2.res.oracle b/tests/syntax/oracle/bts1553_2.res.oracle index 139289f56d4..9293259fe56 100644 --- a/tests/syntax/oracle/bts1553_2.res.oracle +++ b/tests/syntax/oracle/bts1553_2.res.oracle @@ -7,6 +7,8 @@ }; /* compiler builtin: __builtin_va_list __builtin_next_arg(void); */ + /* compiler builtin: + unsigned int __builtin_offsetof(unsigned int); */ /* compiler builtin: void __builtin_stdarg_start(__builtin_va_list); */ /* compiler builtin: @@ -40,6 +42,8 @@ }; /* compiler builtin: __builtin_va_list __builtin_next_arg(void); */ + /* compiler builtin: + unsigned int __builtin_offsetof(unsigned int); */ /* compiler builtin: void __builtin_stdarg_start(__builtin_va_list); */ /* compiler builtin: diff --git a/tests/syntax/oracle/check_builtin_bts1440.res.oracle b/tests/syntax/oracle/check_builtin_bts1440.res.oracle index 2641ac4bf88..4e0e7ae6c6a 100644 --- a/tests/syntax/oracle/check_builtin_bts1440.res.oracle +++ b/tests/syntax/oracle/check_builtin_bts1440.res.oracle @@ -209,6 +209,8 @@ unsigned int __builtin_object_size(void *, int); + unsigned int __builtin_offsetof(unsigned int); + int __builtin_parity(unsigned int); int __builtin_parityl(unsigned long); diff --git a/tests/syntax/oracle/get_astinfo_bts1136.res.oracle b/tests/syntax/oracle/get_astinfo_bts1136.res.oracle index 6366ae5e8ee..cffcd6e4b73 100644 --- a/tests/syntax/oracle/get_astinfo_bts1136.res.oracle +++ b/tests/syntax/oracle/get_astinfo_bts1136.res.oracle @@ -1,13 +1,13 @@ [kernel] Parsing tests/syntax/get_astinfo_bts1136.i (no preprocessing) -found variable vid:20 formal in f -found variable vid:23 formal in g -found variable vid:26 formal in h -found variable vid:28 formal in i -found variable vid:30 formal in j -found variable vid:32 formal in k -[do_v] vid:26 formal in h -[do_v] vid:23 formal in g -[do_v] vid:20 formal in f -[do_v] vid:32 local in k -[do_v] vid:30 local in j -[do_v] vid:28 local in i +found variable vid:22 formal in f +found variable vid:25 formal in g +found variable vid:28 formal in h +found variable vid:30 formal in i +found variable vid:32 formal in j +found variable vid:34 formal in k +[do_v] vid:28 formal in h +[do_v] vid:25 formal in g +[do_v] vid:22 formal in f +[do_v] vid:34 local in k +[do_v] vid:32 local in j +[do_v] vid:30 local in i diff --git a/tests/syntax/oracle/offsetof.res.oracle b/tests/syntax/oracle/offsetof.res.oracle index 0829a102008..17beec4a697 100644 --- a/tests/syntax/oracle/offsetof.res.oracle +++ b/tests/syntax/oracle/offsetof.res.oracle @@ -1,6 +1,4 @@ [kernel] Parsing tests/syntax/offsetof.c (with preprocessing) -[kernel:typing:implicit-function-declaration] tests/syntax/offsetof.c:6: Warning: - Calling undeclared function __builtin_offsetof. Old style K&R code? /* Generated by Frama-C */ #include "stddef.h" void main(void) diff --git a/tests/syntax/oracle/reorder.res.oracle b/tests/syntax/oracle/reorder.res.oracle index 44b5d5c8aa5..446708bfa1c 100644 --- a/tests/syntax/oracle/reorder.res.oracle +++ b/tests/syntax/oracle/reorder.res.oracle @@ -30,10 +30,10 @@ void g(void); /*@ logic ℤ l= 1; */ int x; -/*@ logic ℤ j= l; - */ /*@ logic ℤ k= l; */ +/*@ logic ℤ j= l; + */ /*@ logic ℤ i= j + k; */ /*@ ensures i ≡ i; */ diff --git a/tests/syntax/oracle/static_formals_1.res.oracle b/tests/syntax/oracle/static_formals_1.res.oracle index 33d75e1e69f..94353adf96c 100644 --- a/tests/syntax/oracle/static_formals_1.res.oracle +++ b/tests/syntax/oracle/static_formals_1.res.oracle @@ -1,24 +1,24 @@ [kernel] Parsing tests/syntax/static_formals_1.c (with preprocessing) [kernel] Parsing tests/syntax/static_formals_2.c (with preprocessing) /* Generated by Frama-C */ -/*@ requires /* vid:23, lvid:23 */x < 10; */ -static int /* vid:54 */f(int /* vid:23, lvid:23 */x); +/*@ requires /* vid:25, lvid:25 */x < 10; */ +static int /* vid:58 */f(int /* vid:25, lvid:25 */x); -int /* vid:28 */g(void) +int /* vid:30 */g(void) { - int /* vid:29 */tmp; - /* vid:29 */tmp = /* vid:54 */f(4); - return /* vid:29 */tmp; + int /* vid:31 */tmp; + /* vid:31 */tmp = /* vid:58 */f(4); + return /* vid:31 */tmp; } -/*@ requires /* vid:49, lvid:49 */x < 10; */ -static int /* vid:55 */f_0(int /* vid:49, lvid:49 */x); +/*@ requires /* vid:53, lvid:53 */x < 10; */ +static int /* vid:59 */f_0(int /* vid:53, lvid:53 */x); -int /* vid:52 */h(void) +int /* vid:56 */h(void) { - int /* vid:53 */tmp; - /* vid:53 */tmp = /* vid:55 */f_0(6); - return /* vid:53 */tmp; + int /* vid:57 */tmp; + /* vid:57 */tmp = /* vid:59 */f_0(6); + return /* vid:57 */tmp; } diff --git a/tests/syntax/oracle/syntactic_hook.res.oracle b/tests/syntax/oracle/syntactic_hook.res.oracle index f91bf389eda..4d15d03a3ad 100644 --- a/tests/syntax/oracle/syntactic_hook.res.oracle +++ b/tests/syntax/oracle/syntactic_hook.res.oracle @@ -1,22 +1,22 @@ [kernel] Parsing tests/syntax/syntactic_hook.i (no preprocessing) [kernel] tests/syntax/syntactic_hook.i:5: - New global node introducing identifier f(20) + New global node introducing identifier f(22) [kernel] First occurrence of f [kernel] tests/syntax/syntactic_hook.i:7: - New global node introducing identifier k(23) + New global node introducing identifier k(25) [kernel] First occurrence of k [kernel] tests/syntax/syntactic_hook.i:9: - New global node introducing identifier k(23) + New global node introducing identifier k(25) [kernel] New occurrence of existing identifier k [kernel] tests/syntax/syntactic_hook.i:11: - New global node introducing identifier main(29) + New global node introducing identifier main(31) [kernel] First occurrence of main [kernel] tests/syntax/syntactic_hook.i:13: - New global node introducing identifier t(33) + New global node introducing identifier t(35) [kernel] First occurrence of t [kernel] tests/syntax/syntactic_hook.i:13: Warning: [SH]: definition of local function t -[kernel] :0: New global node introducing identifier g(35) +[kernel] :0: New global node introducing identifier g(37) [kernel] First occurrence of g [kernel:typing:implicit-function-declaration] tests/syntax/syntactic_hook.i:17: Warning: Calling undeclared function g. Old style K&R code? diff --git a/tests/value/oracle/attribute-aligned.res.oracle b/tests/value/oracle/attribute-aligned.res.oracle index 160214c6a77..c451f494f10 100644 --- a/tests/value/oracle/attribute-aligned.res.oracle +++ b/tests/value/oracle/attribute-aligned.res.oracle @@ -1,6 +1,4 @@ [kernel] Parsing tests/value/attribute-aligned.c (with preprocessing) -[kernel:typing:implicit-function-declaration] tests/value/attribute-aligned.c:17: Warning: - Calling undeclared function __builtin_offsetof. Old style K&R code? [eva] Analyzing a complete application starting at main [eva] Computing initial state [eva] Initial state computed -- GitLab From fe36d79933d4fd5f24a8cdb090fcc53aa75722b9 Mon Sep 17 00:00:00 2001 From: Virgile Prevosto <virgile.prevosto@m4x.org> Date: Wed, 25 Mar 2020 19:13:38 +0100 Subject: [PATCH 046/218] [libc] better support for SIG_DFL, SIG_IGN and SIG_ERR so that Eva won't raise an alarm on them. --- share/libc/signal.h | 10 +- .../ast_printing/cil_printer.ml | 20 ++- tests/libc/oracle/signal_h.res.oracle | 2 +- tests/value/invalid_pointer.c | 5 + .../value/oracle/invalid_pointer.0.res.oracle | 166 ++++++++++-------- .../value/oracle/invalid_pointer.1.res.oracle | 98 ++++++----- 6 files changed, 178 insertions(+), 123 deletions(-) diff --git a/share/libc/signal.h b/share/libc/signal.h index 3cd1853ea45..01f6d674da7 100644 --- a/share/libc/signal.h +++ b/share/libc/signal.h @@ -46,9 +46,13 @@ typedef void (*__fc_sighandler_t) (int); /* for BSD 4.4 */ typedef __fc_sighandler_t sig_t; -#define SIG_DFL ((__fc_sighandler_t)0) /* default signal handling */ -#define SIG_IGN ((__fc_sighandler_t)1) /* ignore signal */ -#define SIG_ERR ((__fc_sighandler_t)-1) /* error return from signal */ +extern sig_t __fc_sig_dfl; +extern sig_t __fc_sig_ign; +extern sig_t __fc_sig_err; + +#define SIG_DFL __fc_sig_dfl /* default signal handling */ +#define SIG_IGN __fc_sig_ign /* ignore signal */ +#define SIG_ERR __fc_sig_err /* error return from signal */ #define SIG_BLOCK 0 #define SIG_UNBLOCK 1 diff --git a/src/kernel_services/ast_printing/cil_printer.ml b/src/kernel_services/ast_printing/cil_printer.ml index 37a6a46cd2c..186378fef09 100644 --- a/src/kernel_services/ast_printing/cil_printer.ml +++ b/src/kernel_services/ast_printing/cil_printer.ml @@ -54,6 +54,16 @@ module Extensions = struct end let set_extension_handler = Extensions.set_handler +let rename_builtins = Datatype.String.Hashtbl.create 17 + +let () = + List.iter (fun (x,y) -> Datatype.String.Hashtbl.add rename_builtins x y) + [ + "__fc_sig_dfl", "SIG_DFL"; + "__fc_sig_ign", "SIG_IGN"; + "__fc_sig_err", "SIG_ERR"; + ] + (* Deprecated functions *) let set_deprecated_extension_handler = Extensions.set_deprecated_handler @@ -642,7 +652,15 @@ class cil_printer () = object (self) | CEnum {einame = s} -> self#varname fmt s (*** VARIABLES ***) - method varname fmt v = pp_print_string fmt v + method varname fmt v = + let v = + if not (Kernel.PrintLibc.get ()) && + Datatype.String.Hashtbl.mem rename_builtins v + then + Datatype.String.Hashtbl.find rename_builtins v + else v + in + pp_print_string fmt v (* variable use *) method varinfo fmt v = diff --git a/tests/libc/oracle/signal_h.res.oracle b/tests/libc/oracle/signal_h.res.oracle index 9d071e5884c..2b9a206e15c 100644 --- a/tests/libc/oracle/signal_h.res.oracle +++ b/tests/libc/oracle/signal_h.res.oracle @@ -126,7 +126,7 @@ function sigaction: precondition 'valid_read_act_or_null' got status valid. [eva] tests/libc/signal_h.c:48: function sigaction: precondition 'separation,separated_acts' got status valid. -[eva] share/libc/signal.h:212: +[eva] share/libc/signal.h:216: cannot evaluate ACSL term, unsupported ACSL construct: logic coercion struct sigaction -> set<struct sigaction> [eva] Done for function sigaction [eva] computing for function sigaction <- main. diff --git a/tests/value/invalid_pointer.c b/tests/value/invalid_pointer.c index bde7ed009dc..09d7babf80b 100644 --- a/tests/value/invalid_pointer.c +++ b/tests/value/invalid_pointer.c @@ -5,6 +5,7 @@ #include <__fc_builtin.h> #include <stdint.h> +#include <signal.h> /* Tests the emission of \object_pointer alarms when -warn-invalid-pointer is enabled. The second run should emit no alarm. */ @@ -175,4 +176,8 @@ void main () { union_pointer (); write_pointer (); object_pointer_predicate (); + // should not emit an alarm + signal (SIGUSR1, SIG_IGN); + signal (SIGUSR2, SIG_ERR); + signal (SIGUNUSED, SIG_DFL); } diff --git a/tests/value/oracle/invalid_pointer.0.res.oracle b/tests/value/oracle/invalid_pointer.0.res.oracle index 4f0f2133ff5..4d5ac453516 100644 --- a/tests/value/oracle/invalid_pointer.0.res.oracle +++ b/tests/value/oracle/invalid_pointer.0.res.oracle @@ -1,5 +1,5 @@ [kernel] Parsing tests/value/invalid_pointer.c (with preprocessing) -[kernel:typing:int-conversion] tests/value/invalid_pointer.c:111: Warning: +[kernel:typing:int-conversion] tests/value/invalid_pointer.c:112: Warning: Conversion from a pointer to an integer without an explicit cast [eva] Analyzing a complete application starting at main [eva] Computing initial state @@ -8,173 +8,183 @@ NULL[rbits 80 to 247] ∈ [--..--] undet ∈ [--..--] [eva] computing for function pointer_computation <- main. - Called from tests/value/invalid_pointer.c:171. -[eva:alarm] tests/value/invalid_pointer.c:19: Warning: + Called from tests/value/invalid_pointer.c:172. +[eva:alarm] tests/value/invalid_pointer.c:20: Warning: invalid pointer creation. assert \object_pointer(p - 1); -[eva:alarm] tests/value/invalid_pointer.c:22: Warning: +[eva:alarm] tests/value/invalid_pointer.c:23: Warning: invalid pointer creation. assert \object_pointer(p + 1); -[eva:alarm] tests/value/invalid_pointer.c:24: Warning: +[eva:alarm] tests/value/invalid_pointer.c:25: Warning: invalid pointer creation. assert \object_pointer(p + i); -[eva:alarm] tests/value/invalid_pointer.c:26: Warning: - invalid pointer creation. assert \object_pointer(p - j); [eva:alarm] tests/value/invalid_pointer.c:27: Warning: + invalid pointer creation. assert \object_pointer(p - j); +[eva:alarm] tests/value/invalid_pointer.c:28: Warning: invalid pointer creation. assert \object_pointer(p - 1); [eva] computing for function Frama_C_interval <- pointer_computation <- main. - Called from tests/value/invalid_pointer.c:30. + Called from tests/value/invalid_pointer.c:31. [eva] using specification for function Frama_C_interval -[eva] tests/value/invalid_pointer.c:30: +[eva] tests/value/invalid_pointer.c:31: function Frama_C_interval: precondition 'order' got status valid. [eva] Done for function Frama_C_interval -[eva:alarm] tests/value/invalid_pointer.c:31: Warning: +[eva:alarm] tests/value/invalid_pointer.c:32: Warning: invalid pointer creation. assert \object_pointer(q + offset1); [eva] computing for function Frama_C_interval <- pointer_computation <- main. - Called from tests/value/invalid_pointer.c:32. -[eva] tests/value/invalid_pointer.c:32: + Called from tests/value/invalid_pointer.c:33. +[eva] tests/value/invalid_pointer.c:33: function Frama_C_interval: precondition 'order' got status valid. [eva] Done for function Frama_C_interval -[eva:alarm] tests/value/invalid_pointer.c:33: Warning: +[eva:alarm] tests/value/invalid_pointer.c:34: Warning: invalid pointer creation. assert \object_pointer(q + offset2); [eva] Recording results for pointer_computation [eva] Done for function pointer_computation [eva] computing for function pointer_in_loops <- main. - Called from tests/value/invalid_pointer.c:172. -[eva] tests/value/invalid_pointer.c:42: + Called from tests/value/invalid_pointer.c:173. +[eva] tests/value/invalid_pointer.c:43: Trace partitioning superposing up to 100 states -[eva:alarm] tests/value/invalid_pointer.c:51: Warning: +[eva:alarm] tests/value/invalid_pointer.c:52: Warning: invalid pointer creation. assert \object_pointer(q - 1); [eva] Recording results for pointer_in_loops [eva] Done for function pointer_in_loops [eva] computing for function int_conversion <- main. - Called from tests/value/invalid_pointer.c:173. -[eva:alarm] tests/value/invalid_pointer.c:63: Warning: + Called from tests/value/invalid_pointer.c:174. +[eva:alarm] tests/value/invalid_pointer.c:64: Warning: invalid pointer creation. assert \object_pointer((int *)42); [eva] computing for function Frama_C_interval <- int_conversion <- main. - Called from tests/value/invalid_pointer.c:65. -[eva] tests/value/invalid_pointer.c:65: + Called from tests/value/invalid_pointer.c:66. +[eva] tests/value/invalid_pointer.c:66: function Frama_C_interval: precondition 'order' got status valid. [eva] Done for function Frama_C_interval [eva] computing for function Frama_C_interval <- int_conversion <- main. - Called from tests/value/invalid_pointer.c:67. -[eva] tests/value/invalid_pointer.c:67: + Called from tests/value/invalid_pointer.c:68. +[eva] tests/value/invalid_pointer.c:68: function Frama_C_interval: precondition 'order' got status valid. [eva] Done for function Frama_C_interval -[eva:alarm] tests/value/invalid_pointer.c:69: Warning: +[eva:alarm] tests/value/invalid_pointer.c:70: Warning: invalid pointer creation. assert \object_pointer((int *)x); [eva] computing for function Frama_C_interval <- int_conversion <- main. - Called from tests/value/invalid_pointer.c:71. -[eva] tests/value/invalid_pointer.c:71: + Called from tests/value/invalid_pointer.c:72. +[eva] tests/value/invalid_pointer.c:72: function Frama_C_interval: precondition 'order' got status valid. [eva] Done for function Frama_C_interval -[eva:alarm] tests/value/invalid_pointer.c:72: Warning: - invalid pointer creation. assert \object_pointer((int *)x); [eva:alarm] tests/value/invalid_pointer.c:73: Warning: + invalid pointer creation. assert \object_pointer((int *)x); +[eva:alarm] tests/value/invalid_pointer.c:74: Warning: invalid pointer creation. assert \object_pointer((int *)undet); [eva] Recording results for int_conversion [eva] Done for function int_conversion [eva] computing for function addrof <- main. - Called from tests/value/invalid_pointer.c:174. -[eva:alarm] tests/value/invalid_pointer.c:81: Warning: + Called from tests/value/invalid_pointer.c:175. +[eva:alarm] tests/value/invalid_pointer.c:82: Warning: invalid pointer creation. assert \object_pointer(&a[11]); -[eva:alarm] tests/value/invalid_pointer.c:83: Warning: +[eva:alarm] tests/value/invalid_pointer.c:84: Warning: invalid pointer creation. assert \object_pointer(&a[(int)(-1)]); -[eva:alarm] tests/value/invalid_pointer.c:85: Warning: +[eva:alarm] tests/value/invalid_pointer.c:86: Warning: invalid pointer creation. assert \object_pointer(&a[offset]); [eva] Recording results for addrof [eva] Done for function addrof [eva] computing for function union_pointer <- main. - Called from tests/value/invalid_pointer.c:175. -[eva:alarm] tests/value/invalid_pointer.c:101: Warning: + Called from tests/value/invalid_pointer.c:176. +[eva:alarm] tests/value/invalid_pointer.c:102: Warning: invalid pointer creation. assert \object_pointer(u.pointer); -[eva:alarm] tests/value/invalid_pointer.c:104: Warning: +[eva:alarm] tests/value/invalid_pointer.c:105: Warning: invalid pointer creation. assert \object_pointer(u.pointer); [eva] Recording results for union_pointer [eva] Done for function union_pointer [eva] computing for function write_pointer <- main. - Called from tests/value/invalid_pointer.c:176. -[eva:alarm] tests/value/invalid_pointer.c:114: Warning: + Called from tests/value/invalid_pointer.c:177. +[eva:alarm] tests/value/invalid_pointer.c:115: Warning: invalid pointer creation. assert \object_pointer(p); -[eva:alarm] tests/value/invalid_pointer.c:117: Warning: +[eva:alarm] tests/value/invalid_pointer.c:118: Warning: invalid pointer creation. assert \object_pointer(p); [eva] Recording results for write_pointer [eva] Done for function write_pointer [eva] computing for function object_pointer_predicate <- main. - Called from tests/value/invalid_pointer.c:177. -[eva] tests/value/invalid_pointer.c:126: assertion got status valid. -[eva:alarm] tests/value/invalid_pointer.c:128: Warning: + Called from tests/value/invalid_pointer.c:178. +[eva] tests/value/invalid_pointer.c:127: assertion got status valid. +[eva:alarm] tests/value/invalid_pointer.c:129: Warning: invalid pointer creation. assert \object_pointer(p - 1); -[eva] tests/value/invalid_pointer.c:132: assertion got status valid. -[eva:alarm] tests/value/invalid_pointer.c:134: Warning: +[eva] tests/value/invalid_pointer.c:133: assertion got status valid. +[eva:alarm] tests/value/invalid_pointer.c:135: Warning: invalid pointer creation. assert \object_pointer(p + 1); -[eva:alarm] tests/value/invalid_pointer.c:137: Warning: +[eva:alarm] tests/value/invalid_pointer.c:138: Warning: invalid pointer creation. assert \object_pointer(p + undet); -[eva] tests/value/invalid_pointer.c:138: assertion got status valid. [eva] tests/value/invalid_pointer.c:139: assertion got status valid. -[eva] tests/value/invalid_pointer.c:140: +[eva] tests/value/invalid_pointer.c:140: assertion got status valid. +[eva] tests/value/invalid_pointer.c:141: Frama_C_show_each_object_pointer: {{ &x + {0; 4} }} -[eva:alarm] tests/value/invalid_pointer.c:141: Warning: +[eva:alarm] tests/value/invalid_pointer.c:142: Warning: invalid pointer creation. assert \object_pointer((int *)((unsigned int)((unsigned int)(&x) + (unsigned int)undet))); -[eva] tests/value/invalid_pointer.c:142: assertion got status valid. [eva] tests/value/invalid_pointer.c:143: assertion got status valid. -[eva] tests/value/invalid_pointer.c:144: +[eva] tests/value/invalid_pointer.c:144: assertion got status valid. +[eva] tests/value/invalid_pointer.c:145: Frama_C_show_each_object_pointer_char: {{ &x + {0; 1; 2; 3; 4} }} [eva] computing for function Frama_C_interval <- object_pointer_predicate <- main. - Called from tests/value/invalid_pointer.c:145. -[eva] tests/value/invalid_pointer.c:145: + Called from tests/value/invalid_pointer.c:146. +[eva] tests/value/invalid_pointer.c:146: function Frama_C_interval: precondition 'order' got status valid. [eva] Done for function Frama_C_interval -[eva] tests/value/invalid_pointer.c:147: assertion got status valid. -[eva:alarm] tests/value/invalid_pointer.c:148: Warning: +[eva] tests/value/invalid_pointer.c:148: assertion got status valid. +[eva:alarm] tests/value/invalid_pointer.c:149: Warning: invalid pointer creation. assert \object_pointer(p + i); -[eva] tests/value/invalid_pointer.c:149: assertion got status valid. -[eva:alarm] tests/value/invalid_pointer.c:150: Warning: +[eva] tests/value/invalid_pointer.c:150: assertion got status valid. +[eva:alarm] tests/value/invalid_pointer.c:151: Warning: invalid pointer creation. assert \object_pointer(p + undet); -[eva] tests/value/invalid_pointer.c:151: assertion got status valid. -[eva] tests/value/invalid_pointer.c:152: +[eva] tests/value/invalid_pointer.c:152: assertion got status valid. +[eva] tests/value/invalid_pointer.c:153: Frama_C_show_each_object_pointer_array: {{ &x + {0; 4} ; &array + [0..256],0%4 }} -[eva] tests/value/invalid_pointer.c:154: assertion got status valid. -[eva:alarm] tests/value/invalid_pointer.c:157: Warning: +[eva] tests/value/invalid_pointer.c:155: assertion got status valid. +[eva:alarm] tests/value/invalid_pointer.c:158: Warning: assertion got status unknown. -[eva:alarm] tests/value/invalid_pointer.c:159: Warning: - invalid pointer creation. assert \object_pointer((int *)50); [eva:alarm] tests/value/invalid_pointer.c:160: Warning: - assertion got status unknown. + invalid pointer creation. assert \object_pointer((int *)50); [eva:alarm] tests/value/invalid_pointer.c:161: Warning: - invalid pointer creation. assert \object_pointer((int *)undet); + assertion got status unknown. [eva:alarm] tests/value/invalid_pointer.c:162: Warning: + invalid pointer creation. assert \object_pointer((int *)undet); +[eva:alarm] tests/value/invalid_pointer.c:163: Warning: assertion got status unknown. -[eva:alarm] tests/value/invalid_pointer.c:164: Warning: +[eva:alarm] tests/value/invalid_pointer.c:165: Warning: invalid pointer creation. assert \object_pointer((int *)100); [eva] Recording results for object_pointer_predicate [eva] Done for function object_pointer_predicate +[eva] computing for function signal <- main. + Called from tests/value/invalid_pointer.c:180. +[eva] using specification for function signal +[eva] Done for function signal +[eva] computing for function signal <- main. + Called from tests/value/invalid_pointer.c:181. +[eva] Done for function signal +[eva] computing for function signal <- main. + Called from tests/value/invalid_pointer.c:182. +[eva] Done for function signal [eva] Recording results for main [eva] done for function main -[eva] tests/value/invalid_pointer.c:19: +[eva] tests/value/invalid_pointer.c:20: assertion 'Eva,pointer_value' got final status invalid. -[eva] tests/value/invalid_pointer.c:22: +[eva] tests/value/invalid_pointer.c:23: assertion 'Eva,pointer_value' got final status invalid. -[eva] tests/value/invalid_pointer.c:63: +[eva] tests/value/invalid_pointer.c:64: assertion 'Eva,pointer_value' got final status invalid. -[eva] tests/value/invalid_pointer.c:69: +[eva] tests/value/invalid_pointer.c:70: assertion 'Eva,pointer_value' got final status invalid. -[eva] tests/value/invalid_pointer.c:81: +[eva] tests/value/invalid_pointer.c:82: assertion 'Eva,pointer_value' got final status invalid. -[eva] tests/value/invalid_pointer.c:83: +[eva] tests/value/invalid_pointer.c:84: assertion 'Eva,pointer_value' got final status invalid. -[eva] tests/value/invalid_pointer.c:101: +[eva] tests/value/invalid_pointer.c:102: assertion 'Eva,pointer_value' got final status invalid. -[eva] tests/value/invalid_pointer.c:117: +[eva] tests/value/invalid_pointer.c:118: assertion 'Eva,pointer_value' got final status invalid. -[eva] tests/value/invalid_pointer.c:128: +[eva] tests/value/invalid_pointer.c:129: assertion 'Eva,pointer_value' got final status invalid. -[eva] tests/value/invalid_pointer.c:134: +[eva] tests/value/invalid_pointer.c:135: assertion 'Eva,pointer_value' got final status invalid. -[eva] tests/value/invalid_pointer.c:159: +[eva] tests/value/invalid_pointer.c:160: assertion 'Eva,pointer_value' got final status invalid. -[eva] tests/value/invalid_pointer.c:164: +[eva] tests/value/invalid_pointer.c:165: assertion 'Eva,pointer_value' got final status invalid. [scope:rm_asserts] removing 2 assertion(s) [eva] ====== VALUES COMPUTED ====== @@ -352,6 +362,8 @@ [from] Computing for function write_pointer [from] Done for function write_pointer [from] Computing for function main +[from] Computing for function signal <-main +[from] Done for function signal [from] Done for function main [from] ====== DEPENDENCIES COMPUTED ====== These dependencies hold at termination for the executions that terminate: @@ -368,6 +380,8 @@ Frama_C_entropy_source FROM Frama_C_entropy_source (and SELF) [from] Function pointer_in_loops: NO EFFECTS +[from] Function signal: + \result FROM ANYTHING(origin:Unknown) [from] Function union_pointer: NO EFFECTS [from] Function write_pointer: @@ -406,4 +420,4 @@ [inout] Out (internal) for function main: Frama_C_entropy_source [inout] Inputs for function main: - Frama_C_entropy_source; undet + Frama_C_entropy_source; SIG_DFL; SIG_IGN; SIG_ERR; undet diff --git a/tests/value/oracle/invalid_pointer.1.res.oracle b/tests/value/oracle/invalid_pointer.1.res.oracle index ccb4096a72d..f8121ed36eb 100644 --- a/tests/value/oracle/invalid_pointer.1.res.oracle +++ b/tests/value/oracle/invalid_pointer.1.res.oracle @@ -1,5 +1,5 @@ [kernel] Parsing tests/value/invalid_pointer.c (with preprocessing) -[kernel:typing:int-conversion] tests/value/invalid_pointer.c:111: Warning: +[kernel:typing:int-conversion] tests/value/invalid_pointer.c:112: Warning: Conversion from a pointer to an integer without an explicit cast [eva] Analyzing a complete application starting at main [eva] Computing initial state @@ -8,101 +8,111 @@ NULL[rbits 80 to 247] ∈ [--..--] undet ∈ [--..--] [eva] computing for function pointer_computation <- main. - Called from tests/value/invalid_pointer.c:171. + Called from tests/value/invalid_pointer.c:172. [eva] computing for function Frama_C_interval <- pointer_computation <- main. - Called from tests/value/invalid_pointer.c:30. + Called from tests/value/invalid_pointer.c:31. [eva] using specification for function Frama_C_interval -[eva] tests/value/invalid_pointer.c:30: +[eva] tests/value/invalid_pointer.c:31: function Frama_C_interval: precondition 'order' got status valid. [eva] Done for function Frama_C_interval [eva] computing for function Frama_C_interval <- pointer_computation <- main. - Called from tests/value/invalid_pointer.c:32. -[eva] tests/value/invalid_pointer.c:32: + Called from tests/value/invalid_pointer.c:33. +[eva] tests/value/invalid_pointer.c:33: function Frama_C_interval: precondition 'order' got status valid. [eva] Done for function Frama_C_interval [eva] Recording results for pointer_computation [eva] Done for function pointer_computation [eva] computing for function pointer_in_loops <- main. - Called from tests/value/invalid_pointer.c:172. -[eva] tests/value/invalid_pointer.c:42: + Called from tests/value/invalid_pointer.c:173. +[eva] tests/value/invalid_pointer.c:43: Trace partitioning superposing up to 100 states -[eva] tests/value/invalid_pointer.c:53: +[eva] tests/value/invalid_pointer.c:54: Frama_C_show_each_bottom: {{ &t + {-4} }} [eva] Recording results for pointer_in_loops [eva] Done for function pointer_in_loops [eva] computing for function int_conversion <- main. - Called from tests/value/invalid_pointer.c:173. + Called from tests/value/invalid_pointer.c:174. [eva] computing for function Frama_C_interval <- int_conversion <- main. - Called from tests/value/invalid_pointer.c:65. -[eva] tests/value/invalid_pointer.c:65: + Called from tests/value/invalid_pointer.c:66. +[eva] tests/value/invalid_pointer.c:66: function Frama_C_interval: precondition 'order' got status valid. [eva] Done for function Frama_C_interval [eva] computing for function Frama_C_interval <- int_conversion <- main. - Called from tests/value/invalid_pointer.c:67. -[eva] tests/value/invalid_pointer.c:67: + Called from tests/value/invalid_pointer.c:68. +[eva] tests/value/invalid_pointer.c:68: function Frama_C_interval: precondition 'order' got status valid. [eva] Done for function Frama_C_interval [eva] computing for function Frama_C_interval <- int_conversion <- main. - Called from tests/value/invalid_pointer.c:71. -[eva] tests/value/invalid_pointer.c:71: + Called from tests/value/invalid_pointer.c:72. +[eva] tests/value/invalid_pointer.c:72: function Frama_C_interval: precondition 'order' got status valid. [eva] Done for function Frama_C_interval [eva] Recording results for int_conversion [eva] Done for function int_conversion [eva] computing for function addrof <- main. - Called from tests/value/invalid_pointer.c:174. + Called from tests/value/invalid_pointer.c:175. [eva] Recording results for addrof [eva] Done for function addrof [eva] computing for function union_pointer <- main. - Called from tests/value/invalid_pointer.c:175. + Called from tests/value/invalid_pointer.c:176. [eva] Recording results for union_pointer [eva] Done for function union_pointer [eva] computing for function write_pointer <- main. - Called from tests/value/invalid_pointer.c:176. + Called from tests/value/invalid_pointer.c:177. [eva] Recording results for write_pointer [eva] Done for function write_pointer [eva] computing for function object_pointer_predicate <- main. - Called from tests/value/invalid_pointer.c:177. -[eva] tests/value/invalid_pointer.c:126: assertion got status valid. -[eva:alarm] tests/value/invalid_pointer.c:129: Warning: + Called from tests/value/invalid_pointer.c:178. +[eva] tests/value/invalid_pointer.c:127: assertion got status valid. +[eva:alarm] tests/value/invalid_pointer.c:130: Warning: assertion got status invalid (stopping propagation). -[eva] tests/value/invalid_pointer.c:132: assertion got status valid. -[eva:alarm] tests/value/invalid_pointer.c:135: Warning: +[eva] tests/value/invalid_pointer.c:133: assertion got status valid. +[eva:alarm] tests/value/invalid_pointer.c:136: Warning: assertion got status invalid (stopping propagation). -[eva:alarm] tests/value/invalid_pointer.c:138: Warning: +[eva:alarm] tests/value/invalid_pointer.c:139: Warning: assertion got status unknown. -[eva] tests/value/invalid_pointer.c:139: assertion got status valid. -[eva] tests/value/invalid_pointer.c:140: +[eva] tests/value/invalid_pointer.c:140: assertion got status valid. +[eva] tests/value/invalid_pointer.c:141: Frama_C_show_each_object_pointer: {{ &x + {0; 4} }} -[eva:alarm] tests/value/invalid_pointer.c:142: Warning: +[eva:alarm] tests/value/invalid_pointer.c:143: Warning: assertion got status unknown. -[eva] tests/value/invalid_pointer.c:143: assertion got status valid. -[eva] tests/value/invalid_pointer.c:144: +[eva] tests/value/invalid_pointer.c:144: assertion got status valid. +[eva] tests/value/invalid_pointer.c:145: Frama_C_show_each_object_pointer_char: {{ &x + {0; 1; 2; 3; 4} }} [eva] computing for function Frama_C_interval <- object_pointer_predicate <- main. - Called from tests/value/invalid_pointer.c:145. -[eva] tests/value/invalid_pointer.c:145: + Called from tests/value/invalid_pointer.c:146. +[eva] tests/value/invalid_pointer.c:146: function Frama_C_interval: precondition 'order' got status valid. [eva] Done for function Frama_C_interval -[eva] tests/value/invalid_pointer.c:147: assertion got status valid. -[eva:alarm] tests/value/invalid_pointer.c:149: Warning: +[eva] tests/value/invalid_pointer.c:148: assertion got status valid. +[eva:alarm] tests/value/invalid_pointer.c:150: Warning: assertion got status unknown. -[eva:alarm] tests/value/invalid_pointer.c:151: Warning: +[eva:alarm] tests/value/invalid_pointer.c:152: Warning: assertion got status unknown. -[eva] tests/value/invalid_pointer.c:152: +[eva] tests/value/invalid_pointer.c:153: Frama_C_show_each_object_pointer_array: {{ &x + {0; 4} ; &array + [0..256],0%4 }} -[eva] tests/value/invalid_pointer.c:154: assertion got status valid. -[eva:alarm] tests/value/invalid_pointer.c:157: Warning: +[eva] tests/value/invalid_pointer.c:155: assertion got status valid. +[eva:alarm] tests/value/invalid_pointer.c:158: Warning: assertion got status unknown. -[eva:alarm] tests/value/invalid_pointer.c:160: Warning: +[eva:alarm] tests/value/invalid_pointer.c:161: Warning: assertion got status unknown. -[eva:alarm] tests/value/invalid_pointer.c:162: Warning: +[eva:alarm] tests/value/invalid_pointer.c:163: Warning: assertion got status unknown. -[eva:alarm] tests/value/invalid_pointer.c:165: Warning: +[eva:alarm] tests/value/invalid_pointer.c:166: Warning: assertion got status invalid (stopping propagation). [eva] Recording results for object_pointer_predicate [eva] Done for function object_pointer_predicate +[eva] computing for function signal <- main. + Called from tests/value/invalid_pointer.c:180. +[eva] using specification for function signal +[eva] Done for function signal +[eva] computing for function signal <- main. + Called from tests/value/invalid_pointer.c:181. +[eva] Done for function signal +[eva] computing for function signal <- main. + Called from tests/value/invalid_pointer.c:182. +[eva] Done for function signal [eva] Recording results for main [eva] done for function main [scope:rm_asserts] removing 2 assertion(s) @@ -280,6 +290,8 @@ [from] Computing for function write_pointer [from] Done for function write_pointer [from] Computing for function main +[from] Computing for function signal <-main +[from] Done for function signal [from] Done for function main [from] ====== DEPENDENCIES COMPUTED ====== These dependencies hold at termination for the executions that terminate: @@ -296,6 +308,8 @@ Frama_C_entropy_source FROM Frama_C_entropy_source (and SELF) [from] Function pointer_in_loops: NO EFFECTS +[from] Function signal: + \result FROM ANYTHING(origin:Unknown) [from] Function union_pointer: NO EFFECTS [from] Function write_pointer: @@ -334,4 +348,4 @@ [inout] Out (internal) for function main: Frama_C_entropy_source [inout] Inputs for function main: - Frama_C_entropy_source; undet + Frama_C_entropy_source; SIG_DFL; SIG_IGN; SIG_ERR; undet -- GitLab From 297788c4592eef0393847079a873b5466102ce08 Mon Sep 17 00:00:00 2001 From: Virgile Prevosto <virgile.prevosto@m4x.org> Date: Wed, 25 Mar 2020 19:19:42 +0100 Subject: [PATCH 047/218] [tests] add pretty-printing test for treatment of new builtins --- tests/syntax/oracle/signal.res.oracle | 12 ++++++++++++ tests/syntax/signal.c | 7 +++++++ 2 files changed, 19 insertions(+) create mode 100644 tests/syntax/oracle/signal.res.oracle create mode 100644 tests/syntax/signal.c diff --git a/tests/syntax/oracle/signal.res.oracle b/tests/syntax/oracle/signal.res.oracle new file mode 100644 index 00000000000..7f9d11fa241 --- /dev/null +++ b/tests/syntax/oracle/signal.res.oracle @@ -0,0 +1,12 @@ +[kernel] Parsing tests/syntax/signal.c (with preprocessing) +/* Generated by Frama-C */ +#include "signal.h" +void f(void) +{ + signal(10,SIG_IGN); + signal(12,SIG_ERR); + signal(31,SIG_DFL); + return; +} + + diff --git a/tests/syntax/signal.c b/tests/syntax/signal.c new file mode 100644 index 00000000000..31221db005b --- /dev/null +++ b/tests/syntax/signal.c @@ -0,0 +1,7 @@ +#include <signal.h> + +void f() { + signal (SIGUSR1, SIG_IGN); + signal (SIGUSR2, SIG_ERR); + signal (SIGUNUSED, SIG_DFL); +} -- GitLab From 4a09815e6cded2c45202da5ebde7a44977d383f1 Mon Sep 17 00:00:00 2001 From: Virgile Prevosto <virgile.prevosto@m4x.org> Date: Thu, 26 Mar 2020 13:47:31 +0100 Subject: [PATCH 048/218] [libc] Avoid confusing Eva on the value of SIG_IGN, SIG_DFL and SIG_ERR --- share/libc/signal.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/share/libc/signal.h b/share/libc/signal.h index 01f6d674da7..063ba74ba58 100644 --- a/share/libc/signal.h +++ b/share/libc/signal.h @@ -46,13 +46,13 @@ typedef void (*__fc_sighandler_t) (int); /* for BSD 4.4 */ typedef __fc_sighandler_t sig_t; -extern sig_t __fc_sig_dfl; -extern sig_t __fc_sig_ign; -extern sig_t __fc_sig_err; +extern void __fc_sig_dfl(int); +extern void __fc_sig_ign(int); +extern void __fc_sig_err(int); -#define SIG_DFL __fc_sig_dfl /* default signal handling */ -#define SIG_IGN __fc_sig_ign /* ignore signal */ -#define SIG_ERR __fc_sig_err /* error return from signal */ +#define SIG_DFL (&__fc_sig_dfl) /* default signal handling */ +#define SIG_IGN (&__fc_sig_ign) /* ignore signal */ +#define SIG_ERR (&__fc_sig_err) /* error return from signal */ #define SIG_BLOCK 0 #define SIG_UNBLOCK 1 -- GitLab From ac4373cce47479dc97ec0021e9932bebb3a30cb6 Mon Sep 17 00:00:00 2001 From: Virgile Prevosto <virgile.prevosto@m4x.org> Date: Thu, 26 Mar 2020 14:40:54 +0100 Subject: [PATCH 049/218] [printer] special treatment for __fc_sig_* following their new declaration --- src/kernel_services/ast_printing/cil_printer.ml | 7 +++++++ tests/value/oracle/invalid_pointer.0.res.oracle | 2 +- tests/value/oracle/invalid_pointer.1.res.oracle | 2 +- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/kernel_services/ast_printing/cil_printer.ml b/src/kernel_services/ast_printing/cil_printer.ml index 186378fef09..e1642d5c48b 100644 --- a/src/kernel_services/ast_printing/cil_printer.ml +++ b/src/kernel_services/ast_printing/cil_printer.ml @@ -54,6 +54,10 @@ module Extensions = struct end let set_extension_handler = Extensions.set_handler +(* for specific builtin functions that act as placeholder for C macros. + For each name f below, pretty-printer will replace f and &f with the + corresponding name. Be sure to keep the list in sync with share/libc. +*) let rename_builtins = Datatype.String.Hashtbl.create 17 let () = @@ -781,6 +785,9 @@ class cil_printer () = object (self) Neither cookie nor keyword for you. *) | AlignOf t -> fprintf fmt "__alignof__(%a)" (self#typ None) t | AlignOfE e -> fprintf fmt "__alignof__(%a)" self#exp_non_decay e + | AddrOf ((Var v, NoOffset)) + when Datatype.String.Hashtbl.mem rename_builtins v.vname -> + self#varinfo fmt v | AddrOf lv -> fprintf fmt "& %a" (self#lval_prec Precedence.addrOfLevel) lv | StartOf(lv) -> if state.print_cil_as_is || non_decay then diff --git a/tests/value/oracle/invalid_pointer.0.res.oracle b/tests/value/oracle/invalid_pointer.0.res.oracle index 4d5ac453516..49074590ec4 100644 --- a/tests/value/oracle/invalid_pointer.0.res.oracle +++ b/tests/value/oracle/invalid_pointer.0.res.oracle @@ -420,4 +420,4 @@ [inout] Out (internal) for function main: Frama_C_entropy_source [inout] Inputs for function main: - Frama_C_entropy_source; SIG_DFL; SIG_IGN; SIG_ERR; undet + Frama_C_entropy_source; undet diff --git a/tests/value/oracle/invalid_pointer.1.res.oracle b/tests/value/oracle/invalid_pointer.1.res.oracle index f8121ed36eb..132d1bef54d 100644 --- a/tests/value/oracle/invalid_pointer.1.res.oracle +++ b/tests/value/oracle/invalid_pointer.1.res.oracle @@ -348,4 +348,4 @@ [inout] Out (internal) for function main: Frama_C_entropy_source [inout] Inputs for function main: - Frama_C_entropy_source; SIG_DFL; SIG_IGN; SIG_ERR; undet + Frama_C_entropy_source; undet -- GitLab From de4c7793187af93a2ce642bd9d4b027ed7053d15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Loi=CC=88c=20Correnson?= <loic.correnson@cea.fr> Date: Thu, 26 Mar 2020 11:03:27 +0100 Subject: [PATCH 050/218] [wp] implement OBJ validity access mode --- src/plugins/wp/Cvalues.ml | 5 ++ src/plugins/wp/Cvalues.mli | 1 + src/plugins/wp/LogicSemantics.ml | 6 +- src/plugins/wp/MemMemory.ml | 1 + src/plugins/wp/MemMemory.mli | 1 + src/plugins/wp/MemTyped.ml | 6 +- src/plugins/wp/MemVar.ml | 60 +++++++++++++------ src/plugins/wp/Sigs.ml | 1 + .../wp/share/why3/frama_c_wp/memory.mlw | 5 +- 9 files changed, 61 insertions(+), 25 deletions(-) diff --git a/src/plugins/wp/Cvalues.ml b/src/plugins/wp/Cvalues.ml index 5440affcb5d..10fa328fa1b 100644 --- a/src/plugins/wp/Cvalues.ml +++ b/src/plugins/wp/Cvalues.ml @@ -357,6 +357,11 @@ let plain lt e = type 'a printer = Format.formatter -> 'a -> unit +let pp_acs fmt = function + | RW -> Format.pp_print_string fmt "RW" + | RD -> Format.pp_print_string fmt "RD" + | OBJ -> Format.pp_print_string fmt "OBJ" + let pp_bound fmt = function None -> () | Some p -> F.pp_term fmt p let pp_value pp fmt = function diff --git a/src/plugins/wp/Cvalues.mli b/src/plugins/wp/Cvalues.mli index 1393505ab5a..f98a7923cb5 100644 --- a/src/plugins/wp/Cvalues.mli +++ b/src/plugins/wp/Cvalues.mli @@ -35,6 +35,7 @@ val equation : Sigs.equation -> pred type 'a printer = Format.formatter -> 'a -> unit +val pp_acs : acs printer val pp_bound : term option printer val pp_value : 'a printer -> 'a value printer val pp_logic : 'a printer -> 'a logic printer diff --git a/src/plugins/wp/LogicSemantics.ml b/src/plugins/wp/LogicSemantics.ml index 825ace458d1..2a90684fe56 100644 --- a/src/plugins/wp/LogicSemantics.ml +++ b/src/plugins/wp/LogicSemantics.ml @@ -871,11 +871,7 @@ struct | Pvalid(label,t) -> valid env RW label t | Pvalid_read(label,t) -> valid env RD label t - - | Pobject_pointer(_label,_t) -> - Warning.error - "\\object_pointer not yet implemented@\n\ - @[<hov 0>(%a)@]" Printer.pp_predicate p + | Pobject_pointer(label,t) -> valid env OBJ label t | Pvalid_function _t -> Warning.error diff --git a/src/plugins/wp/MemMemory.ml b/src/plugins/wp/MemMemory.ml index 4551f143c0d..8352296e1df 100644 --- a/src/plugins/wp/MemMemory.ml +++ b/src/plugins/wp/MemMemory.ml @@ -62,6 +62,7 @@ let l_havoc = Qed.Engine.{ let p_valid_rd = Lang.extern_fp ~library "valid_rd" let p_valid_rw = Lang.extern_fp ~library "valid_rw" +let p_valid_obj = Lang.extern_fp ~library "valid_obj" let p_invalid = Lang.extern_fp ~library "invalid" let p_separated = Lang.extern_fp ~library "separated" let p_included = Lang.extern_fp ~library "included" diff --git a/src/plugins/wp/MemMemory.mli b/src/plugins/wp/MemMemory.mli index 0a92156a9ed..ab60842d69a 100644 --- a/src/plugins/wp/MemMemory.mli +++ b/src/plugins/wp/MemMemory.mli @@ -62,6 +62,7 @@ val p_separated : lfun val p_included : lfun val p_valid_rd : lfun val p_valid_rw : lfun +val p_valid_obj : lfun val p_invalid : lfun val p_eqmem : lfun diff --git a/src/plugins/wp/MemTyped.ml b/src/plugins/wp/MemTyped.ml index 9dce8f268df..e1317a92d94 100644 --- a/src/plugins/wp/MemTyped.ml +++ b/src/plugins/wp/MemTyped.ml @@ -954,7 +954,11 @@ let loc_diff obj p q = (* -------------------------------------------------------------------------- *) let s_valid sigma acs p n = - let p_valid = match acs with RW -> p_valid_rw | RD -> p_valid_rd in + let p_valid = match acs with + | RW -> p_valid_rw + | RD -> p_valid_rd + | OBJ -> p_valid_obj + in p_call p_valid [Sigma.value sigma T_alloc;p;n] let s_invalid sigma p n = diff --git a/src/plugins/wp/MemVar.ml b/src/plugins/wp/MemVar.ml index ca7a5873b1d..fd09f824c2c 100644 --- a/src/plugins/wp/MemVar.ml +++ b/src/plugins/wp/MemVar.ml @@ -739,6 +739,9 @@ struct let fits_inside cond a b n = p_leq e_zero a :: p_lt b (e_int n) :: cond + let fits_off_by_one cond a b n = + p_leq e_zero a :: p_leq b (e_int n) :: cond + let stay_outside cond a b n = p_lt b e_zero :: p_leq (e_int n) a :: cond @@ -754,6 +757,13 @@ struct | Some( _ , None ) -> unsized_array () | None -> raise ShiftMismatch + (* Append conditions for and array offset (te,k) to fits in obj *) + let array_check fitting cond te k obj = + match Ctypes.get_array obj with + | Some( e , Some n ) when Ctypes.equal e te -> fitting cond k k n + | Some( _ , None ) -> unsized_array () + | _ -> block_check fitting cond (obj,1) (te,k,k) + (* Append conditions for [offset] to fits [object], provided [a<=b]. *) let rec offset_fits cond obj offset = match offset with @@ -761,14 +771,8 @@ struct | Field fd :: ofs -> offset_fits cond (Ctypes.object_of fd.ftype) ofs | Shift(te,k) :: ofs -> - match Ctypes.get_array obj with - | Some( e , Some n ) when Ctypes.equal e te -> - let cond = p_leq e_zero k :: p_lt k (e_int n) :: cond in - offset_fits cond e ofs - | Some( _ , None ) -> unsized_array () - | _ -> - let cond = block_check fits_inside cond (obj,1) (te,k,k) in - offset_fits cond te ofs + let cond = array_check fits_inside cond te k obj in + offset_fits cond te ofs (* Append conditions to [cond] for [range=(elt,a,b)], starting at [offset], consisting of [a..b] elements with type [elt] to fits inside the block, @@ -796,19 +800,39 @@ struct (* --- Validity --- *) (* -------------------------------------------------------------------------- *) - let valid_offset obj ofs = - F.p_conj (offset_fits [] obj ofs) - - let valid_range obj ofs range = - F.p_conj (range_check fits_inside [] (obj,1) ofs range) + let rec last_field_shift acs obj ofs = + match acs , obj , ofs with + | OBJ , _ , [Shift(te,k)] -> Some(te,k,obj) + | OBJ , C_comp c , (Field fd :: ofs) -> + begin + match List.rev c.cfields with + | fd0::_ when Fieldinfo.equal fd fd0 -> + last_field_shift acs (Ctypes.object_of fd.ftype) ofs + | _ -> None + end + | _ -> None + + let valid_offset acs obj ofs = + match last_field_shift acs obj ofs with + | Some(te,k,obj) -> + F.p_conj (array_check fits_off_by_one [] te k obj) + | None -> + F.p_conj (offset_fits [] obj ofs) + + let valid_range acs obj ofs range = + match last_field_shift acs obj ofs with + | Some _ -> + F.p_conj (range_check fits_off_by_one [] (obj,1) ofs range) + | _ -> + F.p_conj (range_check fits_inside [] (obj,1) ofs range) (* varinfo *) let valid_base sigma acs mem x = if x.vglob then - if acs = RW && Cil.typeHasQualifier "const" x.vtype - then p_false - else p_true + match acs with + | RW -> if Cil.typeHasQualifier "const" x.vtype then p_false else p_true + | RD | OBJ -> p_true else match mem with | CVAL | HEAP -> p_bool (ALLOC.value sigma.alloc x) @@ -819,12 +843,12 @@ struct let valid_offset_path sigma acs mem x ofs = p_and (valid_base sigma acs mem x) - (valid_offset (vobject mem x) ofs) + (valid_offset acs (vobject mem x) ofs) let valid_range_path sigma acs mem x ofs rg = p_and (valid_base sigma acs mem x) - (valid_range (vobject mem x) ofs rg) + (valid_range acs (vobject mem x) ofs rg) (* in-model validation *) diff --git a/src/plugins/wp/Sigs.ml b/src/plugins/wp/Sigs.ml index c296519519c..72d1972ac59 100644 --- a/src/plugins/wp/Sigs.ml +++ b/src/plugins/wp/Sigs.ml @@ -46,6 +46,7 @@ type equation = type acs = | RW (** Read-Write Access *) | RD (** Read-Only Access *) + | OBJ (** Valid Object Pointer *) (** Abstract location or concrete value *) type 'a value = diff --git a/src/plugins/wp/share/why3/frama_c_wp/memory.mlw b/src/plugins/wp/share/why3/frama_c_wp/memory.mlw index 1dd6a2d7234..e91550d73ce 100644 --- a/src/plugins/wp/share/why3/frama_c_wp/memory.mlw +++ b/src/plugins/wp/share/why3/frama_c_wp/memory.mlw @@ -75,6 +75,9 @@ theory Memory predicate valid_rd (m : map int int) (p:addr) (n:int) = n > 0 -> ( 0 <> p.base /\ 0 <= p.offset /\ p.offset + n <= m[p.base] ) + predicate valid_obj (m : map int int) (p:addr) (n:int) = + n > 0 -> ( 0 <> p.base /\ 0 <= p.offset /\ p.offset + n <= 1 + m[p.base] ) + predicate invalid (m : map int int) (p:addr) (n:int) = n > 0 -> ( m[p.base] <= p.offset \/ p.offset + n <= 0 ) @@ -170,4 +173,4 @@ theory Memory axiom addr_of_null : int_of_addr null = 0 -end \ No newline at end of file +end -- GitLab From a83af1552903442e286a25849351c7f63402b8e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Loi=CC=88c=20Correnson?= <loic.correnson@cea.fr> Date: Thu, 26 Mar 2020 12:28:33 +0100 Subject: [PATCH 051/218] [wp] test for invalid pointers --- .../wp/share/why3/frama_c_wp/memory.mlw | 3 +- .../wp/tests/wp_acsl/invalid_pointer.c | 57 ++++++++ .../wp_acsl/oracle/invalid_pointer.res.oracle | 126 ++++++++++++++++++ .../546d68cf73aa7d1be7397f0dba7ab57b.json | 2 + .../6135a695451f38570cc5e98d983b3fc5.json | 2 + .../82fda005a00dfb2bafda2e7a61e31a0e.json | 2 + .../a09f29e9995f66e54188484d0f6a022c.json | 1 + .../a1789ac93bbdd1b61d2668d397e828b5.json | 2 + .../a66c1f9591316a451c831ed9aa33375a.json | 2 + .../bff665fbed54b18d00114b87eaddf2d7.json | 2 + .../e73bf6bee511f053358c2e0d3561a7e1.json | 2 + .../edc73eb8a8cf742d31cbce5dfed79215.json | 2 + .../f957b00472bc5ec2c8193749f227c435.json | 1 + .../oracle_qualif/invalid_pointer.res.oracle | 36 +++++ 14 files changed, 239 insertions(+), 1 deletion(-) create mode 100644 src/plugins/wp/tests/wp_acsl/invalid_pointer.c create mode 100644 src/plugins/wp/tests/wp_acsl/oracle/invalid_pointer.res.oracle create mode 100644 src/plugins/wp/tests/wp_acsl/oracle_qualif/invalid_pointer.0.session/cache/546d68cf73aa7d1be7397f0dba7ab57b.json create mode 100644 src/plugins/wp/tests/wp_acsl/oracle_qualif/invalid_pointer.0.session/cache/6135a695451f38570cc5e98d983b3fc5.json create mode 100644 src/plugins/wp/tests/wp_acsl/oracle_qualif/invalid_pointer.0.session/cache/82fda005a00dfb2bafda2e7a61e31a0e.json create mode 100644 src/plugins/wp/tests/wp_acsl/oracle_qualif/invalid_pointer.0.session/cache/a09f29e9995f66e54188484d0f6a022c.json create mode 100644 src/plugins/wp/tests/wp_acsl/oracle_qualif/invalid_pointer.0.session/cache/a1789ac93bbdd1b61d2668d397e828b5.json create mode 100644 src/plugins/wp/tests/wp_acsl/oracle_qualif/invalid_pointer.0.session/cache/a66c1f9591316a451c831ed9aa33375a.json create mode 100644 src/plugins/wp/tests/wp_acsl/oracle_qualif/invalid_pointer.0.session/cache/bff665fbed54b18d00114b87eaddf2d7.json create mode 100644 src/plugins/wp/tests/wp_acsl/oracle_qualif/invalid_pointer.0.session/cache/e73bf6bee511f053358c2e0d3561a7e1.json create mode 100644 src/plugins/wp/tests/wp_acsl/oracle_qualif/invalid_pointer.0.session/cache/edc73eb8a8cf742d31cbce5dfed79215.json create mode 100644 src/plugins/wp/tests/wp_acsl/oracle_qualif/invalid_pointer.0.session/cache/f957b00472bc5ec2c8193749f227c435.json create mode 100644 src/plugins/wp/tests/wp_acsl/oracle_qualif/invalid_pointer.res.oracle diff --git a/src/plugins/wp/share/why3/frama_c_wp/memory.mlw b/src/plugins/wp/share/why3/frama_c_wp/memory.mlw index e91550d73ce..912a953c523 100644 --- a/src/plugins/wp/share/why3/frama_c_wp/memory.mlw +++ b/src/plugins/wp/share/why3/frama_c_wp/memory.mlw @@ -76,7 +76,8 @@ theory Memory n > 0 -> ( 0 <> p.base /\ 0 <= p.offset /\ p.offset + n <= m[p.base] ) predicate valid_obj (m : map int int) (p:addr) (n:int) = - n > 0 -> ( 0 <> p.base /\ 0 <= p.offset /\ p.offset + n <= 1 + m[p.base] ) + n > 0 -> ( p = null \/ + ( 0 <> p.base /\ 0 <= p.offset /\ p.offset + n <= 1 + m[p.base] )) predicate invalid (m : map int int) (p:addr) (n:int) = n > 0 -> ( m[p.base] <= p.offset \/ p.offset + n <= 0 ) diff --git a/src/plugins/wp/tests/wp_acsl/invalid_pointer.c b/src/plugins/wp/tests/wp_acsl/invalid_pointer.c new file mode 100644 index 00000000000..14e08fdd4b9 --- /dev/null +++ b/src/plugins/wp/tests/wp_acsl/invalid_pointer.c @@ -0,0 +1,57 @@ +/* Tests for \object_pointer() */ + +void memvar(void) +{ + int x; + //@check M1: !\object_pointer(&x-1); + //@check P0: \object_pointer(&x); + //@check P1: \object_pointer(&x+1); + //@check P2: !\object_pointer(&x+2); +} + +void pointer(void) +{ + int x; + int *p = &x ; + *p = 1 ; + //@check M1: !\object_pointer(p-1); + //@check P0: \object_pointer(p); + //@check P1: \object_pointer(p+1); + //@check P2: !\object_pointer(p+2); + //@check NULL: \object_pointer(\null); +} + +void array(void) +{ + int k; + int a[25]; + int *q = &a[k]; + //@check ARR: (0 <= k <= 25) <==> \object_pointer(q); +} + +struct S { + int f ; + int g ; +}; + +struct A { + int m[10]; +}; + +void compound(void) +{ + struct S u ; + //@check M1: !\object_pointer(&u-1); + //@check P0: \object_pointer(&u); + //@check P1: \object_pointer(&u+1); + //@check P2: !\object_pointer(&u+2); + struct S s ; + struct S *p = &s ; + //@check F: \object_pointer(&(p->f)); + //@check G: \object_pointer(&(p->g)); + //@check F2: \object_pointer(&(p->f)+2); + //@check G2: !\object_pointer(&(p->g)+2); + int k ; + struct A a ; + //@check AM: (0 <= k <= 10) <==> \object_pointer(&a.m[k]); +} diff --git a/src/plugins/wp/tests/wp_acsl/oracle/invalid_pointer.res.oracle b/src/plugins/wp/tests/wp_acsl/oracle/invalid_pointer.res.oracle new file mode 100644 index 00000000000..f1bb59e94b4 --- /dev/null +++ b/src/plugins/wp/tests/wp_acsl/oracle/invalid_pointer.res.oracle @@ -0,0 +1,126 @@ +# frama-c -wp [...] +[kernel] Parsing tests/wp_acsl/invalid_pointer.c (with preprocessing) +[wp] Running WP plugin... +[wp] Loading driver 'share/wp.driver' +[wp] Warning: Missing RTE guards +[wp] tests/wp_acsl/invalid_pointer.c:21: Warning: void object +------------------------------------------------------------ + Function array +------------------------------------------------------------ + +Goal Check 'ARR' (file tests/wp_acsl/invalid_pointer.c, line 29): +Assume { Type: is_sint32(k). (* Heap *) Type: linked(Malloc_0). } +Prove: ((0 <= k) /\ (k <= 25)) <-> + valid_obj(Malloc_0[L_a_32 <- 25], shift_sint32(global(L_a_32), k), 1). + +------------------------------------------------------------ +------------------------------------------------------------ + Function compound +------------------------------------------------------------ + +Goal Check 'M1' (file tests/wp_acsl/invalid_pointer.c, line 44): +Prove: true. + +------------------------------------------------------------ + +Goal Check 'P0' (file tests/wp_acsl/invalid_pointer.c, line 45): +Prove: true. + +------------------------------------------------------------ + +Goal Check 'P1' (file tests/wp_acsl/invalid_pointer.c, line 46): +Prove: true. + +------------------------------------------------------------ + +Goal Check 'P2' (file tests/wp_acsl/invalid_pointer.c, line 47): +Prove: true. + +------------------------------------------------------------ + +Goal Check 'F' (file tests/wp_acsl/invalid_pointer.c, line 50): +Assume { (* Heap *) Type: linked(Malloc_0). } +Prove: valid_obj(Malloc_0[L_s_37 <- 2], shiftfield_F1_S_f(global(L_s_37)), 1). + +------------------------------------------------------------ + +Goal Check 'G' (file tests/wp_acsl/invalid_pointer.c, line 51): +Assume { (* Heap *) Type: linked(Malloc_0). } +Prove: valid_obj(Malloc_0[L_s_37 <- 2], shiftfield_F1_S_g(global(L_s_37)), 1). + +------------------------------------------------------------ + +Goal Check 'F2' (file tests/wp_acsl/invalid_pointer.c, line 52): +Assume { (* Heap *) Type: linked(Malloc_0). } +Prove: valid_obj(Malloc_0[L_s_37 <- 2], + shift_sint32(shiftfield_F1_S_f(global(L_s_37)), 2), 1). + +------------------------------------------------------------ + +Goal Check 'G2' (file tests/wp_acsl/invalid_pointer.c, line 53): +Assume { (* Heap *) Type: linked(Malloc_0). } +Prove: !valid_obj(Malloc_0[L_s_37 <- 2], + shift_sint32(shiftfield_F1_S_g(global(L_s_37)), 2), 1). + +------------------------------------------------------------ + +Goal Check 'AM' (file tests/wp_acsl/invalid_pointer.c, line 56): +Prove: true. + +------------------------------------------------------------ +------------------------------------------------------------ + Function memvar +------------------------------------------------------------ + +Goal Check 'M1' (file tests/wp_acsl/invalid_pointer.c, line 6): +Prove: true. + +------------------------------------------------------------ + +Goal Check 'P0' (file tests/wp_acsl/invalid_pointer.c, line 7): +Prove: true. + +------------------------------------------------------------ + +Goal Check 'P1' (file tests/wp_acsl/invalid_pointer.c, line 8): +Prove: true. + +------------------------------------------------------------ + +Goal Check 'P2' (file tests/wp_acsl/invalid_pointer.c, line 9): +Prove: true. + +------------------------------------------------------------ +------------------------------------------------------------ + Function pointer +------------------------------------------------------------ + +Goal Check 'M1' (file tests/wp_acsl/invalid_pointer.c, line 17): +Assume { (* Heap *) Type: linked(Malloc_0). } +Prove: !valid_obj(Malloc_0[L_x_27 <- 1], shift_sint32(global(L_x_27), -1), 1). + +------------------------------------------------------------ + +Goal Check 'P0' (file tests/wp_acsl/invalid_pointer.c, line 18): +Assume { (* Heap *) Type: linked(Malloc_0). } +Prove: valid_obj(Malloc_0[L_x_27 <- 1], global(L_x_27), 1). + +------------------------------------------------------------ + +Goal Check 'P1' (file tests/wp_acsl/invalid_pointer.c, line 19): +Assume { (* Heap *) Type: linked(Malloc_0). } +Prove: valid_obj(Malloc_0[L_x_27 <- 1], shift_sint32(global(L_x_27), 1), 1). + +------------------------------------------------------------ + +Goal Check 'P2' (file tests/wp_acsl/invalid_pointer.c, line 20): +Assume { (* Heap *) Type: linked(Malloc_0). } +Prove: !valid_obj(Malloc_0[L_x_27 <- 1], shift_sint32(global(L_x_27), 2), 1). + +------------------------------------------------------------ + +Goal Check 'NULL' (file tests/wp_acsl/invalid_pointer.c, line 21): +Assume { (* Heap *) Type: linked(Malloc_0). } +Prove: valid_obj(Malloc_0[L_x_27 <- 1], null, 1). + +------------------------------------------------------------ diff --git a/src/plugins/wp/tests/wp_acsl/oracle_qualif/invalid_pointer.0.session/cache/546d68cf73aa7d1be7397f0dba7ab57b.json b/src/plugins/wp/tests/wp_acsl/oracle_qualif/invalid_pointer.0.session/cache/546d68cf73aa7d1be7397f0dba7ab57b.json new file mode 100644 index 00000000000..d824319ad4a --- /dev/null +++ b/src/plugins/wp/tests/wp_acsl/oracle_qualif/invalid_pointer.0.session/cache/546d68cf73aa7d1be7397f0dba7ab57b.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0104, + "steps": 15 } diff --git a/src/plugins/wp/tests/wp_acsl/oracle_qualif/invalid_pointer.0.session/cache/6135a695451f38570cc5e98d983b3fc5.json b/src/plugins/wp/tests/wp_acsl/oracle_qualif/invalid_pointer.0.session/cache/6135a695451f38570cc5e98d983b3fc5.json new file mode 100644 index 00000000000..73bc5ac39eb --- /dev/null +++ b/src/plugins/wp/tests/wp_acsl/oracle_qualif/invalid_pointer.0.session/cache/6135a695451f38570cc5e98d983b3fc5.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0128, + "steps": 10 } diff --git a/src/plugins/wp/tests/wp_acsl/oracle_qualif/invalid_pointer.0.session/cache/82fda005a00dfb2bafda2e7a61e31a0e.json b/src/plugins/wp/tests/wp_acsl/oracle_qualif/invalid_pointer.0.session/cache/82fda005a00dfb2bafda2e7a61e31a0e.json new file mode 100644 index 00000000000..c84d43dcd68 --- /dev/null +++ b/src/plugins/wp/tests/wp_acsl/oracle_qualif/invalid_pointer.0.session/cache/82fda005a00dfb2bafda2e7a61e31a0e.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0105, + "steps": 15 } diff --git a/src/plugins/wp/tests/wp_acsl/oracle_qualif/invalid_pointer.0.session/cache/a09f29e9995f66e54188484d0f6a022c.json b/src/plugins/wp/tests/wp_acsl/oracle_qualif/invalid_pointer.0.session/cache/a09f29e9995f66e54188484d0f6a022c.json new file mode 100644 index 00000000000..518bcc1fe1c --- /dev/null +++ b/src/plugins/wp/tests/wp_acsl/oracle_qualif/invalid_pointer.0.session/cache/a09f29e9995f66e54188484d0f6a022c.json @@ -0,0 +1 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.01, "steps": 14 } diff --git a/src/plugins/wp/tests/wp_acsl/oracle_qualif/invalid_pointer.0.session/cache/a1789ac93bbdd1b61d2668d397e828b5.json b/src/plugins/wp/tests/wp_acsl/oracle_qualif/invalid_pointer.0.session/cache/a1789ac93bbdd1b61d2668d397e828b5.json new file mode 100644 index 00000000000..bcc741b8f32 --- /dev/null +++ b/src/plugins/wp/tests/wp_acsl/oracle_qualif/invalid_pointer.0.session/cache/a1789ac93bbdd1b61d2668d397e828b5.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0087, + "steps": 8 } diff --git a/src/plugins/wp/tests/wp_acsl/oracle_qualif/invalid_pointer.0.session/cache/a66c1f9591316a451c831ed9aa33375a.json b/src/plugins/wp/tests/wp_acsl/oracle_qualif/invalid_pointer.0.session/cache/a66c1f9591316a451c831ed9aa33375a.json new file mode 100644 index 00000000000..41a0ec6c820 --- /dev/null +++ b/src/plugins/wp/tests/wp_acsl/oracle_qualif/invalid_pointer.0.session/cache/a66c1f9591316a451c831ed9aa33375a.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0099, + "steps": 10 } diff --git a/src/plugins/wp/tests/wp_acsl/oracle_qualif/invalid_pointer.0.session/cache/bff665fbed54b18d00114b87eaddf2d7.json b/src/plugins/wp/tests/wp_acsl/oracle_qualif/invalid_pointer.0.session/cache/bff665fbed54b18d00114b87eaddf2d7.json new file mode 100644 index 00000000000..46a81b15502 --- /dev/null +++ b/src/plugins/wp/tests/wp_acsl/oracle_qualif/invalid_pointer.0.session/cache/bff665fbed54b18d00114b87eaddf2d7.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0149, + "steps": 22 } diff --git a/src/plugins/wp/tests/wp_acsl/oracle_qualif/invalid_pointer.0.session/cache/e73bf6bee511f053358c2e0d3561a7e1.json b/src/plugins/wp/tests/wp_acsl/oracle_qualif/invalid_pointer.0.session/cache/e73bf6bee511f053358c2e0d3561a7e1.json new file mode 100644 index 00000000000..d4e438038a9 --- /dev/null +++ b/src/plugins/wp/tests/wp_acsl/oracle_qualif/invalid_pointer.0.session/cache/e73bf6bee511f053358c2e0d3561a7e1.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0116, + "steps": 15 } diff --git a/src/plugins/wp/tests/wp_acsl/oracle_qualif/invalid_pointer.0.session/cache/edc73eb8a8cf742d31cbce5dfed79215.json b/src/plugins/wp/tests/wp_acsl/oracle_qualif/invalid_pointer.0.session/cache/edc73eb8a8cf742d31cbce5dfed79215.json new file mode 100644 index 00000000000..5a8ea347aa4 --- /dev/null +++ b/src/plugins/wp/tests/wp_acsl/oracle_qualif/invalid_pointer.0.session/cache/edc73eb8a8cf742d31cbce5dfed79215.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0106, + "steps": 16 } diff --git a/src/plugins/wp/tests/wp_acsl/oracle_qualif/invalid_pointer.0.session/cache/f957b00472bc5ec2c8193749f227c435.json b/src/plugins/wp/tests/wp_acsl/oracle_qualif/invalid_pointer.0.session/cache/f957b00472bc5ec2c8193749f227c435.json new file mode 100644 index 00000000000..1731ee73796 --- /dev/null +++ b/src/plugins/wp/tests/wp_acsl/oracle_qualif/invalid_pointer.0.session/cache/f957b00472bc5ec2c8193749f227c435.json @@ -0,0 +1 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.01, "steps": 11 } diff --git a/src/plugins/wp/tests/wp_acsl/oracle_qualif/invalid_pointer.res.oracle b/src/plugins/wp/tests/wp_acsl/oracle_qualif/invalid_pointer.res.oracle new file mode 100644 index 00000000000..600fdf9a79b --- /dev/null +++ b/src/plugins/wp/tests/wp_acsl/oracle_qualif/invalid_pointer.res.oracle @@ -0,0 +1,36 @@ +# frama-c -wp [...] +[kernel] Parsing tests/wp_acsl/invalid_pointer.c (with preprocessing) +[wp] Running WP plugin... +[wp] Loading driver 'share/wp.driver' +[wp] Warning: Missing RTE guards +[wp] tests/wp_acsl/invalid_pointer.c:21: Warning: void object +[wp] 19 goals scheduled +[wp] [Alt-Ergo] Goal typed_array_check_ARR : Valid +[wp] [Qed] Goal typed_compound_check_M1 : Valid +[wp] [Qed] Goal typed_compound_check_P0 : Valid +[wp] [Qed] Goal typed_compound_check_P1 : Valid +[wp] [Qed] Goal typed_compound_check_P2 : Valid +[wp] [Alt-Ergo] Goal typed_compound_check_F : Valid +[wp] [Alt-Ergo] Goal typed_compound_check_G : Valid +[wp] [Alt-Ergo] Goal typed_compound_check_F2 : Valid +[wp] [Alt-Ergo] Goal typed_compound_check_G2 : Valid +[wp] [Qed] Goal typed_compound_check_AM : Valid +[wp] [Qed] Goal typed_memvar_check_M1 : Valid +[wp] [Qed] Goal typed_memvar_check_P0 : Valid +[wp] [Qed] Goal typed_memvar_check_P1 : Valid +[wp] [Qed] Goal typed_memvar_check_P2 : Valid +[wp] [Alt-Ergo] Goal typed_pointer_check_M1 : Valid +[wp] [Alt-Ergo] Goal typed_pointer_check_P0 : Valid +[wp] [Alt-Ergo] Goal typed_pointer_check_P1 : Valid +[wp] [Alt-Ergo] Goal typed_pointer_check_P2 : Valid +[wp] [Alt-Ergo] Goal typed_pointer_check_NULL : Valid +[wp] Proved goals: 19 / 19 + Qed: 9 + Alt-Ergo: 10 +------------------------------------------------------------ + Functions WP Alt-Ergo Total Success + memvar 4 - 4 100% + pointer - 5 5 100% + array - 1 1 100% + compound 5 4 9 100% +------------------------------------------------------------ -- GitLab From b8874fb700d8d16746fb220dc9acd3cffe83c052 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Loi=CC=88c=20Correnson?= <loic.correnson@cea.fr> Date: Thu, 26 Mar 2020 14:37:07 +0100 Subject: [PATCH 052/218] [wp] changelog for invalid pointers --- src/plugins/wp/Changelog | 1 + 1 file changed, 1 insertion(+) diff --git a/src/plugins/wp/Changelog b/src/plugins/wp/Changelog index cc5e3751d47..3329a913f3c 100644 --- a/src/plugins/wp/Changelog +++ b/src/plugins/wp/Changelog @@ -20,6 +20,7 @@ # <Prover>: prover ############################################################################### +- WP [2020/03/26] Added support for invalid-pointer predicate - WP [2020/02/21] Why3 prover version fallback - WP [2020/02/21] Why3 prover full-names use ':' instead of ',' -* WP [2020/02/20] Fixes handling of LoopCurrent in loop invariants -- GitLab From f04b27337cd18d8cfee94522b622bd7dd03abadb Mon Sep 17 00:00:00 2001 From: Virgile Prevosto <virgile.prevosto@m4x.org> Date: Fri, 27 Mar 2020 13:33:29 +0100 Subject: [PATCH 053/218] [printer] never show __fc_sig_* identifiers unless user really wants it --- src/kernel_services/ast_printing/cil_printer.ml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kernel_services/ast_printing/cil_printer.ml b/src/kernel_services/ast_printing/cil_printer.ml index e1642d5c48b..9acb7457ad8 100644 --- a/src/kernel_services/ast_printing/cil_printer.ml +++ b/src/kernel_services/ast_printing/cil_printer.ml @@ -658,7 +658,7 @@ class cil_printer () = object (self) (*** VARIABLES ***) method varname fmt v = let v = - if not (Kernel.PrintLibc.get ()) && + if not state.print_cil_as_is && Datatype.String.Hashtbl.mem rename_builtins v then Datatype.String.Hashtbl.find rename_builtins v -- GitLab From 5baea9a06124fc0aa2f837b5a8ffb77ca629e997 Mon Sep 17 00:00:00 2001 From: Virgile Prevosto <virgile.prevosto@m4x.org> Date: Fri, 27 Mar 2020 17:40:52 +0100 Subject: [PATCH 054/218] [parser] reject label at end of block --- src/kernel_internals/parsing/cparser.mly | 4 ---- tests/syntax/oracle/wrong_label.res.oracle | 10 ++++++++++ tests/syntax/wrong_label.i | 7 +++++++ 3 files changed, 17 insertions(+), 4 deletions(-) create mode 100644 tests/syntax/oracle/wrong_label.res.oracle create mode 100644 tests/syntax/wrong_label.i diff --git a/src/kernel_internals/parsing/cparser.mly b/src/kernel_internals/parsing/cparser.mly index 666053a2830..ff02e392e7f 100644 --- a/src/kernel_internals/parsing/cparser.mly +++ b/src/kernel_internals/parsing/cparser.mly @@ -875,10 +875,6 @@ block_element_list: | annot_list_opt statement block_element_list { $1 @ $2 @ $3 } | annot_list_opt pragma block_element_list { $1 @ $3 } -/*(* GCC accepts a label at the end of a block *)*/ -| annot_list_opt id_or_typename_as_id COLON - { let loc = Cil_datatype.Location.of_lexing_loc (Parsing.rhs_start_pos 2, Parsing.rhs_end_pos 3) in - $1 @ no_ghost [LABEL ($2, no_ghost_stmt (NOP loc), loc)] } ; annot_list_opt: diff --git a/tests/syntax/oracle/wrong_label.res.oracle b/tests/syntax/oracle/wrong_label.res.oracle new file mode 100644 index 00000000000..b95ec14c206 --- /dev/null +++ b/tests/syntax/oracle/wrong_label.res.oracle @@ -0,0 +1,10 @@ +[kernel] Parsing tests/syntax/wrong_label.i (no preprocessing) +[kernel] tests/syntax/wrong_label.i:6: + syntax error: + Location: line 6, between columns 3 and 8, before or at token: } + 4 + 5 void main() { + 6 {_LOR:} // KO: labels can't be at the end of a block. + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + 7 } +[kernel] Frama-C aborted: invalid user input. diff --git a/tests/syntax/wrong_label.i b/tests/syntax/wrong_label.i new file mode 100644 index 00000000000..90e1020b409 --- /dev/null +++ b/tests/syntax/wrong_label.i @@ -0,0 +1,7 @@ +void f() { + /*@ assert \true; */ +} + +void main() { + {_LOR:} // KO: labels can't be at the end of a block. +} -- GitLab From 8e5537477dead6c8a99c8ade77c1384570efa2bf Mon Sep 17 00:00:00 2001 From: Virgile Prevosto <virgile.prevosto@m4x.org> Date: Fri, 27 Mar 2020 18:22:57 +0100 Subject: [PATCH 055/218] [parser] Fix long-standing shift/reduce conflict in logic parser original issue introduced here: b9a1eb430b05c3deb87a00d856f96be5dc147d5f --- src/kernel_internals/parsing/logic_parser.mly | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/kernel_internals/parsing/logic_parser.mly b/src/kernel_internals/parsing/logic_parser.mly index b19f7e478bd..59ed65b49bb 100644 --- a/src/kernel_internals/parsing/logic_parser.mly +++ b/src/kernel_internals/parsing/logic_parser.mly @@ -720,9 +720,12 @@ cv: ; type_spec_cv: - type_spec { $1 } + type_spec cv_after { $2 $1 } | cv type_spec_cv { LTattribute ($2, $1) } -| type_spec_cv cv { LTattribute ($1, $2) } + +cv_after: + /* empty */ { fun t -> t } +| cv cv_after { fun t -> $2 (LTattribute (t,$1)) } cast_logic_type: | type_spec_cv abs_spec_cv_option { $2 $1 } -- GitLab From 0f047e66ede839178216544404e482d1376f787b Mon Sep 17 00:00:00 2001 From: Virgile Prevosto <virgile.prevosto@m4x.org> Date: Mon, 30 Mar 2020 08:08:20 +0200 Subject: [PATCH 056/218] [tests] fixes buggy tests --- tests/cil/ghost_cfg.c | 4 ++-- tests/syntax/ghost_lexing.i | 2 +- tests/syntax/unroll_labels.i | 6 +++--- tests/value/loop_array.i | 2 +- tests/value/loop_join.i | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/tests/cil/ghost_cfg.c b/tests/cil/ghost_cfg.c index c65e13840a6..15c916efa38 100644 --- a/tests/cil/ghost_cfg.c +++ b/tests/cil/ghost_cfg.c @@ -89,7 +89,7 @@ int ghost_goto_ghost(){ //@ ghost goto X ; // reaches return without executing "x = 2" x = 2; - //@ ghost X: + //@ ghost X:; return 0; } @@ -154,7 +154,7 @@ int main(){ int x = 4 ; - //@ ghost X: + //@ ghost X:; x = 2 ; } diff --git a/tests/syntax/ghost_lexing.i b/tests/syntax/ghost_lexing.i index b2a74f89f75..03dc066c147 100644 --- a/tests/syntax/ghost_lexing.i +++ b/tests/syntax/ghost_lexing.i @@ -16,7 +16,7 @@ void test2(int x) { } void f() { - /*@ ghost L: */ G++; + /*@ ghost L:; */ G++; /*@ assert \at(G,L) + 1 == G; */ L1: /*@ ghost H=G; */ G++; if (G < 30) goto L1; diff --git a/tests/syntax/unroll_labels.i b/tests/syntax/unroll_labels.i index 4807505a700..4ccad645f15 100644 --- a/tests/syntax/unroll_labels.i +++ b/tests/syntax/unroll_labels.i @@ -62,7 +62,7 @@ void main2 () { i += 1; goto foo; i += 1; - foo: + foo:; } } } @@ -76,7 +76,7 @@ void main2_done () { i += 1; goto foo; i += 1; - foo: + foo:; } } } @@ -99,7 +99,7 @@ void main3 (int c) { foo: i += 1; } - up: + up:; } } diff --git a/tests/value/loop_array.i b/tests/value/loop_array.i index 9a279023fb6..5d644af2bb6 100644 --- a/tests/value/loop_array.i +++ b/tests/value/loop_array.i @@ -19,5 +19,5 @@ void main () { if (i == 400) goto l_end_loop; } - l_end_loop: + l_end_loop:; } diff --git a/tests/value/loop_join.i b/tests/value/loop_join.i index 2abaeb65fcc..19bcb4fc323 100644 --- a/tests/value/loop_join.i +++ b/tests/value/loop_join.i @@ -12,5 +12,5 @@ void main () { if (i == 400) goto l_end_loop; } - l_end_loop: + l_end_loop:; } -- GitLab From bb79c5955da0029ef855978519284cca405b0d50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20B=C3=BChler?= <david.buhler@cea.fr> Date: Mon, 30 Mar 2020 09:07:11 +0200 Subject: [PATCH 057/218] Updates the Changelog for MR !2555. --- Changelog | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Changelog b/Changelog index d7a8acc7c53..ecda215fe0c 100644 --- a/Changelog +++ b/Changelog @@ -17,6 +17,11 @@ Open Source Release <next-release> ################################## +- RTE [2020/03/30] Emits alarm on invalid pointers when option is on +- Eva [2020/03/30] Emits alarm on invalid pointers when option is on +- Kernel [2020/03/30] New option -warn-invalid-pointer (disabled by + default) to warn on invalid pointer arithmetics resulting in a + pointer that does not point to an object or one past an object. - RTE [2020/03/27] Emits alarm on pointer downcast when option is on - Eva [2020/03/27] Emits alarm on pointer downcast when option is on - Kernel [2020/03/27] New option -warn-pointer-downcast (activated by -- GitLab From 12cf9d55133b10b7b2cd19dbe6a7cd034d72e969 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Loi=CC=88c=20Correnson?= <loic.correnson@cea.fr> Date: Thu, 26 Mar 2020 16:07:15 +0100 Subject: [PATCH 058/218] [logic] grouping ocaml doc --- .../ast_queries/logic_utils.ml | 33 +++++++++++-------- .../ast_queries/logic_utils.mli | 32 +++++++++++------- 2 files changed, 41 insertions(+), 24 deletions(-) diff --git a/src/kernel_services/ast_queries/logic_utils.ml b/src/kernel_services/ast_queries/logic_utils.ml index ea652d98361..a77518acee2 100644 --- a/src/kernel_services/ast_queries/logic_utils.ml +++ b/src/kernel_services/ast_queries/logic_utils.ml @@ -263,6 +263,10 @@ let mk_cast ?(loc=Cil_datatype.Location.unknown) ?(force=false) newt t = | _ -> mk_cast t in aux1 t.term_type t +(* -------------------------------------------------------------------------- *) +(* --- Constant Conversions --- *) +(* -------------------------------------------------------------------------- *) + let real_of_float s f = { r_literal = s ; r_nearest = f ; r_upper = f ; r_lower = f } @@ -329,8 +333,7 @@ let numeric_coerce ltyp t = | _ -> coerce t (* Don't forget to keep is_zero_comparable - and scalar_term_to_predicate in sync. -*) + and scalar_term_to_predicate in sync. *) let is_zero_comparable t = match unroll_type t.term_type with @@ -379,9 +382,13 @@ let scalar_term_to_boolean = in scalar_term_conversion conversion +(* -------------------------------------------------------------------------- *) +(* --- Expr Conversion --- *) +(* -------------------------------------------------------------------------- *) + let rec expr_to_term ~cast e = - let e_typ = unrollType (Cil.typeOf e) in let loc = e.eloc in + let typ = unrollType (Cil.typeOf e) in let result = match e.enode with | Const c -> TConst (constant_to_lconstant c) | SizeOf t -> TSizeOf t @@ -400,7 +407,7 @@ let rec expr_to_term ~cast e = | ( Cil_types.Lt | Cil_types.Gt | Cil_types.Le | Cil_types.Ge | Cil_types.Eq | Cil_types.Ne| Cil_types.LAnd | Cil_types.LOr), _ -> Some Logic_const.boolean_type - | _, true -> Some (typ_to_logic_type e_typ) + | _, true -> Some (typ_to_logic_type typ) | _, false -> None in let tnode = TBinOp (op,l',r') in @@ -410,7 +417,7 @@ let rec expr_to_term ~cast e = integer/float/pointer here, and (2) there is no implicit conversion Boolean -> integer. *) begin match tcast with - | Some lt -> (mk_cast e_typ (Logic_const.term tnode lt)).term_node + | Some lt -> (mk_cast typ (Logic_const.term tnode lt)).term_node | None -> tnode end | UnOp (op, u, _) -> @@ -433,12 +440,12 @@ let rec expr_to_term ~cast e = (* See comments for binop case above. *) let tcast = match op, cast with | Cil_types.LNot, _ -> Some Logic_const.boolean_type - | _, true -> Some (typ_to_logic_type e_typ) + | _, true -> Some (typ_to_logic_type typ) | _, false -> None in let tnode = TUnOp (op, u') in begin match tcast with - | Some lt -> (mk_cast e_typ (Logic_const.term tnode lt)).term_node + | Some lt -> (mk_cast typ (Logic_const.term tnode lt)).term_node | None -> tnode end | AlignOfE e -> TAlignOfE (expr_to_term ~cast e) @@ -446,14 +453,14 @@ let rec expr_to_term ~cast e = | Lval lv -> TLval (lval_to_term_lval ~cast lv) | Info (e,_) -> (expr_to_term ~cast e).term_node in - let tres = Logic_const.term ~loc result (Ctype e_typ) in + let tres = Logic_const.term ~loc result (Ctype typ) in if cast then tres else match e.enode with (* all immediate values keep their C type by default, and are only lifted to integer/real if needed. *) | Const _ | Lval _ | CastE _ -> tres - | _ -> numeric_coerce (typ_to_logic_type e_typ) tres + | _ -> numeric_coerce (typ_to_logic_type typ) tres and expr_to_term_coerce ~cast e = let t = expr_to_term ~cast e in @@ -497,6 +504,10 @@ and expr_to_predicate ~cast e = "Cannot convert into predicate the C expression %a" Cil_printer.pp_exp e +(* ************************************************************************* *) +(** {1 Various utilities} *) +(* ************************************************************************* *) + let array_with_range arr size = let loc = arr.eloc in let arr = Cil.stripCasts arr in @@ -521,10 +532,6 @@ let remove_logic_coerce t = | TLogic_coerce(_,t) -> t | _ -> t -(* ************************************************************************* *) -(** {1 Various utilities} *) -(* ************************************************************************* *) - let rec remove_term_offset o = match o with TNoOffset -> TNoOffset, TNoOffset diff --git a/src/kernel_services/ast_queries/logic_utils.mli b/src/kernel_services/ast_queries/logic_utils.mli index b3a51cdf016..3853a02c250 100644 --- a/src/kernel_services/ast_queries/logic_utils.mli +++ b/src/kernel_services/ast_queries/logic_utils.mli @@ -157,8 +157,9 @@ val pointer_comparable: ?loc:location -> term -> term -> predicate (** \pointer_comparable @since Fluorine-20130401 *) -(** {3 Conversion from exp to term}*) -(** translates a C expression into an "equivalent" logical term. +(** {2 Conversion from exp to term} + + translates a C expression into an "equivalent" logical term. [cast] specifies how C arithmetic operators are translated. When [cast] is [true], the translation returns a logic [term] having the same semantics of the C [expr] by introducing casts (i.e. the C expr [a+b] @@ -169,6 +170,7 @@ val pointer_comparable: ?loc:location -> term -> term -> predicate addition is translated into an addition of [real] numbers). @plugin development guide *) val expr_to_term : cast:bool -> exp -> term + (** same as {!expr_to_term}, except that if the new term has an arithmetic type, it is automatically coerced into real (or integer for integral types). @@ -176,13 +178,6 @@ val expr_to_term : cast:bool -> exp -> term *) val expr_to_term_coerce: cast:bool -> exp -> term -val is_zero_comparable: term -> bool -(** [true] if the given term has a type for which a comparison to 0 exists - (i.e. scalar C types, logic integers and reals). - - @since Sulfur-20171101 -*) - val expr_to_predicate: cast:bool -> exp -> identified_predicate (** same as {expr_to_term}, but the result is a predicate. Expressions starting with relational operators ([==], [<=], etc) are translated directly. @@ -194,6 +189,21 @@ val expr_to_predicate: cast:bool -> exp -> identified_predicate @since Sulfur-20171101 *) +val is_zero_comparable: term -> bool +(** [true] if the given term has a type for which a comparison to 0 exists + (i.e. scalar C types, logic integers and reals). + + @since Sulfur-20171101 +*) + +val scalar_term_to_boolean: term -> term +(** Compare the given term with the constant 0 (of the appropriate type) + to return the result of the comparison [e <> 0] as a boolean term. + + @raise Fatal error if the argument cannot be compared to 0 + @since Frama-C+dev +*) + val scalar_term_to_predicate: term -> predicate (** Compare the given term with the constant 0 (of the appropriate type) to return the result of the comparison [e <> 0]. @@ -216,6 +226,8 @@ val lconstant_to_constant: logic_constant-> constant by the parser as valid floats *) val string_to_float_lconstant: string -> logic_constant +(** {2 Various Utilities} *) + (** [remove_term_offset o] returns [o] without its last offset and this last offset. *) val remove_term_offset : @@ -240,8 +252,6 @@ val is_result : term -> bool val lhost_c_type : term_lhost -> typ -(** {2 Predicates} *) - (** [true] if the predicate is Ptrue. @since Nitrogen-20111001 *) val is_trivially_true: predicate -> bool -- GitLab From a3616e895d21c43d8d3031529eb390cefb3c9379 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Loi=CC=88c=20Correnson?= <loic.correnson@cea.fr> Date: Thu, 26 Mar 2020 18:17:14 +0100 Subject: [PATCH 059/218] [wp] fix sub-float operation --- src/plugins/wp/Cfloat.ml | 9 ++++++--- src/plugins/wp/Cfloat.mli | 1 + src/plugins/wp/share/why3/frama_c_wp/cfloat.mlw | 9 +++++++-- .../wp/tests/wp_plugin/oracle/float_real.1.res.oracle | 4 ++-- 4 files changed, 16 insertions(+), 7 deletions(-) diff --git a/src/plugins/wp/Cfloat.ml b/src/plugins/wp/Cfloat.ml index 39c437ff77f..24d629f9c2c 100644 --- a/src/plugins/wp/Cfloat.ml +++ b/src/plugins/wp/Cfloat.ml @@ -91,6 +91,7 @@ type op = | NE | NEG | ADD + | SUB | MUL | DIV | REAL @@ -105,6 +106,7 @@ let op_name = function | NE -> "ne" | NEG -> "neg" | ADD -> "add" + | SUB -> "sub" | MUL -> "mul" | DIV -> "div" | REAL -> "of" @@ -275,6 +277,7 @@ let compute_float op ulp xs = match op , xs with | NEG , [ x ] -> qmake ulp (Q.neg (exact x)) | ADD , [ x ; y ] -> qmake ulp (Q.add (exact x) (exact y)) + | SUB , [ x ; y ] -> qmake ulp (Q.sub (exact x) (exact y)) | MUL , [ x ; y ] -> qmake ulp (Q.mul (exact x) (exact y)) | DIV , [ x ; y ] -> let res = match Q.div (exact x) (exact y) with @@ -293,6 +296,7 @@ let compute_real op xs = match op , xs with | NEG , [ x ] -> F.e_opp x | ADD , [ x ; y ] -> F.e_add x y + | SUB , [ x ; y ] -> F.e_sub x y | MUL , [ x ; y ] -> F.e_mul x y | DIV , [ x ; y ] -> F.e_div x y | (ROUND|REAL) , [ x ] -> x @@ -350,6 +354,7 @@ let flt_le ft = Compute.get (Context.get model, ft, LE) |> fst let flt_lt ft = Compute.get (Context.get model, ft, LT) |> fst let flt_neg ft = Compute.get (Context.get model, ft, NEG) |> fst let flt_add ft = Compute.get (Context.get model, ft, ADD) |> fst +let flt_sub ft = Compute.get (Context.get model, ft, SUB) |> fst let flt_mul ft = Compute.get (Context.get model, ft, MUL) |> fst let flt_div ft = Compute.get (Context.get model, ft, DIV) |> fst let flt_of_real ft = Compute.get (Context.get model, ft, ROUND) |> fst @@ -435,16 +440,14 @@ let fcmp rop fop f x y = | Float -> p_call (fop f) [x;y] let fadd = fbinop e_add flt_add +let fsub = fbinop e_sub flt_sub let fmul = fbinop e_mul flt_mul let fdiv = fbinop e_div flt_div - let fopp f x = match Context.get model with | Real -> e_opp x | Float -> e_fun ~result:(ftau f) (flt_neg f) [x] -let fsub f x y = fadd f x (fopp f y) - let flt = fcmp p_lt flt_lt let fle = fcmp p_leq flt_le let feq = fcmp p_equal flt_eq diff --git a/src/plugins/wp/Cfloat.mli b/src/plugins/wp/Cfloat.mli index 344ddbc093e..c685e9139ea 100644 --- a/src/plugins/wp/Cfloat.mli +++ b/src/plugins/wp/Cfloat.mli @@ -50,6 +50,7 @@ type op = | NE | NEG | ADD + | SUB | MUL | DIV | REAL diff --git a/src/plugins/wp/share/why3/frama_c_wp/cfloat.mlw b/src/plugins/wp/share/why3/frama_c_wp/cfloat.mlw index 3cfc3d7f07f..3f1bc5eb1b7 100644 --- a/src/plugins/wp/share/why3/frama_c_wp/cfloat.mlw +++ b/src/plugins/wp/share/why3/frama_c_wp/cfloat.mlw @@ -145,10 +145,15 @@ theory Cfloat function add_f32 (x:f32) (y:f32) : f32 = F32.(.+) x y function add_f64 (x:f64) (y:f64) : f64 = F64.(.+) x y + (* Substraction *) + + function sub_f32 (x:f32) (y:f32) : f32 = F32.(.-) x y + function sub_f64 (x:f64) (y:f64) : f64 = F64.(.-) x y + (* Multiplication *) - function mul_f32 (x:f32) (y:f32) : f32 = F32.(.-) x y - function mul_f64 (x:f64) (y:f64) : f64 = F64.(.-) x y + function mul_f32 (x:f32) (y:f32) : f32 = F32.(.*) x y + function mul_f64 (x:f64) (y:f64) : f64 = F64.(.*) x y (* Division *) diff --git a/src/plugins/wp/tests/wp_plugin/oracle/float_real.1.res.oracle b/src/plugins/wp/tests/wp_plugin/oracle/float_real.1.res.oracle index bd279cccc87..4249f034461 100644 --- a/src/plugins/wp/tests/wp_plugin/oracle/float_real.1.res.oracle +++ b/src/plugins/wp/tests/wp_plugin/oracle/float_real.1.res.oracle @@ -13,11 +13,11 @@ Goal Post-condition (file tests/wp_plugin/float_real.i, line 14) in 'dequal': Assume { Type: is_sint32(dequal_0). - If lt_f64(add_f64(x, neg_f64(y)), + If lt_f64(sub_f64(x, y), to_f64((5902958103587057.0/590295810358705651712))) Then { If lt_f64(to_f64((-5902958103587057.0/590295810358705651712)), - add_f64(x, neg_f64(y))) + sub_f64(x, y)) Then { (* Return *) Have: dequal_0 = 1. } Else { (* Return *) Have: dequal_0 = 0. } } -- GitLab From 95e3102be01cd09813c5741041323c2710506854 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Loi=CC=88c=20Correnson?= <loic.correnson@cea.fr> Date: Thu, 26 Mar 2020 18:18:10 +0100 Subject: [PATCH 060/218] [kernel] add float & double bulitins --- src/kernel_internals/typing/logic_builtin.ml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/kernel_internals/typing/logic_builtin.ml b/src/kernel_internals/typing/logic_builtin.ml index 02d4a73809e..961fc5b3aac 100644 --- a/src/kernel_internals/typing/logic_builtin.ml +++ b/src/kernel_internals/typing/logic_builtin.ml @@ -293,6 +293,18 @@ let init = (*"\\round_quad", [], ["m", rounding_mode; "x", Lreal], long_double_type;*) + "\\neg_float",[],["x",float_type], float_type; + "\\add_float",[],["x",float_type;"y",float_type], float_type; + "\\sub_float",[],["x",float_type;"y",float_type], float_type; + "\\mul_float",[],["x",float_type;"y",float_type], float_type; + "\\div_float",[],["x",float_type;"y",float_type], float_type; + + "\\neg_double",[],["x",double_type], double_type; + "\\add_double",[],["x",double_type;"y",double_type], double_type; + "\\sub_double",[],["x",double_type;"y",double_type], double_type; + "\\mul_double",[],["x",double_type;"y",double_type], double_type; + "\\div_double",[],["x",double_type;"y",double_type], double_type; + "\\min", [], ["s", set_of_integer], Linteger; "\\max", [], ["s", set_of_integer], Linteger; -- GitLab From b1355b8bea80908eb3708f4c7524ed2a4c4825b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Loi=CC=88c=20Correnson?= <loic.correnson@cea.fr> Date: Thu, 26 Mar 2020 18:18:42 +0100 Subject: [PATCH 061/218] [wp] support for float builtins --- src/plugins/wp/Cfloat.ml | 42 ++++++++++++++++++++++++++-------------- 1 file changed, 28 insertions(+), 14 deletions(-) diff --git a/src/plugins/wp/Cfloat.ml b/src/plugins/wp/Cfloat.ml index 24d629f9c2c..64e1cfd7065 100644 --- a/src/plugins/wp/Cfloat.ml +++ b/src/plugins/wp/Cfloat.ml @@ -360,31 +360,45 @@ let flt_div ft = Compute.get (Context.get model, ft, DIV) |> fst let flt_of_real ft = Compute.get (Context.get model, ft, ROUND) |> fst let real_of_flt ft = Compute.get (Context.get model, ft, REAL) |> fst - (* -------------------------------------------------------------------------- *) (* --- Builtins --- *) (* -------------------------------------------------------------------------- *) -let make_hack ?(converse=false) ft op xs = +let builtin kind ft op xs = let phi, impl = Compute.get ((Context.get model), ft, op) in - let xs = (if converse then List.rev xs else xs) in - try impl xs with Not_found -> F.e_fun ~result:Logic.Bool phi xs - -let register_builtin ft = + let xs = (if kind=`ReV then List.rev xs else xs) in + try impl xs with Not_found -> + let result = match kind with + | `Binop | `Unop -> ftau ft + | `Rel | `ReV -> Logic.Bool + in F.e_fun ~result phi xs + +let register_builtins ft = begin let suffix = float_name ft in - LogicBuiltins.hack ("\\eq_" ^ suffix) (make_hack ft EQ) ; - LogicBuiltins.hack ("\\ne_" ^ suffix) (make_hack ft NE) ; - LogicBuiltins.hack ("\\lt_" ^ suffix) (make_hack ~converse:false ft LT) ; - LogicBuiltins.hack ("\\gt_" ^ suffix) (make_hack ~converse:true ft LT) ; - LogicBuiltins.hack ("\\le_" ^ suffix) (make_hack ~converse:false ft LE) ; - LogicBuiltins.hack ("\\ge_" ^ suffix) (make_hack ~converse:true ft LE) + let register (prefix,kind,op) = + LogicBuiltins.hack + (Printf.sprintf "\\%s_%s" prefix suffix) + (builtin kind ft op) + in List.iter register [ + "eq",`Rel,EQ ; + "ne",`Rel,NE ; + "lt",`Rel,LT ; + "gt",`ReV,LT ; + "le",`Rel,LE ; + "ge",`ReV,LE ; + "neg",`Unop,NEG ; + "add",`Binop,ADD ; + "sub",`Binop,SUB ; + "mul",`Binop,MUL ; + "div",`Binop,DIV ; + ] ; end let () = Context.register begin fun () -> - register_builtin Float32 ; - register_builtin Float64 ; + register_builtins Float32 ; + register_builtins Float64 ; end (* -------------------------------------------------------------------------- *) -- GitLab From 595dd4745cd0aa2ba4fd32f9ff7fca8454ab52e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Loi=CC=88c=20Correnson?= <loic.correnson@cea.fr> Date: Thu, 26 Mar 2020 18:33:40 +0100 Subject: [PATCH 062/218] [eval] support for float builtins --- src/plugins/value/legacy/eval_terms.ml | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/src/plugins/value/legacy/eval_terms.ml b/src/plugins/value/legacy/eval_terms.ml index 995160e3482..0ae0bdbcced 100644 --- a/src/plugins/value/legacy/eval_terms.ml +++ b/src/plugins/value/legacy/eval_terms.ml @@ -720,6 +720,16 @@ let known_logic_funs = [ "\\sign", ACSL; "\\min", ACSL; "\\max", ACSL; + "\\neg_float",ACSL; + "\\add_float",ACSL; + "\\sub_float",ACSL; + "\\mul_float",ACSL; + "\\div_float",ACSL; + "\\neg_double",ACSL; + "\\add_double",ACSL; + "\\sub_double",ACSL; + "\\mul_double",ACSL; + "\\div_double",ACSL; ] let known_predicates = [ "\\warning", ACSL; @@ -1354,11 +1364,13 @@ and eval_known_logic_function ~alarm_mode env li labels args = eval_logic_charchr builtin { env with e_cur = lbl } s.eover c.eover s.ldeps c.ldeps - | ("atan2" | "atan2f" | "fmod" | "fmodf" | "pow" | "powf"), + | ( "atan2" | "atan2f" | "fmod" | "fmodf" | "pow" | "powf" + | "\\add_float" | "\\sub_float" | "\\mul_float" | "\\div_float" + | "\\add_double" | "\\sub_double" | "\\mul_double" | "\\div_double" ), _, _, [arg1; arg2] -> eval_float_builtin_arity2 ~alarm_mode env lvi.lv_name arg1 arg2 - | ("sqrt" | "sqrtf"),_,_, [arg] -> + | ( "sqrt" | "sqrtf" | "\\neg_float" | "\\neg_double" ),_,_, [arg] -> eval_float_builtin_arity1 ~alarm_mode env lvi.lv_name arg | "\\sign", _, _, [arg] -> @@ -1410,6 +1422,14 @@ and eval_float_builtin_arity2 ~alarm_mode env name arg1 arg2 = | "fmodf" -> Fval.fmod Fval.Single | "pow" -> Fval.pow Fval.Double | "powf" -> Fval.pow Fval.Single + | "\\add_float" -> Fval.add Fval.Single + | "\\sub_float" -> Fval.sub Fval.Single + | "\\mul_float" -> Fval.mul Fval.Single + | "\\div_float" -> Fval.div Fval.Single + | "\\add_double" -> Fval.add Fval.Double + | "\\sub_double" -> Fval.sub Fval.Double + | "\\mul_double" -> Fval.mul Fval.Double + | "\\div_double" -> Fval.div Fval.Double | _ -> assert false in let r1 = eval_term ~alarm_mode env arg1 in @@ -1432,6 +1452,7 @@ and eval_float_builtin_arity1 ~alarm_mode env name arg = let fcaml = match name with | "sqrt" -> Fval.sqrt Fval.Double | "sqrtf" -> Fval.sqrt Fval.Single + | "\\neg_float" | "\\neg_double" -> Fval.neg | _ -> assert false in let r = eval_term ~alarm_mode env arg in -- GitLab From 62b761624ab9993350ae470f0bd641625263b2ae Mon Sep 17 00:00:00 2001 From: Andre Maroneze <andre.oliveiramaroneze@cea.fr> Date: Mon, 30 Mar 2020 15:48:57 +0200 Subject: [PATCH 063/218] Update Changelog for MR !2601 --- Changelog | 1 + 1 file changed, 1 insertion(+) diff --git a/Changelog b/Changelog index ecda215fe0c..dbefdf6029f 100644 --- a/Changelog +++ b/Changelog @@ -17,6 +17,7 @@ Open Source Release <next-release> ################################## +*! Kernel [2020/03/30] Reject labels at end of blocks. - RTE [2020/03/30] Emits alarm on invalid pointers when option is on - Eva [2020/03/30] Emits alarm on invalid pointers when option is on - Kernel [2020/03/30] New option -warn-invalid-pointer (disabled by -- GitLab From 323fc1d4ea59da3d124ef707b544184ac45daba8 Mon Sep 17 00:00:00 2001 From: Andre Maroneze <andre.oliveiramaroneze@cea.fr> Date: Fri, 12 Jul 2019 16:28:38 +0200 Subject: [PATCH 064/218] [Libc] improve C99/POSIX compatibility --- share/libc/math.h | 3 + .../report/tests/report/oracle/csv.csv | 2 +- tests/idct/oracle/ieee_1180_1990.res.oracle | 234 ++++++++--------- tests/libc/math_h.c | 12 +- tests/libc/oracle/math_h.res.oracle | 244 +++++++++--------- 5 files changed, 251 insertions(+), 244 deletions(-) diff --git a/share/libc/math.h b/share/libc/math.h index 6ae90331c2e..ff2ef56a2db 100644 --- a/share/libc/math.h +++ b/share/libc/math.h @@ -61,6 +61,9 @@ typedef double double_t; #define FP_SUBNORMAL 3 #define FP_NORMAL 4 +#define FP_ILOGB0 __FC_INT_MIN +#define FP_ILOGBNAN __FC_INT_MIN + #include "float.h" // for DBL_MIN and FLT_MIN /*@ diff --git a/src/plugins/report/tests/report/oracle/csv.csv b/src/plugins/report/tests/report/oracle/csv.csv index c44a659ed70..4a8fc2e347b 100644 --- a/src/plugins/report/tests/report/oracle/csv.csv +++ b/src/plugins/report/tests/report/oracle/csv.csv @@ -1,5 +1,5 @@ directory file line function property kind status property -FRAMAC_SHARE/libc math.h 522 pow precondition Unknown finite_logic_res: \is_finite(pow(x, y)) +FRAMAC_SHARE/libc math.h 525 pow precondition Unknown finite_logic_res: \is_finite(pow(x, y)) tests/report csv.c 11 main1 signed_overflow Unknown -2147483648 ≤ x * x tests/report csv.c 11 main1 signed_overflow Unknown x * x ≤ 2147483647 tests/report csv.c 12 main1 index_bound Unknown 0 ≤ x diff --git a/tests/idct/oracle/ieee_1180_1990.res.oracle b/tests/idct/oracle/ieee_1180_1990.res.oracle index 9cd3bd3d041..73d8292ef2d 100644 --- a/tests/idct/oracle/ieee_1180_1990.res.oracle +++ b/tests/idct/oracle/ieee_1180_1990.res.oracle @@ -2291,7 +2291,7 @@ [ Extern ] Assigns nothing assigns \nothing; Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/math.h, line 67) +[ Extern ] Froms (file share/libc/math.h, line 70) assigns \result \from x; Unverifiable but considered Valid. [ Valid ] Default behavior @@ -2335,7 +2335,7 @@ [ Extern ] Assigns nothing assigns \nothing; Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/math.h, line 91) +[ Extern ] Froms (file share/libc/math.h, line 94) assigns \result \from x; Unverifiable but considered Valid. [ Valid ] Default behavior @@ -2367,28 +2367,28 @@ [ Extern ] Post-condition for 'domain_error' 'errno_set' ensures errno_set: __fc_errno ≡ 1 Unverifiable but considered Valid. -[ Extern ] Assigns (file share/libc/math.h, line 128) +[ Extern ] Assigns (file share/libc/math.h, line 131) assigns __fc_errno, \result; Unverifiable but considered Valid. -[ Extern ] Assigns for 'domain_error' (file share/libc/math.h, line 135) +[ Extern ] Assigns for 'domain_error' (file share/libc/math.h, line 138) assigns __fc_errno, \result; Unverifiable but considered Valid. [ Extern ] Assigns for 'normal' nothing assigns \nothing; Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/math.h, line 128) +[ Extern ] Froms (file share/libc/math.h, line 131) assigns __fc_errno \from x; Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/math.h, line 128) +[ Extern ] Froms (file share/libc/math.h, line 131) assigns \result \from x; Unverifiable but considered Valid. -[ Extern ] Froms for 'domain_error' (file share/libc/math.h, line 135) +[ Extern ] Froms for 'domain_error' (file share/libc/math.h, line 138) assigns __fc_errno \from x; Unverifiable but considered Valid. -[ Extern ] Froms for 'domain_error' (file share/libc/math.h, line 135) +[ Extern ] Froms for 'domain_error' (file share/libc/math.h, line 138) assigns \result \from x; Unverifiable but considered Valid. -[ Extern ] Froms for 'normal' (file share/libc/math.h, line 131) +[ Extern ] Froms for 'normal' (file share/libc/math.h, line 134) assigns \result \from x; Unverifiable but considered Valid. [ Valid ] Default behavior @@ -2411,28 +2411,28 @@ [ Extern ] Post-condition for 'domain_error' 'errno_set' ensures errno_set: __fc_errno ≡ 1 Unverifiable but considered Valid. -[ Extern ] Assigns (file share/libc/math.h, line 142) +[ Extern ] Assigns (file share/libc/math.h, line 145) assigns __fc_errno, \result; Unverifiable but considered Valid. -[ Extern ] Assigns for 'domain_error' (file share/libc/math.h, line 149) +[ Extern ] Assigns for 'domain_error' (file share/libc/math.h, line 152) assigns __fc_errno, \result; Unverifiable but considered Valid. [ Extern ] Assigns for 'normal' nothing assigns \nothing; Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/math.h, line 142) +[ Extern ] Froms (file share/libc/math.h, line 145) assigns __fc_errno \from x; Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/math.h, line 142) +[ Extern ] Froms (file share/libc/math.h, line 145) assigns \result \from x; Unverifiable but considered Valid. -[ Extern ] Froms for 'domain_error' (file share/libc/math.h, line 149) +[ Extern ] Froms for 'domain_error' (file share/libc/math.h, line 152) assigns __fc_errno \from x; Unverifiable but considered Valid. -[ Extern ] Froms for 'domain_error' (file share/libc/math.h, line 149) +[ Extern ] Froms for 'domain_error' (file share/libc/math.h, line 152) assigns \result \from x; Unverifiable but considered Valid. -[ Extern ] Froms for 'normal' (file share/libc/math.h, line 145) +[ Extern ] Froms for 'normal' (file share/libc/math.h, line 148) assigns \result \from x; Unverifiable but considered Valid. [ Valid ] Default behavior @@ -2455,28 +2455,28 @@ [ Extern ] Post-condition for 'domain_error' 'errno_set' ensures errno_set: __fc_errno ≡ 1 Unverifiable but considered Valid. -[ Extern ] Assigns (file share/libc/math.h, line 156) +[ Extern ] Assigns (file share/libc/math.h, line 159) assigns __fc_errno, \result; Unverifiable but considered Valid. -[ Extern ] Assigns for 'domain_error' (file share/libc/math.h, line 163) +[ Extern ] Assigns for 'domain_error' (file share/libc/math.h, line 166) assigns __fc_errno, \result; Unverifiable but considered Valid. [ Extern ] Assigns for 'normal' nothing assigns \nothing; Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/math.h, line 156) +[ Extern ] Froms (file share/libc/math.h, line 159) assigns __fc_errno \from x; Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/math.h, line 156) +[ Extern ] Froms (file share/libc/math.h, line 159) assigns \result \from x; Unverifiable but considered Valid. -[ Extern ] Froms for 'domain_error' (file share/libc/math.h, line 163) +[ Extern ] Froms for 'domain_error' (file share/libc/math.h, line 166) assigns __fc_errno \from x; Unverifiable but considered Valid. -[ Extern ] Froms for 'domain_error' (file share/libc/math.h, line 163) +[ Extern ] Froms for 'domain_error' (file share/libc/math.h, line 166) assigns \result \from x; Unverifiable but considered Valid. -[ Extern ] Froms for 'normal' (file share/libc/math.h, line 159) +[ Extern ] Froms for 'normal' (file share/libc/math.h, line 162) assigns \result \from x; Unverifiable but considered Valid. [ Valid ] Default behavior @@ -2499,28 +2499,28 @@ [ Extern ] Post-condition for 'domain_error' 'errno_set' ensures errno_set: __fc_errno ≡ 1 Unverifiable but considered Valid. -[ Extern ] Assigns (file share/libc/math.h, line 170) +[ Extern ] Assigns (file share/libc/math.h, line 173) assigns __fc_errno, \result; Unverifiable but considered Valid. -[ Extern ] Assigns for 'domain_error' (file share/libc/math.h, line 177) +[ Extern ] Assigns for 'domain_error' (file share/libc/math.h, line 180) assigns __fc_errno, \result; Unverifiable but considered Valid. [ Extern ] Assigns for 'normal' nothing assigns \nothing; Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/math.h, line 170) +[ Extern ] Froms (file share/libc/math.h, line 173) assigns __fc_errno \from x; Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/math.h, line 170) +[ Extern ] Froms (file share/libc/math.h, line 173) assigns \result \from x; Unverifiable but considered Valid. -[ Extern ] Froms for 'domain_error' (file share/libc/math.h, line 177) +[ Extern ] Froms for 'domain_error' (file share/libc/math.h, line 180) assigns __fc_errno \from x; Unverifiable but considered Valid. -[ Extern ] Froms for 'domain_error' (file share/libc/math.h, line 177) +[ Extern ] Froms for 'domain_error' (file share/libc/math.h, line 180) assigns \result \from x; Unverifiable but considered Valid. -[ Extern ] Froms for 'normal' (file share/libc/math.h, line 173) +[ Extern ] Froms for 'normal' (file share/libc/math.h, line 176) assigns \result \from x; Unverifiable but considered Valid. [ Valid ] Default behavior @@ -2543,28 +2543,28 @@ [ Extern ] Post-condition for 'domain_error' 'errno_set' ensures errno_set: __fc_errno ≡ 1 Unverifiable but considered Valid. -[ Extern ] Assigns (file share/libc/math.h, line 184) +[ Extern ] Assigns (file share/libc/math.h, line 187) assigns __fc_errno, \result; Unverifiable but considered Valid. -[ Extern ] Assigns for 'domain_error' (file share/libc/math.h, line 191) +[ Extern ] Assigns for 'domain_error' (file share/libc/math.h, line 194) assigns __fc_errno, \result; Unverifiable but considered Valid. [ Extern ] Assigns for 'normal' nothing assigns \nothing; Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/math.h, line 184) +[ Extern ] Froms (file share/libc/math.h, line 187) assigns __fc_errno \from x; Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/math.h, line 184) +[ Extern ] Froms (file share/libc/math.h, line 187) assigns \result \from x; Unverifiable but considered Valid. -[ Extern ] Froms for 'domain_error' (file share/libc/math.h, line 191) +[ Extern ] Froms for 'domain_error' (file share/libc/math.h, line 194) assigns __fc_errno \from x; Unverifiable but considered Valid. -[ Extern ] Froms for 'domain_error' (file share/libc/math.h, line 191) +[ Extern ] Froms for 'domain_error' (file share/libc/math.h, line 194) assigns \result \from x; Unverifiable but considered Valid. -[ Extern ] Froms for 'normal' (file share/libc/math.h, line 187) +[ Extern ] Froms for 'normal' (file share/libc/math.h, line 190) assigns \result \from x; Unverifiable but considered Valid. [ Valid ] Default behavior @@ -2587,28 +2587,28 @@ [ Extern ] Post-condition for 'domain_error' 'errno_set' ensures errno_set: __fc_errno ≡ 1 Unverifiable but considered Valid. -[ Extern ] Assigns (file share/libc/math.h, line 198) +[ Extern ] Assigns (file share/libc/math.h, line 201) assigns __fc_errno, \result; Unverifiable but considered Valid. -[ Extern ] Assigns for 'domain_error' (file share/libc/math.h, line 205) +[ Extern ] Assigns for 'domain_error' (file share/libc/math.h, line 208) assigns __fc_errno, \result; Unverifiable but considered Valid. [ Extern ] Assigns for 'normal' nothing assigns \nothing; Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/math.h, line 198) +[ Extern ] Froms (file share/libc/math.h, line 201) assigns __fc_errno \from x; Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/math.h, line 198) +[ Extern ] Froms (file share/libc/math.h, line 201) assigns \result \from x; Unverifiable but considered Valid. -[ Extern ] Froms for 'domain_error' (file share/libc/math.h, line 205) +[ Extern ] Froms for 'domain_error' (file share/libc/math.h, line 208) assigns __fc_errno \from x; Unverifiable but considered Valid. -[ Extern ] Froms for 'domain_error' (file share/libc/math.h, line 205) +[ Extern ] Froms for 'domain_error' (file share/libc/math.h, line 208) assigns \result \from x; Unverifiable but considered Valid. -[ Extern ] Froms for 'normal' (file share/libc/math.h, line 201) +[ Extern ] Froms for 'normal' (file share/libc/math.h, line 204) assigns \result \from x; Unverifiable but considered Valid. [ Valid ] Default behavior @@ -2634,7 +2634,7 @@ [ Extern ] Assigns nothing assigns \nothing; Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/math.h, line 212) +[ Extern ] Froms (file share/libc/math.h, line 215) assigns \result \from x; Unverifiable but considered Valid. [ Valid ] Default behavior @@ -2654,7 +2654,7 @@ [ Extern ] Assigns nothing assigns \nothing; Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/math.h, line 219) +[ Extern ] Froms (file share/libc/math.h, line 222) assigns \result \from x; Unverifiable but considered Valid. [ Valid ] Default behavior @@ -2674,7 +2674,7 @@ [ Extern ] Assigns nothing assigns \nothing; Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/math.h, line 226) +[ Extern ] Froms (file share/libc/math.h, line 229) assigns \result \from x; Unverifiable but considered Valid. [ Valid ] Default behavior @@ -2691,7 +2691,7 @@ [ Extern ] Assigns nothing assigns \nothing; Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/math.h, line 234) +[ Extern ] Froms (file share/libc/math.h, line 237) assigns \result \from x, y; Unverifiable but considered Valid. [ Valid ] Default behavior @@ -2708,7 +2708,7 @@ [ Extern ] Assigns nothing assigns \nothing; Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/math.h, line 241) +[ Extern ] Froms (file share/libc/math.h, line 244) assigns \result \from x, y; Unverifiable but considered Valid. [ Valid ] Default behavior @@ -2731,7 +2731,7 @@ [ Extern ] Assigns nothing assigns \nothing; Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/math.h, line 249) +[ Extern ] Froms (file share/libc/math.h, line 252) assigns \result \from x; Unverifiable but considered Valid. [ Valid ] Default behavior @@ -2751,7 +2751,7 @@ [ Extern ] Assigns nothing assigns \nothing; Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/math.h, line 256) +[ Extern ] Froms (file share/libc/math.h, line 259) assigns \result \from x; Unverifiable but considered Valid. [ Valid ] Default behavior @@ -2771,7 +2771,7 @@ [ Extern ] Assigns nothing assigns \nothing; Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/math.h, line 263) +[ Extern ] Froms (file share/libc/math.h, line 266) assigns \result \from x; Unverifiable but considered Valid. [ Valid ] Default behavior @@ -2791,7 +2791,7 @@ [ Extern ] Assigns nothing assigns \nothing; Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/math.h, line 270) +[ Extern ] Froms (file share/libc/math.h, line 273) assigns \result \from x; Unverifiable but considered Valid. [ Valid ] Default behavior @@ -2811,7 +2811,7 @@ [ Extern ] Assigns nothing assigns \nothing; Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/math.h, line 277) +[ Extern ] Froms (file share/libc/math.h, line 280) assigns \result \from x; Unverifiable but considered Valid. [ Valid ] Default behavior @@ -2831,7 +2831,7 @@ [ Extern ] Assigns nothing assigns \nothing; Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/math.h, line 284) +[ Extern ] Froms (file share/libc/math.h, line 287) assigns \result \from x; Unverifiable but considered Valid. [ Valid ] Default behavior @@ -2851,10 +2851,10 @@ [ Extern ] Post-condition for 'domain_error' 'errno_set' ensures errno_set: __fc_errno ≡ 1 Unverifiable but considered Valid. -[ Extern ] Assigns (file share/libc/math.h, line 295) +[ Extern ] Assigns (file share/libc/math.h, line 298) assigns __fc_errno, \result; Unverifiable but considered Valid. -[ Extern ] Assigns for 'domain_error' (file share/libc/math.h, line 306) +[ Extern ] Assigns for 'domain_error' (file share/libc/math.h, line 309) assigns __fc_errno, \result; Unverifiable but considered Valid. [ Extern ] Assigns for 'infinite' nothing @@ -2863,22 +2863,22 @@ [ Extern ] Assigns for 'normal' nothing assigns \nothing; Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/math.h, line 295) +[ Extern ] Froms (file share/libc/math.h, line 298) assigns __fc_errno \from x; Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/math.h, line 295) +[ Extern ] Froms (file share/libc/math.h, line 298) assigns \result \from x; Unverifiable but considered Valid. -[ Extern ] Froms for 'domain_error' (file share/libc/math.h, line 306) +[ Extern ] Froms for 'domain_error' (file share/libc/math.h, line 309) assigns __fc_errno \from x; Unverifiable but considered Valid. -[ Extern ] Froms for 'domain_error' (file share/libc/math.h, line 306) +[ Extern ] Froms for 'domain_error' (file share/libc/math.h, line 309) assigns \result \from x; Unverifiable but considered Valid. -[ Extern ] Froms for 'infinite' (file share/libc/math.h, line 302) +[ Extern ] Froms for 'infinite' (file share/libc/math.h, line 305) assigns \result \from x; Unverifiable but considered Valid. -[ Extern ] Froms for 'normal' (file share/libc/math.h, line 298) +[ Extern ] Froms for 'normal' (file share/libc/math.h, line 301) assigns \result \from x; Unverifiable but considered Valid. [ Valid ] Default behavior @@ -2907,10 +2907,10 @@ [ Extern ] Post-condition for 'domain_error' 'errno_set' ensures errno_set: __fc_errno ≡ 1 Unverifiable but considered Valid. -[ Extern ] Assigns (file share/libc/math.h, line 313) +[ Extern ] Assigns (file share/libc/math.h, line 316) assigns __fc_errno, \result; Unverifiable but considered Valid. -[ Extern ] Assigns for 'domain_error' (file share/libc/math.h, line 324) +[ Extern ] Assigns for 'domain_error' (file share/libc/math.h, line 327) assigns __fc_errno, \result; Unverifiable but considered Valid. [ Extern ] Assigns for 'infinite' nothing @@ -2919,22 +2919,22 @@ [ Extern ] Assigns for 'normal' nothing assigns \nothing; Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/math.h, line 313) +[ Extern ] Froms (file share/libc/math.h, line 316) assigns __fc_errno \from x; Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/math.h, line 313) +[ Extern ] Froms (file share/libc/math.h, line 316) assigns \result \from x; Unverifiable but considered Valid. -[ Extern ] Froms for 'domain_error' (file share/libc/math.h, line 324) +[ Extern ] Froms for 'domain_error' (file share/libc/math.h, line 327) assigns __fc_errno \from x; Unverifiable but considered Valid. -[ Extern ] Froms for 'domain_error' (file share/libc/math.h, line 324) +[ Extern ] Froms for 'domain_error' (file share/libc/math.h, line 327) assigns \result \from x; Unverifiable but considered Valid. -[ Extern ] Froms for 'infinite' (file share/libc/math.h, line 320) +[ Extern ] Froms for 'infinite' (file share/libc/math.h, line 323) assigns \result \from x; Unverifiable but considered Valid. -[ Extern ] Froms for 'normal' (file share/libc/math.h, line 316) +[ Extern ] Froms for 'normal' (file share/libc/math.h, line 319) assigns \result \from x; Unverifiable but considered Valid. [ Valid ] Default behavior @@ -2963,10 +2963,10 @@ [ Extern ] Post-condition for 'domain_error' 'errno_set' ensures errno_set: __fc_errno ≡ 1 Unverifiable but considered Valid. -[ Extern ] Assigns (file share/libc/math.h, line 331) +[ Extern ] Assigns (file share/libc/math.h, line 334) assigns __fc_errno, \result; Unverifiable but considered Valid. -[ Extern ] Assigns for 'domain_error' (file share/libc/math.h, line 342) +[ Extern ] Assigns for 'domain_error' (file share/libc/math.h, line 345) assigns __fc_errno, \result; Unverifiable but considered Valid. [ Extern ] Assigns for 'infinite' nothing @@ -2975,22 +2975,22 @@ [ Extern ] Assigns for 'normal' nothing assigns \nothing; Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/math.h, line 331) +[ Extern ] Froms (file share/libc/math.h, line 334) assigns __fc_errno \from x; Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/math.h, line 331) +[ Extern ] Froms (file share/libc/math.h, line 334) assigns \result \from x; Unverifiable but considered Valid. -[ Extern ] Froms for 'domain_error' (file share/libc/math.h, line 342) +[ Extern ] Froms for 'domain_error' (file share/libc/math.h, line 345) assigns __fc_errno \from x; Unverifiable but considered Valid. -[ Extern ] Froms for 'domain_error' (file share/libc/math.h, line 342) +[ Extern ] Froms for 'domain_error' (file share/libc/math.h, line 345) assigns \result \from x; Unverifiable but considered Valid. -[ Extern ] Froms for 'infinite' (file share/libc/math.h, line 338) +[ Extern ] Froms for 'infinite' (file share/libc/math.h, line 341) assigns \result \from x; Unverifiable but considered Valid. -[ Extern ] Froms for 'normal' (file share/libc/math.h, line 334) +[ Extern ] Froms for 'normal' (file share/libc/math.h, line 337) assigns \result \from x; Unverifiable but considered Valid. [ Valid ] Default behavior @@ -3019,7 +3019,7 @@ [ Extern ] Assigns nothing assigns \nothing; Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/math.h, line 370) +[ Extern ] Froms (file share/libc/math.h, line 373) assigns \result \from x; Unverifiable but considered Valid. [ Valid ] Default behavior @@ -3039,7 +3039,7 @@ [ Extern ] Assigns nothing assigns \nothing; Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/math.h, line 378) +[ Extern ] Froms (file share/libc/math.h, line 381) assigns \result \from x; Unverifiable but considered Valid. [ Valid ] Default behavior @@ -3056,7 +3056,7 @@ [ Extern ] Assigns nothing assigns \nothing; Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/math.h, line 408) +[ Extern ] Froms (file share/libc/math.h, line 411) assigns \result \from x; Unverifiable but considered Valid. [ Valid ] Default behavior @@ -3073,7 +3073,7 @@ [ Extern ] Assigns nothing assigns \nothing; Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/math.h, line 415) +[ Extern ] Froms (file share/libc/math.h, line 418) assigns \result \from x; Unverifiable but considered Valid. [ Valid ] Default behavior @@ -3090,7 +3090,7 @@ [ Extern ] Assigns nothing assigns \nothing; Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/math.h, line 422) +[ Extern ] Froms (file share/libc/math.h, line 425) assigns \result \from x; Unverifiable but considered Valid. [ Valid ] Default behavior @@ -3107,7 +3107,7 @@ [ Extern ] Assigns nothing assigns \nothing; Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/math.h, line 429) +[ Extern ] Froms (file share/libc/math.h, line 432) assigns \result \from x; Unverifiable but considered Valid. [ Valid ] Default behavior @@ -3124,7 +3124,7 @@ [ Extern ] Assigns nothing assigns \nothing; Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/math.h, line 436) +[ Extern ] Froms (file share/libc/math.h, line 439) assigns \result \from x; Unverifiable but considered Valid. [ Valid ] Default behavior @@ -3141,7 +3141,7 @@ [ Extern ] Assigns nothing assigns \nothing; Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/math.h, line 443) +[ Extern ] Froms (file share/libc/math.h, line 446) assigns \result \from x; Unverifiable but considered Valid. [ Valid ] Default behavior @@ -3158,7 +3158,7 @@ [ Extern ] Assigns nothing assigns \nothing; Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/math.h, line 454) +[ Extern ] Froms (file share/libc/math.h, line 457) assigns \result \from x; Unverifiable but considered Valid. [ Valid ] Default behavior @@ -3175,7 +3175,7 @@ [ Extern ] Assigns nothing assigns \nothing; Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/math.h, line 461) +[ Extern ] Froms (file share/libc/math.h, line 464) assigns \result \from x; Unverifiable but considered Valid. [ Valid ] Default behavior @@ -3192,7 +3192,7 @@ [ Extern ] Assigns nothing assigns \nothing; Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/math.h, line 468) +[ Extern ] Froms (file share/libc/math.h, line 471) assigns \result \from x; Unverifiable but considered Valid. [ Valid ] Default behavior @@ -3217,7 +3217,7 @@ [ Extern ] Assigns nothing assigns \nothing; Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/math.h, line 494) +[ Extern ] Froms (file share/libc/math.h, line 497) assigns \result \from x; Unverifiable but considered Valid. [ Valid ] Default behavior @@ -3242,7 +3242,7 @@ [ Extern ] Assigns nothing assigns \nothing; Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/math.h, line 502) +[ Extern ] Froms (file share/libc/math.h, line 505) assigns \result \from x; Unverifiable but considered Valid. [ Valid ] Default behavior @@ -3267,7 +3267,7 @@ [ Extern ] Assigns nothing assigns \nothing; Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/math.h, line 510) +[ Extern ] Froms (file share/libc/math.h, line 513) assigns \result \from x; Unverifiable but considered Valid. [ Valid ] Default behavior @@ -3284,7 +3284,7 @@ [ Extern ] Assigns nothing assigns \nothing; Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/math.h, line 523) +[ Extern ] Froms (file share/libc/math.h, line 526) assigns \result \from x, y; Unverifiable but considered Valid. [ Valid ] Default behavior @@ -3301,7 +3301,7 @@ [ Extern ] Assigns nothing assigns \nothing; Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/math.h, line 530) +[ Extern ] Froms (file share/libc/math.h, line 533) assigns \result \from x, y; Unverifiable but considered Valid. [ Valid ] Default behavior @@ -3330,7 +3330,7 @@ [ Extern ] Assigns nothing assigns \nothing; Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/math.h, line 539) +[ Extern ] Froms (file share/libc/math.h, line 542) assigns \result \from x; Unverifiable but considered Valid. [ Valid ] Default behavior @@ -3353,7 +3353,7 @@ [ Extern ] Assigns nothing assigns \nothing; Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/math.h, line 548) +[ Extern ] Froms (file share/libc/math.h, line 551) assigns \result \from x; Unverifiable but considered Valid. [ Valid ] Default behavior @@ -3373,7 +3373,7 @@ [ Extern ] Assigns nothing assigns \nothing; Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/math.h, line 557) +[ Extern ] Froms (file share/libc/math.h, line 560) assigns \result \from x; Unverifiable but considered Valid. [ Valid ] Default behavior @@ -3390,7 +3390,7 @@ [ Extern ] Assigns nothing assigns \nothing; Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/math.h, line 580) +[ Extern ] Froms (file share/libc/math.h, line 583) assigns \result \from x; Unverifiable but considered Valid. [ Valid ] Default behavior @@ -3407,7 +3407,7 @@ [ Extern ] Assigns nothing assigns \nothing; Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/math.h, line 586) +[ Extern ] Froms (file share/libc/math.h, line 589) assigns \result \from x; Unverifiable but considered Valid. [ Valid ] Default behavior @@ -3424,7 +3424,7 @@ [ Extern ] Assigns nothing assigns \nothing; Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/math.h, line 593) +[ Extern ] Froms (file share/libc/math.h, line 596) assigns \result \from x; Unverifiable but considered Valid. [ Valid ] Default behavior @@ -3441,7 +3441,7 @@ [ Extern ] Assigns nothing assigns \nothing; Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/math.h, line 599) +[ Extern ] Froms (file share/libc/math.h, line 602) assigns \result \from x; Unverifiable but considered Valid. [ Valid ] Default behavior @@ -3458,7 +3458,7 @@ [ Extern ] Assigns nothing assigns \nothing; Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/math.h, line 605) +[ Extern ] Froms (file share/libc/math.h, line 608) assigns \result \from x; Unverifiable but considered Valid. [ Valid ] Default behavior @@ -3475,7 +3475,7 @@ [ Extern ] Assigns nothing assigns \nothing; Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/math.h, line 611) +[ Extern ] Froms (file share/libc/math.h, line 614) assigns \result \from x; Unverifiable but considered Valid. [ Valid ] Default behavior @@ -3492,7 +3492,7 @@ [ Extern ] Assigns nothing assigns \nothing; Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/math.h, line 633) +[ Extern ] Froms (file share/libc/math.h, line 636) assigns \result \from x; Unverifiable but considered Valid. [ Valid ] Default behavior @@ -3509,7 +3509,7 @@ [ Extern ] Assigns nothing assigns \nothing; Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/math.h, line 639) +[ Extern ] Froms (file share/libc/math.h, line 642) assigns \result \from x; Unverifiable but considered Valid. [ Valid ] Default behavior @@ -3526,7 +3526,7 @@ [ Extern ] Assigns nothing assigns \nothing; Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/math.h, line 645) +[ Extern ] Froms (file share/libc/math.h, line 648) assigns \result \from x; Unverifiable but considered Valid. [ Valid ] Default behavior @@ -3543,7 +3543,7 @@ [ Extern ] Assigns nothing assigns \nothing; Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/math.h, line 659) +[ Extern ] Froms (file share/libc/math.h, line 662) assigns \result \from x; Unverifiable but considered Valid. [ Valid ] Default behavior @@ -3560,7 +3560,7 @@ [ Extern ] Assigns nothing assigns \nothing; Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/math.h, line 665) +[ Extern ] Froms (file share/libc/math.h, line 668) assigns \result \from x; Unverifiable but considered Valid. [ Valid ] Default behavior @@ -3577,7 +3577,7 @@ [ Extern ] Assigns nothing assigns \nothing; Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/math.h, line 671) +[ Extern ] Froms (file share/libc/math.h, line 674) assigns \result \from x; Unverifiable but considered Valid. [ Valid ] Default behavior @@ -3594,7 +3594,7 @@ [ Extern ] Assigns nothing assigns \nothing; Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/math.h, line 678) +[ Extern ] Froms (file share/libc/math.h, line 681) assigns \result \from x, y; Unverifiable but considered Valid. [ Valid ] Default behavior @@ -3611,7 +3611,7 @@ [ Extern ] Assigns nothing assigns \nothing; Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/math.h, line 685) +[ Extern ] Froms (file share/libc/math.h, line 688) assigns \result \from x, y; Unverifiable but considered Valid. [ Valid ] Default behavior @@ -3628,7 +3628,7 @@ [ Extern ] Assigns nothing assigns \nothing; Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/math.h, line 706) +[ Extern ] Froms (file share/libc/math.h, line 709) assigns \result \from (indirect: *(tagp + (0 ..))); Unverifiable but considered Valid. [ Valid ] Default behavior @@ -3645,7 +3645,7 @@ [ Extern ] Assigns nothing assigns \nothing; Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/math.h, line 713) +[ Extern ] Froms (file share/libc/math.h, line 716) assigns \result \from (indirect: *(tagp + (0 ..))); Unverifiable but considered Valid. [ Valid ] Default behavior @@ -3662,7 +3662,7 @@ [ Extern ] Assigns nothing assigns \nothing; Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/math.h, line 720) +[ Extern ] Froms (file share/libc/math.h, line 723) assigns \result \from (indirect: *(tagp + (0 ..))); Unverifiable but considered Valid. [ Valid ] Default behavior @@ -3679,7 +3679,7 @@ [ Extern ] Assigns nothing assigns \nothing; Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/math.h, line 768) +[ Extern ] Froms (file share/libc/math.h, line 771) assigns \result \from \nothing; Unverifiable but considered Valid. [ Valid ] Default behavior @@ -3696,7 +3696,7 @@ [ Extern ] Assigns nothing assigns \nothing; Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/math.h, line 774) +[ Extern ] Froms (file share/libc/math.h, line 777) assigns \result \from \nothing; Unverifiable but considered Valid. [ Valid ] Default behavior diff --git a/tests/libc/math_h.c b/tests/libc/math_h.c index 06901268917..95ded2bf103 100644 --- a/tests/libc/math_h.c +++ b/tests/libc/math_h.c @@ -1,5 +1,7 @@ +/* run.config + STDOPT: #"-warn-special-float none" #"-cpp-extra-args=\"-DNONFINITE\"" +*/ #include <math.h> - const double pi = 3.14159265358979323846264338327950288; const double half_pi = 1.57079632679489661923132169163975144; const double e = 2.718281828459045090795598298427648842334747314453125; @@ -17,6 +19,14 @@ const double minus_zero = -0.0; const double one = 1.0; const double minus_one = -1.0; const double large = 1e38; +#ifdef NONFINITE +const double huge_val = HUGE_VAL; +const float huge_valf = HUGE_VALF; +const long double huge_vall = HUGE_VALL; +#endif +const float infinity = INFINITY; +const double fp_ilogb0 = FP_ILOGB0; +const double fp_ilogbnan = FP_ILOGBNAN; #define TEST_VAL(type,f,c) type f##_##c = f(c) diff --git a/tests/libc/oracle/math_h.res.oracle b/tests/libc/oracle/math_h.res.oracle index 3e49cb57de3..cf2aaaa418c 100644 --- a/tests/libc/oracle/math_h.res.oracle +++ b/tests/libc/oracle/math_h.res.oracle @@ -1,5 +1,5 @@ [kernel] Parsing tests/libc/math_h.c (with preprocessing) -[kernel:parser:decimal-float] tests/libc/math_h.c:3: Warning: +[kernel:parser:decimal-float] tests/libc/math_h.c:5: Warning: Floating-point constant 3.14159265358979323846264338327950288 is not represented exactly. Will use 0x1.921fb54442d18p1. (warn-once: no further messages from category 'parser:decimal-float' will be emitted) [eva] Analyzing a complete application starting at main @@ -23,292 +23,286 @@ one ∈ {1.} minus_one ∈ {-1.} large ∈ {1e+38} + huge_val ∈ {inf} + huge_valf ∈ {inf} + huge_vall ∈ {inf} + infinity ∈ {inf} + fp_ilogb0 ∈ {-2147483648.} + fp_ilogbnan ∈ {-2147483648.} [eva] computing for function atan <- main. - Called from tests/libc/math_h.c:35. + Called from tests/libc/math_h.c:45. [eva] using specification for function atan -[eva] tests/libc/math_h.c:35: +[eva] tests/libc/math_h.c:45: function atan: precondition 'finite_arg' got status valid. [eva] Done for function atan [eva] computing for function atan <- main. - Called from tests/libc/math_h.c:35. -[eva] tests/libc/math_h.c:35: + Called from tests/libc/math_h.c:45. +[eva] tests/libc/math_h.c:45: function atan: precondition 'finite_arg' got status valid. [eva] Done for function atan [eva] computing for function atan <- main. - Called from tests/libc/math_h.c:35. -[eva] tests/libc/math_h.c:35: + Called from tests/libc/math_h.c:45. +[eva] tests/libc/math_h.c:45: function atan: precondition 'finite_arg' got status valid. [eva] Done for function atan [eva] computing for function atan <- main. - Called from tests/libc/math_h.c:35. -[eva] tests/libc/math_h.c:35: + Called from tests/libc/math_h.c:45. +[eva] tests/libc/math_h.c:45: function atan: precondition 'finite_arg' got status valid. [eva] Done for function atan [eva] computing for function atan <- main. - Called from tests/libc/math_h.c:35. -[eva] tests/libc/math_h.c:35: + Called from tests/libc/math_h.c:45. +[eva] tests/libc/math_h.c:45: function atan: precondition 'finite_arg' got status valid. [eva] Done for function atan [eva] computing for function atan <- main. - Called from tests/libc/math_h.c:35. -[eva] tests/libc/math_h.c:35: + Called from tests/libc/math_h.c:45. +[eva] tests/libc/math_h.c:45: function atan: precondition 'finite_arg' got status valid. [eva] Done for function atan [eva] computing for function atan <- main. - Called from tests/libc/math_h.c:35. -[eva] tests/libc/math_h.c:35: + Called from tests/libc/math_h.c:45. +[eva] tests/libc/math_h.c:45: function atan: precondition 'finite_arg' got status valid. [eva] Done for function atan [eva] computing for function atan <- main. - Called from tests/libc/math_h.c:35. -[eva] tests/libc/math_h.c:35: + Called from tests/libc/math_h.c:45. +[eva] tests/libc/math_h.c:45: function atan: precondition 'finite_arg' got status valid. [eva] Done for function atan -[eva:alarm] tests/libc/math_h.c:35: Warning: - non-finite double value. assert \is_finite(top); [eva] computing for function atan <- main. - Called from tests/libc/math_h.c:35. -[eva] tests/libc/math_h.c:35: - function atan: precondition 'finite_arg' got status valid. + Called from tests/libc/math_h.c:45. +[eva:alarm] tests/libc/math_h.c:45: Warning: + function atan: precondition 'finite_arg' got status unknown. [eva] Done for function atan [eva] computing for function atanf <- main. - Called from tests/libc/math_h.c:36. + Called from tests/libc/math_h.c:46. [eva] using specification for function atanf -[eva] tests/libc/math_h.c:36: +[eva] tests/libc/math_h.c:46: function atanf: precondition 'finite_arg' got status valid. [eva] Done for function atanf [eva] computing for function atanf <- main. - Called from tests/libc/math_h.c:36. -[eva] tests/libc/math_h.c:36: + Called from tests/libc/math_h.c:46. +[eva] tests/libc/math_h.c:46: function atanf: precondition 'finite_arg' got status valid. [eva] Done for function atanf [eva] computing for function atanf <- main. - Called from tests/libc/math_h.c:36. -[eva] tests/libc/math_h.c:36: + Called from tests/libc/math_h.c:46. +[eva] tests/libc/math_h.c:46: function atanf: precondition 'finite_arg' got status valid. [eva] Done for function atanf [eva] computing for function atanf <- main. - Called from tests/libc/math_h.c:36. -[eva] tests/libc/math_h.c:36: + Called from tests/libc/math_h.c:46. +[eva] tests/libc/math_h.c:46: function atanf: precondition 'finite_arg' got status valid. [eva] Done for function atanf [eva] computing for function atanf <- main. - Called from tests/libc/math_h.c:36. -[eva] tests/libc/math_h.c:36: + Called from tests/libc/math_h.c:46. +[eva] tests/libc/math_h.c:46: function atanf: precondition 'finite_arg' got status valid. [eva] Done for function atanf [eva] computing for function atanf <- main. - Called from tests/libc/math_h.c:36. -[eva] tests/libc/math_h.c:36: + Called from tests/libc/math_h.c:46. +[eva] tests/libc/math_h.c:46: function atanf: precondition 'finite_arg' got status valid. [eva] Done for function atanf [eva] computing for function atanf <- main. - Called from tests/libc/math_h.c:36. -[eva] tests/libc/math_h.c:36: + Called from tests/libc/math_h.c:46. +[eva] tests/libc/math_h.c:46: function atanf: precondition 'finite_arg' got status valid. [eva] Done for function atanf [eva] computing for function atanf <- main. - Called from tests/libc/math_h.c:36. -[eva] tests/libc/math_h.c:36: + Called from tests/libc/math_h.c:46. +[eva] tests/libc/math_h.c:46: function atanf: precondition 'finite_arg' got status valid. [eva] Done for function atanf -[eva:alarm] tests/libc/math_h.c:36: Warning: - non-finite float value. assert \is_finite(f_top); [eva] computing for function atanf <- main. - Called from tests/libc/math_h.c:36. -[eva] tests/libc/math_h.c:36: - function atanf: precondition 'finite_arg' got status valid. + Called from tests/libc/math_h.c:46. +[eva:alarm] tests/libc/math_h.c:46: Warning: + function atanf: precondition 'finite_arg' got status unknown. [eva] Done for function atanf [eva] computing for function atanl <- main. - Called from tests/libc/math_h.c:37. + Called from tests/libc/math_h.c:47. [eva] using specification for function atanl -[eva] tests/libc/math_h.c:37: +[eva] tests/libc/math_h.c:47: function atanl: precondition 'finite_arg' got status valid. [eva] Done for function atanl [eva] computing for function atanl <- main. - Called from tests/libc/math_h.c:37. -[eva] tests/libc/math_h.c:37: + Called from tests/libc/math_h.c:47. +[eva] tests/libc/math_h.c:47: function atanl: precondition 'finite_arg' got status valid. [eva] Done for function atanl [eva] computing for function atanl <- main. - Called from tests/libc/math_h.c:37. -[eva] tests/libc/math_h.c:37: + Called from tests/libc/math_h.c:47. +[eva] tests/libc/math_h.c:47: function atanl: precondition 'finite_arg' got status valid. [eva] Done for function atanl [eva] computing for function atanl <- main. - Called from tests/libc/math_h.c:37. -[eva] tests/libc/math_h.c:37: + Called from tests/libc/math_h.c:47. +[eva] tests/libc/math_h.c:47: function atanl: precondition 'finite_arg' got status valid. [eva] Done for function atanl [eva] computing for function atanl <- main. - Called from tests/libc/math_h.c:37. -[eva] tests/libc/math_h.c:37: + Called from tests/libc/math_h.c:47. +[eva] tests/libc/math_h.c:47: function atanl: precondition 'finite_arg' got status valid. [eva] Done for function atanl [eva] computing for function atanl <- main. - Called from tests/libc/math_h.c:37. -[eva] tests/libc/math_h.c:37: + Called from tests/libc/math_h.c:47. +[eva] tests/libc/math_h.c:47: function atanl: precondition 'finite_arg' got status valid. [eva] Done for function atanl [eva] computing for function atanl <- main. - Called from tests/libc/math_h.c:37. -[eva] tests/libc/math_h.c:37: + Called from tests/libc/math_h.c:47. +[eva] tests/libc/math_h.c:47: function atanl: precondition 'finite_arg' got status valid. [eva] Done for function atanl [eva] computing for function atanl <- main. - Called from tests/libc/math_h.c:37. -[eva] tests/libc/math_h.c:37: + Called from tests/libc/math_h.c:47. +[eva] tests/libc/math_h.c:47: function atanl: precondition 'finite_arg' got status valid. [eva] Done for function atanl -[eva:alarm] tests/libc/math_h.c:37: Warning: - non-finite long double value. assert \is_finite(ld_top); [eva] computing for function atanl <- main. - Called from tests/libc/math_h.c:37. -[eva:alarm] tests/libc/math_h.c:37: Warning: + Called from tests/libc/math_h.c:47. +[eva:alarm] tests/libc/math_h.c:47: Warning: function atanl: precondition 'finite_arg' got status unknown. [eva] Done for function atanl [eva] computing for function fabs <- main. - Called from tests/libc/math_h.c:38. + Called from tests/libc/math_h.c:48. [eva] using specification for function fabs -[eva] tests/libc/math_h.c:38: +[eva] tests/libc/math_h.c:48: function fabs: precondition 'finite_arg' got status valid. [eva] Done for function fabs [eva] computing for function fabs <- main. - Called from tests/libc/math_h.c:38. -[eva] tests/libc/math_h.c:38: + Called from tests/libc/math_h.c:48. +[eva] tests/libc/math_h.c:48: function fabs: precondition 'finite_arg' got status valid. [eva] Done for function fabs [eva] computing for function fabs <- main. - Called from tests/libc/math_h.c:38. -[eva] tests/libc/math_h.c:38: + Called from tests/libc/math_h.c:48. +[eva] tests/libc/math_h.c:48: function fabs: precondition 'finite_arg' got status valid. [eva] Done for function fabs [eva] computing for function fabs <- main. - Called from tests/libc/math_h.c:38. -[eva] tests/libc/math_h.c:38: + Called from tests/libc/math_h.c:48. +[eva] tests/libc/math_h.c:48: function fabs: precondition 'finite_arg' got status valid. [eva] Done for function fabs [eva] computing for function fabs <- main. - Called from tests/libc/math_h.c:38. -[eva] tests/libc/math_h.c:38: + Called from tests/libc/math_h.c:48. +[eva] tests/libc/math_h.c:48: function fabs: precondition 'finite_arg' got status valid. [eva] Done for function fabs [eva] computing for function fabs <- main. - Called from tests/libc/math_h.c:38. -[eva] tests/libc/math_h.c:38: + Called from tests/libc/math_h.c:48. +[eva] tests/libc/math_h.c:48: function fabs: precondition 'finite_arg' got status valid. [eva] Done for function fabs [eva] computing for function fabs <- main. - Called from tests/libc/math_h.c:38. -[eva] tests/libc/math_h.c:38: + Called from tests/libc/math_h.c:48. +[eva] tests/libc/math_h.c:48: function fabs: precondition 'finite_arg' got status valid. [eva] Done for function fabs [eva] computing for function fabs <- main. - Called from tests/libc/math_h.c:38. -[eva] tests/libc/math_h.c:38: + Called from tests/libc/math_h.c:48. +[eva] tests/libc/math_h.c:48: function fabs: precondition 'finite_arg' got status valid. [eva] Done for function fabs -[eva:alarm] tests/libc/math_h.c:38: Warning: - non-finite double value. assert \is_finite(top); [eva] computing for function fabs <- main. - Called from tests/libc/math_h.c:38. -[eva] tests/libc/math_h.c:38: - function fabs: precondition 'finite_arg' got status valid. + Called from tests/libc/math_h.c:48. +[eva:alarm] tests/libc/math_h.c:48: Warning: + function fabs: precondition 'finite_arg' got status unknown. [eva] Done for function fabs [eva] computing for function fabsf <- main. - Called from tests/libc/math_h.c:39. + Called from tests/libc/math_h.c:49. [eva] using specification for function fabsf -[eva] tests/libc/math_h.c:39: +[eva] tests/libc/math_h.c:49: function fabsf: precondition 'finite_arg' got status valid. [eva] Done for function fabsf [eva] computing for function fabsf <- main. - Called from tests/libc/math_h.c:39. -[eva] tests/libc/math_h.c:39: + Called from tests/libc/math_h.c:49. +[eva] tests/libc/math_h.c:49: function fabsf: precondition 'finite_arg' got status valid. [eva] Done for function fabsf [eva] computing for function fabsf <- main. - Called from tests/libc/math_h.c:39. -[eva] tests/libc/math_h.c:39: + Called from tests/libc/math_h.c:49. +[eva] tests/libc/math_h.c:49: function fabsf: precondition 'finite_arg' got status valid. [eva] Done for function fabsf [eva] computing for function fabsf <- main. - Called from tests/libc/math_h.c:39. -[eva] tests/libc/math_h.c:39: + Called from tests/libc/math_h.c:49. +[eva] tests/libc/math_h.c:49: function fabsf: precondition 'finite_arg' got status valid. [eva] Done for function fabsf [eva] computing for function fabsf <- main. - Called from tests/libc/math_h.c:39. -[eva] tests/libc/math_h.c:39: + Called from tests/libc/math_h.c:49. +[eva] tests/libc/math_h.c:49: function fabsf: precondition 'finite_arg' got status valid. [eva] Done for function fabsf [eva] computing for function fabsf <- main. - Called from tests/libc/math_h.c:39. -[eva] tests/libc/math_h.c:39: + Called from tests/libc/math_h.c:49. +[eva] tests/libc/math_h.c:49: function fabsf: precondition 'finite_arg' got status valid. [eva] Done for function fabsf [eva] computing for function fabsf <- main. - Called from tests/libc/math_h.c:39. -[eva] tests/libc/math_h.c:39: + Called from tests/libc/math_h.c:49. +[eva] tests/libc/math_h.c:49: function fabsf: precondition 'finite_arg' got status valid. [eva] Done for function fabsf [eva] computing for function fabsf <- main. - Called from tests/libc/math_h.c:39. -[eva] tests/libc/math_h.c:39: + Called from tests/libc/math_h.c:49. +[eva] tests/libc/math_h.c:49: function fabsf: precondition 'finite_arg' got status valid. [eva] Done for function fabsf -[eva:alarm] tests/libc/math_h.c:39: Warning: - non-finite float value. assert \is_finite(f_top); [eva] computing for function fabsf <- main. - Called from tests/libc/math_h.c:39. -[eva] tests/libc/math_h.c:39: - function fabsf: precondition 'finite_arg' got status valid. + Called from tests/libc/math_h.c:49. +[eva:alarm] tests/libc/math_h.c:49: Warning: + function fabsf: precondition 'finite_arg' got status unknown. [eva] Done for function fabsf [eva] computing for function fabsl <- main. - Called from tests/libc/math_h.c:40. + Called from tests/libc/math_h.c:50. [eva] using specification for function fabsl -[eva] tests/libc/math_h.c:40: +[eva] tests/libc/math_h.c:50: function fabsl: precondition 'finite_arg' got status valid. [eva] Done for function fabsl [eva] computing for function fabsl <- main. - Called from tests/libc/math_h.c:40. -[eva] tests/libc/math_h.c:40: + Called from tests/libc/math_h.c:50. +[eva] tests/libc/math_h.c:50: function fabsl: precondition 'finite_arg' got status valid. [eva] Done for function fabsl [eva] computing for function fabsl <- main. - Called from tests/libc/math_h.c:40. -[eva] tests/libc/math_h.c:40: + Called from tests/libc/math_h.c:50. +[eva] tests/libc/math_h.c:50: function fabsl: precondition 'finite_arg' got status valid. [eva] Done for function fabsl [eva] computing for function fabsl <- main. - Called from tests/libc/math_h.c:40. -[eva] tests/libc/math_h.c:40: + Called from tests/libc/math_h.c:50. +[eva] tests/libc/math_h.c:50: function fabsl: precondition 'finite_arg' got status valid. [eva] Done for function fabsl [eva] computing for function fabsl <- main. - Called from tests/libc/math_h.c:40. -[eva] tests/libc/math_h.c:40: + Called from tests/libc/math_h.c:50. +[eva] tests/libc/math_h.c:50: function fabsl: precondition 'finite_arg' got status valid. [eva] Done for function fabsl [eva] computing for function fabsl <- main. - Called from tests/libc/math_h.c:40. -[eva] tests/libc/math_h.c:40: + Called from tests/libc/math_h.c:50. +[eva] tests/libc/math_h.c:50: function fabsl: precondition 'finite_arg' got status valid. [eva] Done for function fabsl [eva] computing for function fabsl <- main. - Called from tests/libc/math_h.c:40. -[eva] tests/libc/math_h.c:40: + Called from tests/libc/math_h.c:50. +[eva] tests/libc/math_h.c:50: function fabsl: precondition 'finite_arg' got status valid. [eva] Done for function fabsl [eva] computing for function fabsl <- main. - Called from tests/libc/math_h.c:40. -[eva] tests/libc/math_h.c:40: + Called from tests/libc/math_h.c:50. +[eva] tests/libc/math_h.c:50: function fabsl: precondition 'finite_arg' got status valid. [eva] Done for function fabsl -[eva:alarm] tests/libc/math_h.c:40: Warning: - non-finite long double value. assert \is_finite(ld_top); [eva] computing for function fabsl <- main. - Called from tests/libc/math_h.c:40. -[eva:alarm] tests/libc/math_h.c:40: Warning: + Called from tests/libc/math_h.c:50. +[eva:alarm] tests/libc/math_h.c:50: Warning: function fabsl: precondition 'finite_arg' got status unknown. [eva] Done for function fabsl [eva] Recording results for main -- GitLab From cef75793eb3b261939ed77ab0e6238d3c29aa94f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Loi=CC=88c=20Correnson?= <loic.correnson@cea.fr> Date: Mon, 30 Mar 2020 15:29:27 +0200 Subject: [PATCH 065/218] [kernel] refactor expr-to-term --- .Makefile.lint | 1 - src/kernel_internals/typing/asm_contracts.ml | 240 +++++++-------- src/kernel_internals/typing/cabs2cil.ml | 6 +- src/kernel_services/ast_data/alarms.ml | 73 ++--- .../ast_data/statuses_by_call.ml | 2 +- .../ast_queries/logic_typing.ml | 2 +- .../ast_queries/logic_utils.ml | 273 ++++++++++-------- .../ast_queries/logic_utils.mli | 79 +++-- .../ast_transformations/inline.ml | 2 +- src/plugins/aorai/aorai_dataflow.ml | 2 +- src/plugins/aorai/aorai_utils.ml | 9 +- src/plugins/instantiate/basic_blocks.ml | 6 +- src/plugins/occurrence/register_gui.ml | 2 +- src/plugins/studia/studia_gui.ml | 2 +- src/plugins/value/domains/traces_domain.ml | 8 +- src/plugins/wp/LogicSemantics.ml | 2 +- tests/spec/expr_to_term.ml | 6 +- 17 files changed, 392 insertions(+), 323 deletions(-) diff --git a/.Makefile.lint b/.Makefile.lint index 0fffac31e24..140545ce013 100644 --- a/.Makefile.lint +++ b/.Makefile.lint @@ -10,7 +10,6 @@ ML_LINT_KO+=src/kernel_internals/runtime/messages.ml ML_LINT_KO+=src/kernel_internals/runtime/messages.mli ML_LINT_KO+=src/kernel_internals/runtime/special_hooks.ml ML_LINT_KO+=src/kernel_internals/typing/allocates.ml -ML_LINT_KO+=src/kernel_internals/typing/asm_contracts.ml ML_LINT_KO+=src/kernel_internals/typing/frontc.mli ML_LINT_KO+=src/kernel_internals/typing/infer_annotations.ml ML_LINT_KO+=src/kernel_internals/typing/mergecil.mli diff --git a/src/kernel_internals/typing/asm_contracts.ml b/src/kernel_internals/typing/asm_contracts.ml index 45ea1252e59..d87771d648f 100644 --- a/src/kernel_internals/typing/asm_contracts.ml +++ b/src/kernel_internals/typing/asm_contracts.ml @@ -33,24 +33,24 @@ let emitter = let find_out_lval l = let treat_one_lval (output, input) (_,constr, lv) = - let tlv = Logic_utils.lval_to_term_lval ~cast:false lv in + let tlv = Logic_utils.lval_to_term_lval lv in match constr with - | "" -> tlv :: output, input - | _ -> - (* '+' indicates that the lval is used both as input and as output. - GNU syntax allows it only at the beginning of the constraint, but - actual implementation is more liberal and emits only a warning. - *) - if String.contains constr '+' then begin - if constr.[0] <> '+' then - Kernel.warning - "output constraint '+' is not at the beginning in output operand"; - tlv::output, - (* avoid sharing ids *) - Visitor.visitFramacTermLval - (new Visitor.frama_c_refresh(Project.current())) tlv - :: input - end else tlv::output, input + | "" -> tlv :: output, input + | _ -> + (* '+' indicates that the lval is used both as input and as output. + GNU syntax allows it only at the beginning of the constraint, but + actual implementation is more liberal and emits only a warning. + *) + if String.contains constr '+' then begin + if constr.[0] <> '+' then + Kernel.warning + "output constraint '+' is not at the beginning in output operand"; + tlv::output, + (* avoid sharing ids *) + Visitor.visitFramacTermLval + (new Visitor.frama_c_refresh(Project.current())) tlv + :: input + end else tlv::output, input in let output, input = List.fold_left treat_one_lval ([],[]) l @@ -63,7 +63,7 @@ let extract_term_lval acc (_,_,e) = object inherit Visitor.frama_c_inplace method! vlval lv = - res := Logic_utils.lval_to_term_lval ~cast:false lv :: !res; + res := Logic_utils.lval_to_term_lval lv :: !res; Cil.SkipChildren end in @@ -112,123 +112,123 @@ let extract_mem_terms ~loc l = List.rev (List.fold_left (extract_mem_term ~loc) [] l) class visit_assembly = -object(self) - inherit Visitor.frama_c_inplace + object(self) + inherit Visitor.frama_c_inplace - method! vinst i = - let stmt = Extlib.the self#current_stmt in - let kf = Extlib.the self#current_kf in - match i with + method! vinst i = + let stmt = Extlib.the self#current_stmt in + let kf = Extlib.the self#current_kf in + match i with | Asm(_, _, Some { asm_outputs; asm_inputs; asm_clobbers }, loc) -> - let lv_out, lv_from = find_out_lval asm_outputs in - let lv_from = lv_from @ find_input_lval asm_inputs in - let mem_output = extract_mem_terms ~loc lv_from in - let lv_out = lv_out @ mem_output in - let lv_from = lv_from @ mem_output in - let lv_from = - List.filter - (fun lv -> - not (Logic_utils.isLogicArrayType (Cil.typeOfTermLval lv))) - lv_from + let lv_out, lv_from = find_out_lval asm_outputs in + let lv_from = lv_from @ find_input_lval asm_inputs in + let mem_output = extract_mem_terms ~loc lv_from in + let lv_out = lv_out @ mem_output in + let lv_from = lv_from @ mem_output in + let lv_from = + List.filter + (fun lv -> + not (Logic_utils.isLogicArrayType (Cil.typeOfTermLval lv))) + lv_from + in + (* the only interesting information for clobbers is the + presence of the "memory" keyword, which indicates that + memory may have been accessed (read or write) outside of + the locations explicitly referred to as output or + input. We can't do much more than emitting a warning and + considering that nothing is touched beyond normally + specified outputs and inputs. *) + let mem_clobbered = List.mem "memory" asm_clobbers in + if mem_clobbered then begin + let source = fst (Cil_datatype.Instr.loc i) in + let once = true in + Kernel.warning + ~once ~source + "Clobber list contains \"memory\" argument. Assuming no \ + side effects beyond those mentioned in operands." + end; + let to_id_term lv = + Logic_const.new_identified_term + (Logic_const.term ~loc (TLval lv) (Cil.typeOfTermLval lv)) + in + let to_id_from lv = + let typ = Cil.typeOfTermLval lv in + let base_term = Logic_const.term ~loc (TLval lv) typ in + let term = + if Logic_utils.isLogicPointerType typ || + Logic_utils.isLogicArrayType typ + then { base_term with term_name = ["indirect"] } + else base_term in - (* the only interesting information for clobbers is the - presence of the "memory" keyword, which indicates that - memory may have been accessed (read or write) outside of - the locations explicitly referred to as output or - input. We can't do much more than emitting a warning and - considering that nothing is touched beyond normally - specified outputs and inputs. *) - let mem_clobbered = List.mem "memory" asm_clobbers in - if mem_clobbered then begin - let source = fst (Cil_datatype.Instr.loc i) in - let once = true in - Kernel.warning - ~once ~source - "Clobber list contains \"memory\" argument. Assuming no \ - side effects beyond those mentioned in operands." - end; - let to_id_term lv = - Logic_const.new_identified_term - (Logic_const.term ~loc (TLval lv) (Cil.typeOfTermLval lv)) - in - let to_id_from lv = - let typ = Cil.typeOfTermLval lv in - let base_term = Logic_const.term ~loc (TLval lv) typ in - let term = - if Logic_utils.isLogicPointerType typ || - Logic_utils.isLogicArrayType typ - then { base_term with term_name = ["indirect"] } - else base_term - in - Logic_const.new_identified_term term - in - let assigns () = - Writes - (List.map - (fun x -> (to_id_term x, From (List.map to_id_from lv_from))) - lv_out) - in - let filter ca = - match ca.annot_content with - (* search for a statement contract that applies to all cases. *) - | AStmtSpec ([],_) -> true - | _ -> false - in - let contracts = Annotations.code_annot ~filter stmt in - (match contracts with - | [] -> - let assigns = assigns () in - let bhv = Cil.mk_behavior ~assigns () in - let spec = Cil.empty_funspec () in - spec.spec_behavior <- [ bhv ]; - let ca = - Logic_const.new_code_annotation (AStmtSpec ([],spec)) - in - Annotations.add_code_annot emitter ~kf stmt ca; - if not mem_clobbered && Kernel.AsmContractsAutoValidate.get() - then begin - let active = [] in - let ip_assigns = - Property.ip_assigns_of_behavior kf (Kstmt stmt) ~active bhv in - let ip_from = - Property.ip_from_of_behavior kf (Kstmt stmt) ~active bhv in - List.iter - Property_status.( - fun x -> emit emitter ~hyps:[] x True) - (Extlib.list_of_opt ip_assigns @ ip_from) - end - | [ { annot_content = AStmtSpec ([], spec) } ] -> - (* Already existing contracts. Just add assigns clause for - behaviors that do not already have one. *) + Logic_const.new_identified_term term + in + let assigns () = + Writes + (List.map + (fun x -> (to_id_term x, From (List.map to_id_from lv_from))) + lv_out) + in + let filter ca = + match ca.annot_content with + (* search for a statement contract that applies to all cases. *) + | AStmtSpec ([],_) -> true + | _ -> false + in + let contracts = Annotations.code_annot ~filter stmt in + (match contracts with + | [] -> + let assigns = assigns () in + let bhv = Cil.mk_behavior ~assigns () in + let spec = Cil.empty_funspec () in + spec.spec_behavior <- [ bhv ]; + let ca = + Logic_const.new_code_annotation (AStmtSpec ([],spec)) + in + Annotations.add_code_annot emitter ~kf stmt ca; + if not mem_clobbered && Kernel.AsmContractsAutoValidate.get() + then begin + let active = [] in + let ip_assigns = + Property.ip_assigns_of_behavior kf (Kstmt stmt) ~active bhv in + let ip_from = + Property.ip_from_of_behavior kf (Kstmt stmt) ~active bhv in List.iter - (fun bhv -> - match bhv.b_assigns with - | WritesAny -> - let behavior = bhv.b_name in - let assigns = assigns () in - let keep_empty = false in - Annotations.add_assigns - ~keep_empty emitter kf ~stmt ~behavior assigns; - | Writes _ -> ()) - spec.spec_behavior - | _ -> - Kernel.fatal "Several contracts found for the same statement %a" - Printer.pp_stmt stmt - ); - Cil.SkipChildren + Property_status.( + fun x -> emit emitter ~hyps:[] x True) + (Extlib.list_of_opt ip_assigns @ ip_from) + end + | [ { annot_content = AStmtSpec ([], spec) } ] -> + (* Already existing contracts. Just add assigns clause for + behaviors that do not already have one. *) + List.iter + (fun bhv -> + match bhv.b_assigns with + | WritesAny -> + let behavior = bhv.b_name in + let assigns = assigns () in + let keep_empty = false in + Annotations.add_assigns + ~keep_empty emitter kf ~stmt ~behavior assigns; + | Writes _ -> ()) + spec.spec_behavior + | _ -> + Kernel.fatal "Several contracts found for the same statement %a" + Printer.pp_stmt stmt + ); + Cil.SkipChildren | Asm(_,_,None,_) -> Kernel.feedback ~dkey:Kernel.dkey_asm_contracts "Ignoring basic assembly instruction"; Cil.SkipChildren | _ -> Cil.SkipChildren -end + end let transform file = if Kernel.AsmContractsGenerate.get() then Visitor.visitFramacFileSameGlobals (new visit_assembly) file let () = - File.add_code_transformation_after_cleanup + File.add_code_transformation_after_cleanup ~deps:[(module Kernel.AsmContractsGenerate); (module Kernel.AsmContractsAutoValidate) ] category diff --git a/src/kernel_internals/typing/cabs2cil.ml b/src/kernel_internals/typing/cabs2cil.ml index 57c91da7c3e..6dc8c4bda1a 100644 --- a/src/kernel_internals/typing/cabs2cil.ml +++ b/src/kernel_internals/typing/cabs2cil.ml @@ -8856,9 +8856,9 @@ and createLocal ghost ((_, sto, _, _) as specs) (se0 +++ ( let castloc = CurrentLoc.get () in let talloca_size = - let telt_size = Logic_utils.expr_to_term ~cast:false elt_size in - let tlen = Logic_utils.expr_to_term ~cast:false len in - Logic_const.term (TBinOp (Mult,telt_size,tlen)) telt_size.term_type + let size = Logic_utils.expr_to_term ~coerce:true elt_size in + let tlen = Logic_utils.expr_to_term ~coerce:true len in + Logic_const.term (TBinOp (Mult,size,tlen)) Linteger in let pos_size = let zero = Logic_const.tinteger ~loc:castloc 0 in diff --git a/src/kernel_services/ast_data/alarms.ml b/src/kernel_services/ast_data/alarms.ml index f251a750c84..903e79bb9f0 100644 --- a/src/kernel_services/ast_data/alarms.ml +++ b/src/kernel_services/ast_data/alarms.ml @@ -451,21 +451,21 @@ let overflowed_expr_to_term ~loc e = let loc = best_loc ~loc e.eloc in match e.enode with | UnOp(op, e, ty) -> - let t = Logic_utils.expr_to_term ~cast:true e in - let ty = Logic_utils.typ_to_logic_type ty in + let t = Logic_utils.expr_to_term ~coerce:true e in + let ty = Logic_utils.coerced ty in Logic_const.term ~loc (TUnOp(op, t)) ty | BinOp(op, e1, e2, ty) -> - let t1 = Logic_utils.expr_to_term ~cast:true e1 in - let t2 = Logic_utils.expr_to_term ~cast:true e2 in - let ty = Logic_utils.typ_to_logic_type ty in + let t1 = Logic_utils.expr_to_term ~coerce:true e1 in + let t2 = Logic_utils.expr_to_term ~coerce:true e2 in + let ty = Logic_utils.coerced ty in Logic_const.term ~loc (TBinOp(op, t1, t2)) ty - | _ -> Logic_utils.expr_to_term ~cast:true e + | _ -> Logic_utils.expr_to_term ~coerce:true e (* Creates \is_finite((fkind)e) or \is_nan((fkind)e) according to [predicate]. *) let create_special_float_predicate ~loc e fkind predicate = let loc = best_loc ~loc e.eloc in - let t = Logic_utils.expr_to_term ~cast:true e in + let t = Logic_utils.expr_to_term e in let typ = match fkind with | FFloat -> Cil.floatType | FDouble -> Cil.doubleType @@ -490,7 +490,7 @@ let create_predicate ?(loc=Location.unknown) alarm = | Division_by_zero e -> (* e != 0 *) let loc = best_loc ~loc e.eloc in - let t = Logic_utils.expr_to_term ~cast:true e in + let t = Logic_utils.expr_to_term ~coerce:true e in Logic_const.prel ~loc (Rneq, t, Cil.lzero ()) | Memory_access(lv, read) -> @@ -500,22 +500,23 @@ let create_predicate ?(loc=Location.unknown) alarm = | For_writing -> Logic_const.pvalid in let e = Cil.mkAddrOrStartOf ~loc lv in - let t = Logic_utils.expr_to_term ~cast:true e in + let t = Logic_utils.expr_to_term e in valid ~loc (Logic_const.here_label, t) | Index_out_of_bound(e1, e2) -> (* 0 <= e1 < e2, left part if None, right part if Some e *) let loc = best_loc ~loc e1.eloc in - let t1 = Logic_utils.expr_to_term ~cast:true e1 in + let t1 = Logic_utils.expr_to_term ~coerce:true e1 in (match e2 with - | None -> Logic_const.prel ~loc (Rle, Cil.lzero (), t1) + | None -> + Logic_const.prel ~loc (Rle, Cil.lzero (), t1) | Some e2 -> - let t2 = Logic_utils.expr_to_term ~cast:true e2 in + let t2 = Logic_utils.expr_to_term ~coerce:true e2 in Logic_const.prel ~loc (Rlt, t1, t2)) | Invalid_pointer e -> let loc = best_loc ~loc e.eloc in - let t = Logic_utils.expr_to_term ~cast:true e in + let t = Logic_utils.expr_to_term e in if Cil.isFunPtrType (Cil.typeOf e) then Logic_const.pvalid_function ~loc t else Logic_const.pobject_pointer ~loc (Logic_const.here_label, t) @@ -523,12 +524,12 @@ let create_predicate ?(loc=Location.unknown) alarm = | Invalid_shift(e, n) -> (* 0 <= e < n *) let loc = best_loc ~loc e.eloc in - let t = Logic_utils.expr_to_term ~cast:true e in + let t = Logic_utils.expr_to_term ~coerce:true e in let low_cmp = Logic_const.prel ~loc (Rle, Cil.lzero (), t) in (match n with | None -> low_cmp | Some n -> - let tn = Logic_const.tint ~loc (Integer.of_int n) in + let tn = Logic_const.tinteger ~loc n in let up_cmp = Logic_const.prel ~loc (Rlt, t, tn) in Logic_const.pand ~loc (low_cmp, up_cmp)) @@ -544,21 +545,21 @@ let create_predicate ?(loc=Location.unknown) alarm = let zero = Cil.lzero () in Logic_const.term (TCastE (typ, zero)) (Ctype typ) end - | Some e -> Logic_utils.expr_to_term ~cast:true e + | Some e -> Logic_utils.expr_to_term e in - let t2 = Logic_utils.expr_to_term ~cast:true e2 in + let t2 = Logic_utils.expr_to_term e2 in Logic_utils.pointer_comparable ~loc t1 t2 | Differing_blocks(e1, e2) -> (* \base_addr(e1) == \base_addr(e2) *) let loc = best_loc ~loc e1.eloc in - let t1 = Logic_utils.expr_to_term ~cast:true e1 in + let t1 = Logic_utils.expr_to_term e1 in let here = Logic_const.here_label in let typ = Ctype Cil.charPtrType in let t1 = Logic_const.term ~loc:(best_loc loc e1.eloc) (Tbase_addr(here, t1)) typ in - let t2 = Logic_utils.expr_to_term ~cast:true e2 in + let t2 = Logic_utils.expr_to_term e2 in let t2 = Logic_const.term ~loc:(best_loc loc e2.eloc) (Tbase_addr(here, t2)) typ in @@ -569,10 +570,10 @@ let create_predicate ?(loc=Location.unknown) alarm = let loc = best_loc ~loc e.eloc in let t = match kind with | Pointer_downcast -> - let t = Logic_utils.expr_to_term ~cast:true e in + let t = Logic_utils.expr_to_term e in Logic_const.tcast ~loc t Cil.theMachine.upointType | Signed_downcast | Unsigned_downcast -> - Logic_utils.expr_to_term ~cast:true e + Logic_utils.expr_to_term ~coerce:true e | _ -> (* For overflows, the computation must be done on mathematical types, else the value is necessarily in bounds. *) @@ -580,7 +581,9 @@ let create_predicate ?(loc=Location.unknown) alarm = in let tn = Logic_const.tint ~loc n in Logic_const.prel ~loc - (match bound with Lower_bound -> Rle, tn, t | Upper_bound -> Rle, t, tn) + (match bound with + | Lower_bound -> Rle, tn, t + | Upper_bound -> Rle, t, tn) | Float_to_int(e, n, bound) -> (* n < e or e < n according to bound *) @@ -588,27 +591,31 @@ let create_predicate ?(loc=Location.unknown) alarm = let te = overflowed_expr_to_term ~loc e in let t = Logic_const.tlogic_coerce ~loc te Lreal in let n = - (match bound with Lower_bound -> Integer.sub | Upper_bound -> Integer.add) + (match bound with + | Lower_bound -> Integer.sub + | Upper_bound -> Integer.add) n Integer.one in let tn = Logic_const.tlogic_coerce ~loc (Logic_const.tint ~loc n) Lreal in Logic_const.prel ~loc - (match bound with Lower_bound -> Rlt, tn, t | Upper_bound -> Rlt, t, tn) + (match bound with + | Lower_bound -> Rlt, tn, t + | Upper_bound -> Rlt, t, tn) | Not_separated(lv1, lv2) -> (* \separated(lv1, lv2) *) let e1 = Cil.mkAddrOf ~loc lv1 in - let t1 = Logic_utils.expr_to_term ~cast:true e1 in + let t1 = Logic_utils.expr_to_term e1 in let e2 = Cil.mkAddrOf ~loc lv2 in - let t2 = Logic_utils.expr_to_term ~cast:true e2 in + let t2 = Logic_utils.expr_to_term e2 in Logic_const.pseparated ~loc [ t1; t2 ] | Overlap(lv1, lv2) -> (* (lv1 == lv2) || \separated(lv1, lv2) *) let e1 = Cil.mkAddrOf ~loc lv1 in - let t1 = Logic_utils.expr_to_term ~cast:true e1 in + let t1 = Logic_utils.expr_to_term e1 in let e2 = Cil.mkAddrOf ~loc lv2 in - let t2 = Logic_utils.expr_to_term ~cast:true e2 in + let t2 = Logic_utils.expr_to_term e2 in let eq = Logic_const.prel ~loc (Req, t1, t2) in let sep = Logic_const.pseparated ~loc [ t1; t2 ] in Logic_const.por ~loc (eq, sep) @@ -616,13 +623,13 @@ let create_predicate ?(loc=Location.unknown) alarm = | Uninitialized lv -> (* \initialized(lv) *) let e = Cil.mkAddrOrStartOf ~loc lv in - let t = Logic_utils.expr_to_term ~cast:false e in + let t = Logic_utils.expr_to_term e in Logic_const.pinitialized ~loc (Logic_const.here_label, t) | Dangling lv -> (* !\dangling(lv) *) let e = Cil.mkAddrOrStartOf ~loc lv in - let t = Logic_utils.expr_to_term ~cast:false e in + let t = Logic_utils.expr_to_term e in Logic_const.(pnot ~loc (pdangling ~loc (Logic_const.here_label, t))) | Is_nan_or_infinite (e, fkind) -> @@ -648,14 +655,14 @@ let create_predicate ?(loc=Location.unknown) alarm = that has unexpected type %a (unrolled as %a)" Printer.pp_exp e Printer.pp_typ t Printer.pp_typ t' in - let t = Logic_utils.expr_to_term ~cast:true e in + let t = Logic_utils.expr_to_term e in Logic_const.(pvalid_function ~loc t) | Uninitialized_union llv -> (* \initialized(lv_1) || ... || \initialized(lv_n) *) let make_lval_predicate lv = let e = Cil.mkAddrOrStartOf ~loc lv in - let t = Logic_utils.expr_to_term ~cast:false e in + let t = Logic_utils.expr_to_term e in Logic_const.pinitialized ~loc (Logic_const.here_label, t) in List.fold_left (fun acc lv -> @@ -666,7 +673,7 @@ let create_predicate ?(loc=Location.unknown) alarm = | Invalid_bool lv -> let e = Cil.new_exp ~loc (Lval lv) in - let t = Logic_utils.expr_to_term ~cast:false e in + let t = Logic_utils.expr_to_term ~coerce:true e in let zero = Logic_const.prel ~loc (Req, t, Cil.lzero ()) in let one = Logic_const.prel ~loc (Req, t, Cil.lone ()) in Logic_const.por ~loc (zero, one) diff --git a/src/kernel_services/ast_data/statuses_by_call.ml b/src/kernel_services/ast_data/statuses_by_call.ml index d5deb1ab108..2487ade6c49 100644 --- a/src/kernel_services/ast_data/statuses_by_call.ml +++ b/src/kernel_services/ast_data/statuses_by_call.ml @@ -160,7 +160,7 @@ let rec associate acc ~formals ~concretes = | [], _ -> acc | _, [] -> raise Non_Transposable | formal :: formals, concrete :: concretes -> - let term = Logic_utils.expr_to_term ~cast:true concrete in + let term = Logic_utils.expr_to_term concrete in associate ((formal, term) :: acc) ~formals ~concretes let transpose_pred_at_callsite ~formals ~concretes pred = diff --git a/src/kernel_services/ast_queries/logic_typing.ml b/src/kernel_services/ast_queries/logic_typing.ml index f6a1c015fb9..27e77ae549a 100644 --- a/src/kernel_services/ast_queries/logic_typing.ml +++ b/src/kernel_services/ast_queries/logic_typing.ml @@ -801,7 +801,7 @@ struct let attrs = Cil.filter_qualifier_attributes attrs in let field = C.find_comp_field comp f in let typ = Cil.typeOffset ty field in - Logic_utils.offset_to_term_offset ~cast:false field, + Logic_utils.offset_to_term_offset field, Ctype (Cil.typeAddAttributes attrs typ) with Not_found -> C.error loc "cannot find field %s" f) | _ -> diff --git a/src/kernel_services/ast_queries/logic_utils.ml b/src/kernel_services/ast_queries/logic_utils.ml index a77518acee2..8a43475ab1c 100644 --- a/src/kernel_services/ast_queries/logic_utils.ml +++ b/src/kernel_services/ast_queries/logic_utils.ml @@ -123,11 +123,11 @@ let plain_array_to_ptr ty = let array_to_ptr = plain_or_set plain_array_to_ptr -let typ_to_logic_type e_typ = - let ty = Cil.unrollType e_typ in +let coerced typ = + let ty = Cil.unrollType typ in if Cil.isIntegralType ty then Linteger else if Cil.isFloatingType ty then Lreal - else Ctype e_typ + else Ctype typ let predicate_of_identified_predicate ip = ip.ip_content @@ -292,7 +292,6 @@ let lconstant_to_constant c = match c with | LReal r -> CReal (r.r_nearest,FDouble,Some r.r_literal) | LEnum e -> CEnum e - let string_to_float_lconstant string = let f = snd (Floating_point.parse string) in (* If the string has suffix 'F' or 'D', then it represents a single or double @@ -346,24 +345,27 @@ let is_zero_comparable t = let scalar_term_conversion conversion t = let loc = t.term_loc in - let arith_conversion () = conversion ~loc false t (Cil.lzero ~loc ()) in - let ptr_conversion () = - conversion ~loc false t (Logic_const.term ~loc Tnull t.term_type) - in + let arith_conversion t = + conversion ~loc false t (Cil.lzero ~loc ()) in + let real_conversion ?ltyp t = + conversion ~loc false t (Logic_const.treal_zero ~loc ?ltyp ()) in + let ptr_conversion t = + conversion ~loc false t (Logic_const.term ~loc Tnull t.term_type) in + let bool_conversion t = + let ctrue = Logic_env.Logic_ctor_info.find "\\true" in + conversion ~loc true t (term ~loc (TDataCons(ctrue,[])) boolean_type) in match unroll_type t.term_type with - | Ctype (TInt _) -> arith_conversion () - | Ctype (TFloat _) -> - conversion ~loc false t (Logic_const.treal_zero ~loc ~ltyp:t.term_type ()) - | Ctype (TPtr _) -> ptr_conversion () - | Ctype (TArray _) -> ptr_conversion () + | Ctype (TInt _) -> arith_conversion t + | Ctype (TFloat _) as ltyp -> real_conversion ~ltyp t + | Ctype (TPtr _) -> ptr_conversion t + | Ctype (TArray _) -> ptr_conversion t (* Could be transformed to \true: an array is never \null *) - | Ctype (TFun _) -> ptr_conversion () + | Ctype (TFun _) -> ptr_conversion t (* decay as pointer *) - | Linteger -> arith_conversion () - | Lreal -> conversion ~loc false t (Logic_const.treal_zero ~loc ()) + | Linteger -> arith_conversion t + | Lreal -> real_conversion t | Ltype ({lt_name = name},[]) when name = Utf8_logic.boolean -> - let ctrue = Logic_env.Logic_ctor_info.find "\\true" in - conversion ~loc true t (term ~loc (TDataCons(ctrue,[])) boolean_type) + bool_conversion t | Ltype _ | Lvar _ | Larrow _ | Ctype (TVoid _ | TNamed _ | TComp _ | TEnum _ | TBuiltin_va_list _) -> Kernel.fatal @@ -386,124 +388,159 @@ let scalar_term_to_boolean = (* --- Expr Conversion --- *) (* -------------------------------------------------------------------------- *) -let rec expr_to_term ~cast e = +let is_boolean_binop op = + let open Cil_types in + match op with + | Lt | Gt | Le | Ge | Eq | Ne | LAnd | LOr -> true + | PlusA | PlusPI | IndexPI | MinusA | MinusPI | MinusPP + | Mult | Div | Mod | Shiftlt | Shiftrt | BAnd | BXor | BOr -> false + +let float_builtin prefix fkind = + let name = match fkind with + | FFloat -> Printf.sprintf "\\%s_float" prefix + | FDouble | FLongDouble -> Printf.sprintf "\\%s_double" prefix + in match Logic_env.find_all_logic_functions name with + | [ lf ] -> Some lf + | _ -> Kernel.fatal "Missing or ambiguous builtin %S" name + +let is_float_binop op typ = + match typ, op with + | TFloat(fkind,_) , PlusA -> float_builtin "add" fkind + | TFloat(fkind,_) , MinusA -> float_builtin "sub" fkind + | TFloat(fkind,_) , Mult -> float_builtin "mul" fkind + | TFloat(fkind,_) , Div -> float_builtin "div" fkind + | _ -> None + +let is_float_unop op typ = + match typ, op with + | TFloat(fkind,_) , Neg -> float_builtin "neg" fkind + | _ -> None + +let rec expr_to_term ?(coerce=false) e = let loc = e.eloc in - let typ = unrollType (Cil.typeOf e) in - let result = match e.enode with - | Const c -> TConst (constant_to_lconstant c) - | SizeOf t -> TSizeOf t - | SizeOfE e -> TSizeOfE (expr_to_term ~cast e) - | SizeOfStr s -> TSizeOfStr s - | StartOf lv -> TStartOf (lval_to_term_lval ~cast lv) - | AddrOf lv -> TAddrOf (lval_to_term_lval ~cast lv) - | CastE (ty,e) -> (mk_cast (unrollType ty) (expr_to_term ~cast e)).term_node - | BinOp (op, l, r, _) -> - let l' = expr_to_term_coerce ~cast l in - let r' = expr_to_term_coerce ~cast r in - (* type of the conversion of e in the logic. Beware that boolean - operators have boolean type. *) - let tcast = - match op, cast with - | ( Cil_types.Lt | Cil_types.Gt | Cil_types.Le | Cil_types.Ge - | Cil_types.Eq | Cil_types.Ne| Cil_types.LAnd | Cil_types.LOr), - _ -> Some Logic_const.boolean_type - | _, true -> Some (typ_to_logic_type typ) - | _, false -> None - in - let tnode = TBinOp (op,l',r') in - (* if [cast], we add a cast. Otherwise, when [op] is an operator - returning a boolean, we need to cast the whole expression as an - integral type, because (1) the recursive subcalls expect an - integer/float/pointer here, and (2) there is no implicit conversion - Boolean -> integer. *) - begin match tcast with - | Some lt -> (mk_cast typ (Logic_const.term tnode lt)).term_node - | None -> tnode + let typ = Cil.unrollType (Cil.typeOf e) in + let ctyp = Ctype typ in + let node,ltyp = + match e.enode with + | Const c -> TConst (constant_to_lconstant c) , coerced typ + | StartOf lv -> TStartOf (lval_to_term_lval lv) , ctyp + | AddrOf lv -> TAddrOf (lval_to_term_lval lv) , ctyp + | BinOp (op, a, b, _) -> + if is_boolean_binop op then + let tc = expr_to_boolean e in + Tif( tc , Cil.lone ~loc () , Cil.lzero ~loc () ), + Linteger + else begin match is_float_binop op typ with + | Some phi -> + let va = expr_to_term a in + let vb = expr_to_term b in + Tapp(phi,[],[va;vb]) , ctyp + | None -> + let va = expr_to_term ~coerce:true a in + let vb = expr_to_term ~coerce:true b in + TBinOp(op,va,vb) , coerced typ end - | UnOp (op, u, _) -> - let u' = expr_to_term_coerce ~cast u in - let u' = - match op with - | Cil_types.LNot -> - (match u'.term_node with - | TCastE(_, t) when is_boolean_type t.term_type -> t - | _ when is_boolean_type u'.term_type -> u' - | _ when is_zero_comparable u' -> - scalar_term_to_boolean u' - | _ -> - Kernel.fatal - "expr_to_term: unexpected argument of ! operator %a, \ - converted to %a" - Cil_printer.pp_exp u Cil_printer.pp_term u') - | _ -> u' - in - (* See comments for binop case above. *) - let tcast = match op, cast with - | Cil_types.LNot, _ -> Some Logic_const.boolean_type - | _, true -> Some (typ_to_logic_type typ) - | _, false -> None - in - let tnode = TUnOp (op, u') in - begin match tcast with - | Some lt -> (mk_cast typ (Logic_const.term tnode lt)).term_node - | None -> tnode + | UnOp (LNot, c, _) -> + let tc = expr_to_boolean c in + Tif( tc , Cil.lzero ~loc () , Cil.lone ~loc () ), + Linteger + | UnOp(op, a, _) -> + begin match is_float_unop op typ with + | Some phi -> + let va = expr_to_term ~coerce:true a in + Tapp(phi,[],[va]) , ctyp + | None -> + let va = expr_to_term ~coerce:true a in + TUnOp(op,va) , coerced typ end - | AlignOfE e -> TAlignOfE (expr_to_term ~cast e) - | AlignOf typ -> TAlignOf typ - | Lval lv -> TLval (lval_to_term_lval ~cast lv) - | Info (e,_) -> (expr_to_term ~cast e).term_node + | SizeOf t -> TSizeOf t, ctyp + | SizeOfE e -> TSizeOf (Cil.typeOf e), ctyp + | SizeOfStr s -> TSizeOfStr s, ctyp + | AlignOf typ -> TAlignOf typ, ctyp + | AlignOfE e -> TAlignOf (Cil.typeOf e), ctyp + | Lval lv -> TLval (lval_to_term_lval lv), ctyp + | CastE (ty,e) -> + let t = mk_cast ~loc ty (expr_to_term ~coerce e) in + t.term_node , t.term_type + | Info (e,_) -> + let t = expr_to_term ~coerce e in + t.term_node , t.term_type in - let tres = Logic_const.term ~loc result (Ctype typ) in - if cast then tres - else - match e.enode with - (* all immediate values keep their C type by default, and are only lifted - to integer/real if needed. *) - | Const _ | Lval _ | CastE _ -> tres - | _ -> numeric_coerce (typ_to_logic_type typ) tres - -and expr_to_term_coerce ~cast e = - let t = expr_to_term ~cast e in - match Logic_const.unroll_ltdef t.term_type with - | Ctype typ when Cil.isIntegralType typ || Cil.isFloatingType typ -> - let ltyp = typ_to_logic_type typ in - numeric_coerce ltyp t - | _ -> t + let v = mk_cast ~loc typ @@ Logic_const.term ~loc node ltyp in + match typ with + | TInt _ when coerce -> numeric_coerce Linteger v + | TFloat _ when coerce -> numeric_coerce Lreal v + | _ -> v -and lval_to_term_lval ~cast (host,offset) = - host_to_term_host ~cast host, offset_to_term_offset ~cast offset +and lval_to_term_lval (host,offset) = + host_to_term_lhost host, offset_to_term_offset offset -and host_to_term_host ~cast = function +and host_to_term_lhost = function | Var s -> TVar (Cil.cvar_to_lvar s) - | Mem e -> TMem (expr_to_term ~cast e) (*no need of numeric coercion - pointer *) + | Mem e -> TMem (expr_to_term e) -and offset_to_term_offset ~cast:cast = function +and offset_to_term_offset = function | NoOffset -> TNoOffset + | Field (fi,off) -> + TField(fi,offset_to_term_offset off) | Index (e,off) -> - TIndex (expr_to_term_coerce ~cast e,offset_to_term_offset ~cast off) - | Field (fi,off) -> TField(fi,offset_to_term_offset ~cast off) + TIndex (expr_to_term ~coerce:true e,offset_to_term_offset off) -and expr_to_predicate ~cast e = +and expr_to_boolean e = let open Cil_types in + let tbool n = Logic_const.term n Logic_const.boolean_type in match e.enode with - | BinOp ((Lt | Gt | Le | Ge | Eq | Ne as op), l, r, _) -> - let tl = expr_to_term ~cast l in - let tr = expr_to_term ~cast r in - let rel = match op with - | Lt -> Rlt | Gt -> Rgt | Le -> Rle | Ge -> Rge | Eq -> Req | Ne -> Rneq - | _ -> assert false - in - let pred = Prel (rel, tl, tr) in - Logic_const.new_predicate (Logic_const.unamed ~loc:e.eloc pred) + | UnOp(BNot, a,_) -> + tbool @@ TUnOp(BNot, expr_to_boolean a) + | BinOp((BAnd|BOr) as op,a,b,_) -> + let va = expr_to_boolean a in + let vb = expr_to_boolean b in + tbool @@ TBinOp(op,va,vb) + | BinOp(op, a, b, _) when is_boolean_binop op -> + let va = expr_to_term ~coerce:true a in + let vb = expr_to_term ~coerce:true b in + tbool @@ TBinOp(op,va,vb) | _ -> - let t = expr_to_term ~cast e in + let t = expr_to_term ~coerce:true e in if is_zero_comparable t then - Logic_const.new_predicate (scalar_term_to_predicate t) + scalar_term_to_boolean t else Kernel.fatal "Cannot convert into predicate the C expression %a" Cil_printer.pp_exp e +and expr_to_predicate e = + let open Cil_types in + let unamed = Logic_const.unamed ~loc:e.eloc in + let prel r a b = + let va = expr_to_term ~coerce:true a in + let vb = expr_to_term ~coerce:true b in + unamed @@ Prel(r,va,vb) + in match e.enode with + | BinOp(Lt, a, b, _) -> prel Rlt a b + | BinOp(Le, a, b, _) -> prel Rle a b + | BinOp(Gt, a, b, _) -> prel Rgt a b + | BinOp(Ge, a, b, _) -> prel Rge a b + | BinOp(Eq, a, b, _) -> prel Req a b + | BinOp(Ne, a, b, _) -> prel Rneq a b + | BinOp(BAnd, a, b, _) -> + unamed @@ Pand(expr_to_predicate a,expr_to_predicate b) + | BinOp(BOr, a, b, _) -> + unamed @@ Por(expr_to_predicate a,expr_to_predicate b) + | UnOp(BNot, a, _) -> + unamed @@ Pnot(expr_to_predicate a) + | _ -> + let t = expr_to_term ~coerce:true e in + if is_zero_comparable t then + scalar_term_to_predicate t + else + Kernel.fatal + "Cannot convert into predicate the C expression %a" + Cil_printer.pp_exp e + +and expr_to_ipredicate e = + Logic_const.new_predicate (expr_to_predicate e) + (* ************************************************************************* *) (** {1 Various utilities} *) (* ************************************************************************* *) @@ -513,8 +550,8 @@ let array_with_range arr size = let arr = Cil.stripCasts arr in let typ_arr = typeOf arr in let no_cast = isAnyCharPtrType typ_arr || isAnyCharArrayType typ_arr in - let char_ptr = typ_to_logic_type Cil.charPtrType in - let arr = expr_to_term ~cast:true arr in + let char_ptr = Ctype Cil.charPtrType in + let arr = expr_to_term arr in let arr = if no_cast then arr else mk_cast ~loc Cil.charPtrType arr diff --git a/src/kernel_services/ast_queries/logic_utils.mli b/src/kernel_services/ast_queries/logic_utils.mli index 3853a02c250..25dff3363f4 100644 --- a/src/kernel_services/ast_queries/logic_utils.mli +++ b/src/kernel_services/ast_queries/logic_utils.mli @@ -86,7 +86,7 @@ val logicCType : logic_type -> typ val array_to_ptr : logic_type -> logic_type (** C type to logic type, with implicit conversion for arithmetic types. *) -val typ_to_logic_type : typ -> logic_type +val coerced : typ -> logic_type (** {2 Predicates} *) @@ -157,36 +157,62 @@ val pointer_comparable: ?loc:location -> term -> term -> predicate (** \pointer_comparable @since Fluorine-20130401 *) -(** {2 Conversion from exp to term} - - translates a C expression into an "equivalent" logical term. - [cast] specifies how C arithmetic operators are translated. - When [cast] is [true], the translation returns a logic [term] having the - same semantics of the C [expr] by introducing casts (i.e. the C expr [a+b] - can be translated as [(char)(((char)a)+(char)b)] to preserve the modulo - feature of the C addition). - Otherwise, no such casts are introduced and the C arithmetic operators are - translated into perfect mathematical operators (i.e. a floating point - addition is translated into an addition of [real] numbers). - @plugin development guide *) -val expr_to_term : cast:bool -> exp -> term +(** {2 Conversion from exp to term} *) -(** same as {!expr_to_term}, except that if the new term has an arithmetic - type, it is automatically coerced into real (or integer for integral types). +val expr_to_term : ?coerce:bool -> exp -> term +(** Returns a logic term that has exactly the same semantics than the + original C-expression. The type of the resulting term is determined + by the [~coerce] flag as follows: + - when [~coerce:false] is given (the default) the term has the same + c-type than the original expression. + - when [~coerce:true] is given, if the original expression has an int or + float type, then the returned term is coerced into the integer or real + logic type, respectively. - @since Magnesium-20151001 + Remark: when the original expression is a comparison, it is evaluated as + a [_Bool] or [integer] depending on the [~coerce] flag. + To obtain a boolean or predicate, use [expr_to_boolean] or + [expr_to_predicate] instead. + + @modify Frama-C+dev +*) + +val expr_to_predicate: exp -> predicate +(** Returns a predicate semantically equivalent to the condition + of the original C-expression. + + This is different than [expr_to_term e |> scalar_term_to_predicate] + since it directly translate C-relations into logic ones. + + @raise Fatal error if the expression is not a comparison and cannot be + compared to zero. + @since Sulfur-20171101 + @modify Frama-C+dev *) -val expr_to_term_coerce: cast:bool -> exp -> term -val expr_to_predicate: cast:bool -> exp -> identified_predicate -(** same as {expr_to_term}, but the result is a predicate. Expressions starting - with relational operators ([==], [<=], etc) are translated directly. - Otherwise, the result of [expr_to_predicate e] is the predicate - [e <> 0]. +val expr_to_ipredicate: exp -> identified_predicate +(** Returns a predicate semantically equivalent to the condition + of the original C-expression. + + Identical to [expr_to_predicate e |> Logic_const.new_predicate]. + + @raise Fatal error if the expression is not a comparison and cannot be + compared to zero. + @since Sulfur-20171101 + @modify Frama-C+dev +*) + +val expr_to_boolean: exp -> term +(** Returns a boolean term semantically equivalent to the condition + of the original C-expression. + + This is different than [expr_to_term e |> scalar_term_to_predicate] + since it directly translate C-relations into logic ones. @raise Fatal error if the expression is not a comparison and cannot be compared to zero. @since Sulfur-20171101 + @modify Frama-C+dev *) val is_zero_comparable: term -> bool @@ -212,10 +238,9 @@ val scalar_term_to_predicate: term -> predicate @since Sulfur-20171101 *) -val lval_to_term_lval : cast:bool -> lval -> term_lval -val host_to_term_host : cast:bool -> lhost -> term_lhost -val offset_to_term_offset : - cast:bool -> offset -> term_offset +val lval_to_term_lval : lval -> term_lval +val host_to_term_lhost : lhost -> term_lhost +val offset_to_term_offset : offset -> term_offset val constant_to_lconstant: constant -> logic_constant val lconstant_to_constant: logic_constant-> constant diff --git a/src/kernel_services/ast_transformations/inline.ml b/src/kernel_services/ast_transformations/inline.ml index 5cdbfc0f1e2..c078078909a 100644 --- a/src/kernel_services/ast_transformations/inline.ml +++ b/src/kernel_services/ast_transformations/inline.ml @@ -96,7 +96,7 @@ let inline_call loc caller callee return args = method! vterm_lval (host,offset) = match host, return with | TResult _, Some lv -> - let tlv = Logic_utils.lval_to_term_lval ~cast:false lv in + let tlv = Logic_utils.lval_to_term_lval lv in let offset = Visitor.visitFramacTermOffset self offset in Cil.ChangeToPost (Logic_const.addTermOffsetLval offset tlv, Extlib.id) diff --git a/src/plugins/aorai/aorai_dataflow.ml b/src/plugins/aorai/aorai_dataflow.ml index e869e3dd345..554af1f3639 100644 --- a/src/plugins/aorai/aorai_dataflow.ml +++ b/src/plugins/aorai/aorai_dataflow.ml @@ -449,7 +449,7 @@ module Computer(I: Init) = struct "too few arguments in call to %a" Printer.pp_varinfo f | p::prms, a::args -> let lv = Logic_const.tvar (Cil.cvar_to_lvar p) in - let la = Logic_utils.expr_to_term ~cast:false a in + let la = Logic_utils.expr_to_term a in let value = Cil_datatype.Term.Map.add la (Fixed 0) Cil_datatype.Term.Map.empty diff --git a/src/plugins/aorai/aorai_utils.ml b/src/plugins/aorai/aorai_utils.ml index ff3c2f3a3fe..c4fb25191c1 100644 --- a/src/plugins/aorai/aorai_utils.ml +++ b/src/plugins/aorai/aorai_utils.ml @@ -138,7 +138,7 @@ let isCrossableAtInit tr func = let rec aux t = match t.term_node with | TConst (LEnum ei) -> - aux (Logic_utils.expr_to_term ~cast:false ei.eival) + aux (Logic_utils.expr_to_term ei.eival) | TLval lv -> (match aux_lv lv with | Some t -> t @@ -241,7 +241,7 @@ let isCrossableAtInit tr func = and aux_init off initinfo = match off, initinfo with | TNoOffset, SingleInit e -> - Some (aux (Logic_utils.expr_to_term ~cast:false e)) + Some (aux (Logic_utils.expr_to_term e)) | TIndex(t,oth), CompoundInit (ct,initl) -> (match (aux t).term_node with | TConst(Integer(i1,_)) -> @@ -653,7 +653,7 @@ let one_term () = Cil.lconstant Integer.one (** Returns a term representing the variable associated to the given varinfo *) let mk_term_from_vi vi = Logic_const.term - (TLval((Logic_utils.lval_to_term_lval ~cast:true (Cil.var vi)))) + (TLval((Logic_utils.lval_to_term_lval (Cil.var vi)))) (Ctype Cil.intType) (** Given an lval term 'host' and an integer value 'off', it returns a lval term host[off]. *) @@ -681,8 +681,7 @@ let mk_offseted_array_states_as_enum host off = (Ctype Cil.intType) (** Returns a lval term associated to the curState generated variable. *) -let host_state_term() = - lval_to_term_lval ~cast:true (state_lval()) +let host_state_term() = lval_to_term_lval (state_lval()) (* (** Returns a lval term associated to the curStateOld generated variable. *) let host_stateOld_term () = diff --git a/src/plugins/instantiate/basic_blocks.ml b/src/plugins/instantiate/basic_blocks.ml index 660db8c83c0..744917afbad 100644 --- a/src/plugins/instantiate/basic_blocks.ml +++ b/src/plugins/instantiate/basic_blocks.ml @@ -131,7 +131,7 @@ let rec tunref_range ?loc ptr len = and tunref_range_unfold ?loc lval typ = match typ with | Ctype(TArray(typ, Some e, _, _)) -> - let len = Logic_utils.expr_to_term ~cast:false e in + let len = Logic_utils.expr_to_term ~coerce:true e in let last = tminus ?loc len (tinteger ?loc 1) in let range = trange ?loc (Some (tinteger ?loc 0), Some last) in let lval = addTermOffsetLval (TIndex(range, TNoOffset)) lval in @@ -218,7 +218,7 @@ and pall_elems_eq ?loc depth t1 t2 len = and peq_unfold ?loc depth t1 t2 = match Logic_utils.unroll_type t1.term_type with | Ctype(TArray(_, Some len, _, _)) -> - let len = Logic_utils.expr_to_term ~cast:false len in + let len = Logic_utils.expr_to_term ~coerce:true len in pall_elems_eq ?loc depth t1 t2 len | _ -> prel ?loc (Req, t1, t2) @@ -236,7 +236,7 @@ and punfold_pred ?loc ?(dyn_len = None) depth t1 pred = | Ctype(TArray(_, opt_len, _, _)) -> let len = match opt_len, dyn_len with - | Some len, None -> Logic_utils.expr_to_term ~cast:false len + | Some len, None -> Logic_utils.expr_to_term ~coerce:true len | _ , Some len -> len | None, None -> Options.fatal "Unfolding array: cannot find a length" diff --git a/src/plugins/occurrence/register_gui.ml b/src/plugins/occurrence/register_gui.ml index aafb865f349..d7b8da68dfc 100644 --- a/src/plugins/occurrence/register_gui.ml +++ b/src/plugins/occurrence/register_gui.ml @@ -127,7 +127,7 @@ let occurrence_highlighter buffer loc ~start ~stop = | PTermLval (_,ki,_,term_lval) -> let same_tlval (_kf, k, l) = Logic_utils.is_same_tlval - (Logic_utils.lval_to_term_lval ~cast:true l) + (Logic_utils.lval_to_term_lval l) term_lval && Kinstr.equal k ki in diff --git a/src/plugins/studia/studia_gui.ml b/src/plugins/studia/studia_gui.ml index a235a6f490b..65638eed878 100644 --- a/src/plugins/studia/studia_gui.ml +++ b/src/plugins/studia/studia_gui.ml @@ -54,7 +54,7 @@ let get_lval_opt main_ui kf localizable = match localizable with | Pretty_source.PLval (Some _kf, (Kstmt _stmt), lv) -> let lv_txt = Pretty_utils.to_string Printer.pp_lval lv in - let tlv = Logic_utils.lval_to_term_lval ~cast:false lv in + let tlv = Logic_utils.lval_to_term_lval lv in Some (lv_txt, tlv) | Pretty_source.PTermLval (Some _kf, (Kstmt _stmt), _, tlv) -> let tlv_txt = Pretty_utils.to_string Printer.pp_term_lval tlv in diff --git a/src/plugins/value/domains/traces_domain.ml b/src/plugins/value/domains/traces_domain.ml index 1761500f38f..72492be5df5 100644 --- a/src/plugins/value/domains/traces_domain.ml +++ b/src/plugins/value/domains/traces_domain.ml @@ -1080,10 +1080,12 @@ let rec stmts_of_cfg cfg current var_map locals return_exp acc = | Assume (_, exp,b) -> let exp = subst_in_exp var_map exp in - let predicate = (Logic_utils.expr_to_predicate ~cast:true exp).Cil_types.ip_content in + let predicate = Logic_utils.expr_to_predicate exp in let predicate = if b then predicate else Logic_const.pnot predicate in - let code_annot = Logic_const.new_code_annotation(Cil_types.AAssert([],Assert,predicate)) in - let stmt = Cil.mkStmtOneInstr ~valid_sid (Cil_types.Code_annot(code_annot,dummy_loc)) in + let code_node = Cil_types.AAssert([],Assert,predicate) in + let code_annot = Logic_const.new_code_annotation code_node in + let stmt_kind = Cil_types.Code_annot(code_annot,exp.eloc) in + let stmt = Cil.mkStmtOneInstr ~valid_sid stmt_kind in stmts_of_cfg cfg n var_map locals return_exp (stmt::acc) | EnterScope (_, vs) -> diff --git a/src/plugins/wp/LogicSemantics.ml b/src/plugins/wp/LogicSemantics.ml index 2a90684fe56..b15809c85bb 100644 --- a/src/plugins/wp/LogicSemantics.ml +++ b/src/plugins/wp/LogicSemantics.ml @@ -1027,7 +1027,7 @@ struct (* -------------------------------------------------------------------------- *) let assigned_of_lval env ~unfold (lv : Cil_types.lval) = - assignable_lval env ~unfold (Logic_utils.lval_to_term_lval ~cast:false lv) + assignable_lval env ~unfold (Logic_utils.lval_to_term_lval lv) let assigned_of_froms env ~unfold froms = List.concat diff --git a/tests/spec/expr_to_term.ml b/tests/spec/expr_to_term.ml index 17478ac46f1..e6fb35a7376 100644 --- a/tests/spec/expr_to_term.ml +++ b/tests/spec/expr_to_term.ml @@ -14,7 +14,7 @@ let check_expr_term check fct s e = | (_, { ip_content = { pred_content = Papp(_,_,[l;_]) } }) -> l | _ -> Kernel.fatal "Unexpected ensures %a" Printer.pp_post_cond e in - let term' = Logic_utils.expr_to_term ~cast:false exp in + let term' = Logic_utils.expr_to_term ~coerce:true exp in let term' = Logic_utils.mk_cast Cil.intType term' in if check && not (Cil_datatype.Term.equal term term') then Kernel.fatal @@ -29,7 +29,7 @@ let treat_fct check fct = let stmts = (Kernel_function.get_definition fct).sbody.bstmts in let stmts = List.filter - (function + (function { skind = Instr (Set (lv,_,_)) } -> (match lv with (Var v,_) -> v.vglob | _ -> true) | { skind = If _ } -> true @@ -41,7 +41,7 @@ let treat_fct check fct = (* A bit fragile, but should do the trick as long as the test itself does not get too complicated (regarding the C code at least). *) if not (List.length stmts = List.length ensures) then - Kernel.fatal + Kernel.fatal "Stmts:@\n%a@\nPreds:@\n%a@\n" (Pretty_utils.pp_list ~sep:"@\n@\n" Printer.pp_stmt) stmts (Pretty_utils.pp_list ~sep:"@\n@\n" Printer.pp_post_cond) ensures; -- GitLab From 6a2cbd4b639cd20cdead0669b9f3c8ef7d753b0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Loi=CC=88c=20Correnson?= <loic.correnson@cea.fr> Date: Tue, 31 Mar 2020 09:50:03 +0200 Subject: [PATCH 066/218] [kernel] cast & coerce simpifications --- src/kernel_services/ast_queries/cil.ml | 9 ++++- src/kernel_services/ast_queries/cil.mli | 3 ++ .../ast_queries/logic_utils.ml | 34 ++++++++----------- 3 files changed, 26 insertions(+), 20 deletions(-) diff --git a/src/kernel_services/ast_queries/cil.ml b/src/kernel_services/ast_queries/cil.ml index d9330b5ab30..a3de91f6122 100644 --- a/src/kernel_services/ast_queries/cil.ml +++ b/src/kernel_services/ast_queries/cil.ml @@ -3063,6 +3063,13 @@ let intKindForValue i (unsigned: bool) = else if fitsInInt ILongLong i then ILongLong else raise Not_representable +(* True is an double constant is finite for a kind *) +let isFiniteFloat fk v = + Floating_point.isfinite @@ + match fk with + | FFloat -> Floating_point.round_to_single_precision_float v + | _ -> v + (* Construct an integer constant with possible truncation if the kind is not specified *) let kinteger64 ~loc ?repr ?kind i = @@ -3631,7 +3638,7 @@ let typeOf_array_elem t = let no_op_coerce typ t = match typ with - | Lreal -> true + | Lreal -> isLogicRealOrFloatType t.term_type | Linteger -> isLogicIntegralType t.term_type | Ltype _ when Logic_const.is_boolean_type typ -> isLogicPureBooleanType t.term_type diff --git a/src/kernel_services/ast_queries/cil.mli b/src/kernel_services/ast_queries/cil.mli index c372bb6514c..9e47d0eedd8 100644 --- a/src/kernel_services/ast_queries/cil.mli +++ b/src/kernel_services/ast_queries/cil.mli @@ -2136,6 +2136,9 @@ val max_unsigned_number: int -> Integer.t (** True if the integer fits within the kind's range *) val fitsInInt: ikind -> Integer.t -> bool +(** True if the float is finite for the kind's range *) +val isFiniteFloat: fkind -> float -> bool + exception Not_representable (** raised by {!intKindForValue}. *) diff --git a/src/kernel_services/ast_queries/logic_utils.ml b/src/kernel_services/ast_queries/logic_utils.ml index 8a43475ab1c..c79a9d15400 100644 --- a/src/kernel_services/ast_queries/logic_utils.ml +++ b/src/kernel_services/ast_queries/logic_utils.ml @@ -307,29 +307,25 @@ let string_to_float_lconstant string = LReal { r_nearest = f.f_nearest; r_upper = f.f_upper; r_lower = f.f_lower; r_literal = string } +let mk_coerce ltyp t = + Logic_const.term ~loc:t.term_loc (TLogic_coerce(ltyp, t)) ltyp + let numeric_coerce ltyp t = - let coerce t = - Logic_const.term ~loc:t.term_loc (TLogic_coerce(ltyp, t)) ltyp - in let oldt = unroll_type t.term_type in if Cil_datatype.Logic_type.equal oldt ltyp then t else match t.term_node with - | TLogic_coerce(t,e) when Cil.no_op_coerce t e -> coerce e - | TConst(Integer(i,_)) -> - (match oldt, ltyp with - | Ctype (TInt(ikind,_)), Linteger when Cil.fitsInInt ikind i -> - { t with term_type = Linteger } - | _ -> coerce t) - | TCastE(typ, ({ term_node = TConst(Integer(i,_))} as t')) -> - (match unrollType typ with - | TInt (ikind,_) when Cil.fitsInInt ikind i -> - (match unroll_type t'.term_type with - | Linteger -> t' - | Ctype (TInt (ikind,_)) when Cil.fitsInInt ikind i -> - { t' with term_type = Linteger } - | _ -> coerce t') - | _ -> coerce t) - | _ -> coerce t + | TLogic_coerce(lt,e) when Cil.no_op_coerce lt e -> mk_coerce ltyp e + | TConst(Integer _) when ltyp = Linteger -> { t with term_type = Linteger } + | TConst(LReal _ ) when ltyp = Lreal -> { t with term_type = Lreal } + | TCastE(ty,e) -> + begin match ltyp, Cil.unrollType ty, e.term_node with + | Linteger, TInt(ik,_), TConst(Integer(v,_)) + when Cil.fitsInInt ik v -> { e with term_type = Linteger } + | Lreal, TFloat(fk,_), TConst(LReal r) + when Cil.isFiniteFloat fk r.r_nearest -> { e with term_type = Lreal } + | _ -> mk_coerce ltyp t + end + | _ -> mk_coerce ltyp t (* Don't forget to keep is_zero_comparable and scalar_term_to_predicate in sync. *) -- GitLab From 7b40de168d895cffa57f95230f61af87121c19bf Mon Sep 17 00:00:00 2001 From: Andre Maroneze <andre.oliveiramaroneze@cea.fr> Date: Mon, 30 Mar 2020 16:24:48 +0200 Subject: [PATCH 067/218] [Userman] add diagram about source preparation --- doc/userman/source-preparation.graphml | 780 +++++++++++++++++++++++++ doc/userman/source-preparation.pdf | Bin 0 -> 169710 bytes doc/userman/user-sources.tex | 25 + 3 files changed, 805 insertions(+) create mode 100644 doc/userman/source-preparation.graphml create mode 100644 doc/userman/source-preparation.pdf diff --git a/doc/userman/source-preparation.graphml b/doc/userman/source-preparation.graphml new file mode 100644 index 00000000000..a62a5c58f6c --- /dev/null +++ b/doc/userman/source-preparation.graphml @@ -0,0 +1,780 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:java="http://www.yworks.com/xml/yfiles-common/1.0/java" xmlns:sys="http://www.yworks.com/xml/yfiles-common/markup/primitives/2.0" xmlns:x="http://www.yworks.com/xml/yfiles-common/markup/2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:y="http://www.yworks.com/xml/graphml" xmlns:yed="http://www.yworks.com/xml/yed/3" xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://www.yworks.com/xml/schema/graphml/1.1/ygraphml.xsd"> + <!--Created by yEd 3.19--> + <key attr.name="Description" attr.type="string" for="graph" id="d0"/> + <key for="port" id="d1" yfiles.type="portgraphics"/> + <key for="port" id="d2" yfiles.type="portgeometry"/> + <key for="port" id="d3" yfiles.type="portuserdata"/> + <key attr.name="url" attr.type="string" for="node" id="d4"/> + <key attr.name="description" attr.type="string" for="node" id="d5"/> + <key for="node" id="d6" yfiles.type="nodegraphics"/> + <key for="graphml" id="d7" yfiles.type="resources"/> + <key attr.name="url" attr.type="string" for="edge" id="d8"/> + <key attr.name="description" attr.type="string" for="edge" id="d9"/> + <key for="edge" id="d10" yfiles.type="edgegraphics"/> + <graph edgedefault="directed" id="G"> + <data key="d0"/> + <node id="n0"> + <data key="d6"> + <y:ShapeNode> + <y:Geometry height="233.5" width="1144.0" x="167.625" y="608.3519359999999"/> + <y:Fill hasColor="false" transparent="false"/> + <y:BorderStyle color="#FF9900" raised="false" type="line" width="3.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Noto Sans" fontSize="20" fontStyle="bold" hasBackgroundColor="false" hasLineColor="false" height="31.239974975585938" horizontalTextPosition="center" iconTextGap="4" modelName="eight_pos" modelPosition="s" textColor="#FF9900" verticalTextPosition="bottom" visible="true" width="113.41987609863281" x="515.2900619506836" y="237.5">frama-c *.c</y:NodeLabel> + <y:Shape type="roundrectangle"/> + </y:ShapeNode> + </data> + </node> + <node id="n1"> + <data key="d6"> + <y:ShapeNode> + <y:Geometry height="247.75" width="393.75" x="180.125" y="601.3519359999999"/> + <y:Fill hasColor="false" transparent="false"/> + <y:BorderStyle color="#3366FF" raised="false" type="dashed" width="2.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Noto Sans" fontSize="20" fontStyle="italic" hasBackgroundColor="false" hasLineColor="false" height="31.239974975585938" horizontalTextPosition="center" iconTextGap="4" modelName="eight_pos" modelPosition="s" textColor="#3366FF" verticalTextPosition="bottom" visible="true" width="269.4997863769531" x="62.12510681152344" y="251.75">delegated to a C preprocessor</y:NodeLabel> + <y:Shape type="roundrectangle"/> + </y:ShapeNode> + </data> + </node> + <node id="n2"> + <data key="d6"> + <y:ShapeNode> + <y:Geometry height="233.5" width="1144.0" x="167.625" y="344.8519359999999"/> + <y:Fill hasColor="false" transparent="false"/> + <y:BorderStyle color="#3366FF" raised="false" type="line" width="3.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Noto Sans" fontSize="20" fontStyle="bold" hasBackgroundColor="false" hasLineColor="false" height="31.239974975585938" horizontalTextPosition="center" iconTextGap="4" modelName="eight_pos" modelPosition="n" textColor="#3366FF" verticalTextPosition="bottom" visible="true" width="69.2999267578125" x="537.3500366210938" y="-35.23997497558594">gcc *.c</y:NodeLabel> + <y:Shape type="roundrectangle"/> + </y:ShapeNode> + </data> + </node> + <node id="n3"> + <data key="d6"> + <y:ShapeNode> + <y:Geometry height="73.0" width="113.0" x="191.0" y="367.0"/> + <y:Fill color="#C0C0C0" transparent="false"/> + <y:BorderStyle hasColor="false" raised="false" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Noto Sans" fontSize="20" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="31.239974975585938" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="93.57991027832031" x="9.710044860839844" y="20.88001251220703">source1.c<y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:Shape type="rectangle"/> + </y:ShapeNode> + </data> + </node> + <node id="n4"> + <data key="d6"> + <y:ShapeNode> + <y:Geometry height="73.0" width="113.0" x="504.0" y="367.0"/> + <y:Fill color="#C0C0C0" transparent="false"/> + <y:BorderStyle hasColor="false" raised="false" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Noto Sans" fontSize="20" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="31.239974975585938" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="89.13990783691406" x="11.930046081542969" y="20.88001251220703">source1.i<y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:Shape type="rectangle"/> + </y:ShapeNode> + </data> + </node> + <node id="n5"> + <data key="d6"> + <y:ShapeNode> + <y:Geometry height="73.0" width="113.0" x="783.75" y="367.0"/> + <y:Fill color="#C0C0C0" transparent="false"/> + <y:BorderStyle hasColor="false" raised="false" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Noto Sans" fontSize="20" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="58.479949951171875" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="64.5399169921875" x="24.23004150390625" y="7.2600250244140625">partial +AST<y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:Shape type="rectangle"/> + </y:ShapeNode> + </data> + </node> + <node id="n6"> + <data key="d6"> + <y:ShapeNode> + <y:Geometry height="73.0" width="113.0" x="978.75" y="485.0"/> + <y:Fill color="#C0C0C0" transparent="false"/> + <y:BorderStyle hasColor="false" raised="false" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Noto Sans" fontSize="20" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="31.239974975585938" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="96.07991027832031" x="8.460044860839844" y="20.88001251220703">source2.o<y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:Shape type="rectangle"/> + </y:ShapeNode> + </data> + </node> + <node id="n7"> + <data key="d6"> + <y:ShapeNode> + <y:Geometry height="73.0" width="113.0" x="1162.75" y="425.0"/> + <y:Fill color="#C0C0C0" transparent="false"/> + <y:BorderStyle hasColor="false" raised="false" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Noto Sans" fontSize="20" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="31.239974975585938" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="106.27986145019531" x="3.3600692749023438" y="20.88001251220703">executable<y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:Shape type="rectangle"/> + </y:ShapeNode> + </data> + </node> + <node id="n8"> + <data key="d6"> + <y:ShapeNode> + <y:Geometry height="73.0" width="113.0" x="191.0" y="485.0"/> + <y:Fill color="#C0C0C0" transparent="false"/> + <y:BorderStyle hasColor="false" raised="false" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Noto Sans" fontSize="20" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="31.239974975585938" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="93.57991027832031" x="9.710044860839844" y="20.88001251220703">source2.c<y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:Shape type="rectangle"/> + </y:ShapeNode> + </data> + </node> + <node id="n9"> + <data key="d6"> + <y:ShapeNode> + <y:Geometry height="73.0" width="113.0" x="504.0" y="485.0"/> + <y:Fill color="#C0C0C0" transparent="false"/> + <y:BorderStyle hasColor="false" raised="false" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Noto Sans" fontSize="20" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="31.239974975585938" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="89.13990783691406" x="11.930046081542969" y="20.88001251220703">source2.i<y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:Shape type="rectangle"/> + </y:ShapeNode> + </data> + </node> + <node id="n10"> + <data key="d6"> + <y:ShapeNode> + <y:Geometry height="73.0" width="113.0" x="783.75" y="485.0"/> + <y:Fill color="#C0C0C0" transparent="false"/> + <y:BorderStyle hasColor="false" raised="false" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Noto Sans" fontSize="20" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="58.479949951171875" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="64.5399169921875" x="24.23004150390625" y="7.2600250244140625">partial +AST<y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:Shape type="rectangle"/> + </y:ShapeNode> + </data> + </node> + <node id="n11"> + <data key="d6"> + <y:ShapeNode> + <y:Geometry height="73.0" width="113.0" x="191.0" y="630.5"/> + <y:Fill color="#C0C0C0" transparent="false"/> + <y:BorderStyle hasColor="false" raised="false" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Noto Sans" fontSize="20" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="58.479949951171875" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="97.35992431640625" x="7.820037841796875" y="7.2600250244140625">source1.c +(C + ACSL)<y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:Shape type="rectangle"/> + </y:ShapeNode> + </data> + </node> + <node id="n12"> + <data key="d6"> + <y:ShapeNode> + <y:Geometry height="73.0" width="113.0" x="451.0" y="630.5"/> + <y:Fill color="#C0C0C0" transparent="false"/> + <y:BorderStyle hasColor="false" raised="false" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Noto Sans" fontSize="20" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="58.479949951171875" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="98.73989868164062" x="7.1300506591796875" y="7.2600250244140625">source1.ci +(see ¹)<y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:Shape type="rectangle"/> + </y:ShapeNode> + </data> + </node> + <node id="n13"> + <data key="d6"> + <y:ShapeNode> + <y:Geometry height="73.0" width="86.0" x="905.5" y="630.5"/> + <y:Fill color="#C0C0C0" transparent="false"/> + <y:BorderStyle hasColor="false" raised="false" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Noto Sans" fontSize="20" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="58.479949951171875" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="64.5399169921875" x="10.73004150390625" y="7.2600250244140625">partial +AST<y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:Shape type="rectangle"/> + </y:ShapeNode> + </data> + </node> + <node id="n14"> + <data key="d6"> + <y:ShapeNode> + <y:Geometry height="73.0" width="66.0" x="1012.625" y="688.5"/> + <y:Fill color="#C0C0C0" transparent="false"/> + <y:BorderStyle hasColor="false" raised="false" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Noto Sans" fontSize="20" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="31.239974975585938" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="38.879974365234375" x="13.560012817382812" y="20.88001251220703">AST<y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:Shape type="rectangle"/> + </y:ShapeNode> + </data> + </node> + <node id="n15"> + <data key="d6"> + <y:ShapeNode> + <y:Geometry height="73.0" width="113.0" x="1185.75" y="688.5"/> + <y:Fill color="#C0C0C0" transparent="false"/> + <y:BorderStyle hasColor="false" raised="false" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Noto Sans" fontSize="20" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="58.479949951171875" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="97.23988342285156" x="7.880058288574219" y="7.2600250244140625">analyses / + GUI<y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:Shape type="rectangle"/> + </y:ShapeNode> + </data> + </node> + <node id="n16"> + <data key="d6"> + <y:ShapeNode> + <y:Geometry height="73.0" width="113.0" x="191.0" y="748.5"/> + <y:Fill color="#C0C0C0" transparent="false"/> + <y:BorderStyle hasColor="false" raised="false" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Noto Sans" fontSize="20" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="58.479949951171875" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="97.35992431640625" x="7.820037841796875" y="7.2600250244140625">source2.c +(C + ACSL)<y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:Shape type="rectangle"/> + </y:ShapeNode> + </data> + </node> + <node id="n17"> + <data key="d6"> + <y:ShapeNode> + <y:Geometry height="73.0" width="113.0" x="451.0" y="748.5"/> + <y:Fill color="#C0C0C0" transparent="false"/> + <y:BorderStyle hasColor="false" raised="false" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Noto Sans" fontSize="20" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="58.479949951171875" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="98.73989868164062" x="7.1300506591796875" y="7.2600250244140625">source2.ci +(see ¹)<y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:Shape type="rectangle"/> + </y:ShapeNode> + </data> + </node> + <node id="n18"> + <data key="d6"> + <y:ShapeNode> + <y:Geometry height="73.0" width="86.0" x="905.5" y="748.5"/> + <y:Fill color="#C0C0C0" transparent="false"/> + <y:BorderStyle hasColor="false" raised="false" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Noto Sans" fontSize="20" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="58.479949951171875" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="64.5399169921875" x="10.73004150390625" y="7.2600250244140625">partial +AST<y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:Shape type="rectangle"/> + </y:ShapeNode> + </data> + </node> + <node id="n19"> + <data key="d6"> + <y:ShapeNode> + <y:Geometry height="42.0" width="146.0" x="845.5" y="704.0"/> + <y:Fill hasColor="false" transparent="false"/> + <y:BorderStyle hasColor="false" raised="false" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Noto Sans" fontSize="16" fontStyle="italic" hasBackgroundColor="false" hasLineColor="false" height="25.792043685913086" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="110.9442138671875" x="17.52789306640625" y="8.103978157043457">merging phase<y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:Shape type="rectangle"/> + </y:ShapeNode> + </data> + </node> + <node id="n20"> + <data key="d6"> + <y:ShapeNode> + <y:Geometry height="73.0" width="113.0" x="978.75" y="367.0"/> + <y:Fill color="#C0C0C0" transparent="false"/> + <y:BorderStyle hasColor="false" raised="false" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Noto Sans" fontSize="20" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="31.239974975585938" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="96.07991027832031" x="8.460044860839844" y="20.88001251220703">source1.o<y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:Shape type="rectangle"/> + </y:ShapeNode> + </data> + </node> + <node id="n21"> + <data key="d6"> + <y:ShapeNode> + <y:Geometry height="73.0" width="113.0" x="716.0" y="630.5"/> + <y:Fill color="#C0C0C0" transparent="false"/> + <y:BorderStyle hasColor="false" raised="false" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Noto Sans" fontSize="20" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="58.479949951171875" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="89.13990783691406" x="11.930046081542969" y="7.2600250244140625">source1.i +(see ²)<y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:Shape type="rectangle"/> + </y:ShapeNode> + </data> + </node> + <node id="n22"> + <data key="d6"> + <y:ShapeNode> + <y:Geometry height="36.0" width="393.75" x="292.125" y="919.248064"/> + <y:Fill hasColor="false" transparent="false"/> + <y:BorderStyle hasColor="false" raised="false" type="line" width="1.0"/> + <y:NodeLabel alignment="left" autoSizePolicy="content" fontFamily="Noto Sans" fontSize="20" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="31.239974975585938" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="400.55950927734375" x="-3.404754638671875" y="2.3800125122070312"> ¹ preprocessed C + un-preprocessed ACSL<y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:Shape type="rectangle"/> + </y:ShapeNode> + </data> + </node> + <node id="n23"> + <data key="d6"> + <y:ShapeNode> + <y:Geometry height="73.0" width="113.0" x="716.0" y="748.5"/> + <y:Fill color="#C0C0C0" transparent="false"/> + <y:BorderStyle hasColor="false" raised="false" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Noto Sans" fontSize="20" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="58.479949951171875" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="89.13990783691406" x="11.930046081542969" y="7.2600250244140625">source2.i +(see ²)<y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:Shape type="rectangle"/> + </y:ShapeNode> + </data> + </node> + <node id="n24"> + <data key="d6"> + <y:ShapeNode> + <y:Geometry height="3.599999999999909" width="522.0" x="228.0" y="896.75"/> + <y:Fill color="#C0C0C0" transparent="false"/> + <y:BorderStyle hasColor="false" raised="false" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" backgroundColor="#FFFFFF" fontFamily="Noto Sans" fontSize="20" fontStyle="bolditalic" hasLineColor="false" height="31.239974975585938" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#808080" verticalTextPosition="bottom" visible="true" width="105.11988830566406" x="227.35598505070777" y="-13.819987487793014">section 5.2<y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.03623741226731758" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:Shape type="rectangle"/> + </y:ShapeNode> + </data> + </node> + <node id="n25"> + <data key="d6"> + <y:ShapeNode> + <y:Geometry height="3.599999999999909" width="245.25" x="783.75" y="896.75"/> + <y:Fill color="#C0C0C0" transparent="false"/> + <y:BorderStyle hasColor="false" raised="false" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" backgroundColor="#FFFFFF" fontFamily="Noto Sans" fontSize="20" fontStyle="bolditalic" hasLineColor="false" height="31.239974975585938" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#808080" verticalTextPosition="bottom" visible="true" width="105.11988830566406" x="78.95228120572756" y="-13.819987487793014">section 5.3<y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.03623741226731758" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:Shape type="rectangle"/> + </y:ShapeNode> + </data> + </node> + <node id="n26"> + <data key="d6"> + <y:ShapeNode> + <y:Geometry height="3.599999999999909" width="199.79999999999995" x="1062.5499999999997" y="896.75"/> + <y:Fill color="#C0C0C0" transparent="false"/> + <y:BorderStyle hasColor="false" raised="false" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" backgroundColor="#FFFFFF" fontFamily="Noto Sans" fontSize="20" fontStyle="bolditalic" hasLineColor="false" height="31.239974975585938" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#808080" verticalTextPosition="bottom" visible="true" width="105.11988830566406" x="54.5802908181779" y="-13.819987487793014">section 5.4<y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.03623741226731758" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:Shape type="rectangle"/> + </y:ShapeNode> + </data> + </node> + <node id="n27"> + <data key="d6"> + <y:ShapeNode> + <y:Geometry height="36.0" width="393.75" x="783.75" y="919.248064"/> + <y:Fill hasColor="false" transparent="false"/> + <y:BorderStyle hasColor="false" raised="false" type="line" width="1.0"/> + <y:NodeLabel alignment="left" autoSizePolicy="content" fontFamily="Noto Sans" fontSize="20" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="31.239974975585938" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="364.19964599609375" x="4.0" y="2.3800125122070312">² preprocessed C + preprocessed ACSL<y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="-0.5" labelRatioY="0.0" nodeRatioX="-0.5" nodeRatioY="0.0" offsetX="4.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:Shape type="rectangle"/> + </y:ShapeNode> + </data> + </node> + <edge id="e0" source="n3" target="n4"> + <data key="d10"> + <y:PolyLineEdge> + <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/> + <y:LineStyle color="#000000" type="line" width="1.0"/> + <y:Arrows source="none" target="standard"/> + <y:EdgeLabel alignment="center" backgroundColor="#FFFFFF" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Noto Sans" fontSize="20" fontStyle="plain" hasLineColor="false" height="58.479949951171875" horizontalTextPosition="center" iconTextGap="4" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" verticalTextPosition="bottom" visible="true" width="138.35984802246094" x="30.82007598876953" y="-29.239974975585938">preprocessing +(-E)<y:LabelModel> + <y:SmartEdgeLabelModel autoRotationEnabled="false" defaultAngle="0.0" defaultDistance="10.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartEdgeLabelModelParameter angle="0.0" distance="30.0" distanceToCenter="true" position="center" ratio="0.5" segment="0"/> + </y:ModelParameter> + <y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/> + </y:EdgeLabel> + <y:BendStyle smoothed="false"/> + </y:PolyLineEdge> + </data> + </edge> + <edge id="e1" source="n4" target="n5"> + <data key="d10"> + <y:PolyLineEdge> + <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/> + <y:LineStyle color="#000000" type="line" width="1.0"/> + <y:Arrows source="none" target="standard"/> + <y:EdgeLabel alignment="center" backgroundColor="#FFFFFF" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Noto Sans" fontSize="20" fontStyle="plain" hasLineColor="false" height="58.479949951171875" horizontalTextPosition="center" iconTextGap="4" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" verticalTextPosition="bottom" visible="true" width="136.73985290527344" x="15.005073547363281" y="-29.239974975585938">parsing +(-fsyntax-only)<y:LabelModel> + <y:SmartEdgeLabelModel autoRotationEnabled="false" defaultAngle="0.0" defaultDistance="10.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartEdgeLabelModelParameter angle="0.0" distance="30.0" distanceToCenter="true" position="center" ratio="0.5" segment="0"/> + </y:ModelParameter> + <y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/> + </y:EdgeLabel> + <y:BendStyle smoothed="false"/> + </y:PolyLineEdge> + </data> + </edge> + <edge id="e2" source="n20" target="n7"> + <data key="d10"> + <y:PolyLineEdge> + <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/> + <y:LineStyle color="#000000" type="line" width="1.0"/> + <y:Arrows source="none" target="standard"/> + <y:EdgeLabel alignment="center" backgroundColor="#FFFFFF" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Noto Sans" fontSize="20" fontStyle="plain" hasLineColor="false" height="31.239974975585938" horizontalTextPosition="center" iconTextGap="4" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" verticalTextPosition="bottom" visible="true" width="37.359954833984375" x="16.820022583007812" y="27.025368115416654">link<y:LabelModel> + <y:SmartEdgeLabelModel autoRotationEnabled="false" defaultAngle="0.0" defaultDistance="10.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartEdgeLabelModelParameter angle="0.0" distance="30.0" distanceToCenter="true" position="right" ratio="0.5" segment="0"/> + </y:ModelParameter> + <y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/> + </y:EdgeLabel> + <y:BendStyle smoothed="false"/> + </y:PolyLineEdge> + </data> + </edge> + <edge id="e3" source="n5" target="n20"> + <data key="d10"> + <y:PolyLineEdge> + <y:Path sx="0.0" sy="0.0" tx="9.25" ty="0.0"/> + <y:LineStyle color="#000000" type="line" width="1.0"/> + <y:Arrows source="none" target="standard"/> + <y:EdgeLabel alignment="center" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Noto Sans" fontSize="20" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" horizontalTextPosition="center" iconTextGap="4" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" verticalTextPosition="bottom" visible="true" width="4.0" x="39.0" y="-2.0"> + <y:LabelModel> + <y:SmartEdgeLabelModel autoRotationEnabled="false" defaultAngle="0.0" defaultDistance="10.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartEdgeLabelModelParameter angle="0.0" distance="30.0" distanceToCenter="true" position="center" ratio="0.5" segment="0"/> + </y:ModelParameter> + <y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/> + </y:EdgeLabel> + <y:BendStyle smoothed="false"/> + </y:PolyLineEdge> + </data> + </edge> + <edge id="e4" source="n8" target="n9"> + <data key="d10"> + <y:PolyLineEdge> + <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/> + <y:LineStyle color="#000000" type="line" width="1.0"/> + <y:Arrows source="none" target="standard"/> + <y:EdgeLabel alignment="center" backgroundColor="#FFFFFF" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Noto Sans" fontSize="20" fontStyle="plain" hasLineColor="false" height="58.479949951171875" horizontalTextPosition="center" iconTextGap="4" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" verticalTextPosition="bottom" visible="true" width="138.35984802246094" x="30.82007598876953" y="-29.239974975585938">preprocessing +(-E)<y:LabelModel> + <y:SmartEdgeLabelModel autoRotationEnabled="false" defaultAngle="0.0" defaultDistance="10.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartEdgeLabelModelParameter angle="0.0" distance="30.0" distanceToCenter="true" position="center" ratio="0.5" segment="0"/> + </y:ModelParameter> + <y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/> + </y:EdgeLabel> + <y:BendStyle smoothed="false"/> + </y:PolyLineEdge> + </data> + </edge> + <edge id="e5" source="n9" target="n10"> + <data key="d10"> + <y:PolyLineEdge> + <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/> + <y:LineStyle color="#000000" type="line" width="1.0"/> + <y:Arrows source="none" target="standard"/> + <y:EdgeLabel alignment="center" backgroundColor="#FFFFFF" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Noto Sans" fontSize="20" fontStyle="plain" hasLineColor="false" height="58.479949951171875" horizontalTextPosition="center" iconTextGap="4" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" verticalTextPosition="bottom" visible="true" width="136.73985290527344" x="15.005073547363281" y="-29.239974975585938">parsing +(-fsyntax-only)<y:LabelModel> + <y:SmartEdgeLabelModel autoRotationEnabled="false" defaultAngle="0.0" defaultDistance="10.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartEdgeLabelModelParameter angle="0.0" distance="30.0" distanceToCenter="true" position="center" ratio="0.5" segment="0"/> + </y:ModelParameter> + <y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/> + </y:EdgeLabel> + <y:BendStyle smoothed="false"/> + </y:PolyLineEdge> + </data> + </edge> + <edge id="e6" source="n10" target="n6"> + <data key="d10"> + <y:PolyLineEdge> + <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/> + <y:LineStyle color="#000000" type="line" width="1.0"/> + <y:Arrows source="none" target="standard"/> + <y:BendStyle smoothed="false"/> + </y:PolyLineEdge> + </data> + </edge> + <edge id="e7" source="n11" target="n12"> + <data key="d10"> + <y:PolyLineEdge> + <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/> + <y:LineStyle color="#000000" type="line" width="1.0"/> + <y:Arrows source="none" target="standard"/> + <y:EdgeLabel alignment="center" backgroundColor="#FFFFFF" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Noto Sans" fontSize="16" fontStyle="plain" hasLineColor="false" height="47.58408737182617" horizontalTextPosition="center" iconTextGap="4" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" verticalTextPosition="bottom" visible="true" width="111.48825073242188" x="17.755874633789062" y="-23.792043685913086">C +preprocessing<y:LabelModel> + <y:SmartEdgeLabelModel autoRotationEnabled="false" defaultAngle="0.0" defaultDistance="10.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartEdgeLabelModelParameter angle="0.0" distance="30.0" distanceToCenter="true" position="center" ratio="0.5" segment="0"/> + </y:ModelParameter> + <y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/> + </y:EdgeLabel> + <y:BendStyle smoothed="false"/> + </y:PolyLineEdge> + </data> + </edge> + <edge id="e8" source="n12" target="n21"> + <data key="d10"> + <y:PolyLineEdge> + <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/> + <y:LineStyle color="#000000" type="line" width="1.0"/> + <y:Arrows source="none" target="standard"/> + <y:EdgeLabel alignment="center" backgroundColor="#FFFFFF" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Noto Sans" fontSize="16" fontStyle="plain" hasLineColor="false" height="47.58408737182617" horizontalTextPosition="center" iconTextGap="4" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" verticalTextPosition="bottom" visible="true" width="111.48825073242188" x="20.255874633789062" y="-23.792043685913086">ACSL +preprocessing<y:LabelModel> + <y:SmartEdgeLabelModel autoRotationEnabled="false" defaultAngle="0.0" defaultDistance="10.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartEdgeLabelModelParameter angle="0.0" distance="30.0" distanceToCenter="true" position="center" ratio="0.5" segment="0"/> + </y:ModelParameter> + <y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/> + </y:EdgeLabel> + <y:BendStyle smoothed="false"/> + </y:PolyLineEdge> + </data> + </edge> + <edge id="e9" source="n14" target="n15"> + <data key="d10"> + <y:PolyLineEdge> + <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/> + <y:LineStyle color="#000000" type="line" width="1.0"/> + <y:Arrows source="none" target="standard"/> + <y:EdgeLabel alignment="center" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Noto Sans" fontSize="16" fontStyle="italic" hasBackgroundColor="false" hasLineColor="false" height="47.58408737182617" horizontalTextPosition="center" iconTextGap="4" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" verticalTextPosition="bottom" visible="true" width="103.9041748046875" x="1.61041259765625" y="-23.792043685913086">normalization +phase<y:LabelModel> + <y:SmartEdgeLabelModel autoRotationEnabled="false" defaultAngle="0.0" defaultDistance="10.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartEdgeLabelModelParameter angle="0.0" distance="30.0" distanceToCenter="true" position="center" ratio="0.0" segment="0"/> + </y:ModelParameter> + <y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/> + </y:EdgeLabel> + <y:BendStyle smoothed="false"/> + </y:PolyLineEdge> + </data> + </edge> + <edge id="e10" source="n13" target="n14"> + <data key="d10"> + <y:PolyLineEdge> + <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/> + <y:LineStyle color="#000000" type="line" width="1.0"/> + <y:Arrows source="none" target="standard"/> + <y:EdgeLabel alignment="center" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Noto Sans" fontSize="20" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" horizontalTextPosition="center" iconTextGap="4" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" verticalTextPosition="bottom" visible="true" width="4.0" x="8.5625" y="4.3076203295929645"> + <y:LabelModel> + <y:SmartEdgeLabelModel autoRotationEnabled="false" defaultAngle="0.0" defaultDistance="10.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartEdgeLabelModelParameter angle="0.0" distance="30.0" distanceToCenter="true" position="center" ratio="0.5" segment="0"/> + </y:ModelParameter> + <y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/> + </y:EdgeLabel> + <y:BendStyle smoothed="false"/> + </y:PolyLineEdge> + </data> + </edge> + <edge id="e11" source="n16" target="n17"> + <data key="d10"> + <y:PolyLineEdge> + <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/> + <y:LineStyle color="#000000" type="line" width="1.0"/> + <y:Arrows source="none" target="standard"/> + <y:EdgeLabel alignment="center" backgroundColor="#FFFFFF" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Noto Sans" fontSize="16" fontStyle="plain" hasLineColor="false" height="47.58408737182617" horizontalTextPosition="center" iconTextGap="4" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" verticalTextPosition="bottom" visible="true" width="111.48825073242188" x="17.755874633789062" y="-23.792043685913086">C +preprocessing<y:LabelModel> + <y:SmartEdgeLabelModel autoRotationEnabled="false" defaultAngle="0.0" defaultDistance="10.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartEdgeLabelModelParameter angle="0.0" distance="30.0" distanceToCenter="true" position="center" ratio="0.5" segment="0"/> + </y:ModelParameter> + <y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/> + </y:EdgeLabel> + <y:BendStyle smoothed="false"/> + </y:PolyLineEdge> + </data> + </edge> + <edge id="e12" source="n17" target="n23"> + <data key="d10"> + <y:PolyLineEdge> + <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/> + <y:LineStyle color="#000000" type="line" width="1.0"/> + <y:Arrows source="none" target="standard"/> + <y:EdgeLabel alignment="center" backgroundColor="#FFFFFF" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Noto Sans" fontSize="16" fontStyle="plain" hasLineColor="false" height="47.58408737182617" horizontalTextPosition="center" iconTextGap="4" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" verticalTextPosition="bottom" visible="true" width="111.48825073242188" x="20.255874633789062" y="-23.792043685913086">ACSL +preprocessing<y:LabelModel> + <y:SmartEdgeLabelModel autoRotationEnabled="false" defaultAngle="0.0" defaultDistance="10.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartEdgeLabelModelParameter angle="0.0" distance="30.0" distanceToCenter="true" position="center" ratio="0.5" segment="0"/> + </y:ModelParameter> + <y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/> + </y:EdgeLabel> + <y:BendStyle smoothed="false"/> + </y:PolyLineEdge> + </data> + </edge> + <edge id="e13" source="n18" target="n14"> + <data key="d10"> + <y:PolyLineEdge> + <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/> + <y:LineStyle color="#000000" type="line" width="1.0"/> + <y:Arrows source="none" target="standard"/> + <y:BendStyle smoothed="false"/> + </y:PolyLineEdge> + </data> + </edge> + <edge id="e14" source="n6" target="n7"> + <data key="d10"> + <y:PolyLineEdge> + <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/> + <y:LineStyle color="#000000" type="line" width="1.0"/> + <y:Arrows source="none" target="standard"/> + <y:EdgeLabel alignment="center" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Noto Sans" fontSize="20" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" horizontalTextPosition="center" iconTextGap="4" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" underlinedText="true" verticalTextPosition="bottom" visible="true" width="4.0" x="33.5" y="-13.576080322265625"> + <y:LabelModel> + <y:SmartEdgeLabelModel autoRotationEnabled="false" defaultAngle="0.0" defaultDistance="10.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartEdgeLabelModelParameter angle="0.0" distance="30.0" distanceToCenter="true" position="center" ratio="0.5" segment="0"/> + </y:ModelParameter> + <y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/> + </y:EdgeLabel> + <y:BendStyle smoothed="false"/> + </y:PolyLineEdge> + </data> + </edge> + <edge id="e15" source="n21" target="n13"> + <data key="d10"> + <y:PolyLineEdge> + <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/> + <y:LineStyle color="#000000" type="line" width="1.0"/> + <y:Arrows source="none" target="standard"/> + <y:EdgeLabel alignment="center" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Noto Sans" fontSize="16" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="25.792043685913086" horizontalTextPosition="center" iconTextGap="4" modelName="two_pos" modelPosition="head" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" verticalTextPosition="bottom" visible="true" width="60.944122314453125" x="7.7779388427734375" y="-27.792043685913086">parsing<y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/> + </y:EdgeLabel> + <y:BendStyle smoothed="false"/> + </y:PolyLineEdge> + </data> + </edge> + <edge id="e16" source="n23" target="n18"> + <data key="d10"> + <y:PolyLineEdge> + <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/> + <y:LineStyle color="#000000" type="line" width="1.0"/> + <y:Arrows source="none" target="standard"/> + <y:EdgeLabel alignment="center" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Noto Sans" fontSize="16" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="25.792043685913086" horizontalTextPosition="center" iconTextGap="4" modelName="two_pos" modelPosition="head" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" verticalTextPosition="bottom" visible="true" width="60.944122314453125" x="7.7779388427734375" y="-27.792043685913086">parsing<y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/> + </y:EdgeLabel> + <y:BendStyle smoothed="false"/> + </y:PolyLineEdge> + </data> + </edge> + </graph> + <data key="d7"> + <y:Resources/> + </data> +</graphml> diff --git a/doc/userman/source-preparation.pdf b/doc/userman/source-preparation.pdf new file mode 100644 index 0000000000000000000000000000000000000000..eb623d94e7b1d7762d41335b5a9a4f5a88b95434 GIT binary patch literal 169710 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≪O5P_zWnujI_~E?LZx{D)$#BH78ZH5fe2W8Ucb(( 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 literal 0 HcmV?d00001 diff --git a/doc/userman/user-sources.tex b/doc/userman/user-sources.tex index 7ac40af185f..ee189cbe97c 100644 --- a/doc/userman/user-sources.tex +++ b/doc/userman/user-sources.tex @@ -4,6 +4,31 @@ ojson\chapter{Preparing the Sources} This chapter explains how to specify the source files that form the basis of an analysis project, and describes options that influence parsing. +\section{Overview of source processing in \FramaC}\label{sec:overview} + +For small projects and tests, processing the sources in \FramaC is as simple +as running \texttt{frama-c *.c}. For more complex projects, however, +some problems may arise when using this command, and the user must be aware +of the several steps involved in \FramaC source processing to fix them. + +The diagram in Figure~\ref{fig:source-preparation} presents an overview +of the steps described in this chapter. For comparison purposes, we add +the equivalent process performed by a compiler such as GCC. + +\begin{figure}[htbp] + \begin{center} + \includegraphics[width=\textwidth]{source-preparation.pdf} + \caption{Overview of source preparation steps: as performed by GCC + (top) and as performed by \FramaC (bottom).} + \label{fig:source-preparation} + \end{center} +\end{figure} + +The following sections describe various options related to the steps shown +in the figure. Note that some plug-ins, such as \textsf{Variadic} +(described in chapter~\ref{user-variadic}), perform further AST +transformations before most analyses are run. + \section{Pre-processing the Source Files}\label{sec:preprocessing} The list of files to analyze must be provided on the command line, or -- GitLab From 96eb60c9c9b17e6c8f1c76f8d34d0c41a072222c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Loi=CC=88c=20Correnson?= <loic.correnson@cea.fr> Date: Tue, 31 Mar 2020 10:59:01 +0200 Subject: [PATCH 068/218] [kernel] unsupported long double builtins --- src/kernel_services/ast_queries/logic_utils.ml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/kernel_services/ast_queries/logic_utils.ml b/src/kernel_services/ast_queries/logic_utils.ml index c79a9d15400..b3fa33f9651 100644 --- a/src/kernel_services/ast_queries/logic_utils.ml +++ b/src/kernel_services/ast_queries/logic_utils.ml @@ -394,7 +394,8 @@ let is_boolean_binop op = let float_builtin prefix fkind = let name = match fkind with | FFloat -> Printf.sprintf "\\%s_float" prefix - | FDouble | FLongDouble -> Printf.sprintf "\\%s_double" prefix + | FDouble -> Printf.sprintf "\\%s_double" prefix + | FLongDouble -> Kernel.not_yet_implemented "Builtins for long double type" in match Logic_env.find_all_logic_functions name with | [ lf ] -> Some lf | _ -> Kernel.fatal "Missing or ambiguous builtin %S" name -- GitLab From d64d60138c258dd1527df682314d349ac4a81c1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Loi=CC=88c=20Correnson?= <loic.correnson@cea.fr> Date: Tue, 31 Mar 2020 10:59:30 +0200 Subject: [PATCH 069/218] [kernel] renaming & typos in logic utils --- src/kernel_services/ast_data/alarms.ml | 8 +++---- .../ast_queries/logic_utils.ml | 22 +++++++++---------- .../ast_queries/logic_utils.mli | 12 +++++----- 3 files changed, 21 insertions(+), 21 deletions(-) diff --git a/src/kernel_services/ast_data/alarms.ml b/src/kernel_services/ast_data/alarms.ml index 903e79bb9f0..a0845e81504 100644 --- a/src/kernel_services/ast_data/alarms.ml +++ b/src/kernel_services/ast_data/alarms.ml @@ -452,13 +452,13 @@ let overflowed_expr_to_term ~loc e = match e.enode with | UnOp(op, e, ty) -> let t = Logic_utils.expr_to_term ~coerce:true e in - let ty = Logic_utils.coerced ty in - Logic_const.term ~loc (TUnOp(op, t)) ty + let lty = Logic_utils.coerce_type ty in + Logic_const.term ~loc (TUnOp(op, t)) lty | BinOp(op, e1, e2, ty) -> let t1 = Logic_utils.expr_to_term ~coerce:true e1 in let t2 = Logic_utils.expr_to_term ~coerce:true e2 in - let ty = Logic_utils.coerced ty in - Logic_const.term ~loc (TBinOp(op, t1, t2)) ty + let lty = Logic_utils.coerce_type ty in + Logic_const.term ~loc (TBinOp(op, t1, t2)) lty | _ -> Logic_utils.expr_to_term ~coerce:true e (* Creates \is_finite((fkind)e) or \is_nan((fkind)e) according to diff --git a/src/kernel_services/ast_queries/logic_utils.ml b/src/kernel_services/ast_queries/logic_utils.ml index b3fa33f9651..18313884188 100644 --- a/src/kernel_services/ast_queries/logic_utils.ml +++ b/src/kernel_services/ast_queries/logic_utils.ml @@ -123,7 +123,7 @@ let plain_array_to_ptr ty = let array_to_ptr = plain_or_set plain_array_to_ptr -let coerced typ = +let coerce_type typ = let ty = Cil.unrollType typ in if Cil.isIntegralType ty then Linteger else if Cil.isFloatingType ty then Lreal @@ -341,7 +341,7 @@ let is_zero_comparable t = let scalar_term_conversion conversion t = let loc = t.term_loc in - let arith_conversion t = + let int_conversion t = conversion ~loc false t (Cil.lzero ~loc ()) in let real_conversion ?ltyp t = conversion ~loc false t (Logic_const.treal_zero ~loc ?ltyp ()) in @@ -351,14 +351,14 @@ let scalar_term_conversion conversion t = let ctrue = Logic_env.Logic_ctor_info.find "\\true" in conversion ~loc true t (term ~loc (TDataCons(ctrue,[])) boolean_type) in match unroll_type t.term_type with - | Ctype (TInt _) -> arith_conversion t + | Ctype (TInt _) -> int_conversion t | Ctype (TFloat _) as ltyp -> real_conversion ~ltyp t | Ctype (TPtr _) -> ptr_conversion t | Ctype (TArray _) -> ptr_conversion t (* Could be transformed to \true: an array is never \null *) | Ctype (TFun _) -> ptr_conversion t (* decay as pointer *) - | Linteger -> arith_conversion t + | Linteger -> int_conversion t | Lreal -> real_conversion t | Ltype ({lt_name = name},[]) when name = Utf8_logic.boolean -> bool_conversion t @@ -400,7 +400,7 @@ let float_builtin prefix fkind = | [ lf ] -> Some lf | _ -> Kernel.fatal "Missing or ambiguous builtin %S" name -let is_float_binop op typ = +let get_float_binop op typ = match typ, op with | TFloat(fkind,_) , PlusA -> float_builtin "add" fkind | TFloat(fkind,_) , MinusA -> float_builtin "sub" fkind @@ -408,7 +408,7 @@ let is_float_binop op typ = | TFloat(fkind,_) , Div -> float_builtin "div" fkind | _ -> None -let is_float_unop op typ = +let get_float_unop op typ = match typ, op with | TFloat(fkind,_) , Neg -> float_builtin "neg" fkind | _ -> None @@ -419,7 +419,7 @@ let rec expr_to_term ?(coerce=false) e = let ctyp = Ctype typ in let node,ltyp = match e.enode with - | Const c -> TConst (constant_to_lconstant c) , coerced typ + | Const c -> TConst (constant_to_lconstant c) , coerce_type typ | StartOf lv -> TStartOf (lval_to_term_lval lv) , ctyp | AddrOf lv -> TAddrOf (lval_to_term_lval lv) , ctyp | BinOp (op, a, b, _) -> @@ -427,7 +427,7 @@ let rec expr_to_term ?(coerce=false) e = let tc = expr_to_boolean e in Tif( tc , Cil.lone ~loc () , Cil.lzero ~loc () ), Linteger - else begin match is_float_binop op typ with + else begin match get_float_binop op typ with | Some phi -> let va = expr_to_term a in let vb = expr_to_term b in @@ -435,20 +435,20 @@ let rec expr_to_term ?(coerce=false) e = | None -> let va = expr_to_term ~coerce:true a in let vb = expr_to_term ~coerce:true b in - TBinOp(op,va,vb) , coerced typ + TBinOp(op,va,vb) , coerce_type typ end | UnOp (LNot, c, _) -> let tc = expr_to_boolean c in Tif( tc , Cil.lzero ~loc () , Cil.lone ~loc () ), Linteger | UnOp(op, a, _) -> - begin match is_float_unop op typ with + begin match get_float_unop op typ with | Some phi -> let va = expr_to_term ~coerce:true a in Tapp(phi,[],[va]) , ctyp | None -> let va = expr_to_term ~coerce:true a in - TUnOp(op,va) , coerced typ + TUnOp(op,va) , coerce_type typ end | SizeOf t -> TSizeOf t, ctyp | SizeOfE e -> TSizeOf (Cil.typeOf e), ctyp diff --git a/src/kernel_services/ast_queries/logic_utils.mli b/src/kernel_services/ast_queries/logic_utils.mli index 25dff3363f4..6f37795a6e9 100644 --- a/src/kernel_services/ast_queries/logic_utils.mli +++ b/src/kernel_services/ast_queries/logic_utils.mli @@ -86,7 +86,7 @@ val logicCType : logic_type -> typ val array_to_ptr : logic_type -> logic_type (** C type to logic type, with implicit conversion for arithmetic types. *) -val coerced : typ -> logic_type +val coerce_type : typ -> logic_type (** {2 Predicates} *) @@ -160,17 +160,17 @@ val pointer_comparable: ?loc:location -> term -> term -> predicate (** {2 Conversion from exp to term} *) val expr_to_term : ?coerce:bool -> exp -> term -(** Returns a logic term that has exactly the same semantics than the +(** Returns a logic term that has exactly the same semantics as the original C-expression. The type of the resulting term is determined by the [~coerce] flag as follows: - when [~coerce:false] is given (the default) the term has the same - c-type than the original expression. + c-type as the original expression. - when [~coerce:true] is given, if the original expression has an int or float type, then the returned term is coerced into the integer or real logic type, respectively. Remark: when the original expression is a comparison, it is evaluated as - a [_Bool] or [integer] depending on the [~coerce] flag. + an [int] or an [integer] depending on the [~coerce] flag. To obtain a boolean or predicate, use [expr_to_boolean] or [expr_to_predicate] instead. @@ -181,7 +181,7 @@ val expr_to_predicate: exp -> predicate (** Returns a predicate semantically equivalent to the condition of the original C-expression. - This is different than [expr_to_term e |> scalar_term_to_predicate] + This is different from [expr_to_term e |> scalar_term_to_predicate] since it directly translate C-relations into logic ones. @raise Fatal error if the expression is not a comparison and cannot be @@ -206,7 +206,7 @@ val expr_to_boolean: exp -> term (** Returns a boolean term semantically equivalent to the condition of the original C-expression. - This is different than [expr_to_term e |> scalar_term_to_predicate] + This is different from [expr_to_term e |> scalar_term_to_predicate] since it directly translate C-relations into logic ones. @raise Fatal error if the expression is not a comparison and cannot be -- GitLab From fb42dae6d78704503674cc760376481abff8e307 Mon Sep 17 00:00:00 2001 From: Allan Blanchard <allan.blanchard@cea.fr> Date: Tue, 31 Mar 2020 11:08:32 +0200 Subject: [PATCH 070/218] [ghost] Fixes error msg for ignored ghost-else --- src/kernel_internals/parsing/cparser.mly | 4 +++- tests/syntax/ghost_else_bad.c | 4 ++-- tests/syntax/oracle/ghost_else_bad.1.res.oracle | 2 ++ 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/kernel_internals/parsing/cparser.mly b/src/kernel_internals/parsing/cparser.mly index 73fd674857b..6f2547db91f 100644 --- a/src/kernel_internals/parsing/cparser.mly +++ b/src/kernel_internals/parsing/cparser.mly @@ -923,7 +923,9 @@ else_part: %prec ghost_else_no_else /* To force the non ghost else to be attached to the current if */ | LGHOST_ELSE annotated_statement RGHOST ELSE annotated_statement { - Format.eprintf "Warning: %a: Invalid ghost else ignored@." Cil_datatype.Location.pretty $1 ; + let loc = Cil_datatype.Location.of_lexing_loc (Parsing.symbol_start_pos (), Parsing.symbol_end_pos ()) in + Kernel.warning ~wkey:Kernel.wkey_ghost_bad_use ~source:(fst loc) + "Invalid ghost else ignored@." ; in_block $5 } diff --git a/tests/syntax/ghost_else_bad.c b/tests/syntax/ghost_else_bad.c index 8f6bf609bff..00a3bc684d1 100644 --- a/tests/syntax/ghost_else_bad.c +++ b/tests/syntax/ghost_else_bad.c @@ -1,6 +1,6 @@ /* run.config OPT: -no-autoload-plugins -cpp-extra-args="-DERROR_LOC_WITH_COMMENTS" - OPT: -no-autoload-plugins -cpp-extra-args="-DALREADY_HAS_ELSE" -print + OPT: -no-autoload-plugins -cpp-extra-args="-DALREADY_HAS_ELSE" -print -kernel-warn-key ghost:bad-use=feedback OPT: -no-autoload-plugins -cpp-extra-args="-DBAD_ANNOT_POSITION" */ @@ -22,7 +22,7 @@ void if_ghost_else_block_comments_then_error(int x, int y) { #endif -#ifdef ALREADY_HAS_ELSE +#ifdef ALREADY_HAS_ELSE // Must warn that the ghost else cannot appear since there is already a else // Thus the ghost else is ignored and the resulting code does not comprise it diff --git a/tests/syntax/oracle/ghost_else_bad.1.res.oracle b/tests/syntax/oracle/ghost_else_bad.1.res.oracle index fae04332c74..80c7b0204ac 100644 --- a/tests/syntax/oracle/ghost_else_bad.1.res.oracle +++ b/tests/syntax/oracle/ghost_else_bad.1.res.oracle @@ -1,4 +1,6 @@ [kernel] Parsing tests/syntax/ghost_else_bad.c (with preprocessing) +[kernel:ghost:bad-use] tests/syntax/ghost_else_bad.c:32: + Invalid ghost else ignored /* Generated by Frama-C */ void if_ghost_else_block_bad(int x, int y) { -- GitLab From 316223950ea30cbe75326f4868c3c6b002ed5596 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Loi=CC=88c=20Correnson?= <loic.correnson@cea.fr> Date: Tue, 31 Mar 2020 11:48:28 +0200 Subject: [PATCH 071/218] [tests] fix expr-to-term test & oracle --- tests/spec/expr_to_term.i | 16 ++++++++++--- tests/spec/expr_to_term.ml | 20 +++++++++------- tests/spec/oracle/expr_to_term.res.oracle | 29 +++++++++++++++++++---- 3 files changed, 48 insertions(+), 17 deletions(-) diff --git a/tests/spec/expr_to_term.i b/tests/spec/expr_to_term.i index 5320e071398..e0e88714416 100644 --- a/tests/spec/expr_to_term.i +++ b/tests/spec/expr_to_term.i @@ -2,14 +2,19 @@ MODULE: @PTEST_DIR@/@PTEST_NAME@.cmxs OPT: -print */ + + +// This predicate is modified by expr_to_term.ml plugin to compare +// the assigned l-value or condition at provided stmt id with the logical term + +/*@ predicate int_eq(int logical, int from_stmt_id) = logical == from_stmt_id; */ + int x[10]; struct S { int y; int z; } s; int t; -/*@ predicate int_eq(int logical, int from_c) = logical == from_c; */ - /*@ ensures int_eq(*(int*)((unsigned)0x1 + 0x2),(int)0); */ int f() { @@ -29,7 +34,12 @@ int main() { t = 4; } -/*@ ensures int_eq((int)!t,(int)5); */ +/*@ ensures int_eq((int)(t!=0 ? 0 : 1),(int)5); */ int g() { if (!t) return 2; else return 3; } + +/*@ ensures int_eq((int)(t<5 ? 1 : 0),(int)6); */ +int h() { + if (t<5) return 2; else return 3; +} diff --git a/tests/spec/expr_to_term.ml b/tests/spec/expr_to_term.ml index e6fb35a7376..b6ce6b3ab15 100644 --- a/tests/spec/expr_to_term.ml +++ b/tests/spec/expr_to_term.ml @@ -2,7 +2,7 @@ open Cil_types let emitter = Emitter.(create "Test" [Funspec] ~correctness:[] ~tuning:[]) -let check_expr_term check fct s e = +let check_expr_term check fct s post = let exp = match s.skind with | Instr (Set (lv,_,loc)) -> Cil.new_exp ~loc (Lval lv) @@ -10,12 +10,11 @@ let check_expr_term check fct s e = | _ -> Kernel.fatal "Unexpected statement %a" Printer.pp_stmt s in let term = - match e with + match post with | (_, { ip_content = { pred_content = Papp(_,_,[l;_]) } }) -> l - | _ -> Kernel.fatal "Unexpected ensures %a" Printer.pp_post_cond e + | _ -> Kernel.fatal "Unexpected ensures %a" Printer.pp_post_cond post in - let term' = Logic_utils.expr_to_term ~coerce:true exp in - let term' = Logic_utils.mk_cast Cil.intType term' in + let term' = Logic_utils.expr_to_term ~coerce:false exp in if check && not (Cil_datatype.Term.equal term term') then Kernel.fatal "translation of C expression %a is %a, inconsistent with logic term %a" @@ -52,9 +51,12 @@ let compute () = let main = Globals.Functions.find_by_name "main" in let f = Globals.Functions.find_by_name "f" in let g = Globals.Functions.find_by_name "g" in - treat_fct true main; - treat_fct false f; - treat_fct true g - + let h = Globals.Functions.find_by_name "h" in + begin + treat_fct true main; + treat_fct false f; + treat_fct true g; + treat_fct true h; + end let () = Db.Main.extend compute diff --git a/tests/spec/oracle/expr_to_term.res.oracle b/tests/spec/oracle/expr_to_term.res.oracle index a378207a1b9..fcb612aeeff 100644 --- a/tests/spec/oracle/expr_to_term.res.oracle +++ b/tests/spec/oracle/expr_to_term.res.oracle @@ -4,12 +4,14 @@ struct S { int y ; int z ; }; +/*@ +predicate int_eq(int logical, int from_stmt_id) = logical ≡ from_stmt_id; + */ int x[10]; struct S s; int t; -/*@ predicate int_eq(int logical, int from_c) = logical ≡ from_c; - */ -/*@ ensures int_eq(*((int *)(0x1 + 0x2)), *((int *)(0x1 + 0x2))); +/*@ ensures + int_eq(*((int *)(0x1 + 0x2)), *((int *)((unsigned int)(0x1 + 0x2)))); ensures int_eq(*((int *)(0x1 + 0x2)), (int)0); */ int f(void) @@ -40,8 +42,8 @@ int main(void) return __retres; } -/*@ ensures int_eq((int)(!(t ≢ 0)), (int)(!(t ≢ 0))); - ensures int_eq((int)(!(t ≢ 0)), (int)5); +/*@ ensures int_eq((int)(t ≢ 0? 0: 1), (int)(t ≢ 0? 0: 1)); + ensures int_eq((int)(t ≢ 0? 0: 1), (int)5); */ int g(void) { @@ -57,4 +59,21 @@ int g(void) return_label: return __retres; } +/*@ ensures int_eq((int)(t < 5? 1: 0), (int)(t < 5? 1: 0)); + ensures int_eq((int)(t < 5? 1: 0), (int)6); + */ +int h(void) +{ + int __retres; + if (t < 5) { + __retres = 2; + goto return_label; + } + else { + __retres = 3; + goto return_label; + } + return_label: return __retres; +} + -- GitLab From f4cd30a274f267365eaf04fa6f2f9fc58b5d3209 Mon Sep 17 00:00:00 2001 From: Virgile Prevosto <virgile.prevosto@m4x.org> Date: Tue, 31 Mar 2020 11:43:00 +0200 Subject: [PATCH 072/218] [ptests] output content of oracle/log file when log/oracle does not exist --- ptests/ptests.ml | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/ptests/ptests.ml b/ptests/ptests.ml index 4db22c91fe2..64401651909 100644 --- a/ptests/ptests.ml +++ b/ptests/ptests.ml @@ -1473,6 +1473,19 @@ let worker_thread () = unlock (); done +let diff_check_exist old_file new_file = + if Sys.file_exists old_file then begin + if Sys.file_exists new_file then begin + !do_diffs ^ " " ^ old_file ^ " " ^ new_file + end else begin + "echo \"" ^ new_file ^ " does not exist. Showing " ^ old_file ^ "\";" ^ + " cat " ^ old_file + end + end else begin + "echo \"" ^ old_file ^ " does not exist. Showing " ^ new_file ^ "\";" ^ + " cat " ^ new_file + end + let do_diff = function | Command_error (diff, kind) -> let log_prefix = log_prefix diff in @@ -1487,7 +1500,7 @@ let do_diff = function let oracle_file = Filename.sanitize (oracle_prefix ^ log_ext ^ ".oracle") in - let diff_string = !do_diffs ^ " " ^ oracle_file ^ " " ^ log_file in + let diff_string = diff_check_exist oracle_file log_file in ignore (launch diff_string) | Target_error execnow -> lock_printf "Custom command failed: %s@\n" execnow.ex_cmd; @@ -1515,9 +1528,7 @@ let do_diff = function let oracle_file = Filename.sanitize (SubDir.make_oracle_file dir file) in - let diff_string = - !do_diffs ^ " " ^ oracle_file ^ " " ^ result_file - in + let diff_string = diff_check_exist oracle_file result_file in ignore (launch diff_string) -- GitLab From d7bd846a248b077ac05dbb22bf21aad76bed986b Mon Sep 17 00:00:00 2001 From: Virgile Prevosto <virgile.prevosto@m4x.org> Date: Tue, 31 Mar 2020 11:48:12 +0200 Subject: [PATCH 073/218] [ptests] Do not count as success presence of err file without oracle More precisely, increase the number of total comparisons but not of Ok ones in that case. --- ptests/ptests.ml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ptests/ptests.ml b/ptests/ptests.ml index 64401651909..2b8a22fe7c6 100644 --- a/ptests/ptests.ml +++ b/ptests/ptests.ml @@ -1363,6 +1363,8 @@ let check_file_is_empty_or_nonexisting diff ~log_file = 0 else begin lock(); + (* signal that there's a problem. *) + shared.summary_log <- shared.summary_log + 1; Queue.push diff shared.diffs; Condition.signal shared.diff_available; unlock(); @@ -1531,7 +1533,6 @@ let do_diff = function let diff_string = diff_check_exist oracle_file result_file in ignore (launch diff_string) - let diff_thread () = lock () ; while true do -- GitLab From 82ede5fa03cb5e76fc447575b9645f6d6f748eb4 Mon Sep 17 00:00:00 2001 From: Andre Maroneze <andre.oliveiramaroneze@cea.fr> Date: Wed, 3 Apr 2019 11:12:40 +0200 Subject: [PATCH 074/218] [Libc] add a few specs for sys/stat.h and sys/types.h --- share/compliance/nonstandard_identifiers.json | 1 + share/libc/sys/stat.h | 45 ++++++++++++++++--- share/libc/sys/types.h | 4 ++ .../tests/known/oracle/printf.res.oracle | 1 + .../oracle/printf_wrong_arity.res.oracle | 1 + tests/libc/oracle/fc_libc.0.res.oracle | 9 ++-- tests/libc/oracle/fc_libc.1.res.oracle | 42 +++++++++++++++-- tests/libc/oracle/sys_stat_h.res.oracle | 33 +++++++++++++- tests/libc/oracle/sys_types.res.oracle | 16 +++++++ tests/libc/sys_stat_h.c | 3 ++ tests/libc/sys_types.c | 6 +++ 11 files changed, 145 insertions(+), 16 deletions(-) create mode 100644 tests/libc/oracle/sys_types.res.oracle create mode 100644 tests/libc/sys_types.c diff --git a/share/compliance/nonstandard_identifiers.json b/share/compliance/nonstandard_identifiers.json index e25a2fe06e2..34dc8300e44 100644 --- a/share/compliance/nonstandard_identifiers.json +++ b/share/compliance/nonstandard_identifiers.json @@ -5,6 +5,7 @@ {"ident":"facilitynames", "header":"syslog.h"}, {"ident":"getresgid", "header":"unistd.h"}, {"ident":"getresuid", "header":"unistd.h"}, + {"ident":"makedev", "header":"sys/types.h"}, {"ident":"option", "header":"getopt.h"}, {"ident":"prioritynames", "header":"syslog.h"}, {"ident":"setresgid", "header":"unistd.h"}, diff --git a/share/libc/sys/stat.h b/share/libc/sys/stat.h index f54dcb99bb3..8dc437102d8 100644 --- a/share/libc/sys/stat.h +++ b/share/libc/sys/stat.h @@ -32,25 +32,58 @@ __BEGIN_DECLS extern int chmod(const char *, mode_t); extern int fchmod(int, mode_t); extern int fstat(int, struct stat *); -extern int lstat(const char *, struct stat *); + +/*@ // missing: may assign to errno: EACCES, ELOOP, ENAMETOOLONG, + // ENOENT, ENOMEM, ENOTDIR, EOVERFLOW, + // EINVAL + // missing: assigns \result, *buf \from 'filesystem' + requires valid_path: valid_read_string(path); + requires valid_buf: \valid(buf); + assigns \result, *buf \from indirect:path, indirect:path[0..strlen(path)]; + ensures result_ok_or_error: \result == 0 || \result == -1; +*/ +extern int lstat(const char *path, struct stat *buf); /*@ // missing: may assign to errno: EACCES, EEXIST, ELOOP, EMLINK, // ENAMETOOLONG, ENOENT, ENOSPC, // ENOTDIR, EROFS // missing: assigns \result \from 'filesystem' - requires valid_string_path: valid_read_string(path); - assigns \result \from indirect:path, indirect:path[0..], indirect:mode; + requires valid_path: valid_read_string(path); + assigns \result \from indirect:path, indirect:path[0..strlen(path)], + indirect:mode; ensures result_ok_or_error: \result == 0 || \result == -1; */ extern int mkdir(const char *path, mode_t mode); -extern int mkfifo(const char *, mode_t); -extern int mknod(const char *, mode_t, dev_t); +/*@ // missing: may assign to errno: EACCES, EEXIST, ELOOP, ENAMETOOLONG, + // ENOENT, ENOTDIR, ENOSPC, EROFS + // missing: assigns \result \from 'filesystem' + // missing: assigns 'filesystem' \from indirect:path, + // indirect:path[0..strlen(path)], mode; + requires valid_path: valid_read_string(path); + assigns \result \from indirect:path, indirect:path[0..strlen(path)], + indirect:mode; + ensures result_ok_or_error: \result == 0 || \result == -1; +*/ +extern int mkfifo(const char *path, mode_t mode); + +/*@ // missing: may assign to errno: EACCES, EEXIST, EINVAL, EIO, ELOOP, + // ENAMETOOLONG, ENOENT, ENOTDIR, ENOSPC, + // EPERM, EROFS + // missing: assigns \result \from 'filesystem' + // missing: assigns 'filesystem' \from indirect:path, + // indirect:path[0..strlen(path)], mode, dev; + requires valid_path: valid_read_string(path); + assigns \result \from indirect:path, indirect:path[0..strlen(path)], + indirect:mode, indirect:dev; + ensures result_ok_or_error: \result == 0 || \result == -1; +*/ +extern int mknod(const char *path, mode_t mode, dev_t dev); /*@ //missing: assigns \from 'filesystem' requires valid_pathname: valid_read_string(pathname); requires valid_buf: \valid(buf); - assigns \result, *buf \from pathname[0..]; + assigns \result, *buf \from pathname[0..strlen(pathname)]; ensures result_ok_or_error: \result == 0 || \result == -1; ensures init_on_success:initialization:buf: \result == 0 ==> \initialized(buf); diff --git a/share/libc/sys/types.h b/share/libc/sys/types.h index 16cf512ac59..41ba9673a06 100644 --- a/share/libc/sys/types.h +++ b/share/libc/sys/types.h @@ -49,6 +49,10 @@ typedef unsigned long u_long; typedef unsigned int u_int; typedef unsigned short u_short; typedef unsigned char u_char; + +// Note: makedev (non-POSIX) is usually a macro; in case of problems, +// consider redefining this. +/*@ assigns \result \from maj, min; */ extern dev_t makedev(int maj, int min); #define __u_char_defined #endif diff --git a/src/plugins/variadic/tests/known/oracle/printf.res.oracle b/src/plugins/variadic/tests/known/oracle/printf.res.oracle index 83d6f21822e..f04b44a2b44 100644 --- a/src/plugins/variadic/tests/known/oracle/printf.res.oracle +++ b/src/plugins/variadic/tests/known/oracle/printf.res.oracle @@ -164,6 +164,7 @@ #include "stdlib.h" #include "string.h" #include "strings.h" +#include "sys/types.h" #include "time.h" #include "wchar.h" /*@ requires valid_read_string(format); diff --git a/src/plugins/variadic/tests/known/oracle/printf_wrong_arity.res.oracle b/src/plugins/variadic/tests/known/oracle/printf_wrong_arity.res.oracle index f04220bcfaa..d7f8115fec3 100644 --- a/src/plugins/variadic/tests/known/oracle/printf_wrong_arity.res.oracle +++ b/src/plugins/variadic/tests/known/oracle/printf_wrong_arity.res.oracle @@ -44,6 +44,7 @@ #include "stdio.c" #include "stdio.h" #include "stdlib.h" +#include "sys/types.h" /*@ requires valid_read_string(format); assigns \result, __fc_stdout->__fc_FILE_data; assigns \result diff --git a/tests/libc/oracle/fc_libc.0.res.oracle b/tests/libc/oracle/fc_libc.0.res.oracle index 4576d6a15ca..02529fbe95f 100644 --- a/tests/libc/oracle/fc_libc.0.res.oracle +++ b/tests/libc/oracle/fc_libc.0.res.oracle @@ -40,7 +40,7 @@ unsetenv (0 call); wcscat (0 call); wcscpy (0 call); wcslen (2 calls); wcsncat (0 call); wcsncpy (0 call); wmemcpy (0 call); wmemset (0 call); - Undefined functions (390) + Undefined functions (394) ========================= FD_CLR (0 call); FD_ISSET (0 call); FD_SET (0 call); FD_ZERO (0 call); Frama_C_int_interval (0 call); Frama_C_long_interval (0 call); @@ -111,8 +111,9 @@ localtime (0 call); log (0 call); log10 (0 call); log10f (0 call); log10l (0 call); log2 (0 call); log2f (0 call); log2l (0 call); logf (0 call); logl (0 call); longjmp (0 call); lrand48 (0 call); - lseek (0 call); malloc (7 calls); mblen (0 call); mbstowcs (0 call); - mbtowc (0 call); mkdir (0 call); mkstemp (0 call); mktime (0 call); + lseek (0 call); lstat (0 call); makedev (0 call); malloc (7 calls); + mblen (0 call); mbstowcs (0 call); mbtowc (0 call); mkdir (0 call); + mkfifo (0 call); mknod (0 call); mkstemp (0 call); mktime (0 call); mrand48 (0 call); nan (0 call); nanf (0 call); nanl (0 call); nanosleep (0 call); nrand48 (0 call); ntohl (0 call); ntohs (0 call); open (0 call); openat (0 call); opendir (0 call); openlog (0 call); @@ -180,7 +181,7 @@ Goto = 89 Assignment = 438 Exit point = 82 - Function = 472 + Function = 476 Function call = 89 Pointer dereferencing = 158 Cyclomatic complexity = 286 diff --git a/tests/libc/oracle/fc_libc.1.res.oracle b/tests/libc/oracle/fc_libc.1.res.oracle index 705dcf5c78c..3ac0899086f 100644 --- a/tests/libc/oracle/fc_libc.1.res.oracle +++ b/tests/libc/oracle/fc_libc.1.res.oracle @@ -4954,6 +4954,10 @@ extern int pclose(FILE *stream); ssize_t getline(char **lineptr, size_t *n, FILE *stream); +/*@ assigns \result; + assigns \result \from maj, min; */ +extern dev_t makedev(int maj, int min); + FILE __fc_initial_stdout = {.__fc_FILE_id = (unsigned int)1, .__fc_FILE_data = 0U}; FILE *__fc_stdout = & __fc_initial_stdout; @@ -7531,14 +7535,44 @@ extern int setitimer(int which, extern int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *errorfds, struct timeval *timeout); -/*@ requires valid_string_path: valid_read_string(path); +/*@ requires valid_path: valid_read_string(path); + requires valid_buf: \valid(buf); + ensures result_ok_or_error: \result ≡ 0 ∨ \result ≡ -1; + assigns \result, *buf; + assigns \result + \from (indirect: path), (indirect: *(path + (0 .. strlen{Old}(path)))); + assigns *buf + \from (indirect: path), (indirect: *(path + (0 .. strlen{Old}(path)))); + */ +extern int lstat(char const *path, struct stat *buf); + +/*@ requires valid_path: valid_read_string(path); ensures result_ok_or_error: \result ≡ 0 ∨ \result ≡ -1; assigns \result; assigns \result - \from (indirect: path), (indirect: *(path + (0 ..))), (indirect: mode); + \from (indirect: path), (indirect: *(path + (0 .. strlen{Old}(path)))), + (indirect: mode); */ extern int mkdir(char const *path, mode_t mode); +/*@ requires valid_path: valid_read_string(path); + ensures result_ok_or_error: \result ≡ 0 ∨ \result ≡ -1; + assigns \result; + assigns \result + \from (indirect: path), (indirect: *(path + (0 .. strlen{Old}(path)))), + (indirect: mode); + */ +extern int mkfifo(char const *path, mode_t mode); + +/*@ requires valid_path: valid_read_string(path); + ensures result_ok_or_error: \result ≡ 0 ∨ \result ≡ -1; + assigns \result; + assigns \result + \from (indirect: path), (indirect: *(path + (0 .. strlen{Old}(path)))), + (indirect: mode), (indirect: dev); + */ +extern int mknod(char const *path, mode_t mode, dev_t dev); + /*@ requires valid_pathname: valid_read_string(pathname); requires valid_buf: \valid(buf); ensures result_ok_or_error: \result ≡ 0 ∨ \result ≡ -1; @@ -7546,8 +7580,8 @@ extern int mkdir(char const *path, mode_t mode); init_on_success: initialization: buf: \result ≡ 0 ⇒ \initialized(\old(buf)); assigns \result, *buf; - assigns \result \from *(pathname + (0 ..)); - assigns *buf \from *(pathname + (0 ..)); + assigns \result \from *(pathname + (0 .. strlen{Old}(pathname))); + assigns *buf \from *(pathname + (0 .. strlen{Old}(pathname))); */ extern int stat(char const *pathname, struct stat *buf); diff --git a/tests/libc/oracle/sys_stat_h.res.oracle b/tests/libc/oracle/sys_stat_h.res.oracle index 713de92c6ef..1fded86b56e 100644 --- a/tests/libc/oracle/sys_stat_h.res.oracle +++ b/tests/libc/oracle/sys_stat_h.res.oracle @@ -28,12 +28,12 @@ Called from tests/libc/sys_stat_h.c:17. [eva] using specification for function mkdir [eva] tests/libc/sys_stat_h.c:17: - function mkdir: precondition 'valid_string_path' got status valid. + function mkdir: precondition 'valid_path' got status valid. [eva] Done for function mkdir [eva] computing for function mkdir <- main. Called from tests/libc/sys_stat_h.c:20. [eva:alarm] tests/libc/sys_stat_h.c:20: Warning: - function mkdir: precondition 'valid_string_path' got status invalid. + function mkdir: precondition 'valid_path' got status invalid. [eva] Done for function mkdir [eva] computing for function mkdir <- main. Called from tests/libc/sys_stat_h.c:20. @@ -45,6 +45,32 @@ [eva] computing for function umask <- main. Called from tests/libc/sys_stat_h.c:22. [eva] Done for function umask +[eva] computing for function lstat <- main. + Called from tests/libc/sys_stat_h.c:23. +[eva] using specification for function lstat +[eva] tests/libc/sys_stat_h.c:23: + function lstat: precondition 'valid_path' got status valid. +[eva] tests/libc/sys_stat_h.c:23: + function lstat: precondition 'valid_buf' got status valid. +[eva] Done for function lstat +[eva] computing for function lstat <- main. + Called from tests/libc/sys_stat_h.c:23. +[eva] Done for function lstat +[eva] computing for function mkfifo <- main. + Called from tests/libc/sys_stat_h.c:24. +[eva] using specification for function mkfifo +[eva] tests/libc/sys_stat_h.c:24: + function mkfifo: precondition 'valid_path' got status valid. +[eva] Done for function mkfifo +[eva] computing for function mknod <- main. + Called from tests/libc/sys_stat_h.c:25. +[eva] using specification for function mknod +[eva] tests/libc/sys_stat_h.c:25: + function mknod: precondition 'valid_path' got status valid. +[eva] Done for function mknod +[eva] computing for function mknod <- main. + Called from tests/libc/sys_stat_h.c:25. +[eva] Done for function mknod [eva] Recording results for main [eva] done for function main [eva] ====== VALUES COMPUTED ====== @@ -55,4 +81,7 @@ r ∈ {-1; 0} r_mkdir ∈ {-1; 0} old_mask ∈ [--..--] + r2 ∈ {-1; 0} + r3 ∈ {-1; 0} + r4 ∈ {-1; 0} __retres ∈ {-1; 0; 1; 2; 3} diff --git a/tests/libc/oracle/sys_types.res.oracle b/tests/libc/oracle/sys_types.res.oracle new file mode 100644 index 00000000000..68e4552bf4e --- /dev/null +++ b/tests/libc/oracle/sys_types.res.oracle @@ -0,0 +1,16 @@ +[kernel] Parsing tests/libc/sys_types.c (with preprocessing) +[eva] Analyzing a complete application starting at main +[eva] Computing initial state +[eva] Initial state computed +[eva:initial-state] Values of globals at initialization + +[eva] computing for function makedev <- main. + Called from tests/libc/sys_types.c:4. +[eva] using specification for function makedev +[eva] Done for function makedev +[eva] Recording results for main +[eva] done for function main +[eva] ====== VALUES COMPUTED ====== +[eva:final-states] Values at end of function main: + dev ∈ [--..--] + __retres ∈ {0} diff --git a/tests/libc/sys_stat_h.c b/tests/libc/sys_stat_h.c index 464a9e8e00e..65ddbfc8890 100644 --- a/tests/libc/sys_stat_h.c +++ b/tests/libc/sys_stat_h.c @@ -20,5 +20,8 @@ int main() { mkdir(non_terminated, 0422); } mode_t old_mask = umask(0644); + int r2 = lstat("/tmp/bla", &st); + int r3 = mkfifo("/tmp/fifo", 0644); + int r4 = mknod("/tmp/fifo2", 0644, 42); return 0; } diff --git a/tests/libc/sys_types.c b/tests/libc/sys_types.c new file mode 100644 index 00000000000..50a3e33fef8 --- /dev/null +++ b/tests/libc/sys_types.c @@ -0,0 +1,6 @@ +#include <sys/types.h> + +int main() { + dev_t dev = makedev(1, 42); + return 0; +} -- GitLab From 95943b673d89184df78dc18bd44f79da8411d610 Mon Sep 17 00:00:00 2001 From: Virgile Prevosto <virgile.prevosto@m4x.org> Date: Tue, 31 Mar 2020 14:06:37 +0200 Subject: [PATCH 075/218] [ptests] slightly more visible message when file is missing --- ptests/ptests.ml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ptests/ptests.ml b/ptests/ptests.ml index 2b8a22fe7c6..9318f4ebd96 100644 --- a/ptests/ptests.ml +++ b/ptests/ptests.ml @@ -1480,12 +1480,12 @@ let diff_check_exist old_file new_file = if Sys.file_exists new_file then begin !do_diffs ^ " " ^ old_file ^ " " ^ new_file end else begin - "echo \"" ^ new_file ^ " does not exist. Showing " ^ old_file ^ "\";" ^ - " cat " ^ old_file + "echo \"+++ " ^ new_file ^ " does not exist. Showing " ^ + old_file ^ "\";" ^ " cat " ^ old_file end end else begin - "echo \"" ^ old_file ^ " does not exist. Showing " ^ new_file ^ "\";" ^ - " cat " ^ new_file + "echo \"--- " ^ old_file ^ " does not exist. Showing " ^ + new_file ^ "\";" ^ " cat " ^ new_file end let do_diff = function -- GitLab From e6661a805280b2820c4eddad26bd3f063354243a Mon Sep 17 00:00:00 2001 From: Andre Maroneze <andre.oliveiramaroneze@cea.fr> Date: Tue, 16 Apr 2019 17:50:52 +0200 Subject: [PATCH 076/218] [Dev] add script for applying creduce to Frama-C crashes --- Makefile | 2 + headers/header_spec.txt | 1 + share/analysis-scripts/creduce.sh | 165 ++++++++++++++++++++++++++++++ 3 files changed, 168 insertions(+) create mode 100755 share/analysis-scripts/creduce.sh diff --git a/Makefile b/Makefile index d7fe1a2f386..491b6b62d61 100644 --- a/Makefile +++ b/Makefile @@ -258,6 +258,7 @@ DISTRIB_FILES:=\ share/analysis-scripts/cmd-dep.sh \ share/analysis-scripts/concat-csv.sh \ share/analysis-scripts/clone.sh \ + share/analysis-scripts/creduce.sh \ $(wildcard share/analysis-scripts/examples/*) \ share/analysis-scripts/fc_stubs.c \ share/analysis-scripts/find_fun.py \ @@ -1932,6 +1933,7 @@ install:: install-lib-$(OCAMLBEST) share/analysis-scripts/cmd-dep.sh \ share/analysis-scripts/concat-csv.sh \ share/analysis-scripts/clone.sh \ + share/analysis-scripts/creduce.sh \ share/analysis-scripts/fc_stubs.c \ share/analysis-scripts/find_fun.py \ share/analysis-scripts/flamegraph.pl \ diff --git a/headers/header_spec.txt b/headers/header_spec.txt index dfdb833077b..2ada5971dd2 100644 --- a/headers/header_spec.txt +++ b/headers/header_spec.txt @@ -114,6 +114,7 @@ ptests/ptests.ml: CEA_LGPL share/_frama-c: CEA_LGPL share/analysis-scripts/benchmark_database.py: .ignore share/analysis-scripts/clone.sh: .ignore +share/analysis-scripts/creduce.sh: CEA_LGPL share/analysis-scripts/fc_stubs.c: .ignore share/analysis-scripts/frama-c.mk: CEA_LGPL share/analysis-scripts/frama_c_results.py: .ignore diff --git a/share/analysis-scripts/creduce.sh b/share/analysis-scripts/creduce.sh new file mode 100755 index 00000000000..009cebf8a7c --- /dev/null +++ b/share/analysis-scripts/creduce.sh @@ -0,0 +1,165 @@ +#!/bin/bash -e +########################################################################## +# # +# This file is part of Frama-C. # +# # +# Copyright (C) 2007-2020 # +# CEA (Commissariat à l'énergie atomique et aux énergies # +# alternatives) # +# # +# you can redistribute it and/or modify it under the terms of the GNU # +# Lesser General Public License as published by the Free Software # +# Foundation, version 2.1. # +# # +# It is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU Lesser General Public License for more details. # +# # +# See the GNU Lesser General Public License version 2.1 # +# for more details (enclosed in the file licenses/LGPLv2.1). # +# # +########################################################################## + +# Script to run C-Reduce (https://embed.cs.utah.edu/creduce) when debugging +# Frama-C crashes with a 'fatal' error, which produces a stack trace and +# a message "Please report". + +### Requirements +# +# - C-Reduce installed in the PATH, or its path given in the +# environment variable CREDUCE; +# +# - GCC, or the path to a compiler with compatible options given in the +# environment variable CC; +# +# - Frama-C installed in the PATH, or its path given in the environment +# variable FRAMAC; +# +# - a source file + a command line which causes Frama-C to crash with +# a 'fatal' error (producing a stack trace). + +### How it works +# +# creduce.sh <file.c> <command line options> +# +# This script creates a temporary directory named 'creducing'. +# It copies <file.c> inside it, then runs creduce. +# creduce runs "frama-c <command line options>" on the copied file, +# modifying it to make it smaller while still crashing. +# +# When done, copy the reduced file and erase directoy 'creducing'. + +if [ $# -lt 1 ]; then + echo "usage: $0 file.c [Frama-C options that cause a crash]" + exit 1 +fi + +file="$1" +base=$(basename "$file") +shift +options="$@" +dir_for_reduction="creducing" + +if [ -z "$CREDUCE" ]; then + CREDUCE="creduce" +fi + +if ! command -v "$CREDUCE" 2>&1 >/dev/null; then + echo "creduce not found, put it in PATH or in environment variable CREDUCE." + exit 1 +fi + +if [[ ! -f "$file" ]]; then + echo "Source file not found (must be first argument): $file" + exit 1 +fi + +if [[ $(dirname "$file") -eq "$dir_for_reduction" ]]; then + echo "error: cannot reduce a file inside the directory used for reduction," + echo " $dir_for_reduction" + exit 1 +fi + +if [[ ! "$options" =~ no-autoload-plugins ]]; then + echo "********************************************************************" + echo "Hint: consider using -no-autoload-plugins -load-module [modules]" + echo " for faster reduction" + echo "********************************************************************" +fi + +if [[ "$base" =~ \.c$ ]]; then + echo "********************************************************************" + echo "Hint: consider passing a preprocessed (.i) file if possible," + echo " otherwise #includes may prevent further reduction" + echo "********************************************************************" +fi + +mkdir -p "$dir_for_reduction" + +if [ -z "$FRAMAC" ]; then + SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" + FRAMAC=$(realpath "$SCRIPT_DIR/../../bin/frama-c") + echo "[info] FRAMAC not set, using binary at: $FRAMAC" +else + echo "[info] using FRAMAC: $FRAMAC" +fi + +if [ -z "$FRAMAC_SHARE" ]; then + FRAMAC_SHARE="$("$FRAMAC" -print-share-path)" +fi + +if [ -z "$CC" ]; then + CC=gcc + CFLAGS+="-fsyntax-only -I\"$FRAMAC_SHARE\"/libc -D__FC_MACHDEP_X86_32 -m32" +fi + +echo "[info] checking syntactic validity with: $CC $CFLAGS" + +cp "$file" "$dir_for_reduction" +cd "$dir_for_reduction" + +cat <<EOF > script_for_creduce.sh +#!/bin/bash -e + +# This script is given to creduce to reduce a Frama-C crashing test case +# (where "crashing" means a 'fatal' exception, with stack trace). + +set +e +$CC $CFLAGS "$base" +if [ \$? -ne 0 ]; then + exit 1 +fi +"$FRAMAC" "$base" $options +retcode=\$? +# see cmdline.ml for the different exit codes returned by Frama-C +if [ \$retcode -eq 125 -o \$retcode -eq 4 ]; then + exit 0 +else + exit 1 +fi +set -e + +EOF + +chmod u+x script_for_creduce.sh + +trap "{ echo \"Creduce interrupted!\"; echo \"\"; echo \"(partially) reduced file: $dir_for_reduction/$base\"; exit 0; }" SIGINT + +echo "File being reduced: $dir_for_reduction/$base (press Ctrl+C to stop at any time)" + +set +e +./script_for_creduce.sh 2>&1 >/tmp/script_for_creduce.out +if [ $? -ne 0 ]; then + echo "error: script did not produce a Frama-C 'fatal' crash." + echo " check the options given to Frama-C to ensure they make Frama-C crash." + echo "" + echo "Script output:" + cat /tmp/script_for_creduce.out + exit 1 +fi +set -e + +"$CREDUCE" script_for_creduce.sh "$base" + +echo "Finished reducing file: $dir_for_reduction/$base" -- GitLab From 33329c9ac295fbe2bda723783e81707bbb3f0268 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Loi=CC=88c=20Correnson?= <loic.correnson@cea.fr> Date: Tue, 31 Mar 2020 16:43:47 +0200 Subject: [PATCH 077/218] [kernel] float coercion at parsing and printing --- .../ast_printing/cil_printer.ml | 8 +++- src/kernel_services/ast_queries/cil.ml | 2 +- .../ast_queries/logic_typing.ml | 5 ++- .../ast_queries/logic_utils.ml | 41 +++++++++++++------ .../ast_queries/logic_utils.mli | 23 +++++++---- src/plugins/aorai/data_for_aorai.ml | 3 +- 6 files changed, 54 insertions(+), 28 deletions(-) diff --git a/src/kernel_services/ast_printing/cil_printer.ml b/src/kernel_services/ast_printing/cil_printer.ml index 9acb7457ad8..5baa9eb235d 100644 --- a/src/kernel_services/ast_printing/cil_printer.ml +++ b/src/kernel_services/ast_printing/cil_printer.ml @@ -2432,7 +2432,13 @@ class cil_printer () = object (self) | TBinOp (op,l,r) -> fprintf fmt "@[%a@ %a@ %a@]" term l self#term_binop op term r | TCastE (ty,e) -> - fprintf fmt "(%a)%a" (self#typ None) ty term e + begin match ty, t.term_node with + | TFloat(fk,_) , TConst(LReal r as cst) when + r.r_upper = r.r_lower && Cil.isFiniteFloat fk r.r_nearest -> + self#logic_constant fmt cst + | _ -> + fprintf fmt "(%a)%a" (self#typ None) ty term e + end | TAddrOf lv -> fprintf fmt "&%a" (self#term_lval_prec Precedence.addrOfLevel) lv | TStartOf lv -> fprintf fmt "(%a)%a" diff --git a/src/kernel_services/ast_queries/cil.ml b/src/kernel_services/ast_queries/cil.ml index a3de91f6122..fb67f20bba8 100644 --- a/src/kernel_services/ast_queries/cil.ml +++ b/src/kernel_services/ast_queries/cil.ml @@ -3638,7 +3638,7 @@ let typeOf_array_elem t = let no_op_coerce typ t = match typ with - | Lreal -> isLogicRealOrFloatType t.term_type + | Lreal -> isLogicArithmeticType t.term_type | Linteger -> isLogicIntegralType t.term_type | Ltype _ when Logic_const.is_boolean_type typ -> isLogicPureBooleanType t.term_type diff --git a/src/kernel_services/ast_queries/logic_typing.ml b/src/kernel_services/ast_queries/logic_typing.ml index 27e77ae549a..d0298228e25 100644 --- a/src/kernel_services/ast_queries/logic_typing.ml +++ b/src/kernel_services/ast_queries/logic_typing.ml @@ -2537,8 +2537,9 @@ struct TConst c, Linteger | _ -> assert false end - | PLconstant (FloatConstant str) -> - TConst (Logic_utils.string_to_float_lconstant str), Lreal + | PLconstant (FloatConstant s) -> + let t = Logic_utils.parse_float ~loc s in + t.term_node , t.term_type | PLconstant (StringConstant s) -> TConst (LStr (unescape s)), Ctype Cil.charPtrType | PLconstant (WStringConstant s) -> diff --git a/src/kernel_services/ast_queries/logic_utils.ml b/src/kernel_services/ast_queries/logic_utils.ml index 18313884188..f48ee5de1bd 100644 --- a/src/kernel_services/ast_queries/logic_utils.ml +++ b/src/kernel_services/ast_queries/logic_utils.ml @@ -270,13 +270,21 @@ let mk_cast ?(loc=Cil_datatype.Location.unknown) ?(force=false) newt t = let real_of_float s f = { r_literal = s ; r_nearest = f ; r_upper = f ; r_lower = f } +let real_of_parsed s p = + let open Floating_point in + { + r_literal = s ; r_nearest = p.f_nearest ; + r_upper = p.f_upper ; + r_lower = p.f_lower ; + } + let constant_to_lconstant c = match c with | CInt64(i,_,s) -> Integer (i,s) | CStr s -> LStr s | CWStr s -> LWStr s | CChr s -> LChr s - | CReal (f,_,Some s) -> LReal (real_of_float s f) | CEnum e -> LEnum e + | CReal (f,_,Some s) -> LReal (real_of_float s f) | CReal (f,fkind,None) -> let s = match fkind with | FFloat -> Format.sprintf "%.8ef" f @@ -292,20 +300,25 @@ let lconstant_to_constant c = match c with | LReal r -> CReal (r.r_nearest,FDouble,Some r.r_literal) | LEnum e -> CEnum e -let string_to_float_lconstant string = - let f = snd (Floating_point.parse string) in +let parse_float ?loc literal = + let fk,v = Floating_point.parse literal in (* If the string has suffix 'F' or 'D', then it represents a single or double constant and the nearest parsed float is exact. Otherwise, use the upper and lower float computed by [parse]. *) - let l = String.length string - 1 in - let last = Char.uppercase_ascii string.[l] in - let exact = last = 'F' || last = 'D' in - if exact - then LReal (real_of_float string f.Floating_point.f_nearest) - else - let open Floating_point in - LReal { r_nearest = f.f_nearest; r_upper = f.f_upper; r_lower = f.f_lower; - r_literal = string } + let is_flt = + let len = String.length literal in + let last = Char.uppercase_ascii literal.[len-1] in + last = 'F' || last = 'D' + in + let creal = + if is_flt + then real_of_float literal v.Floating_point.f_nearest + else real_of_parsed literal v in + let vreal = Logic_const.term ?loc (TConst(LReal creal)) Lreal in + if is_flt then + let ty = TFloat(fk,[]) in + Logic_const.term ?loc (TCastE(ty,vreal)) (Ctype ty) + else vreal let mk_coerce ltyp t = Logic_const.term ~loc:t.term_loc (TLogic_coerce(ltyp, t)) ltyp @@ -314,7 +327,9 @@ let numeric_coerce ltyp t = let oldt = unroll_type t.term_type in if Cil_datatype.Logic_type.equal oldt ltyp then t else match t.term_node with - | TLogic_coerce(lt,e) when Cil.no_op_coerce lt e -> mk_coerce ltyp e + | TLogic_coerce(lt,e) when Cil.no_op_coerce lt e -> + (* coercion hidden by the printer, but still present *) + mk_coerce ltyp e | TConst(Integer _) when ltyp = Linteger -> { t with term_type = Linteger } | TConst(LReal _ ) when ltyp = Lreal -> { t with term_type = Lreal } | TCastE(ty,e) -> diff --git a/src/kernel_services/ast_queries/logic_utils.mli b/src/kernel_services/ast_queries/logic_utils.mli index 6f37795a6e9..81a7c454d54 100644 --- a/src/kernel_services/ast_queries/logic_utils.mli +++ b/src/kernel_services/ast_queries/logic_utils.mli @@ -29,7 +29,7 @@ open Cil_types (** exception raised when a parsed logic expression is syntactically not well-formed. *) -exception Not_well_formed of Cil_types.location * string +exception Not_well_formed of location * string (** basic utilities for logic terms and predicates. See also {! Logic_const} to build terms and predicates. @@ -109,7 +109,7 @@ val mk_logic_StartOf : term -> term (** creates an AddrOf from a TLval. The given logic type is the type of the lval. @since Neon-20140301 *) -val mk_logic_AddrOf: ?loc:Cil_types.location -> term_lval -> logic_type -> term +val mk_logic_AddrOf: ?loc:location -> term_lval -> logic_type -> term (** [true] if the term is a pointer. *) val isLogicPointer : term -> bool @@ -245,11 +245,16 @@ val offset_to_term_offset : offset -> term_offset val constant_to_lconstant: constant -> logic_constant val lconstant_to_constant: logic_constant-> constant -(** Parse the given string as a float logic constant, taking into account - the fact that the constant may not be exactly representable. This - function should only be called on strings that have been recognized - by the parser as valid floats *) -val string_to_float_lconstant: string -> logic_constant +(** Parse the given string as a float or real logic constant. + + The parsed literal is always kept as it is in the resulting term. + The returned term is either a real constant or + real constant casted into a C-float type. + + Unsuffised constants are considered as real numbers. + Literals suffixed by ['f'] or ['d'] are + considered as float constants. *) +val parse_float : ?loc:location -> string -> term (** {2 Various Utilities} *) @@ -406,7 +411,7 @@ val concat_allocation: allocation -> allocation -> allocation val merge_allocation : allocation -> allocation -> allocation val merge_behaviors : - ?oldloc:Cil_types.location -> silent:bool -> funbehavior list -> funbehavior list -> funbehavior list + ?oldloc:location -> silent:bool -> funbehavior list -> funbehavior list -> funbehavior list (** [merge_funspec ?oldloc oldspec newspec] merges [newspec] into [oldspec]. If the funspec belongs to a kernel function, do not forget to call @@ -414,7 +419,7 @@ val merge_behaviors : @modify 20.0-Calcium add optional parameter [oldloc]. *) val merge_funspec : - ?oldloc:Cil_types.location -> ?silent_about_merging_behav:bool -> + ?oldloc:location -> ?silent_about_merging_behav:bool -> funspec -> funspec -> unit (** Reset the given funspec to empty. diff --git a/src/plugins/aorai/data_for_aorai.ml b/src/plugins/aorai/data_for_aorai.ml index 75999fabf9b..1bcaa67755f 100644 --- a/src/plugins/aorai/data_for_aorai.ml +++ b/src/plugins/aorai/data_for_aorai.ml @@ -694,8 +694,7 @@ let type_expr env ?tr ?current e = let e = Cil.parseIntLogic ~loc s in env, e, cond | PCst (Logic_ptree.FloatConstant str) -> - let c = Logic_utils.string_to_float_lconstant str in - env, Logic_const.term (TConst c) Lreal, cond + env, Logic_utils.parse_float ~loc str, cond | PCst (Logic_ptree.StringConstant s) -> let t = Logic_const.term -- GitLab From a0979153cfb43e5603e0354959be973b71042107 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Loi=CC=88c=20Correnson?= <loic.correnson@cea.fr> Date: Tue, 31 Mar 2020 16:58:38 +0200 Subject: [PATCH 078/218] [kernel] update oracles wrt float builtins Only differences comes from using float builtins in expr-to-term --- tests/float/oracle/alarms.0.res.oracle | 12 ++-- tests/float/oracle/alarms.1.res.oracle | 4 +- tests/float/oracle/const1.res.oracle | 2 +- tests/float/oracle/const2.res.oracle | 2 +- tests/float/oracle/const4.0.res.oracle | 2 +- tests/float/oracle/const4.1.res.oracle | 2 +- tests/float/oracle/cte_overflow.res.oracle | 4 +- tests/float/oracle/dr_infinity.res.oracle | 20 ++++--- tests/float/oracle/logic.0.res.oracle | 6 +- tests/float/oracle/nonlin.0.res.oracle | 22 +++---- tests/float/oracle/nonlin.1.res.oracle | 15 ++--- tests/float/oracle/nonlin.2.res.oracle | 2 +- tests/float/oracle/nonlin.3.res.oracle | 22 +++---- tests/float/oracle/nonlin.4.res.oracle | 15 ++--- tests/float/oracle/nonlin.5.res.oracle | 2 +- tests/float/oracle/parse.res.oracle | 5 +- tests/float/oracle/widen.0.res.oracle | 2 +- .../misc/oracle/widen_hints_float.res.oracle | 3 +- tests/rte/oracle/finite_float.res.oracle | 6 +- tests/slicing/oracle/keep_annot.2.res.oracle | 5 +- tests/slicing/oracle/keep_annot.3.res.oracle | 5 +- .../oracle/unravel-variance.0.res.oracle | 58 ++++++++++--------- .../oracle/unravel-variance.1.res.oracle | 58 ++++++++++--------- .../oracle/unravel-variance.2.res.oracle | 58 ++++++++++--------- .../oracle/unravel-variance.3.res.oracle | 58 ++++++++++--------- .../oracle/unravel-variance.4.res.oracle | 58 ++++++++++--------- tests/value/oracle/CruiseControl.res.oracle | 10 ++-- tests/value/oracle/bts1306.res.oracle | 8 +-- tests/value/oracle/gauges.res.oracle | 2 +- tests/value/oracle/library.res.oracle | 2 +- .../value/oracle/propagate_bottom.res.oracle | 18 ++++-- tests/value/oracle/summary.3.res.oracle | 2 +- tests/value/oracle/summary.4.res.oracle | 2 +- 33 files changed, 276 insertions(+), 216 deletions(-) diff --git a/tests/float/oracle/alarms.0.res.oracle b/tests/float/oracle/alarms.0.res.oracle index 9cc4fd7b226..27b0de1e56c 100644 --- a/tests/float/oracle/alarms.0.res.oracle +++ b/tests/float/oracle/alarms.0.res.oracle @@ -71,17 +71,21 @@ [eva] computing for function main2 <- main. Called from tests/float/alarms.i:71. [eva:alarm] tests/float/alarms.i:38: Warning: - non-finite double value. assert \is_finite((double)(1. / 0.)); + non-finite double value. + assert \is_finite(\div_double((double)1., (double)0.)); [eva:alarm] tests/float/alarms.i:39: Warning: - non-finite double value. assert \is_finite((double)(0. / 0.)); + non-finite double value. + assert \is_finite(\div_double((double)0., (double)0.)); [eva] tests/float/alarms.i:41: assertion got status valid. [eva] tests/float/alarms.i:42: assertion got status valid. [eva] tests/float/alarms.i:43: assertion got status valid. [eva] tests/float/alarms.i:44: assertion got status valid. [eva:alarm] tests/float/alarms.i:46: Warning: - non-finite double value. assert \is_finite((double)(1. / 0.)); + non-finite double value. + assert \is_finite(\div_double((double)1., (double)0.)); [eva:alarm] tests/float/alarms.i:50: Warning: - non-finite double value. assert \is_finite((double)(0. / 0.)); + non-finite double value. + assert \is_finite(\div_double((double)0., (double)0.)); [eva] Recording results for main2 [eva] Done for function main2 [eva] computing for function main3 <- main. diff --git a/tests/float/oracle/alarms.1.res.oracle b/tests/float/oracle/alarms.1.res.oracle index 6fe539d7688..0aa572dcab5 100644 --- a/tests/float/oracle/alarms.1.res.oracle +++ b/tests/float/oracle/alarms.1.res.oracle @@ -71,14 +71,14 @@ [eva] computing for function main2 <- main. Called from tests/float/alarms.i:71. [eva:alarm] tests/float/alarms.i:39: Warning: - NaN double value. assert ¬\is_NaN((double)(0. / 0.)); + NaN double value. assert ¬\is_NaN(\div_double((double)0., (double)0.)); [eva] tests/float/alarms.i:41: assertion got status valid. [eva] tests/float/alarms.i:42: assertion got status valid. [eva] tests/float/alarms.i:43: assertion got status valid. [eva] tests/float/alarms.i:44: assertion got status valid. [eva] tests/float/alarms.i:47: assertion got status valid. [eva:alarm] tests/float/alarms.i:50: Warning: - NaN double value. assert ¬\is_NaN((double)(0. / 0.)); + NaN double value. assert ¬\is_NaN(\div_double((double)0., (double)0.)); [eva] Recording results for main2 [eva] Done for function main2 [eva] computing for function main3 <- main. diff --git a/tests/float/oracle/const1.res.oracle b/tests/float/oracle/const1.res.oracle index 638364e2462..a88cc5055cf 100644 --- a/tests/float/oracle/const1.res.oracle +++ b/tests/float/oracle/const1.res.oracle @@ -5,7 +5,7 @@ [eva] Analyzing a complete application starting at main [eva] Computing initial state [eva:alarm] tests/float/const1.i:1: Warning: - non-finite float value. assert \is_finite(1e40f); + non-finite float value. assert \is_finite((float)1e40f); [eva] tests/float/const1.i:1: Warning: evaluation of initializer '(unsigned long long)1e40f' failed [eva] Initial state computed diff --git a/tests/float/oracle/const2.res.oracle b/tests/float/oracle/const2.res.oracle index e13374c9a69..cbf86178708 100644 --- a/tests/float/oracle/const2.res.oracle +++ b/tests/float/oracle/const2.res.oracle @@ -5,7 +5,7 @@ [eva] Analyzing a complete application starting at main [eva] Computing initial state [eva:alarm] tests/float/const2.i:2: Warning: - non-finite float value. assert \is_finite(1e40f); + non-finite float value. assert \is_finite((float)1e40f); [eva] tests/float/const2.i:2: Warning: evaluation of initializer '1e40f' failed [eva] Initial state computed [eva:initial-state] Values of globals at initialization diff --git a/tests/float/oracle/const4.0.res.oracle b/tests/float/oracle/const4.0.res.oracle index fc3b0e788b8..7c1da402c21 100644 --- a/tests/float/oracle/const4.0.res.oracle +++ b/tests/float/oracle/const4.0.res.oracle @@ -6,7 +6,7 @@ [eva] Analyzing a complete application starting at main [eva] Computing initial state [eva:alarm] tests/float/const4.i:7: Warning: - non-finite float value. assert \is_finite(3.405e38f); + non-finite float value. assert \is_finite((float)3.405e38f); [eva] tests/float/const4.i:7: Warning: evaluation of initializer '(double)3.405e38f' failed [eva] Initial state computed diff --git a/tests/float/oracle/const4.1.res.oracle b/tests/float/oracle/const4.1.res.oracle index 5005f2e7aa3..7f138102251 100644 --- a/tests/float/oracle/const4.1.res.oracle +++ b/tests/float/oracle/const4.1.res.oracle @@ -6,7 +6,7 @@ [eva] Analyzing a complete application starting at main [eva] Computing initial state [eva:alarm] tests/float/const4.i:7: Warning: - non-finite float value. assert \is_finite(3.405e38f); + non-finite float value. assert \is_finite((float)3.405e38f); [eva] Initial state computed [eva:initial-state] Values of globals at initialization f1 ∈ [3.39999995214e+38 .. 3.40000015497e+38] diff --git a/tests/float/oracle/cte_overflow.res.oracle b/tests/float/oracle/cte_overflow.res.oracle index c0a3a0173b1..0aea223139c 100644 --- a/tests/float/oracle/cte_overflow.res.oracle +++ b/tests/float/oracle/cte_overflow.res.oracle @@ -13,9 +13,9 @@ [eva:initial-state] Values of globals at initialization v ∈ [--..--] [eva:alarm] tests/float/cte_overflow.i:12: Warning: - non-finite double value. assert \is_finite(1e500); + non-finite double value. assert \is_finite((double)1e500); [eva:alarm] tests/float/cte_overflow.i:17: Warning: - non-finite float value. assert \is_finite(1e80f); + non-finite float value. assert \is_finite((float)1e80f); [eva] Recording results for main [eva] done for function main [eva] tests/float/cte_overflow.i:12: diff --git a/tests/float/oracle/dr_infinity.res.oracle b/tests/float/oracle/dr_infinity.res.oracle index 1a2c304b3a2..8d194475db5 100644 --- a/tests/float/oracle/dr_infinity.res.oracle +++ b/tests/float/oracle/dr_infinity.res.oracle @@ -22,28 +22,34 @@ v ∈ [--..--] [eva] tests/float/dr_infinity.i:9: Frama_C_show_each: {0x1.fffffe0000000p127} [eva:alarm] tests/float/dr_infinity.i:11: Warning: - non-finite float value. assert \is_finite((float)3.402823567797366e+38); + non-finite float value. + assert \is_finite((float)((double)3.402823567797366e+38)); [eva:alarm] tests/float/dr_infinity.i:16: Warning: - non-finite float value. assert \is_finite((float)(x * x)); + non-finite float value. assert \is_finite(\mul_float(x, x)); [eva:alarm] tests/float/dr_infinity.i:21: Warning: - non-finite double value. assert \is_finite((double)(d * (double)10)); + non-finite double value. + assert \is_finite(\mul_double(d, (double)((int)10))); [eva:alarm] tests/float/dr_infinity.i:26: Warning: - non-finite double value. assert \is_finite((double)((double)2 / d)); + non-finite double value. assert \is_finite(\div_double((double)((int)2), d)); [eva:alarm] tests/float/dr_infinity.i:31: Warning: - non-finite double value. assert \is_finite((double)(d / 0.01)); + non-finite double value. assert \is_finite(\div_double(d, (double)0.01)); [eva:alarm] tests/float/dr_infinity.i:36: Warning: non-finite float value. - assert \is_finite((float)((double)((double)x / 0.001))); + assert \is_finite((float)\div_double((double)x, (double)0.001)); [eva:alarm] tests/float/dr_infinity.i:41: Warning: - non-finite double value. assert \is_finite((double)(d / 0.)); + non-finite double value. assert \is_finite(\div_double(d, (double)0.)); [eva] Recording results for main [eva] done for function main [eva] tests/float/dr_infinity.i:11: assertion 'Eva,is_nan_or_infinite' got final status invalid. [eva] tests/float/dr_infinity.i:16: assertion 'Eva,is_nan_or_infinite' got final status invalid. +[eva] tests/float/dr_infinity.i:21: + assertion 'Eva,is_nan_or_infinite' got final status invalid. [eva] tests/float/dr_infinity.i:26: assertion 'Eva,is_nan_or_infinite' got final status invalid. +[eva] tests/float/dr_infinity.i:31: + assertion 'Eva,is_nan_or_infinite' got final status invalid. [eva] tests/float/dr_infinity.i:36: assertion 'Eva,is_nan_or_infinite' got final status invalid. [eva] tests/float/dr_infinity.i:41: diff --git a/tests/float/oracle/logic.0.res.oracle b/tests/float/oracle/logic.0.res.oracle index a78dc74e8ea..2f18d3f38e7 100644 --- a/tests/float/oracle/logic.0.res.oracle +++ b/tests/float/oracle/logic.0.res.oracle @@ -59,7 +59,8 @@ [eva:alarm] tests/float/logic.i:42: Warning: check got status invalid. [eva:alarm] tests/float/logic.i:43: Warning: check got status invalid. [eva:alarm] tests/float/logic.i:45: Warning: - non-finite double value. assert \is_finite((double)(1. / 0.)); + non-finite double value. + assert \is_finite(\div_double((double)1., (double)0.)); [eva:alarm] tests/float/logic.i:64: Warning: check got status unknown. [eva:alarm] tests/float/logic.i:65: Warning: check got status unknown. [eva:alarm] tests/float/logic.i:66: Warning: check got status unknown. @@ -314,7 +315,8 @@ [eva] Recording results for test_comparison_reduction [eva] Done for function test_comparison_reduction [eva:alarm] tests/float/logic.i:133: Warning: - non-finite double value. assert \is_finite((double)(1. / 0.)); + non-finite double value. + assert \is_finite(\div_double((double)1., (double)0.)); [eva] Recording results for test_builtin_comparisons [eva] Done for function test_builtin_comparisons [eva] computing for function test_is_finite <- main. diff --git a/tests/float/oracle/nonlin.0.res.oracle b/tests/float/oracle/nonlin.0.res.oracle index 5e60b7a32e5..fc0648394e7 100644 --- a/tests/float/oracle/nonlin.0.res.oracle +++ b/tests/float/oracle/nonlin.0.res.oracle @@ -171,10 +171,10 @@ [eva] Done for function Frama_C_float_interval [eva:alarm] tests/float/nonlin.c:63: Warning: accessing out of bounds index. - assert 0 ≤ (int)((double)((double)(i * i) + 2.0)); + assert 0 ≤ (int)\add_double(\mul_double(i, i), (double)2.0); [eva:alarm] tests/float/nonlin.c:63: Warning: accessing out of bounds index. - assert (int)((double)((double)(i * i) + 2.0)) < 10; + assert (int)\add_double(\mul_double(i, i), (double)2.0) < 10; [eva] computing for function access_bits <- other <- main. Called from tests/float/nonlin.c:69. [eva] Recording results for access_bits @@ -195,8 +195,9 @@ [eva:alarm] tests/float/nonlin.c:77: Warning: non-finite double value. assert - \is_finite((double)((double)1 / - (double)((double)((double)ff * (double)ff) + 0.000000001))); + \is_finite(\div_double((double)((int)1), + \add_double(\mul_double((double)ff, (double)ff), + (double)0.000000001))); [eva] Recording results for split_alarm [eva] Done for function split_alarm [eva] computing for function norm <- main. @@ -220,12 +221,12 @@ function Frama_C_float_interval: precondition 'order' got status valid. [eva] Done for function Frama_C_float_interval [eva:alarm] tests/float/nonlin.c:92: Warning: - non-finite float value. assert \is_finite((float)(v1 * v1)); + non-finite float value. assert \is_finite(\mul_float(v1, v1)); [eva:alarm] tests/float/nonlin.c:92: Warning: - non-finite float value. assert \is_finite((float)(v2 * v2)); + non-finite float value. assert \is_finite(\mul_float(v2, v2)); [eva:alarm] tests/float/nonlin.c:92: Warning: non-finite float value. - assert \is_finite((float)((float)(v1 * v1) + (float)(v2 * v2))); + assert \is_finite(\add_float(\mul_float(v1, v1), \mul_float(v2, v2))); [eva] Recording results for norm [eva] Done for function norm [eva] computing for function garbled <- main. @@ -243,7 +244,7 @@ [eva:alarm] tests/float/nonlin.c:99: Warning: non-finite float value. assert \is_finite(a_0); [eva:alarm] tests/float/nonlin.c:99: Warning: - non-finite float value. assert \is_finite((float)(a_0 + a_0)); + non-finite float value. assert \is_finite(\add_float(a_0, a_0)); [eva] tests/float/nonlin.c:99: Assigning imprecise value to f. The imprecision originates from Arithmetic @@ -260,7 +261,8 @@ [eva] Done for function Frama_C_float_interval [eva:alarm] tests/float/nonlin.c:113: Warning: non-finite float value. - assert \is_finite((float)(f1 / (float)((float)((float)(f + f) - f) - f1))); + assert + \is_finite(\div_float(f1, \sub_float(\sub_float(\add_float(f, f), f), f1))); [eva] Recording results for around_zeros [eva] Done for function around_zeros [eva] computing for function subdivide_strategy <- main. @@ -276,7 +278,7 @@ non-finite double value. assert \is_finite(nondet); [eva:alarm] tests/float/nonlin.c:135: Warning: non-finite double value. - assert \is_finite((double)((double)(x_0 - d_0) * (double)(x_0 - d_0))); + assert \is_finite(\mul_double(\sub_double(x_0, d_0), \sub_double(x_0, d_0))); [eva] computing for function Frama_C_float_interval <- subdivide_strategy <- main. Called from tests/float/nonlin.c:136. [eva] tests/float/nonlin.c:136: diff --git a/tests/float/oracle/nonlin.1.res.oracle b/tests/float/oracle/nonlin.1.res.oracle index 036f8d26e43..6116e8b7c3b 100644 --- a/tests/float/oracle/nonlin.1.res.oracle +++ b/tests/float/oracle/nonlin.1.res.oracle @@ -177,7 +177,7 @@ [eva:nonlin] tests/float/nonlin.c:63: subdividing on i [eva:alarm] tests/float/nonlin.c:63: Warning: accessing out of bounds index. - assert (int)((double)((double)(i * i) + 2.0)) < 10; + assert (int)\add_double(\mul_double(i, i), (double)2.0) < 10; [eva:nonlin] tests/float/nonlin.c:64: non-linear 's - s', lv 's' [eva:nonlin] tests/float/nonlin.c:64: subdividing on s [eva:nonlin] tests/float/nonlin.c:65: non-linear 's - s', lv 's' @@ -243,12 +243,12 @@ [eva:nonlin] tests/float/nonlin.c:92: subdividing on v1 [eva:nonlin] tests/float/nonlin.c:92: subdividing on v2 [eva:alarm] tests/float/nonlin.c:92: Warning: - non-finite float value. assert \is_finite((float)(v1 * v1)); + non-finite float value. assert \is_finite(\mul_float(v1, v1)); [eva:alarm] tests/float/nonlin.c:92: Warning: - non-finite float value. assert \is_finite((float)(v2 * v2)); + non-finite float value. assert \is_finite(\mul_float(v2, v2)); [eva:alarm] tests/float/nonlin.c:92: Warning: non-finite float value. - assert \is_finite((float)((float)(v1 * v1) + (float)(v2 * v2))); + assert \is_finite(\add_float(\mul_float(v1, v1), \mul_float(v2, v2))); [eva] Recording results for norm [eva] Done for function norm [eva] computing for function garbled <- main. @@ -266,7 +266,7 @@ [eva:alarm] tests/float/nonlin.c:99: Warning: non-finite float value. assert \is_finite(a_0); [eva:alarm] tests/float/nonlin.c:99: Warning: - non-finite float value. assert \is_finite((float)(a_0 + a_0)); + non-finite float value. assert \is_finite(\add_float(a_0, a_0)); [eva] tests/float/nonlin.c:99: Assigning imprecise value to f. The imprecision originates from Arithmetic @@ -287,7 +287,8 @@ [eva:nonlin] tests/float/nonlin.c:113: subdividing on f [eva:alarm] tests/float/nonlin.c:113: Warning: non-finite float value. - assert \is_finite((float)(f1 / (float)((float)((float)(f + f) - f) - f1))); + assert + \is_finite(\div_float(f1, \sub_float(\sub_float(\add_float(f, f), f), f1))); [eva] Recording results for around_zeros [eva] Done for function around_zeros [eva] computing for function subdivide_strategy <- main. @@ -308,7 +309,7 @@ [eva:nonlin] tests/float/nonlin.c:135: subdividing on x_0 [eva:alarm] tests/float/nonlin.c:135: Warning: non-finite double value. - assert \is_finite((double)((double)(x_0 - d_0) * (double)(x_0 - d_0))); + assert \is_finite(\mul_double(\sub_double(x_0, d_0), \sub_double(x_0, d_0))); [eva] computing for function Frama_C_float_interval <- subdivide_strategy <- main. Called from tests/float/nonlin.c:136. [eva] tests/float/nonlin.c:136: diff --git a/tests/float/oracle/nonlin.2.res.oracle b/tests/float/oracle/nonlin.2.res.oracle index 112f643e881..15dfbc52f71 100644 --- a/tests/float/oracle/nonlin.2.res.oracle +++ b/tests/float/oracle/nonlin.2.res.oracle @@ -177,7 +177,7 @@ [eva:nonlin] tests/float/nonlin.c:63: subdividing on i [eva:alarm] tests/float/nonlin.c:63: Warning: accessing out of bounds index. - assert (int)((double)((double)(i * i) + 2.0)) < 10; + assert (int)\add_double(\mul_double(i, i), (double)2.0) < 10; [eva:nonlin] tests/float/nonlin.c:64: non-linear 's - s', lv 's' [eva:nonlin] tests/float/nonlin.c:64: subdividing on s [eva:nonlin] tests/float/nonlin.c:65: non-linear 's - s', lv 's' diff --git a/tests/float/oracle/nonlin.3.res.oracle b/tests/float/oracle/nonlin.3.res.oracle index f791b980831..e6446859b39 100644 --- a/tests/float/oracle/nonlin.3.res.oracle +++ b/tests/float/oracle/nonlin.3.res.oracle @@ -171,10 +171,10 @@ [eva] Done for function Frama_C_float_interval [eva:alarm] tests/float/nonlin.c:63: Warning: accessing out of bounds index. - assert 0 ≤ (int)((double)((double)((float)(i * i)) + 2.0)); + assert 0 ≤ (int)\add_double((double)\mul_float(i, i), (double)2.0); [eva:alarm] tests/float/nonlin.c:63: Warning: accessing out of bounds index. - assert (int)((double)((double)((float)(i * i)) + 2.0)) < 10; + assert (int)\add_double((double)\mul_float(i, i), (double)2.0) < 10; [eva] computing for function access_bits <- other <- main. Called from tests/float/nonlin.c:69. [eva] Recording results for access_bits @@ -195,8 +195,9 @@ [eva:alarm] tests/float/nonlin.c:77: Warning: non-finite double value. assert - \is_finite((double)((double)1 / - (double)((double)((double)ff * (double)ff) + 0.000000001))); + \is_finite(\div_double((double)((int)1), + \add_double(\mul_double((double)ff, (double)ff), + (double)0.000000001))); [eva] Recording results for split_alarm [eva] Done for function split_alarm [eva] computing for function norm <- main. @@ -220,12 +221,12 @@ function Frama_C_float_interval: precondition 'order' got status valid. [eva] Done for function Frama_C_float_interval [eva:alarm] tests/float/nonlin.c:92: Warning: - non-finite float value. assert \is_finite((float)(v1 * v1)); + non-finite float value. assert \is_finite(\mul_float(v1, v1)); [eva:alarm] tests/float/nonlin.c:92: Warning: - non-finite float value. assert \is_finite((float)(v2 * v2)); + non-finite float value. assert \is_finite(\mul_float(v2, v2)); [eva:alarm] tests/float/nonlin.c:92: Warning: non-finite float value. - assert \is_finite((float)((float)(v1 * v1) + (float)(v2 * v2))); + assert \is_finite(\add_float(\mul_float(v1, v1), \mul_float(v2, v2))); [eva] Recording results for norm [eva] Done for function norm [eva] computing for function garbled <- main. @@ -243,7 +244,7 @@ [eva:alarm] tests/float/nonlin.c:99: Warning: non-finite float value. assert \is_finite(a_0); [eva:alarm] tests/float/nonlin.c:99: Warning: - non-finite float value. assert \is_finite((float)(a_0 + a_0)); + non-finite float value. assert \is_finite(\add_float(a_0, a_0)); [eva] tests/float/nonlin.c:99: Assigning imprecise value to f. The imprecision originates from Arithmetic @@ -260,7 +261,8 @@ [eva] Done for function Frama_C_float_interval [eva:alarm] tests/float/nonlin.c:113: Warning: non-finite float value. - assert \is_finite((float)(f1 / (float)((float)((float)(f + f) - f) - f1))); + assert + \is_finite(\div_float(f1, \sub_float(\sub_float(\add_float(f, f), f), f1))); [eva] Recording results for around_zeros [eva] Done for function around_zeros [eva] computing for function subdivide_strategy <- main. @@ -276,7 +278,7 @@ non-finite float value. assert \is_finite(nondet); [eva:alarm] tests/float/nonlin.c:135: Warning: non-finite float value. - assert \is_finite((float)((float)(x_0 - d_0) * (float)(x_0 - d_0))); + assert \is_finite(\mul_float(\sub_float(x_0, d_0), \sub_float(x_0, d_0))); [eva] computing for function Frama_C_float_interval <- subdivide_strategy <- main. Called from tests/float/nonlin.c:136. [eva] tests/float/nonlin.c:136: diff --git a/tests/float/oracle/nonlin.4.res.oracle b/tests/float/oracle/nonlin.4.res.oracle index ba58150afaf..52f4a2d9697 100644 --- a/tests/float/oracle/nonlin.4.res.oracle +++ b/tests/float/oracle/nonlin.4.res.oracle @@ -177,7 +177,7 @@ [eva:nonlin] tests/float/nonlin.c:63: subdividing on i [eva:alarm] tests/float/nonlin.c:63: Warning: accessing out of bounds index. - assert (int)((double)((double)((float)(i * i)) + 2.0)) < 10; + assert (int)\add_double((double)\mul_float(i, i), (double)2.0) < 10; [eva:nonlin] tests/float/nonlin.c:64: non-linear 's - s', lv 's' [eva:nonlin] tests/float/nonlin.c:64: subdividing on s [eva:nonlin] tests/float/nonlin.c:65: non-linear 's - s', lv 's' @@ -243,12 +243,12 @@ [eva:nonlin] tests/float/nonlin.c:92: subdividing on v1 [eva:nonlin] tests/float/nonlin.c:92: subdividing on v2 [eva:alarm] tests/float/nonlin.c:92: Warning: - non-finite float value. assert \is_finite((float)(v1 * v1)); + non-finite float value. assert \is_finite(\mul_float(v1, v1)); [eva:alarm] tests/float/nonlin.c:92: Warning: - non-finite float value. assert \is_finite((float)(v2 * v2)); + non-finite float value. assert \is_finite(\mul_float(v2, v2)); [eva:alarm] tests/float/nonlin.c:92: Warning: non-finite float value. - assert \is_finite((float)((float)(v1 * v1) + (float)(v2 * v2))); + assert \is_finite(\add_float(\mul_float(v1, v1), \mul_float(v2, v2))); [eva] Recording results for norm [eva] Done for function norm [eva] computing for function garbled <- main. @@ -266,7 +266,7 @@ [eva:alarm] tests/float/nonlin.c:99: Warning: non-finite float value. assert \is_finite(a_0); [eva:alarm] tests/float/nonlin.c:99: Warning: - non-finite float value. assert \is_finite((float)(a_0 + a_0)); + non-finite float value. assert \is_finite(\add_float(a_0, a_0)); [eva] tests/float/nonlin.c:99: Assigning imprecise value to f. The imprecision originates from Arithmetic @@ -287,7 +287,8 @@ [eva:nonlin] tests/float/nonlin.c:113: subdividing on f [eva:alarm] tests/float/nonlin.c:113: Warning: non-finite float value. - assert \is_finite((float)(f1 / (float)((float)((float)(f + f) - f) - f1))); + assert + \is_finite(\div_float(f1, \sub_float(\sub_float(\add_float(f, f), f), f1))); [eva] Recording results for around_zeros [eva] Done for function around_zeros [eva] computing for function subdivide_strategy <- main. @@ -308,7 +309,7 @@ [eva:nonlin] tests/float/nonlin.c:135: subdividing on x_0 [eva:alarm] tests/float/nonlin.c:135: Warning: non-finite float value. - assert \is_finite((float)((float)(x_0 - d_0) * (float)(x_0 - d_0))); + assert \is_finite(\mul_float(\sub_float(x_0, d_0), \sub_float(x_0, d_0))); [eva] computing for function Frama_C_float_interval <- subdivide_strategy <- main. Called from tests/float/nonlin.c:136. [eva] tests/float/nonlin.c:136: diff --git a/tests/float/oracle/nonlin.5.res.oracle b/tests/float/oracle/nonlin.5.res.oracle index 36e1a671ef6..04154d9e75b 100644 --- a/tests/float/oracle/nonlin.5.res.oracle +++ b/tests/float/oracle/nonlin.5.res.oracle @@ -177,7 +177,7 @@ [eva:nonlin] tests/float/nonlin.c:63: subdividing on i [eva:alarm] tests/float/nonlin.c:63: Warning: accessing out of bounds index. - assert (int)((double)((double)((float)(i * i)) + 2.0)) < 10; + assert (int)\add_double((double)\mul_float(i, i), (double)2.0) < 10; [eva:nonlin] tests/float/nonlin.c:64: non-linear 's - s', lv 's' [eva:nonlin] tests/float/nonlin.c:64: subdividing on s [eva:nonlin] tests/float/nonlin.c:65: non-linear 's - s', lv 's' diff --git a/tests/float/oracle/parse.res.oracle b/tests/float/oracle/parse.res.oracle index 99068d34513..3d54be548a3 100644 --- a/tests/float/oracle/parse.res.oracle +++ b/tests/float/oracle/parse.res.oracle @@ -14,11 +14,12 @@ [eva] tests/float/parse.i:26: Frama_C_show_each: {0x1.83a99c3ec7eb0p893}, {{ "reached" }} [eva:alarm] tests/float/parse.i:30: Warning: - non-finite double value. assert \is_finite(0.0000001E9999999999999999999); + non-finite double value. + assert \is_finite((double)0.0000001E9999999999999999999); [eva] tests/float/parse.i:36: Warning: cannot parse floating-point constant, returning imprecise result [eva:alarm] tests/float/parse.i:36: Warning: - non-finite long double value. assert \is_finite(0x1p32767L); + non-finite long double value. assert \is_finite((long double)0x1p32767L); [eva:alarm] tests/float/parse.i:37: Warning: non-finite long double value. assert \is_finite(l); [eva:alarm] tests/float/parse.i:37: Warning: diff --git a/tests/float/oracle/widen.0.res.oracle b/tests/float/oracle/widen.0.res.oracle index 218c0d29cca..4c881d40cff 100644 --- a/tests/float/oracle/widen.0.res.oracle +++ b/tests/float/oracle/widen.0.res.oracle @@ -8,7 +8,7 @@ Called from tests/float/widen.c:50. [eva] tests/float/widen.c:13: starting to merge loop iterations [eva:alarm] tests/float/widen.c:14: Warning: - non-finite double value. assert \is_finite((double)(max * 2.)); + non-finite double value. assert \is_finite(\mul_double(max, (double)2.)); [eva] tests/float/widen.c:16: starting to merge loop iterations [eva] tests/float/widen.c:24: Frama_C_show_each_double_inf: [1. .. 1.79769313486e+308] diff --git a/tests/misc/oracle/widen_hints_float.res.oracle b/tests/misc/oracle/widen_hints_float.res.oracle index 45e531fdbc4..0f168648e4d 100644 --- a/tests/misc/oracle/widen_hints_float.res.oracle +++ b/tests/misc/oracle/widen_hints_float.res.oracle @@ -37,7 +37,8 @@ [eva:alarm] tests/misc/widen_hints_float.c:34: Warning: non-finite double value. assert - \is_finite((double)((double)(f3 - (double)64) * (double)(f3 - (double)64))); + \is_finite(\mul_double(\sub_double(f3, (double)((int)64)), + \sub_double(f3, (double)((int)64)))); [eva] Recording results for parabola [eva] Done for function parabola [eva] computing for function trigo <- main. diff --git a/tests/rte/oracle/finite_float.res.oracle b/tests/rte/oracle/finite_float.res.oracle index 3e0ca8cba95..5adab0a6237 100644 --- a/tests/rte/oracle/finite_float.res.oracle +++ b/tests/rte/oracle/finite_float.res.oracle @@ -5,12 +5,12 @@ #include "math.h" void main(void) { - /*@ assert rte: is_nan_or_infinite: \is_finite(0x1p10000); */ + /*@ assert rte: is_nan_or_infinite: \is_finite((double)0x1p10000); */ double d = 0x1p10000; d = 0.; - /*@ assert rte: is_nan_or_infinite: \is_finite((double)(d / d)); */ + /*@ assert rte: is_nan_or_infinite: \is_finite(\div_double(d, d)); */ /*@ assert - rte: is_nan_or_infinite: \is_finite((double)((double)(d / d) + d)); + rte: is_nan_or_infinite: \is_finite(\add_double(\div_double(d, d), d)); */ double e = d / d + d; return; diff --git a/tests/slicing/oracle/keep_annot.2.res.oracle b/tests/slicing/oracle/keep_annot.2.res.oracle index 0cbe4ace479..f8ab7b83c16 100644 --- a/tests/slicing/oracle/keep_annot.2.res.oracle +++ b/tests/slicing/oracle/keep_annot.2.res.oracle @@ -14,8 +14,9 @@ [eva:alarm] tests/slicing/keep_annot.i:41: Warning: non-finite float value. assert - \is_finite((float)((double)((double)u - - (double)((double)*(dabs + (int)(ii + 1)) * 2.0)))); + \is_finite((float)\sub_double((double)u, + \mul_double((double)*(dabs + (int)(ii + 1)), + (double)2.0))); [eva:alarm] tests/slicing/keep_annot.i:42: Warning: assertion got status unknown. [eva] Recording results for L diff --git a/tests/slicing/oracle/keep_annot.3.res.oracle b/tests/slicing/oracle/keep_annot.3.res.oracle index 52b2ca08307..77fc3eb76de 100644 --- a/tests/slicing/oracle/keep_annot.3.res.oracle +++ b/tests/slicing/oracle/keep_annot.3.res.oracle @@ -14,8 +14,9 @@ [eva:alarm] tests/slicing/keep_annot.i:41: Warning: non-finite float value. assert - \is_finite((float)((double)((double)u - - (double)((double)*(dabs + (int)(ii + 1)) * 2.0)))); + \is_finite((float)\sub_double((double)u, + \mul_double((double)*(dabs + (int)(ii + 1)), + (double)2.0))); [eva:alarm] tests/slicing/keep_annot.i:42: Warning: assertion got status unknown. [eva] Recording results for L diff --git a/tests/slicing/oracle/unravel-variance.0.res.oracle b/tests/slicing/oracle/unravel-variance.0.res.oracle index b91a1fe5bed..0538b7db677 100644 --- a/tests/slicing/oracle/unravel-variance.0.res.oracle +++ b/tests/slicing/oracle/unravel-variance.0.res.oracle @@ -21,20 +21,20 @@ [eva:alarm] tests/slicing/unravel-variance.i:35: Warning: non-finite float value. assert \is_finite(x[i]); [eva:alarm] tests/slicing/unravel-variance.i:36: Warning: - non-finite float value. assert \is_finite((float)(x[i] * x[i])); + non-finite float value. assert \is_finite(\mul_float(x[i], x[i])); [eva] tests/slicing/unravel-variance.i:32: starting to merge loop iterations [eva] computing for function scanf <- main. Called from tests/slicing/unravel-variance.i:34. [eva] Done for function scanf [eva:alarm] tests/slicing/unravel-variance.i:35: Warning: - non-finite float value. assert \is_finite((float)(t1 + x[i])); + non-finite float value. assert \is_finite(\add_float(t1, x[i])); [eva:alarm] tests/slicing/unravel-variance.i:36: Warning: accessing uninitialized left-value. assert \initialized(&x[i]); [eva:alarm] tests/slicing/unravel-variance.i:36: Warning: non-finite float value. assert \is_finite(x[i]); [eva:alarm] tests/slicing/unravel-variance.i:36: Warning: non-finite float value. - assert \is_finite((float)(ssq + (float)(x[i] * x[i]))); + assert \is_finite(\add_float(ssq, \mul_float(x[i], x[i]))); [eva] computing for function scanf <- main. Called from tests/slicing/unravel-variance.i:34. [eva] Done for function scanf @@ -47,69 +47,75 @@ [eva:alarm] tests/slicing/unravel-variance.i:35: Warning: accessing out of bounds index. assert i < 1024; [eva:alarm] tests/slicing/unravel-variance.i:38: Warning: - non-finite float value. assert \is_finite((float)(t1 / (float)n)); + non-finite float value. assert \is_finite(\div_float(t1, (float)n)); [eva:alarm] tests/slicing/unravel-variance.i:39: Warning: - non-finite float value. assert \is_finite((float)((float)n * avg)); + non-finite float value. assert \is_finite(\mul_float((float)n, avg)); [eva:alarm] tests/slicing/unravel-variance.i:39: Warning: signed overflow. assert -2147483648 ≤ n - 1; [eva:alarm] tests/slicing/unravel-variance.i:39: Warning: non-finite float value. - assert \is_finite((float)((float)((float)n * avg) * avg)); + assert \is_finite(\mul_float(\mul_float((float)n, avg), avg)); [eva:alarm] tests/slicing/unravel-variance.i:39: Warning: non-finite float value. - assert \is_finite((float)(ssq - (float)((float)((float)n * avg) * avg))); + assert + \is_finite(\sub_float(ssq, \mul_float(\mul_float((float)n, avg), avg))); [eva:alarm] tests/slicing/unravel-variance.i:39: Warning: non-finite float value. assert - \is_finite((float)((float)(ssq - (float)((float)((float)n * avg) * avg)) / - (float)((int)(n - 1)))); + \is_finite(\div_float(\sub_float(ssq, + \mul_float(\mul_float((float)n, avg), avg)), + (float)((int)(n - 1)))); [eva:alarm] tests/slicing/unravel-variance.i:40: Warning: - non-finite float value. assert \is_finite((float)(t1 * avg)); + non-finite float value. assert \is_finite(\mul_float(t1, avg)); [eva:alarm] tests/slicing/unravel-variance.i:40: Warning: - non-finite float value. assert \is_finite((float)(ssq - (float)(t1 * avg))); + non-finite float value. + assert \is_finite(\sub_float(ssq, \mul_float(t1, avg))); [eva:alarm] tests/slicing/unravel-variance.i:40: Warning: non-finite float value. assert - \is_finite((float)((float)(ssq - (float)(t1 * avg)) / (float)((int)(n - 1)))); + \is_finite(\div_float(\sub_float(ssq, \mul_float(t1, avg)), + (float)((int)(n - 1)))); [eva:alarm] tests/slicing/unravel-variance.i:41: Warning: - non-finite float value. assert \is_finite((float)(t1 * t1)); + non-finite float value. assert \is_finite(\mul_float(t1, t1)); [eva:alarm] tests/slicing/unravel-variance.i:41: Warning: non-finite float value. - assert \is_finite((float)((float)(t1 * t1) / (float)n)); + assert \is_finite(\div_float(\mul_float(t1, t1), (float)n)); [eva:alarm] tests/slicing/unravel-variance.i:42: Warning: - non-finite float value. assert \is_finite((float)(ssq - t1)); + non-finite float value. assert \is_finite(\sub_float(ssq, t1)); [eva:alarm] tests/slicing/unravel-variance.i:42: Warning: non-finite float value. - assert \is_finite((float)((float)(ssq - t1) / (float)((int)(n - 1)))); + assert \is_finite(\div_float(\sub_float(ssq, t1), (float)((int)(n - 1)))); [eva:alarm] tests/slicing/unravel-variance.i:46: Warning: accessing uninitialized left-value. assert \initialized(&x[i]); [eva:alarm] tests/slicing/unravel-variance.i:46: Warning: non-finite float value. assert \is_finite(x[i]); [eva:alarm] tests/slicing/unravel-variance.i:46: Warning: - non-finite float value. assert \is_finite((float)(x[i] - avg)); + non-finite float value. assert \is_finite(\sub_float(x[i], avg)); [eva:alarm] tests/slicing/unravel-variance.i:48: Warning: - non-finite float value. assert \is_finite((float)(dev * dev)); + non-finite float value. assert \is_finite(\mul_float(dev, dev)); [eva] tests/slicing/unravel-variance.i:44: starting to merge loop iterations [eva:alarm] tests/slicing/unravel-variance.i:47: Warning: - non-finite float value. assert \is_finite((float)(t2 + dev)); + non-finite float value. assert \is_finite(\add_float(t2, dev)); [eva:alarm] tests/slicing/unravel-variance.i:48: Warning: - non-finite float value. assert \is_finite((float)(t1 + (float)(dev * dev))); + non-finite float value. + assert \is_finite(\add_float(t1, \mul_float(dev, dev))); [eva:alarm] tests/slicing/unravel-variance.i:50: Warning: - non-finite float value. assert \is_finite((float)(t2 * t2)); + non-finite float value. assert \is_finite(\mul_float(t2, t2)); [eva:alarm] tests/slicing/unravel-variance.i:50: Warning: non-finite float value. - assert \is_finite((float)((float)(t2 * t2) / (float)n)); + assert \is_finite(\div_float(\mul_float(t2, t2), (float)n)); [eva:alarm] tests/slicing/unravel-variance.i:50: Warning: non-finite float value. - assert \is_finite((float)(t1 - (float)((float)(t2 * t2) / (float)n))); + assert \is_finite(\sub_float(t1, \div_float(\mul_float(t2, t2), (float)n))); [eva:alarm] tests/slicing/unravel-variance.i:50: Warning: non-finite float value. assert - \is_finite((float)((float)(t1 - (float)((float)(t2 * t2) / (float)n)) / - (float)((int)(n - 1)))); + \is_finite(\div_float(\sub_float(t1, + \div_float(\mul_float(t2, t2), (float)n)), + (float)((int)(n - 1)))); [eva:alarm] tests/slicing/unravel-variance.i:51: Warning: non-finite float value. - assert \is_finite((float)(t1 / (float)((int)(n - 1)))); + assert \is_finite(\div_float(t1, (float)((int)(n - 1)))); [eva:alarm] tests/slicing/unravel-variance.i:52: Warning: overflow in conversion from floating-point to integer. assert -2147483649 < var2; diff --git a/tests/slicing/oracle/unravel-variance.1.res.oracle b/tests/slicing/oracle/unravel-variance.1.res.oracle index 1b7ede21df7..fa17384ccb6 100644 --- a/tests/slicing/oracle/unravel-variance.1.res.oracle +++ b/tests/slicing/oracle/unravel-variance.1.res.oracle @@ -21,20 +21,20 @@ [eva:alarm] tests/slicing/unravel-variance.i:35: Warning: non-finite float value. assert \is_finite(x[i]); [eva:alarm] tests/slicing/unravel-variance.i:36: Warning: - non-finite float value. assert \is_finite((float)(x[i] * x[i])); + non-finite float value. assert \is_finite(\mul_float(x[i], x[i])); [eva] tests/slicing/unravel-variance.i:32: starting to merge loop iterations [eva] computing for function scanf <- main. Called from tests/slicing/unravel-variance.i:34. [eva] Done for function scanf [eva:alarm] tests/slicing/unravel-variance.i:35: Warning: - non-finite float value. assert \is_finite((float)(t1 + x[i])); + non-finite float value. assert \is_finite(\add_float(t1, x[i])); [eva:alarm] tests/slicing/unravel-variance.i:36: Warning: accessing uninitialized left-value. assert \initialized(&x[i]); [eva:alarm] tests/slicing/unravel-variance.i:36: Warning: non-finite float value. assert \is_finite(x[i]); [eva:alarm] tests/slicing/unravel-variance.i:36: Warning: non-finite float value. - assert \is_finite((float)(ssq + (float)(x[i] * x[i]))); + assert \is_finite(\add_float(ssq, \mul_float(x[i], x[i]))); [eva] computing for function scanf <- main. Called from tests/slicing/unravel-variance.i:34. [eva] Done for function scanf @@ -47,69 +47,75 @@ [eva:alarm] tests/slicing/unravel-variance.i:35: Warning: accessing out of bounds index. assert i < 1024; [eva:alarm] tests/slicing/unravel-variance.i:38: Warning: - non-finite float value. assert \is_finite((float)(t1 / (float)n)); + non-finite float value. assert \is_finite(\div_float(t1, (float)n)); [eva:alarm] tests/slicing/unravel-variance.i:39: Warning: - non-finite float value. assert \is_finite((float)((float)n * avg)); + non-finite float value. assert \is_finite(\mul_float((float)n, avg)); [eva:alarm] tests/slicing/unravel-variance.i:39: Warning: signed overflow. assert -2147483648 ≤ n - 1; [eva:alarm] tests/slicing/unravel-variance.i:39: Warning: non-finite float value. - assert \is_finite((float)((float)((float)n * avg) * avg)); + assert \is_finite(\mul_float(\mul_float((float)n, avg), avg)); [eva:alarm] tests/slicing/unravel-variance.i:39: Warning: non-finite float value. - assert \is_finite((float)(ssq - (float)((float)((float)n * avg) * avg))); + assert + \is_finite(\sub_float(ssq, \mul_float(\mul_float((float)n, avg), avg))); [eva:alarm] tests/slicing/unravel-variance.i:39: Warning: non-finite float value. assert - \is_finite((float)((float)(ssq - (float)((float)((float)n * avg) * avg)) / - (float)((int)(n - 1)))); + \is_finite(\div_float(\sub_float(ssq, + \mul_float(\mul_float((float)n, avg), avg)), + (float)((int)(n - 1)))); [eva:alarm] tests/slicing/unravel-variance.i:40: Warning: - non-finite float value. assert \is_finite((float)(t1 * avg)); + non-finite float value. assert \is_finite(\mul_float(t1, avg)); [eva:alarm] tests/slicing/unravel-variance.i:40: Warning: - non-finite float value. assert \is_finite((float)(ssq - (float)(t1 * avg))); + non-finite float value. + assert \is_finite(\sub_float(ssq, \mul_float(t1, avg))); [eva:alarm] tests/slicing/unravel-variance.i:40: Warning: non-finite float value. assert - \is_finite((float)((float)(ssq - (float)(t1 * avg)) / (float)((int)(n - 1)))); + \is_finite(\div_float(\sub_float(ssq, \mul_float(t1, avg)), + (float)((int)(n - 1)))); [eva:alarm] tests/slicing/unravel-variance.i:41: Warning: - non-finite float value. assert \is_finite((float)(t1 * t1)); + non-finite float value. assert \is_finite(\mul_float(t1, t1)); [eva:alarm] tests/slicing/unravel-variance.i:41: Warning: non-finite float value. - assert \is_finite((float)((float)(t1 * t1) / (float)n)); + assert \is_finite(\div_float(\mul_float(t1, t1), (float)n)); [eva:alarm] tests/slicing/unravel-variance.i:42: Warning: - non-finite float value. assert \is_finite((float)(ssq - t1)); + non-finite float value. assert \is_finite(\sub_float(ssq, t1)); [eva:alarm] tests/slicing/unravel-variance.i:42: Warning: non-finite float value. - assert \is_finite((float)((float)(ssq - t1) / (float)((int)(n - 1)))); + assert \is_finite(\div_float(\sub_float(ssq, t1), (float)((int)(n - 1)))); [eva:alarm] tests/slicing/unravel-variance.i:46: Warning: accessing uninitialized left-value. assert \initialized(&x[i]); [eva:alarm] tests/slicing/unravel-variance.i:46: Warning: non-finite float value. assert \is_finite(x[i]); [eva:alarm] tests/slicing/unravel-variance.i:46: Warning: - non-finite float value. assert \is_finite((float)(x[i] - avg)); + non-finite float value. assert \is_finite(\sub_float(x[i], avg)); [eva:alarm] tests/slicing/unravel-variance.i:48: Warning: - non-finite float value. assert \is_finite((float)(dev * dev)); + non-finite float value. assert \is_finite(\mul_float(dev, dev)); [eva] tests/slicing/unravel-variance.i:44: starting to merge loop iterations [eva:alarm] tests/slicing/unravel-variance.i:47: Warning: - non-finite float value. assert \is_finite((float)(t2 + dev)); + non-finite float value. assert \is_finite(\add_float(t2, dev)); [eva:alarm] tests/slicing/unravel-variance.i:48: Warning: - non-finite float value. assert \is_finite((float)(t1 + (float)(dev * dev))); + non-finite float value. + assert \is_finite(\add_float(t1, \mul_float(dev, dev))); [eva:alarm] tests/slicing/unravel-variance.i:50: Warning: - non-finite float value. assert \is_finite((float)(t2 * t2)); + non-finite float value. assert \is_finite(\mul_float(t2, t2)); [eva:alarm] tests/slicing/unravel-variance.i:50: Warning: non-finite float value. - assert \is_finite((float)((float)(t2 * t2) / (float)n)); + assert \is_finite(\div_float(\mul_float(t2, t2), (float)n)); [eva:alarm] tests/slicing/unravel-variance.i:50: Warning: non-finite float value. - assert \is_finite((float)(t1 - (float)((float)(t2 * t2) / (float)n))); + assert \is_finite(\sub_float(t1, \div_float(\mul_float(t2, t2), (float)n))); [eva:alarm] tests/slicing/unravel-variance.i:50: Warning: non-finite float value. assert - \is_finite((float)((float)(t1 - (float)((float)(t2 * t2) / (float)n)) / - (float)((int)(n - 1)))); + \is_finite(\div_float(\sub_float(t1, + \div_float(\mul_float(t2, t2), (float)n)), + (float)((int)(n - 1)))); [eva:alarm] tests/slicing/unravel-variance.i:51: Warning: non-finite float value. - assert \is_finite((float)(t1 / (float)((int)(n - 1)))); + assert \is_finite(\div_float(t1, (float)((int)(n - 1)))); [eva:alarm] tests/slicing/unravel-variance.i:52: Warning: overflow in conversion from floating-point to integer. assert -2147483649 < var2; diff --git a/tests/slicing/oracle/unravel-variance.2.res.oracle b/tests/slicing/oracle/unravel-variance.2.res.oracle index 344a7d901f6..48bf86249b3 100644 --- a/tests/slicing/oracle/unravel-variance.2.res.oracle +++ b/tests/slicing/oracle/unravel-variance.2.res.oracle @@ -21,20 +21,20 @@ [eva:alarm] tests/slicing/unravel-variance.i:35: Warning: non-finite float value. assert \is_finite(x[i]); [eva:alarm] tests/slicing/unravel-variance.i:36: Warning: - non-finite float value. assert \is_finite((float)(x[i] * x[i])); + non-finite float value. assert \is_finite(\mul_float(x[i], x[i])); [eva] tests/slicing/unravel-variance.i:32: starting to merge loop iterations [eva] computing for function scanf <- main. Called from tests/slicing/unravel-variance.i:34. [eva] Done for function scanf [eva:alarm] tests/slicing/unravel-variance.i:35: Warning: - non-finite float value. assert \is_finite((float)(t1 + x[i])); + non-finite float value. assert \is_finite(\add_float(t1, x[i])); [eva:alarm] tests/slicing/unravel-variance.i:36: Warning: accessing uninitialized left-value. assert \initialized(&x[i]); [eva:alarm] tests/slicing/unravel-variance.i:36: Warning: non-finite float value. assert \is_finite(x[i]); [eva:alarm] tests/slicing/unravel-variance.i:36: Warning: non-finite float value. - assert \is_finite((float)(ssq + (float)(x[i] * x[i]))); + assert \is_finite(\add_float(ssq, \mul_float(x[i], x[i]))); [eva] computing for function scanf <- main. Called from tests/slicing/unravel-variance.i:34. [eva] Done for function scanf @@ -47,69 +47,75 @@ [eva:alarm] tests/slicing/unravel-variance.i:35: Warning: accessing out of bounds index. assert i < 1024; [eva:alarm] tests/slicing/unravel-variance.i:38: Warning: - non-finite float value. assert \is_finite((float)(t1 / (float)n)); + non-finite float value. assert \is_finite(\div_float(t1, (float)n)); [eva:alarm] tests/slicing/unravel-variance.i:39: Warning: - non-finite float value. assert \is_finite((float)((float)n * avg)); + non-finite float value. assert \is_finite(\mul_float((float)n, avg)); [eva:alarm] tests/slicing/unravel-variance.i:39: Warning: signed overflow. assert -2147483648 ≤ n - 1; [eva:alarm] tests/slicing/unravel-variance.i:39: Warning: non-finite float value. - assert \is_finite((float)((float)((float)n * avg) * avg)); + assert \is_finite(\mul_float(\mul_float((float)n, avg), avg)); [eva:alarm] tests/slicing/unravel-variance.i:39: Warning: non-finite float value. - assert \is_finite((float)(ssq - (float)((float)((float)n * avg) * avg))); + assert + \is_finite(\sub_float(ssq, \mul_float(\mul_float((float)n, avg), avg))); [eva:alarm] tests/slicing/unravel-variance.i:39: Warning: non-finite float value. assert - \is_finite((float)((float)(ssq - (float)((float)((float)n * avg) * avg)) / - (float)((int)(n - 1)))); + \is_finite(\div_float(\sub_float(ssq, + \mul_float(\mul_float((float)n, avg), avg)), + (float)((int)(n - 1)))); [eva:alarm] tests/slicing/unravel-variance.i:40: Warning: - non-finite float value. assert \is_finite((float)(t1 * avg)); + non-finite float value. assert \is_finite(\mul_float(t1, avg)); [eva:alarm] tests/slicing/unravel-variance.i:40: Warning: - non-finite float value. assert \is_finite((float)(ssq - (float)(t1 * avg))); + non-finite float value. + assert \is_finite(\sub_float(ssq, \mul_float(t1, avg))); [eva:alarm] tests/slicing/unravel-variance.i:40: Warning: non-finite float value. assert - \is_finite((float)((float)(ssq - (float)(t1 * avg)) / (float)((int)(n - 1)))); + \is_finite(\div_float(\sub_float(ssq, \mul_float(t1, avg)), + (float)((int)(n - 1)))); [eva:alarm] tests/slicing/unravel-variance.i:41: Warning: - non-finite float value. assert \is_finite((float)(t1 * t1)); + non-finite float value. assert \is_finite(\mul_float(t1, t1)); [eva:alarm] tests/slicing/unravel-variance.i:41: Warning: non-finite float value. - assert \is_finite((float)((float)(t1 * t1) / (float)n)); + assert \is_finite(\div_float(\mul_float(t1, t1), (float)n)); [eva:alarm] tests/slicing/unravel-variance.i:42: Warning: - non-finite float value. assert \is_finite((float)(ssq - t1)); + non-finite float value. assert \is_finite(\sub_float(ssq, t1)); [eva:alarm] tests/slicing/unravel-variance.i:42: Warning: non-finite float value. - assert \is_finite((float)((float)(ssq - t1) / (float)((int)(n - 1)))); + assert \is_finite(\div_float(\sub_float(ssq, t1), (float)((int)(n - 1)))); [eva:alarm] tests/slicing/unravel-variance.i:46: Warning: accessing uninitialized left-value. assert \initialized(&x[i]); [eva:alarm] tests/slicing/unravel-variance.i:46: Warning: non-finite float value. assert \is_finite(x[i]); [eva:alarm] tests/slicing/unravel-variance.i:46: Warning: - non-finite float value. assert \is_finite((float)(x[i] - avg)); + non-finite float value. assert \is_finite(\sub_float(x[i], avg)); [eva:alarm] tests/slicing/unravel-variance.i:48: Warning: - non-finite float value. assert \is_finite((float)(dev * dev)); + non-finite float value. assert \is_finite(\mul_float(dev, dev)); [eva] tests/slicing/unravel-variance.i:44: starting to merge loop iterations [eva:alarm] tests/slicing/unravel-variance.i:47: Warning: - non-finite float value. assert \is_finite((float)(t2 + dev)); + non-finite float value. assert \is_finite(\add_float(t2, dev)); [eva:alarm] tests/slicing/unravel-variance.i:48: Warning: - non-finite float value. assert \is_finite((float)(t1 + (float)(dev * dev))); + non-finite float value. + assert \is_finite(\add_float(t1, \mul_float(dev, dev))); [eva:alarm] tests/slicing/unravel-variance.i:50: Warning: - non-finite float value. assert \is_finite((float)(t2 * t2)); + non-finite float value. assert \is_finite(\mul_float(t2, t2)); [eva:alarm] tests/slicing/unravel-variance.i:50: Warning: non-finite float value. - assert \is_finite((float)((float)(t2 * t2) / (float)n)); + assert \is_finite(\div_float(\mul_float(t2, t2), (float)n)); [eva:alarm] tests/slicing/unravel-variance.i:50: Warning: non-finite float value. - assert \is_finite((float)(t1 - (float)((float)(t2 * t2) / (float)n))); + assert \is_finite(\sub_float(t1, \div_float(\mul_float(t2, t2), (float)n))); [eva:alarm] tests/slicing/unravel-variance.i:50: Warning: non-finite float value. assert - \is_finite((float)((float)(t1 - (float)((float)(t2 * t2) / (float)n)) / - (float)((int)(n - 1)))); + \is_finite(\div_float(\sub_float(t1, + \div_float(\mul_float(t2, t2), (float)n)), + (float)((int)(n - 1)))); [eva:alarm] tests/slicing/unravel-variance.i:51: Warning: non-finite float value. - assert \is_finite((float)(t1 / (float)((int)(n - 1)))); + assert \is_finite(\div_float(t1, (float)((int)(n - 1)))); [eva:alarm] tests/slicing/unravel-variance.i:52: Warning: overflow in conversion from floating-point to integer. assert -2147483649 < var2; diff --git a/tests/slicing/oracle/unravel-variance.3.res.oracle b/tests/slicing/oracle/unravel-variance.3.res.oracle index 75bbcf89bca..6f444dfaef6 100644 --- a/tests/slicing/oracle/unravel-variance.3.res.oracle +++ b/tests/slicing/oracle/unravel-variance.3.res.oracle @@ -21,20 +21,20 @@ [eva:alarm] tests/slicing/unravel-variance.i:35: Warning: non-finite float value. assert \is_finite(x[i]); [eva:alarm] tests/slicing/unravel-variance.i:36: Warning: - non-finite float value. assert \is_finite((float)(x[i] * x[i])); + non-finite float value. assert \is_finite(\mul_float(x[i], x[i])); [eva] tests/slicing/unravel-variance.i:32: starting to merge loop iterations [eva] computing for function scanf <- main. Called from tests/slicing/unravel-variance.i:34. [eva] Done for function scanf [eva:alarm] tests/slicing/unravel-variance.i:35: Warning: - non-finite float value. assert \is_finite((float)(t1 + x[i])); + non-finite float value. assert \is_finite(\add_float(t1, x[i])); [eva:alarm] tests/slicing/unravel-variance.i:36: Warning: accessing uninitialized left-value. assert \initialized(&x[i]); [eva:alarm] tests/slicing/unravel-variance.i:36: Warning: non-finite float value. assert \is_finite(x[i]); [eva:alarm] tests/slicing/unravel-variance.i:36: Warning: non-finite float value. - assert \is_finite((float)(ssq + (float)(x[i] * x[i]))); + assert \is_finite(\add_float(ssq, \mul_float(x[i], x[i]))); [eva] computing for function scanf <- main. Called from tests/slicing/unravel-variance.i:34. [eva] Done for function scanf @@ -47,69 +47,75 @@ [eva:alarm] tests/slicing/unravel-variance.i:35: Warning: accessing out of bounds index. assert i < 1024; [eva:alarm] tests/slicing/unravel-variance.i:38: Warning: - non-finite float value. assert \is_finite((float)(t1 / (float)n)); + non-finite float value. assert \is_finite(\div_float(t1, (float)n)); [eva:alarm] tests/slicing/unravel-variance.i:39: Warning: - non-finite float value. assert \is_finite((float)((float)n * avg)); + non-finite float value. assert \is_finite(\mul_float((float)n, avg)); [eva:alarm] tests/slicing/unravel-variance.i:39: Warning: signed overflow. assert -2147483648 ≤ n - 1; [eva:alarm] tests/slicing/unravel-variance.i:39: Warning: non-finite float value. - assert \is_finite((float)((float)((float)n * avg) * avg)); + assert \is_finite(\mul_float(\mul_float((float)n, avg), avg)); [eva:alarm] tests/slicing/unravel-variance.i:39: Warning: non-finite float value. - assert \is_finite((float)(ssq - (float)((float)((float)n * avg) * avg))); + assert + \is_finite(\sub_float(ssq, \mul_float(\mul_float((float)n, avg), avg))); [eva:alarm] tests/slicing/unravel-variance.i:39: Warning: non-finite float value. assert - \is_finite((float)((float)(ssq - (float)((float)((float)n * avg) * avg)) / - (float)((int)(n - 1)))); + \is_finite(\div_float(\sub_float(ssq, + \mul_float(\mul_float((float)n, avg), avg)), + (float)((int)(n - 1)))); [eva:alarm] tests/slicing/unravel-variance.i:40: Warning: - non-finite float value. assert \is_finite((float)(t1 * avg)); + non-finite float value. assert \is_finite(\mul_float(t1, avg)); [eva:alarm] tests/slicing/unravel-variance.i:40: Warning: - non-finite float value. assert \is_finite((float)(ssq - (float)(t1 * avg))); + non-finite float value. + assert \is_finite(\sub_float(ssq, \mul_float(t1, avg))); [eva:alarm] tests/slicing/unravel-variance.i:40: Warning: non-finite float value. assert - \is_finite((float)((float)(ssq - (float)(t1 * avg)) / (float)((int)(n - 1)))); + \is_finite(\div_float(\sub_float(ssq, \mul_float(t1, avg)), + (float)((int)(n - 1)))); [eva:alarm] tests/slicing/unravel-variance.i:41: Warning: - non-finite float value. assert \is_finite((float)(t1 * t1)); + non-finite float value. assert \is_finite(\mul_float(t1, t1)); [eva:alarm] tests/slicing/unravel-variance.i:41: Warning: non-finite float value. - assert \is_finite((float)((float)(t1 * t1) / (float)n)); + assert \is_finite(\div_float(\mul_float(t1, t1), (float)n)); [eva:alarm] tests/slicing/unravel-variance.i:42: Warning: - non-finite float value. assert \is_finite((float)(ssq - t1)); + non-finite float value. assert \is_finite(\sub_float(ssq, t1)); [eva:alarm] tests/slicing/unravel-variance.i:42: Warning: non-finite float value. - assert \is_finite((float)((float)(ssq - t1) / (float)((int)(n - 1)))); + assert \is_finite(\div_float(\sub_float(ssq, t1), (float)((int)(n - 1)))); [eva:alarm] tests/slicing/unravel-variance.i:46: Warning: accessing uninitialized left-value. assert \initialized(&x[i]); [eva:alarm] tests/slicing/unravel-variance.i:46: Warning: non-finite float value. assert \is_finite(x[i]); [eva:alarm] tests/slicing/unravel-variance.i:46: Warning: - non-finite float value. assert \is_finite((float)(x[i] - avg)); + non-finite float value. assert \is_finite(\sub_float(x[i], avg)); [eva:alarm] tests/slicing/unravel-variance.i:48: Warning: - non-finite float value. assert \is_finite((float)(dev * dev)); + non-finite float value. assert \is_finite(\mul_float(dev, dev)); [eva] tests/slicing/unravel-variance.i:44: starting to merge loop iterations [eva:alarm] tests/slicing/unravel-variance.i:47: Warning: - non-finite float value. assert \is_finite((float)(t2 + dev)); + non-finite float value. assert \is_finite(\add_float(t2, dev)); [eva:alarm] tests/slicing/unravel-variance.i:48: Warning: - non-finite float value. assert \is_finite((float)(t1 + (float)(dev * dev))); + non-finite float value. + assert \is_finite(\add_float(t1, \mul_float(dev, dev))); [eva:alarm] tests/slicing/unravel-variance.i:50: Warning: - non-finite float value. assert \is_finite((float)(t2 * t2)); + non-finite float value. assert \is_finite(\mul_float(t2, t2)); [eva:alarm] tests/slicing/unravel-variance.i:50: Warning: non-finite float value. - assert \is_finite((float)((float)(t2 * t2) / (float)n)); + assert \is_finite(\div_float(\mul_float(t2, t2), (float)n)); [eva:alarm] tests/slicing/unravel-variance.i:50: Warning: non-finite float value. - assert \is_finite((float)(t1 - (float)((float)(t2 * t2) / (float)n))); + assert \is_finite(\sub_float(t1, \div_float(\mul_float(t2, t2), (float)n))); [eva:alarm] tests/slicing/unravel-variance.i:50: Warning: non-finite float value. assert - \is_finite((float)((float)(t1 - (float)((float)(t2 * t2) / (float)n)) / - (float)((int)(n - 1)))); + \is_finite(\div_float(\sub_float(t1, + \div_float(\mul_float(t2, t2), (float)n)), + (float)((int)(n - 1)))); [eva:alarm] tests/slicing/unravel-variance.i:51: Warning: non-finite float value. - assert \is_finite((float)(t1 / (float)((int)(n - 1)))); + assert \is_finite(\div_float(t1, (float)((int)(n - 1)))); [eva:alarm] tests/slicing/unravel-variance.i:52: Warning: overflow in conversion from floating-point to integer. assert -2147483649 < var2; diff --git a/tests/slicing/oracle/unravel-variance.4.res.oracle b/tests/slicing/oracle/unravel-variance.4.res.oracle index f651a4d6a3b..ac6ef9b1483 100644 --- a/tests/slicing/oracle/unravel-variance.4.res.oracle +++ b/tests/slicing/oracle/unravel-variance.4.res.oracle @@ -21,20 +21,20 @@ [eva:alarm] tests/slicing/unravel-variance.i:35: Warning: non-finite float value. assert \is_finite(x[i]); [eva:alarm] tests/slicing/unravel-variance.i:36: Warning: - non-finite float value. assert \is_finite((float)(x[i] * x[i])); + non-finite float value. assert \is_finite(\mul_float(x[i], x[i])); [eva] tests/slicing/unravel-variance.i:32: starting to merge loop iterations [eva] computing for function scanf <- main. Called from tests/slicing/unravel-variance.i:34. [eva] Done for function scanf [eva:alarm] tests/slicing/unravel-variance.i:35: Warning: - non-finite float value. assert \is_finite((float)(t1 + x[i])); + non-finite float value. assert \is_finite(\add_float(t1, x[i])); [eva:alarm] tests/slicing/unravel-variance.i:36: Warning: accessing uninitialized left-value. assert \initialized(&x[i]); [eva:alarm] tests/slicing/unravel-variance.i:36: Warning: non-finite float value. assert \is_finite(x[i]); [eva:alarm] tests/slicing/unravel-variance.i:36: Warning: non-finite float value. - assert \is_finite((float)(ssq + (float)(x[i] * x[i]))); + assert \is_finite(\add_float(ssq, \mul_float(x[i], x[i]))); [eva] computing for function scanf <- main. Called from tests/slicing/unravel-variance.i:34. [eva] Done for function scanf @@ -47,69 +47,75 @@ [eva:alarm] tests/slicing/unravel-variance.i:35: Warning: accessing out of bounds index. assert i < 1024; [eva:alarm] tests/slicing/unravel-variance.i:38: Warning: - non-finite float value. assert \is_finite((float)(t1 / (float)n)); + non-finite float value. assert \is_finite(\div_float(t1, (float)n)); [eva:alarm] tests/slicing/unravel-variance.i:39: Warning: - non-finite float value. assert \is_finite((float)((float)n * avg)); + non-finite float value. assert \is_finite(\mul_float((float)n, avg)); [eva:alarm] tests/slicing/unravel-variance.i:39: Warning: signed overflow. assert -2147483648 ≤ n - 1; [eva:alarm] tests/slicing/unravel-variance.i:39: Warning: non-finite float value. - assert \is_finite((float)((float)((float)n * avg) * avg)); + assert \is_finite(\mul_float(\mul_float((float)n, avg), avg)); [eva:alarm] tests/slicing/unravel-variance.i:39: Warning: non-finite float value. - assert \is_finite((float)(ssq - (float)((float)((float)n * avg) * avg))); + assert + \is_finite(\sub_float(ssq, \mul_float(\mul_float((float)n, avg), avg))); [eva:alarm] tests/slicing/unravel-variance.i:39: Warning: non-finite float value. assert - \is_finite((float)((float)(ssq - (float)((float)((float)n * avg) * avg)) / - (float)((int)(n - 1)))); + \is_finite(\div_float(\sub_float(ssq, + \mul_float(\mul_float((float)n, avg), avg)), + (float)((int)(n - 1)))); [eva:alarm] tests/slicing/unravel-variance.i:40: Warning: - non-finite float value. assert \is_finite((float)(t1 * avg)); + non-finite float value. assert \is_finite(\mul_float(t1, avg)); [eva:alarm] tests/slicing/unravel-variance.i:40: Warning: - non-finite float value. assert \is_finite((float)(ssq - (float)(t1 * avg))); + non-finite float value. + assert \is_finite(\sub_float(ssq, \mul_float(t1, avg))); [eva:alarm] tests/slicing/unravel-variance.i:40: Warning: non-finite float value. assert - \is_finite((float)((float)(ssq - (float)(t1 * avg)) / (float)((int)(n - 1)))); + \is_finite(\div_float(\sub_float(ssq, \mul_float(t1, avg)), + (float)((int)(n - 1)))); [eva:alarm] tests/slicing/unravel-variance.i:41: Warning: - non-finite float value. assert \is_finite((float)(t1 * t1)); + non-finite float value. assert \is_finite(\mul_float(t1, t1)); [eva:alarm] tests/slicing/unravel-variance.i:41: Warning: non-finite float value. - assert \is_finite((float)((float)(t1 * t1) / (float)n)); + assert \is_finite(\div_float(\mul_float(t1, t1), (float)n)); [eva:alarm] tests/slicing/unravel-variance.i:42: Warning: - non-finite float value. assert \is_finite((float)(ssq - t1)); + non-finite float value. assert \is_finite(\sub_float(ssq, t1)); [eva:alarm] tests/slicing/unravel-variance.i:42: Warning: non-finite float value. - assert \is_finite((float)((float)(ssq - t1) / (float)((int)(n - 1)))); + assert \is_finite(\div_float(\sub_float(ssq, t1), (float)((int)(n - 1)))); [eva:alarm] tests/slicing/unravel-variance.i:46: Warning: accessing uninitialized left-value. assert \initialized(&x[i]); [eva:alarm] tests/slicing/unravel-variance.i:46: Warning: non-finite float value. assert \is_finite(x[i]); [eva:alarm] tests/slicing/unravel-variance.i:46: Warning: - non-finite float value. assert \is_finite((float)(x[i] - avg)); + non-finite float value. assert \is_finite(\sub_float(x[i], avg)); [eva:alarm] tests/slicing/unravel-variance.i:48: Warning: - non-finite float value. assert \is_finite((float)(dev * dev)); + non-finite float value. assert \is_finite(\mul_float(dev, dev)); [eva] tests/slicing/unravel-variance.i:44: starting to merge loop iterations [eva:alarm] tests/slicing/unravel-variance.i:47: Warning: - non-finite float value. assert \is_finite((float)(t2 + dev)); + non-finite float value. assert \is_finite(\add_float(t2, dev)); [eva:alarm] tests/slicing/unravel-variance.i:48: Warning: - non-finite float value. assert \is_finite((float)(t1 + (float)(dev * dev))); + non-finite float value. + assert \is_finite(\add_float(t1, \mul_float(dev, dev))); [eva:alarm] tests/slicing/unravel-variance.i:50: Warning: - non-finite float value. assert \is_finite((float)(t2 * t2)); + non-finite float value. assert \is_finite(\mul_float(t2, t2)); [eva:alarm] tests/slicing/unravel-variance.i:50: Warning: non-finite float value. - assert \is_finite((float)((float)(t2 * t2) / (float)n)); + assert \is_finite(\div_float(\mul_float(t2, t2), (float)n)); [eva:alarm] tests/slicing/unravel-variance.i:50: Warning: non-finite float value. - assert \is_finite((float)(t1 - (float)((float)(t2 * t2) / (float)n))); + assert \is_finite(\sub_float(t1, \div_float(\mul_float(t2, t2), (float)n))); [eva:alarm] tests/slicing/unravel-variance.i:50: Warning: non-finite float value. assert - \is_finite((float)((float)(t1 - (float)((float)(t2 * t2) / (float)n)) / - (float)((int)(n - 1)))); + \is_finite(\div_float(\sub_float(t1, + \div_float(\mul_float(t2, t2), (float)n)), + (float)((int)(n - 1)))); [eva:alarm] tests/slicing/unravel-variance.i:51: Warning: non-finite float value. - assert \is_finite((float)(t1 / (float)((int)(n - 1)))); + assert \is_finite(\div_float(t1, (float)((int)(n - 1)))); [eva:alarm] tests/slicing/unravel-variance.i:52: Warning: overflow in conversion from floating-point to integer. assert -2147483649 < var2; diff --git a/tests/value/oracle/CruiseControl.res.oracle b/tests/value/oracle/CruiseControl.res.oracle index f7ec6058482..42ea97e36d2 100644 --- a/tests/value/oracle/CruiseControl.res.oracle +++ b/tests/value/oracle/CruiseControl.res.oracle @@ -37,17 +37,19 @@ Called from tests/value/CruiseControl.c:242. [eva:alarm] tests/value/CruiseControl.c:172: Warning: non-finite float value. - assert \is_finite((float)(_C_->_L1_CruiseControl - _C_->_L2_CruiseControl)); + assert + \is_finite(\sub_float(_C_->_L1_CruiseControl, _C_->_L2_CruiseControl)); [eva:alarm] tests/value/CruiseControl.c:175: Warning: non-finite float value. - assert \is_finite((float)(_C_->_L3_CruiseControl * _C_->_L6_CruiseControl)); + assert + \is_finite(\mul_float(_C_->_L3_CruiseControl, _C_->_L6_CruiseControl)); [eva:alarm] tests/value/CruiseControl.c:194: Warning: non-finite float value. assert - \is_finite((float)(_C_->_L16_CruiseControl + _C_->_L18_CruiseControl)); + \is_finite(\add_float(_C_->_L16_CruiseControl, _C_->_L18_CruiseControl)); [eva:alarm] tests/value/CruiseControl.c:199: Warning: non-finite float value. - assert \is_finite((float)(_C_->ProportionnalAction + _C_->IntegralAction)); + assert \is_finite(\add_float(_C_->ProportionnalAction, _C_->IntegralAction)); [eva] computing for function SaturateThrottle <- ThrottleRegulation <- ThrottleCmd <- CruiseControl. Called from tests/value/CruiseControl.c:202. diff --git a/tests/value/oracle/bts1306.res.oracle b/tests/value/oracle/bts1306.res.oracle index cae97e181bc..f0036f751b5 100644 --- a/tests/value/oracle/bts1306.res.oracle +++ b/tests/value/oracle/bts1306.res.oracle @@ -7,7 +7,7 @@ [eva] computing for function g <- main. Called from tests/value/bts1306.i:9. [eva:alarm] tests/value/bts1306.i:5: Warning: - non-finite double value. assert \is_finite((double)(x * x)); + non-finite double value. assert \is_finite(\mul_double(x, x)); [eva] Recording results for g [eva] Done for function g [eva] Recording results for main @@ -20,7 +20,7 @@ /* Generated by Frama-C */ void g(double x) { - /*@ assert Eva: is_nan_or_infinite: \is_finite((double)(x * x)); */ + /*@ assert Eva: is_nan_or_infinite: \is_finite(\mul_double(x, x)); */ double y = x * x; return; } @@ -42,7 +42,7 @@ int main(double x) [eva] computing for function g <- main. Called from tests/value/bts1306.i:9. [eva:alarm] tests/value/bts1306.i:5: Warning: - non-finite double value. assert \is_finite((double)(x * x)); + non-finite double value. assert \is_finite(\mul_double(x, x)); [eva] Recording results for g [eva] Done for function g [eva] Recording results for main @@ -55,7 +55,7 @@ int main(double x) /* Generated by Frama-C */ void g(double x) { - /*@ assert Eva: is_nan_or_infinite: \is_finite((double)(x * x)); */ + /*@ assert Eva: is_nan_or_infinite: \is_finite(\mul_double(x, x)); */ double y = x * x; return; } diff --git a/tests/value/oracle/gauges.res.oracle b/tests/value/oracle/gauges.res.oracle index 7cf52beab44..bf8af26b55f 100644 --- a/tests/value/oracle/gauges.res.oracle +++ b/tests/value/oracle/gauges.res.oracle @@ -277,7 +277,7 @@ signed overflow. assert -2147483648 ≤ numNonZero - 1; [eva:alarm] tests/value/gauges.c:202: Warning: non-finite float value. - assert \is_finite((float)(*p * (float)(*tmp * *tmp_0))); + assert \is_finite(\mul_float(*p, \mul_float(*tmp, *tmp_0))); (tmp from A++, tmp_0 from B++) [eva] Recording results for main10_aux [eva] Done for function main10_aux diff --git a/tests/value/oracle/library.res.oracle b/tests/value/oracle/library.res.oracle index abf27f96c2e..16be4cd6f9d 100644 --- a/tests/value/oracle/library.res.oracle +++ b/tests/value/oracle/library.res.oracle @@ -129,7 +129,7 @@ [eva:alarm] tests/value/library.i:44: Warning: non-finite float value. assert \is_finite(*pf); [eva:alarm] tests/value/library.i:44: Warning: - non-finite float value. assert \is_finite((float)(*pf + *pf)); + non-finite float value. assert \is_finite(\add_float(*pf, *pf)); [eva] computing for function k <- main. Called from tests/value/library.i:45. [eva] using specification for function k diff --git a/tests/value/oracle/propagate_bottom.res.oracle b/tests/value/oracle/propagate_bottom.res.oracle index 2b291b99b11..f48513b4b78 100644 --- a/tests/value/oracle/propagate_bottom.res.oracle +++ b/tests/value/oracle/propagate_bottom.res.oracle @@ -17,17 +17,23 @@ [eva:alarm] tests/value/propagate_bottom.i:20: Warning: division by zero. assert 0 ≢ 0; [eva:alarm] tests/value/propagate_bottom.i:25: Warning: - non-finite double value. assert \is_finite((double)(1. / (double)0)); + non-finite double value. + assert \is_finite(\div_double((double)1., (double)((int)0))); [eva:alarm] tests/value/propagate_bottom.i:28: Warning: - non-finite double value. assert \is_finite((double)(1. / (double)0)); + non-finite double value. + assert \is_finite(\div_double((double)1., (double)((int)0))); [eva:alarm] tests/value/propagate_bottom.i:31: Warning: - non-finite double value. assert \is_finite((double)(1. / (double)0)); + non-finite double value. + assert \is_finite(\div_double((double)1., (double)((int)0))); [eva:alarm] tests/value/propagate_bottom.i:34: Warning: - non-finite double value. assert \is_finite((double)(1. / 0.)); + non-finite double value. + assert \is_finite(\div_double((double)1., (double)0.)); [eva:alarm] tests/value/propagate_bottom.i:37: Warning: - non-finite double value. assert \is_finite((double)(1. / 0.)); + non-finite double value. + assert \is_finite(\div_double((double)1., (double)0.)); [eva:alarm] tests/value/propagate_bottom.i:40: Warning: - non-finite double value. assert \is_finite((double)(1. / 0.)); + non-finite double value. + assert \is_finite(\div_double((double)1., (double)0.)); [eva] Recording results for main [eva] done for function main [eva] tests/value/propagate_bottom.i:5: diff --git a/tests/value/oracle/summary.3.res.oracle b/tests/value/oracle/summary.3.res.oracle index f5bcadc1abb..8c983fd90a2 100644 --- a/tests/value/oracle/summary.3.res.oracle +++ b/tests/value/oracle/summary.3.res.oracle @@ -30,7 +30,7 @@ [eva:alarm] tests/value/summary.i:34: Warning: non-finite double value. assert \is_finite(volatile_d); [eva:alarm] tests/value/summary.i:35: Warning: - non-finite double value. assert \is_finite((double)(d - d)); + non-finite double value. assert \is_finite(\sub_double(d, d)); [eva:alarm] tests/value/summary.i:36: Warning: overflow in conversion from floating-point to integer. assert -2147483649 < d; diff --git a/tests/value/oracle/summary.4.res.oracle b/tests/value/oracle/summary.4.res.oracle index 80d3ffdb4b1..3e988afe488 100644 --- a/tests/value/oracle/summary.4.res.oracle +++ b/tests/value/oracle/summary.4.res.oracle @@ -52,7 +52,7 @@ [eva:alarm] tests/value/summary.i:35: Warning: assertion 'rte,is_nan_or_infinite' got status unknown. [eva:alarm] tests/value/summary.i:35: Warning: - non-finite double value. assert \is_finite((double)(d - d)); + non-finite double value. assert \is_finite(\sub_double(d, d)); [eva:alarm] tests/value/summary.i:36: Warning: assertion 'rte,float_to_int' got status unknown. [eva:alarm] tests/value/summary.i:39: Warning: -- GitLab From c4a50e5669cc68576d9f9aaf3c0b6af0a28e0d8d Mon Sep 17 00:00:00 2001 From: Virgile Prevosto <virgile.prevosto@m4x.org> Date: Tue, 31 Mar 2020 17:18:42 +0200 Subject: [PATCH 079/218] [Makefile] compile even if tests/ is absent --- Makefile | 9 +++++++-- share/Makefile.plugin.template | 2 +- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 491b6b62d61..977133d5e91 100644 --- a/Makefile +++ b/Makefile @@ -1413,8 +1413,13 @@ acsl_tests: byte $(PRINT_EXEC) acsl_tests find doc/speclang -name \*.c -exec ./bin/toplevel.byte$(EXE) {} \; > /dev/null -LONELY_TESTS_ML_FILES:=\ - $(sort $(shell find $(TEST_DIRS_AS_PLUGIN:%=tests/%) -not -path '*/\.*' -name '*.ml')) +LONELY_TESTS_DIR:=$(wildcard $(TEST_DIRS_AS_PLUGIN:%=tests/%)) +ifeq ($(strip $(LONELY_TESTS_DIR)),) + LONELY_TESTS_ML_FILES:= +else + LONELY_TESTS_ML_FILES:=\ + $(sort $(shell find $(TEST_DIRS_AS_PLUGIN:%=tests/%) -not -path '*/\.*' -name '*.ml')) +endif $(foreach file,$(LONELY_TESTS_ML_FILES),\ $(eval $(file:%.ml=%.cmo): BFLAGS+=-I $(dir $(file)))) $(foreach file,$(LONELY_TESTS_ML_FILES),\ diff --git a/share/Makefile.plugin.template b/share/Makefile.plugin.template index 3745c5ab7ac..b3c44fc7601 100644 --- a/share/Makefile.plugin.template +++ b/share/Makefile.plugin.template @@ -899,7 +899,7 @@ $(@PLUGIN_NAME@_DIR)/@PLUGIN_NAME@_DEP_REDO $(@PLUGIN_NAME@_DIR)/.depend: \ $(@PLUGIN_NAME@_ML_SRC) \ $(@PLUGIN_NAME@_MLI) \ $(@PLUGIN_NAME@_GUI_MLI)) \ - $(foreach d,$(@PLUGIN_NAME@_TESTS_LIB_DIR),\ + $(foreach d,$(wildcard $(@PLUGIN_NAME@_TESTS_LIB_DIR)),\ -I $d $d*.ml $d*.mli) \ > $(@PLUGIN_NAME@_DIR)/.depend $(CHMOD_RO) $(@PLUGIN_NAME@_DIR)/.depend -- GitLab From 40ca4b52d659e936b24879c6aac9e10e517e516f Mon Sep 17 00:00:00 2001 From: Virgile Prevosto <virgile.prevosto@m4x.org> Date: Tue, 31 Mar 2020 17:39:12 +0200 Subject: [PATCH 080/218] add test case for issue #840 --- tests/slicing/function_lvar.i | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 tests/slicing/function_lvar.i diff --git a/tests/slicing/function_lvar.i b/tests/slicing/function_lvar.i new file mode 100644 index 00000000000..c7d245c4528 --- /dev/null +++ b/tests/slicing/function_lvar.i @@ -0,0 +1,10 @@ +/* run.config* +OPT: -slice-pragma main +*/ +int g(int x) { return x; } + +int main() { + /*@ assert &g == &g; */ + /*@ slice pragma stmt; */ + g(0); +} -- GitLab From 08b595fe0afc72b11036351866e8f595d11f1dea Mon Sep 17 00:00:00 2001 From: Virgile Prevosto <virgile.prevosto@m4x.org> Date: Tue, 31 Mar 2020 19:25:15 +0200 Subject: [PATCH 081/218] ensure updates of varinfo's type use Cil.update_var_type ... so that varinfo and logic_var stay synchronized. --- src/kernel_internals/typing/cabs2cil.ml | 6 ++-- src/kernel_internals/typing/mergecil.ml | 2 +- src/kernel_services/analysis/exn_flow.ml | 9 +++-- src/kernel_services/ast_queries/cil.ml | 36 +++++++++---------- .../ast_transformations/filter.ml | 2 +- .../ast_transformations/inline.ml | 3 +- src/plugins/aorai/aorai_visitors.ml | 2 +- .../e-acsl/src/code_generator/injector.ml | 6 ++-- 8 files changed, 36 insertions(+), 30 deletions(-) diff --git a/src/kernel_internals/typing/cabs2cil.ml b/src/kernel_internals/typing/cabs2cil.ml index 57c91da7c3e..59bf19445eb 100644 --- a/src/kernel_internals/typing/cabs2cil.ml +++ b/src/kernel_internals/typing/cabs2cil.ml @@ -1585,7 +1585,9 @@ struct end else SkipChildren end in - let cleanup_var vi = vi.vtype <- Cil.visitCilType cleanup_types vi.vtype in + let cleanup_var vi = + Cil.update_var_type vi (Cil.visitCilType cleanup_types vi.vtype) + in List.iter cleanup_var c.locals; !currentFunctionFDEC.slocals <- !currentFunctionFDEC.slocals @ !vars; let vars = !vars @ c.locals in @@ -4332,7 +4334,7 @@ let fixFormalsType formals = end in let treat_one_formal v = - v.vtype <- Cil.visitCilType vis v.vtype; + Cil.update_var_type v (Cil.visitCilType vis v.vtype); Hashtbl.add table v.vname v; in List.iter treat_one_formal formals diff --git a/src/kernel_internals/typing/mergecil.ml b/src/kernel_internals/typing/mergecil.ml index d8b6f886817..f1a939b213f 100644 --- a/src/kernel_internals/typing/mergecil.ml +++ b/src/kernel_internals/typing/mergecil.ml @@ -1733,7 +1733,7 @@ let oneFilePass1 (f:file) : unit = "%s@\nOld declaration is unused, silently removing it" msg; ignore_vi oldvi; - vi.vtype <- update_type_repr vi.vtype; + Cil.update_var_type vi (update_type_repr vi.vtype); H.replace vEnv vi.vname vinode; vinode.nrep <- vinode; oldvinode.nrep <- vinode; diff --git a/src/kernel_services/analysis/exn_flow.ml b/src/kernel_services/analysis/exn_flow.ml index ca932fad3b2..a75151352f6 100644 --- a/src/kernel_services/analysis/exn_flow.ml +++ b/src/kernel_services/analysis/exn_flow.ml @@ -603,10 +603,13 @@ object(self) (match v with | Catch_all -> b | Catch_exn (v,[]) -> - v.vtype <- purify v.vtype; update_locals v b;assign_catched_obj v b; b + Cil.update_var_type v (purify v.vtype); + update_locals v b; + assign_catched_obj v b; b | Catch_exn(v,aux) -> let add_one_aux stmts (v,b) = - v.vtype <- purify v.vtype; update_locals v b; + Cil.update_var_type v (purify v.vtype); + update_locals v b; assign_catched_obj v b; add_unreachable_block b :: stmts in @@ -615,7 +618,7 @@ object(self) List.fold_left add_one_aux [Cil.mkStmt (Block b)] aux in let main_block = Cil.mkBlock aux_blocks in - v.vtype <- purify v.vtype; + Cil.update_var_type v (purify v.vtype); update_locals v main_block; main_block) in diff --git a/src/kernel_services/ast_queries/cil.ml b/src/kernel_services/ast_queries/cil.ml index d9330b5ab30..1a2e39284a8 100644 --- a/src/kernel_services/ast_queries/cil.ml +++ b/src/kernel_services/ast_queries/cil.ml @@ -644,6 +644,14 @@ and enforceGhostBlockCoherence ?(force_ghost=false) block = let force_ghost = force_ghost || is_ghost_else block in List.iter (enforceGhostStmtCoherence ~force_ghost) block.bstmts +(* makes sure that the type of a C variable and the type of its associated + logic variable -if any- stay synchronized. See bts 1538 *) +let update_var_type v t = + v.vtype <- if v.vghost then typeAddGhost t else t; + match v.vlogic_var_assoc with + | None -> () + | Some lv -> lv.lv_type <- Ctype t + (* Make a varinfo. Used mostly as a helper function below *) let makeVarinfo ?(source=true) ?(temp=false) ?(referenced=false) ?(ghost=false) ?(loc=Location.unknown) @@ -728,10 +736,10 @@ let setFormals (f: fundec) (forms: varinfo list) = assert (getFormalsDecl f.svar == f.sformals); match unrollType f.svar.vtype with TFun(rt, _, isva, fa) -> - f.svar.vtype <- - TFun(rt, - Some (List.map (fun a -> (a.vname, a.vtype, a.vattr)) forms), - isva, fa) + update_var_type f.svar + (TFun(rt, + Some (List.map (fun a -> (a.vname, a.vtype, a.vattr)) forms), + isva, fa)); | _ -> Kernel.fatal "Set formals. %s does not have function type" f.svar.vname @@ -2649,9 +2657,10 @@ and childrenVarDecl (vis : cilVisitor) (v : varinfo) : varinfo = let o = Visitor_behavior.Get_orig.logic_var vis#behavior lv in visitCilLogicVarDecl vis o in - v.vtype <- visitCilType vis v.vtype; + let typ = visitCilType vis v.vtype in v.vattr <- visitCilAttributes vis v.vattr; v.vlogic_var_assoc <- optMapNoCopy visit_orig_var_assoc v.vlogic_var_assoc; + update_var_type v typ; v and visitCilVarUse vis v = @@ -3610,7 +3619,7 @@ let getReturnType t = let setReturnTypeVI (v: varinfo) (t: typ) = match unrollType v.vtype with | TFun (_, args, va, a) -> - v.vtype <- TFun (t, args, va, a) + update_var_type v (TFun (t, args, va, a)); | _ -> Kernel.fatal "setReturnType: not a function type" let setReturnType (f:fundec) (t:typ) = @@ -5383,12 +5392,11 @@ let setFunctionType (f: fundec) (t: typ) = if List.length f.sformals <> List.length args then Kernel.fatal ~current:true "setFunctionType: number of arguments differs from the number of formals" ; (* Change the function type. *) - f.svar.vtype <- t; + update_var_type f.svar t; (* Change the sformals and we know that indirectly we'll change the * function type *) List.iter2 - (fun (_an,at,aa) f -> - f.vtype <- at; f.vattr <- aa) + (fun (_an,at,aa) f -> update_var_type f at; f.vattr <- aa) args f.sformals | _ -> Kernel.fatal ~current:true "setFunctionType: not a function type" @@ -5402,7 +5410,7 @@ let setFunctionTypeMakeFormals (f: fundec) (t: typ) = Kernel.fatal ~current:true "setFunctionTypMakeFormals called on function %s with some formals already" f.svar.vname ; (* Change the function type. *) - f.svar.vtype <- t; + update_var_type f.svar t; f.sformals <- List.map (fun (n,t,_a) -> makeLocal ~formal:true f n t) args; setFunctionType f t @@ -6505,14 +6513,6 @@ let is_modifiable_lval lv = | _ -> (not (isConstType t) || is_mutable_or_initialized lv) && isCompleteType t -(* makes sure that the type of a C variable and the type of its associated - logic variable -if any- stay synchronized. See bts 1538 *) -let update_var_type v t = - v.vtype <- if v.vghost then typeAddGhost t else t; - match v.vlogic_var_assoc with - | None -> () - | Some lv -> lv.lv_type <- Ctype t - (** Uniquefy the variable names *) let uniqueVarNames (f: file) : unit = (* Setup the alpha conversion table for globals *) diff --git a/src/kernel_services/ast_transformations/filter.ml b/src/kernel_services/ast_transformations/filter.ml index f3fe41bffc0..74c0ccc4622 100644 --- a/src/kernel_services/ast_transformations/filter.ml +++ b/src/kernel_services/ast_transformations/filter.ml @@ -820,7 +820,7 @@ end = struct let mytype = TFun(rt,Some args,va,attrs) in let new_formals = List.map makeFormalsVarDecl args in self#add_formals_bindings new_var new_formals; - new_var.vtype <- mytype; + Cil.update_var_type new_var mytype; List.iter2 (fun x y -> Visitor_behavior.Set.varinfo self#behavior x y; diff --git a/src/kernel_services/ast_transformations/inline.ml b/src/kernel_services/ast_transformations/inline.ml index 5cdbfc0f1e2..b35db0760de 100644 --- a/src/kernel_services/ast_transformations/inline.ml +++ b/src/kernel_services/ast_transformations/inline.ml @@ -248,7 +248,8 @@ let inliner functions_to_inline = object (self) (* Inlining will prevent r to be syntactically seen as initialized or const: *) r.vdefined <- false; - r.vtype <- Cil.typeRemoveAttributes ["const"] r.vtype; + Cil.update_var_type + r (Cil.typeRemoveAttributes ["const"] r.vtype); false, None, (Cil.mkAddrOf loc (Cil.var r)) :: args | Some _, _ -> Kernel.fatal "Attempt to initialize an inexistent varinfo" diff --git a/src/plugins/aorai/aorai_visitors.ml b/src/plugins/aorai/aorai_visitors.ml index f7ad17a9386..004941db674 100644 --- a/src/plugins/aorai/aorai_visitors.ml +++ b/src/plugins/aorai/aorai_visitors.ml @@ -125,7 +125,7 @@ class visit_adding_code_for_synchronisation = - what about varargs? *) let (rettype,args,varargs,_) = Cil.splitFunctionTypeVI vi_pre in - vi_pre.vtype <- TFun(Cil.voidType, args, varargs,[]); + Cil.update_var_type vi_pre (TFun(Cil.voidType, args, varargs,[])); vi_pre.vattr <- []; (* in particular get rid of __no_return if set in vi*) diff --git a/src/plugins/e-acsl/src/code_generator/injector.ml b/src/plugins/e-acsl/src/code_generator/injector.ml index 40d9c3ea1a2..58f3b018d52 100644 --- a/src/plugins/e-acsl/src/code_generator/injector.ml +++ b/src/plugins/e-acsl/src/code_generator/injector.ml @@ -584,7 +584,7 @@ let inject_in_fundec main fundec = (* convert ghost variables *) vi.vghost <- false; let unghost_local vi = - vi.vtype <- Cil.typeRemoveAttributesDeep ["ghost"] vi.vtype ; + Cil.update_var_type vi (Cil.typeRemoveAttributesDeep ["ghost"] vi.vtype); vi.vghost <- false in List.iter unghost_local fundec.slocals; @@ -621,12 +621,12 @@ let unghost_vi vi = (* do not convert extern ghost variables, because they can't be linked, see bts #1392 *) if vi.vstorage <> Extern then vi.vghost <- false; - vi.vtype <- Cil.typeRemoveAttributesDeep ["ghost"] vi.vtype ; + Cil.update_var_type vi (Cil.typeRemoveAttributesDeep ["ghost"] vi.vtype); match Cil.unrollType vi.vtype with | TFun(res, Some l, va, attr) -> (* unghostify function's parameters *) let retype (n, t, a) = n, t, Cil.dropAttribute Cil.frama_c_ghost_formal a in - vi.vtype <- TFun(res, Some (List.map retype l), va, attr) + Cil.update_var_type vi (TFun(res, Some (List.map retype l), va, attr)) | _ -> () -- GitLab From 69007cf41bb055a11f4611a2cbef045ad641bcda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Loi=CC=88c=20Correnson?= <loic.correnson@cea.fr> Date: Tue, 31 Mar 2020 17:42:50 +0200 Subject: [PATCH 082/218] [kernel] refactor logic cast unrolling --- .../ast_queries/logic_utils.ml | 68 ++++++++----------- 1 file changed, 29 insertions(+), 39 deletions(-) diff --git a/src/kernel_services/ast_queries/logic_utils.ml b/src/kernel_services/ast_queries/logic_utils.ml index f48ee5de1bd..c08f9d6d6ae 100644 --- a/src/kernel_services/ast_queries/logic_utils.ml +++ b/src/kernel_services/ast_queries/logic_utils.ml @@ -221,47 +221,36 @@ let mk_logic_pointer_or_StartOf t = Kernel.fatal ~source:(fst t.term_loc) "%a is neither a pointer nor a C array" Cil_printer.pp_term t -let need_logic_cast oldt newt = - not (Cil_datatype.Logic_type.equal (Ctype oldt) (Ctype newt)) +let equal_ltype = Cil_datatype.Logic_type.equal (* Does the same kind of optimization than [Cil.mkCastT] for [Ctype]. *) -let mk_cast ?(loc=Cil_datatype.Location.unknown) ?(force=false) newt t = - let mk_cast t = (* to new type [newt] *) - let typ = Cil.type_remove_attributes_for_logic_type newt - in term ~loc (TCastE (typ, t)) (Ctype typ) - in - let rec aux1 typ t = - match typ with - | Ctype oldt -> - if not (need_logic_cast oldt newt) && not force then t - else begin - match Cil.unrollType newt, t.term_node with - | TPtr _, TCastE (_, t') -> - let rec aux2 = function - | Ctype typ' -> - (match unrollType typ', t'.term_node with - | (TPtr _ as typ''), _ -> - (* Old cast can be removed...*) - if need_logic_cast newt typ'' then mk_cast t' - else (* In fact, both casts can be removed. *) t' - | _, TConst (Integer (i,_)) when Integer.is_zero i -> mk_cast t' - | _ -> mk_cast t - ) - | Ltype (tdef,_) as ty when is_unrollable_ltdef tdef -> - aux2 (unroll_ltdef ty) - | _ -> mk_cast t - in aux2 t'.term_type - | _ -> (* Do not remove old cast because they are conversions !!! *) - mk_cast t - end - | Ltype (tdef,_) as ty when is_unrollable_ltdef tdef -> - aux1 (unroll_ltdef ty) t - | Linteger | Lreal -> - (match t.term_node with - | TLogic_coerce (_,t') -> aux1 t'.term_type t' - | _ -> mk_cast t) - | _ -> mk_cast t - in aux1 t.term_type t +let mk_cast ?loc ?(force=false) newt t = + let newt = Cil.type_remove_attributes_for_logic_type newt in + if equal_ltype (Ctype newt) t.term_type then t else + (* + let rec is_iconst e = match e.term_node with + | TCastE(ty,e) when Cil.isArithmeticOrPointerType ty -> is_iconst e + | TLogic_coerce(Linteger,e) -> is_iconst e + | TConst(Integer _) -> true + | _ -> false in + *) + let rec unroll_cast e = match e.term_node with + | TCastE(oldt,e) + when (Cil.isPointerType newt && Cil.isPointerType oldt) + || equal_ltype (Ctype oldt) (Ctype newt) + -> unroll_cast e + | TLogic_coerce(Linteger,e) + when Cil.isArithmeticOrPointerType newt + -> unroll_cast e + | TLogic_coerce(Lreal,e) + when Cil.isFloatingType newt + -> unroll_cast e + | _ -> e + in + let tres = if force then t else unroll_cast t in + let loc = match loc with None -> t.term_loc | Some loc -> loc in + Logic_const.term ~loc (TCastE (newt, tres)) (Ctype newt) + (* -------------------------------------------------------------------------- *) (* --- Constant Conversions --- *) @@ -472,6 +461,7 @@ let rec expr_to_term ?(coerce=false) e = | AlignOfE e -> TAlignOf (Cil.typeOf e), ctyp | Lval lv -> TLval (lval_to_term_lval lv), ctyp | CastE (ty,e) -> + let coerce = Cil.isIntegralType (Cil.typeOf e) in let t = mk_cast ~loc ty (expr_to_term ~coerce e) in t.term_node , t.term_type | Info (e,_) -> -- GitLab From 6a334acdfa4d74de52b58de99b97268935ef01c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Loi=CC=88c=20Correnson?= <loic.correnson@cea.fr> Date: Tue, 31 Mar 2020 18:18:46 +0200 Subject: [PATCH 083/218] [kernel] updated oracles wrt simplified casts Only modifications introduced by non necessary casts elimination --- tests/rte/oracle/addsub_unsigned.1.res.oracle | 2 +- tests/rte/oracle/addsub_unsigned_typedef.1.res.oracle | 2 +- tests/rte_manual/oracle/unsigned.1.res.oracle | 4 ++-- tests/spec/oracle/null_ptr.res.oracle | 4 ++-- tests/value/oracle/downcast.0.res.oracle | 4 ++-- tests/value/oracle/downcast.1.res.oracle | 4 ++-- tests/value/oracle/downcast.2.res.oracle | 4 ++-- tests/value/oracle/downcast.3.res.oracle | 4 ++-- tests/value/oracle/downcast.4.res.oracle | 4 ++-- 9 files changed, 16 insertions(+), 16 deletions(-) diff --git a/tests/rte/oracle/addsub_unsigned.1.res.oracle b/tests/rte/oracle/addsub_unsigned.1.res.oracle index b30ebf8b1ab..1a6a8a94593 100644 --- a/tests/rte/oracle/addsub_unsigned.1.res.oracle +++ b/tests/rte/oracle/addsub_unsigned.1.res.oracle @@ -19,7 +19,7 @@ int main(void) uy = 0x80000000U + 0x80000000U; /*@ assert rte: unsigned_overflow: 2U * 0x80000000U ≤ 4294967295; */ uy = 2U * 0x80000000U; - /*@ assert rte: unsigned_overflow: ux + (unsigned int)2 ≤ 4294967295; */ + /*@ assert rte: unsigned_overflow: ux + 2 ≤ 4294967295; */ uz = ux + (unsigned int)2; __retres = 0; return __retres; diff --git a/tests/rte/oracle/addsub_unsigned_typedef.1.res.oracle b/tests/rte/oracle/addsub_unsigned_typedef.1.res.oracle index 98f2482e3cc..3c0fc49fce3 100644 --- a/tests/rte/oracle/addsub_unsigned_typedef.1.res.oracle +++ b/tests/rte/oracle/addsub_unsigned_typedef.1.res.oracle @@ -20,7 +20,7 @@ int main(void) uy = 0x80000000U + 0x80000000U; /*@ assert rte: unsigned_overflow: 2U * 0x80000000U ≤ 4294967295; */ uy = 2U * 0x80000000U; - /*@ assert rte: unsigned_overflow: ux + (unsigned int)2 ≤ 4294967295; */ + /*@ assert rte: unsigned_overflow: ux + 2 ≤ 4294967295; */ uz = ux + (uint)2; __retres = 0; return __retres; diff --git a/tests/rte_manual/oracle/unsigned.1.res.oracle b/tests/rte_manual/oracle/unsigned.1.res.oracle index ed1ad94cf29..37e1f70016c 100644 --- a/tests/rte_manual/oracle/unsigned.1.res.oracle +++ b/tests/rte_manual/oracle/unsigned.1.res.oracle @@ -8,8 +8,8 @@ unsigned int f(unsigned int a, unsigned int b) unsigned int z; /*@ assert rte: unsigned_overflow: a << 3 ≤ 4294967295; */ x = a << 3; - /*@ assert rte: unsigned_overflow: 0 ≤ b * (unsigned int)2; */ - /*@ assert rte: unsigned_overflow: b * (unsigned int)2 ≤ 4294967295; */ + /*@ assert rte: unsigned_overflow: 0 ≤ b * 2; */ + /*@ assert rte: unsigned_overflow: b * 2 ≤ 4294967295; */ y = b * (unsigned int)2; /*@ assert rte: unsigned_overflow: 0 ≤ x - y; */ /*@ assert rte: unsigned_overflow: x - y ≤ 4294967295; */ diff --git a/tests/spec/oracle/null_ptr.res.oracle b/tests/spec/oracle/null_ptr.res.oracle index 5412691e03a..c33037bd34a 100644 --- a/tests/spec/oracle/null_ptr.res.oracle +++ b/tests/spec/oracle/null_ptr.res.oracle @@ -10,12 +10,12 @@ */ /*@ predicate eq(char *x, char *y) = x ≡ y; */ -/*@ predicate my_null(char *x) = x ≡ (char *)((void *)0); +/*@ predicate my_null(char *x) = x ≡ (char *)0; */ void f(char *x) { x = (char *)0; - /*@ assert x ≡ (char *)((void *)0); */ ; + /*@ assert x ≡ (char *)0; */ ; /*@ assert my_null(x); */ ; /*@ assert null(x); */ ; /*@ assert eq(x, (char *)0); */ ; diff --git a/tests/value/oracle/downcast.0.res.oracle b/tests/value/oracle/downcast.0.res.oracle index c27a3ff663f..3bcfeedcaf1 100644 --- a/tests/value/oracle/downcast.0.res.oracle +++ b/tests/value/oracle/downcast.0.res.oracle @@ -28,9 +28,9 @@ [eva] computing for function main4_pointer <- main. Called from tests/value/downcast.i:159. [eva:alarm] tests/value/downcast.i:54: Warning: - signed overflow. assert -9223372036854775808 ≤ p + (long long)100; + signed overflow. assert -9223372036854775808 ≤ p + 100; [eva:alarm] tests/value/downcast.i:54: Warning: - signed overflow. assert p + (long long)100 ≤ 9223372036854775807; + signed overflow. assert p + 100 ≤ 9223372036854775807; [eva] Recording results for main4_pointer [eva] Done for function main4_pointer [eva] computing for function main5_wrap_signed <- main. diff --git a/tests/value/oracle/downcast.1.res.oracle b/tests/value/oracle/downcast.1.res.oracle index 4430fdae775..80b62a21f49 100644 --- a/tests/value/oracle/downcast.1.res.oracle +++ b/tests/value/oracle/downcast.1.res.oracle @@ -40,9 +40,9 @@ [eva] computing for function main4_pointer <- main. Called from tests/value/downcast.i:159. [eva:alarm] tests/value/downcast.i:54: Warning: - signed overflow. assert -9223372036854775808 ≤ p + (long long)100; + signed overflow. assert -9223372036854775808 ≤ p + 100; [eva:alarm] tests/value/downcast.i:54: Warning: - signed overflow. assert p + (long long)100 ≤ 9223372036854775807; + signed overflow. assert p + 100 ≤ 9223372036854775807; [eva:alarm] tests/value/downcast.i:56: Warning: signed downcast. assert -2147483648 ≤ p; [eva:alarm] tests/value/downcast.i:56: Warning: diff --git a/tests/value/oracle/downcast.2.res.oracle b/tests/value/oracle/downcast.2.res.oracle index 0c43f9fb2f7..ce711f9fe6a 100644 --- a/tests/value/oracle/downcast.2.res.oracle +++ b/tests/value/oracle/downcast.2.res.oracle @@ -42,9 +42,9 @@ [eva] computing for function main4_pointer <- main. Called from tests/value/downcast.i:159. [eva:alarm] tests/value/downcast.i:54: Warning: - signed overflow. assert -9223372036854775808 ≤ p + (long long)100; + signed overflow. assert -9223372036854775808 ≤ p + 100; [eva:alarm] tests/value/downcast.i:54: Warning: - signed overflow. assert p + (long long)100 ≤ 9223372036854775807; + signed overflow. assert p + 100 ≤ 9223372036854775807; [eva:alarm] tests/value/downcast.i:55: Warning: unsigned downcast. assert 0 ≤ p; [eva:alarm] tests/value/downcast.i:55: Warning: diff --git a/tests/value/oracle/downcast.3.res.oracle b/tests/value/oracle/downcast.3.res.oracle index d25d52f4759..8f130d992c0 100644 --- a/tests/value/oracle/downcast.3.res.oracle +++ b/tests/value/oracle/downcast.3.res.oracle @@ -38,9 +38,9 @@ [eva] computing for function main4_pointer <- main. Called from tests/value/downcast.i:159. [eva:alarm] tests/value/downcast.i:54: Warning: - signed overflow. assert -9223372036854775808 ≤ p + (long long)100; + signed overflow. assert -9223372036854775808 ≤ p + 100; [eva:alarm] tests/value/downcast.i:54: Warning: - signed overflow. assert p + (long long)100 ≤ 9223372036854775807; + signed overflow. assert p + 100 ≤ 9223372036854775807; [eva:alarm] tests/value/downcast.i:56: Warning: signed downcast. assert -2147483648 ≤ p; [eva:alarm] tests/value/downcast.i:56: Warning: diff --git a/tests/value/oracle/downcast.4.res.oracle b/tests/value/oracle/downcast.4.res.oracle index d691ffe3fe1..b2070c3d348 100644 --- a/tests/value/oracle/downcast.4.res.oracle +++ b/tests/value/oracle/downcast.4.res.oracle @@ -28,9 +28,9 @@ [eva] computing for function main4_pointer <- main. Called from tests/value/downcast.i:159. [eva:alarm] tests/value/downcast.i:54: Warning: - signed overflow. assert -9223372036854775808 ≤ p + (long long)100; + signed overflow. assert -9223372036854775808 ≤ p + 100; [eva:alarm] tests/value/downcast.i:54: Warning: - signed overflow. assert p + (long long)100 ≤ 9223372036854775807; + signed overflow. assert p + 100 ≤ 9223372036854775807; [eva] Recording results for main4_pointer [eva] Done for function main4_pointer [eva] computing for function main5_wrap_signed <- main. -- GitLab From a0d20d3fff6ce68ef610db7207327ae4172d5975 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Loi=CC=88c=20Correnson?= <loic.correnson@cea.fr> Date: Tue, 31 Mar 2020 18:30:27 +0200 Subject: [PATCH 084/218] [kernel] fixed oracles wrt old wrong expr-to-term Fixes incorrect internal casts in sub-terms representing integer C-arith. --- tests/constant_propagation/oracle/enum.res.oracle | 4 ++-- tests/syntax/oracle/assembly_gmp.1.res.oracle | 6 +++--- tests/syntax/oracle/assembly_gmp.2.res.oracle | 6 +++--- .../oracle/undeclared_local_bts1113.res.oracle | 12 +++++++++--- tests/syntax/oracle/vla_strlen.res.oracle | 6 +++++- tests/value/oracle/descending.res.oracle | 2 +- tests/value/oracle/downcast.3.res.oracle | 2 +- tests/value/oracle/incompatible_states.res.oracle | 6 ++++-- 8 files changed, 28 insertions(+), 16 deletions(-) diff --git a/tests/constant_propagation/oracle/enum.res.oracle b/tests/constant_propagation/oracle/enum.res.oracle index cbd71cd5823..d7c4e9f6ea0 100644 --- a/tests/constant_propagation/oracle/enum.res.oracle +++ b/tests/constant_propagation/oracle/enum.res.oracle @@ -14,7 +14,7 @@ [eva] Recording results for f [eva] Done for function f [eva:alarm] tests/constant_propagation/enum.i:13: Warning: - signed overflow. assert B + c ≤ 2147483647; + signed overflow. assert (int)B + c ≤ 2147483647; [eva:alarm] tests/constant_propagation/enum.i:15: Warning: signed overflow. assert (int)(y + z) + t ≤ 2147483647; [eva:alarm] tests/constant_propagation/enum.i:15: Warning: @@ -43,7 +43,7 @@ int main(int c, unsigned int u) enum E x = A; int y = f(0U); int z = f(D); - /*@ assert Eva: signed_overflow: B + c ≤ 2147483647; */ + /*@ assert Eva: signed_overflow: (int)B + c ≤ 2147483647; */ int t = B + c; int v = (int)(2U + u); /*@ assert Eva: signed_overflow: (int)(y + z) + t ≤ 2147483647; */ diff --git a/tests/syntax/oracle/assembly_gmp.1.res.oracle b/tests/syntax/oracle/assembly_gmp.1.res.oracle index 63a12b1b07b..70ffc4d780c 100644 --- a/tests/syntax/oracle/assembly_gmp.1.res.oracle +++ b/tests/syntax/oracle/assembly_gmp.1.res.oracle @@ -38,9 +38,9 @@ mp_limb_t mpn_mod_1_1p(mp_srcptr ap, mp_size_t n, mp_limb_t b, p0 = (long)(__m0 * __m1); } /*@ assigns r2, r1, r0; - assigns r2 \from r0, p1, *(ap + (n - 3)), p0; - assigns r1 \from r0, p1, *(ap + (n - 3)), p0; - assigns r0 \from r0, p1, *(ap + (n - 3)), p0; + assigns r2 \from r0, p1, *(ap + (unsigned long)(n - 3)), p0; + assigns r1 \from r0, p1, *(ap + (unsigned long)(n - 3)), p0; + assigns r0 \from r0, p1, *(ap + (unsigned long)(n - 3)), p0; */ __asm__ ( "add\t%6, %q2\n\t" diff --git a/tests/syntax/oracle/assembly_gmp.2.res.oracle b/tests/syntax/oracle/assembly_gmp.2.res.oracle index 2684a9a6655..d3e9aca3737 100644 --- a/tests/syntax/oracle/assembly_gmp.2.res.oracle +++ b/tests/syntax/oracle/assembly_gmp.2.res.oracle @@ -38,9 +38,9 @@ mp_limb_t mpn_mod_1_1p(mp_srcptr ap, mp_size_t n, mp_limb_t b, p0 = (long)(__m0 * __m1); } /*@ assigns r2, r1, r0; - assigns r2 \from r0, p1, *(ap + (n - 3)), p0; - assigns r1 \from r0, p1, *(ap + (n - 3)), p0; - assigns r0 \from r0, p1, *(ap + (n - 3)), p0; + assigns r2 \from r0, p1, *(ap + (unsigned int)(n - 3)), p0; + assigns r1 \from r0, p1, *(ap + (unsigned int)(n - 3)), p0; + assigns r0 \from r0, p1, *(ap + (unsigned int)(n - 3)), p0; */ __asm__ ( "add%I6c\t%2, %5, %6\n\t" diff --git a/tests/syntax/oracle/undeclared_local_bts1113.res.oracle b/tests/syntax/oracle/undeclared_local_bts1113.res.oracle index 809576ab5a8..97b551d63eb 100644 --- a/tests/syntax/oracle/undeclared_local_bts1113.res.oracle +++ b/tests/syntax/oracle/undeclared_local_bts1113.res.oracle @@ -16,19 +16,25 @@ void funk(int rounds) int i; unsigned int __lengthof_k_long_long_size; int k_positive_size[4 - 2]; - /*@ assert alloca_bounds: 0 < sizeof(int) * (2 * rounds) ≤ 4294967295; */ + /*@ + assert alloca_bounds: 0 < sizeof(int) * (int)(2 * rounds) ≤ 4294967295; + */ ; __lengthof_k = (unsigned int)(2 * rounds); int *k = __fc_vla_alloc(sizeof(int) * __lengthof_k); /*@ assert - alloca_bounds: 0 < sizeof(int) * (unsigned int)(2 * rounds) ≤ 4294967295; + alloca_bounds: + 0 < sizeof(int) * (unsigned int)((int)(2 * rounds)) ≤ 4294967295; */ ; __lengthof_kk = (unsigned int)(2 * rounds); int *kk = __fc_vla_alloc(sizeof(int) * __lengthof_kk); long long j = (long long)(rounds * rounds); - /*@ assert alloca_bounds: 0 < sizeof(int) * (j * 2) ≤ 4294967295; */ ; + /*@ + assert alloca_bounds: 0 < sizeof(int) * (long long)(j * 2) ≤ 4294967295; + */ + ; __lengthof_k_long_long_size = (unsigned int)(j * (long long)2); int *k_long_long_size = __fc_vla_alloc(sizeof(int) * __lengthof_k_long_long_size); diff --git a/tests/syntax/oracle/vla_strlen.res.oracle b/tests/syntax/oracle/vla_strlen.res.oracle index 49dc5fb0597..0fe38231c89 100644 --- a/tests/syntax/oracle/vla_strlen.res.oracle +++ b/tests/syntax/oracle/vla_strlen.res.oracle @@ -17,7 +17,11 @@ void f(char *s) unsigned int __lengthof_t; size_t tmp; tmp = strlen((char const *)s); - /*@ assert alloca_bounds: 0 < sizeof(char) * (tmp + 1) ≤ 4294967295; */ ; + /*@ + assert + alloca_bounds: 0 < sizeof(char) * (unsigned int)(tmp + 1) ≤ 4294967295; + */ + ; __lengthof_t = tmp + (size_t)1; char *t = __fc_vla_alloc(sizeof(char) * __lengthof_t); char *p = t; diff --git a/tests/value/oracle/descending.res.oracle b/tests/value/oracle/descending.res.oracle index 3b11d3495c6..7e67df6441b 100644 --- a/tests/value/oracle/descending.res.oracle +++ b/tests/value/oracle/descending.res.oracle @@ -14,7 +14,7 @@ [eva:alarm] tests/value/descending.i:13: Warning: accessing out of bounds index. assert (int)(i - 1) < 10; [eva:alarm] tests/value/descending.i:13: Warning: - accessing uninitialized left-value. assert \initialized(&A[i - 1]); + accessing uninitialized left-value. assert \initialized(&A[(int)(i - 1)]); [eva] Recording results for test1 [eva] Done for function test1 [eva] computing for function test2 <- main. diff --git a/tests/value/oracle/downcast.3.res.oracle b/tests/value/oracle/downcast.3.res.oracle index 8f130d992c0..8d2a9ee99b2 100644 --- a/tests/value/oracle/downcast.3.res.oracle +++ b/tests/value/oracle/downcast.3.res.oracle @@ -61,7 +61,7 @@ [eva] computing for function main6_val_warn_converted_signed <- main. Called from tests/value/downcast.i:161. [eva:alarm] tests/value/downcast.i:75: Warning: - signed downcast. assert (int)65300u ≤ 32767; + signed downcast. assert 65300u ≤ 32767; [eva:alarm] tests/value/downcast.i:91: Warning: signed downcast. assert -32768 ≤ (int)e_1; [eva:alarm] tests/value/downcast.i:95: Warning: diff --git a/tests/value/oracle/incompatible_states.res.oracle b/tests/value/oracle/incompatible_states.res.oracle index 9cd3bb24391..d020cc43176 100644 --- a/tests/value/oracle/incompatible_states.res.oracle +++ b/tests/value/oracle/incompatible_states.res.oracle @@ -22,9 +22,11 @@ function Frama_C_interval: precondition 'order' got status valid. [eva] Done for function Frama_C_interval [eva:alarm] tests/value/incompatible_states.c:38: Warning: - accessing uninitialized left-value. assert \initialized(&t[(2 * i) / 2]); + accessing uninitialized left-value. + assert \initialized(&t[(int)((int)(2 * i) / 2)]); [eva:alarm] tests/value/incompatible_states.c:41: Warning: - accessing uninitialized left-value. assert \initialized(&t[(2 * i) / 2]); + accessing uninitialized left-value. + assert \initialized(&t[(int)((int)(2 * i) / 2)]); [eva] Recording results for main2 [eva] Done for function main2 [eva] computing for function main3 <- main. -- GitLab From 35d02826aa267ef2ed33138940c788b0ea5d4646 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Loi=CC=88c=20Correnson?= <loic.correnson@cea.fr> Date: Tue, 31 Mar 2020 18:31:50 +0200 Subject: [PATCH 085/218] [kernel] updated oracles wrt. sizeof(exp) Old translation was potentially incorrect for sizeof(exp) --- tests/value/oracle/sizeof.res.oracle | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/tests/value/oracle/sizeof.res.oracle b/tests/value/oracle/sizeof.res.oracle index adc483ff665..aa8dc50d410 100644 --- a/tests/value/oracle/sizeof.res.oracle +++ b/tests/value/oracle/sizeof.res.oracle @@ -25,16 +25,16 @@ The imprecision originates from Arithmetic {tests/value/sizeof.i:32} [eva:alarm] tests/value/sizeof.i:33: Warning: accessing out of bounds index. - assert (unsigned int)(sizeof(s1.t) - (unsigned int)i) < 10; + assert (unsigned int)(sizeof(int [10]) - (unsigned int)i) < 10; [eva:alarm] tests/value/sizeof.i:33: Warning: out of bounds write. - assert \valid(&p->t[(unsigned int)(sizeof(s1.t) - (unsigned int)i)]); + assert \valid(&p->t[(unsigned int)(sizeof(int [10]) - (unsigned int)i)]); [eva:alarm] tests/value/sizeof.i:34: Warning: accessing out of bounds index. - assert (unsigned int)(sizeof(s1.t) - (unsigned int)i) < 10; + assert (unsigned int)(sizeof(int [10]) - (unsigned int)i) < 10; [eva:alarm] tests/value/sizeof.i:34: Warning: out of bounds write. - assert \valid(&p->t[(unsigned int)(sizeof(s1.t) - (unsigned int)i)]); + assert \valid(&p->t[(unsigned int)(sizeof(int [10]) - (unsigned int)i)]); [eva] Recording results for main2 [eva] Done for function main2 [eva] computing for function f <- main. @@ -129,19 +129,21 @@ void main2(void) /*@ assert Eva: pointer_downcast: (unsigned int)(&s1) ≤ 2147483647; */ struct s *p = (& s1 + (int)(& s1)) - (int)(& s1); /*@ assert - Eva: index_bound: (unsigned int)(sizeof(s1.t) - (unsigned int)i) < 10; + Eva: index_bound: + (unsigned int)(sizeof(int [10]) - (unsigned int)i) < 10; */ /*@ assert Eva: mem_access: - \valid(&p->t[(unsigned int)(sizeof(s1.t) - (unsigned int)i)]); + \valid(&p->t[(unsigned int)(sizeof(int [10]) - (unsigned int)i)]); */ p->t[sizeof(s1.t) - (unsigned int)i] = 1; /*@ assert - Eva: index_bound: (unsigned int)(sizeof(s1.t) - (unsigned int)i) < 10; + Eva: index_bound: + (unsigned int)(sizeof(int [10]) - (unsigned int)i) < 10; */ /*@ assert Eva: mem_access: - \valid(&p->t[(unsigned int)(sizeof(s1.t) - (unsigned int)i)]); + \valid(&p->t[(unsigned int)(sizeof(int [10]) - (unsigned int)i)]); */ p->t[sizeof(s1.t) - (unsigned int)i] = 2; return; -- GitLab From e5647c8d35b529b71e741e57bf627ed8cbb046a9 Mon Sep 17 00:00:00 2001 From: Virgile Prevosto <virgile.prevosto@m4x.org> Date: Tue, 31 Mar 2020 20:29:33 +0200 Subject: [PATCH 086/218] linting --- .Makefile.lint | 2 - .../ast_transformations/filter.ml | 756 +++++++++--------- .../ast_transformations/filter.mli | 62 +- 3 files changed, 410 insertions(+), 410 deletions(-) diff --git a/.Makefile.lint b/.Makefile.lint index 0fffac31e24..e0d284e28cb 100644 --- a/.Makefile.lint +++ b/.Makefile.lint @@ -83,8 +83,6 @@ ML_LINT_KO+=src/kernel_services/ast_queries/file.mli ML_LINT_KO+=src/kernel_services/ast_queries/logic_const.mli ML_LINT_KO+=src/kernel_services/ast_transformations/clone.ml ML_LINT_KO+=src/kernel_services/ast_transformations/clone.mli -ML_LINT_KO+=src/kernel_services/ast_transformations/filter.ml -ML_LINT_KO+=src/kernel_services/ast_transformations/filter.mli ML_LINT_KO+=src/kernel_services/cmdline_parameters/cmdline.ml ML_LINT_KO+=src/kernel_services/cmdline_parameters/cmdline.mli ML_LINT_KO+=src/kernel_services/cmdline_parameters/parameter_category.ml diff --git a/src/kernel_services/ast_transformations/filter.ml b/src/kernel_services/ast_transformations/filter.ml index 74c0ccc4622..95bbf5768ae 100644 --- a/src/kernel_services/ast_transformations/filter.ml +++ b/src/kernel_services/ast_transformations/filter.ml @@ -91,9 +91,9 @@ end = struct with Not_found -> let fundec = match kf.fundec with - | Definition(f,l) -> Definition ( { f with svar = v },l) - | Declaration(_,_,arg,l) -> - Declaration(Cil.empty_funspec(),v,arg,l) + | Definition(f,l) -> Definition ( { f with svar = v },l) + | Declaration(_,_,arg,l) -> + Declaration(Cil.empty_funspec(),v,arg,l) in let kf = { fundec = fundec; spec = Cil.empty_funspec() } in Cil_datatype.Varinfo.Hashtbl.add tbl v kf; kf @@ -101,13 +101,13 @@ end = struct let rec can_skip keep_stmts stmt = stmt.labels = [] && match stmt.skind with - | Instr (Skip _) -> - debug "@[Statement %d: can%s skip@]@." stmt.sid - (if Stmt.Set.mem stmt keep_stmts then "'t" else ""); - not (Stmt.Set.mem stmt keep_stmts) - | Block b -> is_empty_block keep_stmts b - | UnspecifiedSequence seq -> is_empty_unspecified_sequence keep_stmts seq - | _ -> false + | Instr (Skip _) -> + debug "@[Statement %d: can%s skip@]@." stmt.sid + (if Stmt.Set.mem stmt keep_stmts then "'t" else ""); + not (Stmt.Set.mem stmt keep_stmts) + | Block b -> is_empty_block keep_stmts b + | UnspecifiedSequence seq -> is_empty_unspecified_sequence keep_stmts seq + | _ -> false and is_empty_block keep_stmts block = List.for_all (can_skip keep_stmts) block.bstmts @@ -117,44 +117,44 @@ end = struct let rec mk_new_block keep_stmts s blk loc = (* vblock has already cleaned up the statements (removed skip, etc...), - * but now the block can still be empty or include only one statement. *) + * but now the block can still be empty or include only one statement. *) match blk.bstmts with - | [] | _ when is_empty_block keep_stmts blk -> - (* don't care about local variables since the block is empty. *) - mk_new_stmt s (mk_skip loc) - | { labels = [] } as s1 :: [] -> - (* one statement only, and no label *) - begin - match s1.skind with - | Block b -> - (* drop blk, but keep local declarations. *) - b.blocals <- b.blocals @ blk.blocals; - mk_new_block keep_stmts s b loc - | UnspecifiedSequence seq when blk.blocals = [] -> - mk_new_unspecified_sequence keep_stmts s seq loc - | _ when blk.blocals = [] -> mk_new_stmt s s1.skind - | _ -> mk_new_stmt s (Block blk) - end - | _ -> mk_new_stmt s (Block blk) + | [] | _ when is_empty_block keep_stmts blk -> + (* don't care about local variables since the block is empty. *) + mk_new_stmt s (mk_skip loc) + | { labels = [] } as s1 :: [] -> + (* one statement only, and no label *) + begin + match s1.skind with + | Block b -> + (* drop blk, but keep local declarations. *) + b.blocals <- b.blocals @ blk.blocals; + mk_new_block keep_stmts s b loc + | UnspecifiedSequence seq when blk.blocals = [] -> + mk_new_unspecified_sequence keep_stmts s seq loc + | _ when blk.blocals = [] -> mk_new_stmt s s1.skind + | _ -> mk_new_stmt s (Block blk) + end + | _ -> mk_new_stmt s (Block blk) (* same as above, but for unspecified sequences. *) and mk_new_unspecified_sequence keep_stmts s seq loc = (* vblock has already cleaned up the statements (removed skip, etc...), * but now the block can still be empty or include only one statement. *) match seq with - | [] -> mk_new_stmt s (mk_skip loc) - | _ when is_empty_unspecified_sequence keep_stmts seq -> - mk_new_stmt s (mk_skip loc) - | [stmt,_,_,_,_] -> (* one statement only *) - begin - if stmt.labels <> [] then s.labels <- s.labels @ stmt.labels; - match stmt.skind with - | UnspecifiedSequence seq -> - mk_new_unspecified_sequence keep_stmts s seq loc - | Block b -> mk_new_block keep_stmts s b loc - | _ -> mk_new_stmt s stmt.skind - end - | _ -> mk_new_stmt s (UnspecifiedSequence seq) + | [] -> mk_new_stmt s (mk_skip loc) + | _ when is_empty_unspecified_sequence keep_stmts seq -> + mk_new_stmt s (mk_skip loc) + | [stmt,_,_,_,_] -> (* one statement only *) + begin + if stmt.labels <> [] then s.labels <- s.labels @ stmt.labels; + match stmt.skind with + | UnspecifiedSequence seq -> + mk_new_unspecified_sequence keep_stmts s seq loc + | Block b -> mk_new_block keep_stmts s b loc + | _ -> mk_new_stmt s stmt.skind + end + | _ -> mk_new_stmt s (UnspecifiedSequence seq) let add_label_if_needed mk_label finfo s = let rec pickLabel = function @@ -162,141 +162,141 @@ end = struct | Label _ as lab :: _ when Info.label_visible finfo s lab -> Some lab | _ :: rest -> pickLabel rest in match pickLabel s.labels with - | Some _ -> None - | None -> - let label = mk_label (Cil_datatype.Stmt.loc s) in - debug "add label to sid:%d : %a" s.sid Printer.pp_label label; - s.labels <- label::s.labels; - Some label - - let rm_break_cont ?(cont=true) ?(break=true) mk_label finfo blk = + | Some _ -> None + | None -> + let label = mk_label (Cil_datatype.Stmt.loc s) in + debug "add label to sid:%d : %a" s.sid Printer.pp_label label; + s.labels <- label::s.labels; + Some label + + let rm_break_cont ?(cont=true) ?(break=true) mk_label finfo blk = let change loc s = let dest = match s.succs with dest::_ -> dest | [] -> assert false in let new_l = add_label_if_needed mk_label finfo dest in - mk_new_stmt s (Goto (ref dest, loc)); - debug "changed break/continue into @[%a@]@." - Printer.pp_stmt s; - new_l + mk_new_stmt s (Goto (ref dest, loc)); + debug "changed break/continue into @[%a@]@." + Printer.pp_stmt s; + new_l in let rec rm_aux cont break s = match s.skind with - | Break loc when break && Info.inst_visible finfo s -> - let _ = change loc s in () - | Continue loc when cont && Info.inst_visible finfo s -> - let _ = change loc s in () - | Instr _ | Return _ | Break _ | Continue _ | Goto _ | Throw _ -> () - | If (_, bthen, belse, _) -> - List.iter (rm_aux cont break) bthen.bstmts; - List.iter (rm_aux cont break) belse.bstmts; - | Block blk -> - List.iter (rm_aux cont break) blk.bstmts - | UnspecifiedSequence seq -> - let blk = Cil.block_from_unspecified_sequence seq in - List.iter (rm_aux cont break) blk.bstmts - | Loop _ -> (* don't go inside : break and continue change meaning*) - () - | Switch (_, blk, _, _) -> - (* if change [continue] do it, but stop changing [break] *) - if cont then - let break = false in List.iter (rm_aux cont break) blk.bstmts - | TryFinally _ | TryExcept _ | TryCatch _ -> (* TODO ? *) () + | Break loc when break && Info.inst_visible finfo s -> + let _ = change loc s in () + | Continue loc when cont && Info.inst_visible finfo s -> + let _ = change loc s in () + | Instr _ | Return _ | Break _ | Continue _ | Goto _ | Throw _ -> () + | If (_, bthen, belse, _) -> + List.iter (rm_aux cont break) bthen.bstmts; + List.iter (rm_aux cont break) belse.bstmts; + | Block blk -> + List.iter (rm_aux cont break) blk.bstmts + | UnspecifiedSequence seq -> + let blk = Cil.block_from_unspecified_sequence seq in + List.iter (rm_aux cont break) blk.bstmts + | Loop _ -> (* don't go inside : break and continue change meaning*) + () + | Switch (_, blk, _, _) -> + (* if change [continue] do it, but stop changing [break] *) + if cont then + let break = false in List.iter (rm_aux cont break) blk.bstmts + | TryFinally _ | TryExcept _ | TryCatch _ -> (* TODO ? *) () in List.iter (rm_aux cont break) blk.bstmts (** filter [params] according to [ff] input visibility. - * Can be used to slice both the parameters, the call arguments, - * and the param types. - * Notice that this is just a filtering of the list. - * It doesn't do any transformation of any kind on the element, - * so at the end they are shared with the original list. - * *) + * Can be used to slice both the parameters, the call arguments, + * and the param types. + * Notice that this is just a filtering of the list. + * It doesn't do any transformation of any kind on the element, + * so at the end they are shared with the original list. + * *) let filter_params finfo params = let do_param (n, new_params) var = let new_params = if not (Info.param_visible finfo n) then new_params else new_params @ [var] in - (n+1, new_params) + (n+1, new_params) in let _, new_params = List.fold_left do_param (1, []) params in - new_params + new_params let ff_var (fun_vars: t) kf finfo = let fct_var = Kernel_function.get_vi kf in let name = Info.fct_name fct_var finfo in - try - let ff_var = Hashtbl.find fun_vars name in - debug "[ff_var] Use fct var %s:%d@." ff_var.vname ff_var.vid; - ff_var - with Not_found -> - let ff_var = Cil.copyVarinfo fct_var name in - if not (Info.result_visible kf finfo) then - Cil.setReturnTypeVI ff_var Cil.voidType; - (* Notice that we don't have to filter the parameter types here : - * they will be update by [Cil.setFormals] later on. *) - debug "[ff_var] Mem fct var %s:%d@." - ff_var.vname ff_var.vid; - Hashtbl.add fun_vars name ff_var; - ff_var + try + let ff_var = Hashtbl.find fun_vars name in + debug "[ff_var] Use fct var %s:%d@." ff_var.vname ff_var.vid; + ff_var + with Not_found -> + let ff_var = Cil.copyVarinfo fct_var name in + if not (Info.result_visible kf finfo) then + Cil.setReturnTypeVI ff_var Cil.voidType; + (* Notice that we don't have to filter the parameter types here : + * they will be update by [Cil.setFormals] later on. *) + debug "[ff_var] Mem fct var %s:%d@." + ff_var.vname ff_var.vid; + Hashtbl.add fun_vars name ff_var; + ff_var let optim_if fct keep_stmts s_orig s cond_opt bthen belse loc = let empty_then = is_empty_block keep_stmts bthen in let empty_else = is_empty_block keep_stmts belse in debug "[optim_if] @[sid:%d (orig:%d)@ \ - with %s cond, %s empty then, %s empty else@]@." + with %s cond, %s empty then, %s empty else@]@." s.sid s_orig.sid (if cond_opt = None then "no" else "") (if empty_then then "" else "not") (if empty_else then "" else "not"); match cond_opt with - | Some cond -> - if empty_then && empty_else then mk_new_stmt s (mk_skip loc) - else (* cond visible and something in blocks : keep if *) - mk_new_stmt s (If (cond, bthen, belse, loc)) + | Some cond -> + if empty_then && empty_else then mk_new_stmt s (mk_skip loc) + else (* cond visible and something in blocks : keep if *) + mk_new_stmt s (If (cond, bthen, belse, loc)) | None -> (* no cond *) - let go_then, go_else = Info.cond_edge_visible fct s_orig in - debug - "[condition_truth_value] can go in then = %b - can go in else =%b@." - go_then go_else; - match go_then, empty_then, go_else, empty_else with - | _, true, _, true -> (* both blocks empty -> skip *) - mk_new_stmt s (mk_skip loc) - | true, false, false, true -> - (* else empty and always go to then -> block then *) - mk_new_block keep_stmts s bthen loc - | false, true, true, false -> - (* then empty and always go to else -> block else *) - mk_new_block keep_stmts s belse loc - | false, false, true, _ -> - (* always goes in the 'else' branch, - * but the then branch is not empty : *) - mk_new_stmt s (If (Cil.zero ~loc, bthen, belse, loc)) - | true, false, false, false -> - (* always goes in the 'then' branch, - * but the else branch is not empty : - *) - mk_new_stmt s (If (Cil.one ~loc, bthen, belse, loc)) - | true, true, false, false -> - (* always goes in the 'then' empty branch, - * but the else branch is not empty : - * build (if (0) belse else empty. - *) - mk_new_stmt s (If (Cil.zero ~loc, belse, bthen, loc)) - | true, false, true, false - | false, false, false, false -> - (* if both go_then and go_else are true: - * can go in both branch but don't depend on cond ? - * probably unreachable IF with reachable blocks by goto. - * if both go_else and go_else are false: - * never goes in any branch ? - * both branch visible -> dummy condition *) - mk_new_stmt s (If (Cil.one ~loc, bthen, belse, loc)) - | true, _, true, true - | false, _, false, true -> - (* can go in both or no branch (see above) : empty else *) - mk_new_block keep_stmts s bthen loc - | true, true, true, _ - | false, true, false, _ -> - (* can go in both or no branch (see above) : empty then *) - mk_new_block keep_stmts s belse loc + let go_then, go_else = Info.cond_edge_visible fct s_orig in + debug + "[condition_truth_value] can go in then = %b - can go in else =%b@." + go_then go_else; + match go_then, empty_then, go_else, empty_else with + | _, true, _, true -> (* both blocks empty -> skip *) + mk_new_stmt s (mk_skip loc) + | true, false, false, true -> + (* else empty and always go to then -> block then *) + mk_new_block keep_stmts s bthen loc + | false, true, true, false -> + (* then empty and always go to else -> block else *) + mk_new_block keep_stmts s belse loc + | false, false, true, _ -> + (* always goes in the 'else' branch, + * but the then branch is not empty : *) + mk_new_stmt s (If (Cil.zero ~loc, bthen, belse, loc)) + | true, false, false, false -> + (* always goes in the 'then' branch, + * but the else branch is not empty : + *) + mk_new_stmt s (If (Cil.one ~loc, bthen, belse, loc)) + | true, true, false, false -> + (* always goes in the 'then' empty branch, + * but the else branch is not empty : + * build (if (0) belse else empty. + *) + mk_new_stmt s (If (Cil.zero ~loc, belse, bthen, loc)) + | true, false, true, false + | false, false, false, false -> + (* if both go_then and go_else are true: + * can go in both branch but don't depend on cond ? + * probably unreachable IF with reachable blocks by goto. + * if both go_else and go_else are false: + * never goes in any branch ? + * both branch visible -> dummy condition *) + mk_new_stmt s (If (Cil.one ~loc, bthen, belse, loc)) + | true, _, true, true + | false, _, false, true -> + (* can go in both or no branch (see above) : empty else *) + mk_new_block keep_stmts s bthen loc + | true, true, true, _ + | false, true, false, _ -> + (* can go in both or no branch (see above) : empty then *) + mk_new_block keep_stmts s belse loc let visible_lval vars_visible lval = let visitor = object @@ -318,13 +318,13 @@ end = struct in List.fold_right build l [] (** This visitor is to be used to filter a function. - * It does a deep copy of the source function without the invisible elements. - * It also change the function declaration and filter the function calls. - * - * Many ideas come from [Cil.copyFunctionVisitor] but we were not able to - * directly inherit from it since some processing would not have worked in our - * context (like the [sid] computation for instance). - * *) + * It does a deep copy of the source function without the invisible elements. + * It also change the function declaration and filter the function calls. + * + * Many ideas come from [Cil.copyFunctionVisitor] but we were not able to + * directly inherit from it since some processing would not have worked in our + * context (like the [sid] computation for instance). + * *) class filter_visitor pinfo prj = object(self) inherit Visitor.generic_frama_c_visitor (Visitor_behavior.copy prj) @@ -340,19 +340,19 @@ end = struct val lab_num = ref 0; val lab_prefix = "break_cont" - method private fresh_label loc = + method private fresh_label loc = incr lab_num; let lname = Printf.sprintf "%s_%d" lab_prefix !lab_num in Label (lname, loc, false) method private is_our_label label = match label with - | Label (lname, _, false) -> - let ok = - try - let prefix = String.sub lname 0 (String.length lab_prefix) in - prefix = lab_prefix - with Invalid_argument _ -> false - in ok - | _ -> false + | Label (lname, _, false) -> + let ok = + try + let prefix = String.sub lname 0 (String.length lab_prefix) in + prefix = lab_prefix + with Invalid_argument _ -> false + in ok + | _ -> false method private get_finfo () = Extlib.the fi @@ -366,7 +366,7 @@ end = struct if v.vglob then try let v' = (Hashtbl.find fun_vars v.vname) in - Cil.ChangeTo v' + Cil.ChangeTo v' with Not_found -> Cil.SkipChildren else Cil.SkipChildren (*copy has already been done by default visitor*) @@ -394,17 +394,17 @@ end = struct let formals = filter_params (self#get_finfo ()) formals in List.map (fun v -> - Varinfo.Hashtbl.add local_visible v (); - let v' = Cil.copyVarinfo v v.vname in - Visitor_behavior.Set.varinfo self#behavior v v'; - Visitor_behavior.Set_orig.varinfo self#behavior v' v; - (match v.vlogic_var_assoc, v'.vlogic_var_assoc with - None, None -> () - | Some lv, Some lv' -> - Visitor_behavior.Set.logic_var self#behavior lv lv'; - Visitor_behavior.Set_orig.logic_var self#behavior lv' lv - | _ -> assert false (* copy should be faithful *)); - v') + Varinfo.Hashtbl.add local_visible v (); + let v' = Cil.copyVarinfo v v.vname in + Visitor_behavior.Set.varinfo self#behavior v v'; + Visitor_behavior.Set_orig.varinfo self#behavior v' v; + (match v.vlogic_var_assoc, v'.vlogic_var_assoc with + None, None -> () + | Some lv, Some lv' -> + Visitor_behavior.Set.logic_var self#behavior lv lv'; + Visitor_behavior.Set_orig.logic_var self#behavior lv' lv + | _ -> assert false (* copy should be faithful *)); + v') formals method private filter_locals locals = @@ -421,15 +421,15 @@ end = struct Visitor_behavior.Set.varinfo self#behavior var var'; Visitor_behavior.Set_orig.varinfo self#behavior var' var; (match var.vlogic_var_assoc, var'.vlogic_var_assoc with - None, None -> () - | Some lv, Some lv' -> - Visitor_behavior.Set.logic_var self#behavior lv lv'; - Visitor_behavior.Set_orig.logic_var self#behavior lv' lv - | _ -> assert false (* copy should be faithful *)); + None, None -> () + | Some lv, Some lv' -> + Visitor_behavior.Set.logic_var self#behavior lv lv'; + Visitor_behavior.Set_orig.logic_var self#behavior lv' lv + | _ -> assert false (* copy should be faithful *)); var' :: (filter locals) end else filter locals in let new_locals = filter locals in - new_locals + new_locals method! vcode_annot v = Extlib.may Cil.CurrentLoc.set (Cil_datatype.Code_annotation.loc v); @@ -495,18 +495,18 @@ end = struct (* This optim must be performed after the sliced annotations have been put in the new table. Hence, we must put the action into the queue. - *) + *) Queue.add (fun () -> - b'.bstmts <- - List.filter - (fun st -> - not (Cil.is_skip st.skind) - || st.labels <> [] - || Annotations.has_code_annot st - (*|| ((*Format.eprintf "Skipping %d@.@." st.sid;*) false)*) - ) - b'.bstmts) + b'.bstmts <- + List.filter + (fun st -> + not (Cil.is_skip st.skind) + || st.labels <> [] + || Annotations.has_code_annot st + (*|| ((*Format.eprintf "Skipping %d@.@." st.sid;*) false)*) + ) + b'.bstmts) self#get_filling_actions; b' in @@ -526,7 +526,7 @@ end = struct Visitor_behavior.Set.stmt self#behavior orig s; Visitor_behavior.Set_orig.stmt self#behavior s orig; if keep then self#add_stmt_keep s; - debug "@[finalize sid:%d->sid:%d@]@\n@." old s.sid + debug "@[finalize sid:%d->sid:%d@]@\n@." old s.sid method private process_invisible_stmt s = let finfo = self#get_finfo () in @@ -537,37 +537,37 @@ end = struct self#change_sid s; s.skind <- oldskind; (match s.skind with - | If (_,bthen,belse,loc) -> - let bthen = Cil.visitCilBlock (self:>Cil.cilVisitor) bthen in - let belse = Cil.visitCilBlock (self:>Cil.cilVisitor) belse in - let s_orig = Visitor_behavior.Get_orig.stmt self#behavior s in - optim_if finfo keep_stmts s_orig s None bthen belse loc - | Switch (_exp, body, _, loc) -> - (* the switch is invisible : it can be translated into a block. *) - rm_break_cont ~cont:false (self#fresh_label) finfo body; - let block = Cil.visitCilBlock (self:>Cil.cilVisitor) body in - (mk_new_block keep_stmts s block loc) - | Loop (_, body, loc, _lcont, _lbreak) -> - rm_break_cont (self#fresh_label) finfo body; - let bloop = Cil.visitCilBlock (self:>Cil.cilVisitor) body in - mk_new_block keep_stmts s bloop loc - | Block _ | UnspecifiedSequence _ -> - assert false (* a block is always visible *) - | TryFinally _ | TryExcept _ -> assert false (*TODO*) - | Return (_,l) -> mk_new_stmt s (Return (None,l)) - | Instr (Local_init (v, _, _)) -> - (* The initialization of the variable is useless (e.g. because it is - overwritten before being read). Just treat it as uninitialized. - Note that if the variable itself is invisible, we don't have - anything to do: it will not appear at all in the function. - *) - if Info.loc_var_visible (self#get_finfo()) v then begin - let v' = Visitor_behavior.Get.varinfo self#behavior v in - v'.vdefined <- false; - end; - mk_new_stmt s (mk_stmt_skip s) - | _ -> mk_new_stmt s (mk_stmt_skip s)); - debug "@[<hov 10>[process_invisible_stmt] gives sid:%d@ @[%a@]@]@." + | If (_,bthen,belse,loc) -> + let bthen = Cil.visitCilBlock (self:>Cil.cilVisitor) bthen in + let belse = Cil.visitCilBlock (self:>Cil.cilVisitor) belse in + let s_orig = Visitor_behavior.Get_orig.stmt self#behavior s in + optim_if finfo keep_stmts s_orig s None bthen belse loc + | Switch (_exp, body, _, loc) -> + (* the switch is invisible : it can be translated into a block. *) + rm_break_cont ~cont:false (self#fresh_label) finfo body; + let block = Cil.visitCilBlock (self:>Cil.cilVisitor) body in + (mk_new_block keep_stmts s block loc) + | Loop (_, body, loc, _lcont, _lbreak) -> + rm_break_cont (self#fresh_label) finfo body; + let bloop = Cil.visitCilBlock (self:>Cil.cilVisitor) body in + mk_new_block keep_stmts s bloop loc + | Block _ | UnspecifiedSequence _ -> + assert false (* a block is always visible *) + | TryFinally _ | TryExcept _ -> assert false (*TODO*) + | Return (_,l) -> mk_new_stmt s (Return (None,l)) + | Instr (Local_init (v, _, _)) -> + (* The initialization of the variable is useless (e.g. because it is + overwritten before being read). Just treat it as uninitialized. + Note that if the variable itself is invisible, we don't have + anything to do: it will not appear at all in the function. + *) + if Info.loc_var_visible (self#get_finfo()) v then begin + let v' = Visitor_behavior.Get.varinfo self#behavior v in + v'.vdefined <- false; + end; + mk_new_stmt s (mk_stmt_skip s) + | _ -> mk_new_stmt s (mk_stmt_skip s)); + debug "@[<hov 10>[process_invisible_stmt] gives sid:%d@ @[%a@]@]@." s.sid Printer.pp_stmt s; s in @@ -579,10 +579,10 @@ end = struct we must remove the local static attr indicating that they in fact come from a block: - if the block in which they are in scope disappears completely, - or if the enclosing function itself disappears - (making the variable a good candidate to be removed altogether) + or if the enclosing function itself disappears + (making the variable a good candidate to be removed altogether) - or if we make multiple copies of the enclosing functions (otherwise, - we would have multiple syntactic scope for the same variable). + we would have multiple syntactic scope for the same variable). *) method private remove_local_static_attr v = let new_v = Visitor_behavior.Get.varinfo self#behavior v in @@ -592,74 +592,74 @@ end = struct debug "[process_visible_stmt] does sid:%d@." s.sid; let finfo = self#get_finfo () in (match s.skind with - | Instr (Call (lval, f, args, loc)) -> - let new_call = self#process_call false s lval f args loc in - mk_new_stmt s new_call - | Instr (Local_init(v, ConsInit(f, args, kind), loc)) -> - let new_call = - Cil.treat_constructor_as_func - (self#process_call true s) v f args kind loc - in - (match new_call with - | Instr(Call _) -> - (* initialization's result was found to be useless. *) - v.vdefined <- false - | _ -> ()); - mk_new_stmt s new_call - | _ -> () (* copy the statement before modifying it *) - (* mk_new_stmt s [] s.skind *) + | Instr (Call (lval, f, args, loc)) -> + let new_call = self#process_call false s lval f args loc in + mk_new_stmt s new_call + | Instr (Local_init(v, ConsInit(f, args, kind), loc)) -> + let new_call = + Cil.treat_constructor_as_func + (self#process_call true s) v f args kind loc + in + (match new_call with + | Instr(Call _) -> + (* initialization's result was found to be useless. *) + v.vdefined <- false + | _ -> ()); + mk_new_stmt s new_call + | _ -> () (* copy the statement before modifying it *) + (* mk_new_stmt s [] s.skind *) ); let do_after s' = self#change_sid s'; (match s'.skind with - | If (cond,bthen,belse,loc) -> - let s_orig = Visitor_behavior.Get_orig.stmt self#behavior s' in - optim_if finfo keep_stmts s_orig s' (Some cond) bthen belse loc - | Switch (e,b,c,l) -> - let c' = List.filter (not $ (can_skip keep_stmts)) c in - s'.skind <- Switch(e,b,c',l) - | Block b -> - let loc = Stmt.loc s' in - (* must be performed after the optimisation - of the block itself (see comment in vblock) *) - Queue.add - (fun () -> - if b.bstmts = [] && b.battrs = [] then begin - List.iter self#remove_local_static_attr b.bstatics; - s'.skind <- (Instr (Skip loc)) - end) - self#get_filling_actions - | UnspecifiedSequence _ -> - let loc = Stmt.loc s' in - let visible_stmt = - let info = self#get_finfo () in - (fun s -> Info.inst_visible info !s) - in - Queue.add - (fun () -> - match s'.skind with - | UnspecifiedSequence l -> - let res = - List.filter (fun (s,_,_,_,_) -> not (is_skip s.skind)) l - in - let res = - List.map - (fun (s,m,w,r,c) -> - (s, - List.filter (visible_lval local_visible) m, - List.filter (visible_lval local_visible) w, - List.filter (visible_lval local_visible) r, - List.filter visible_stmt c + | If (cond,bthen,belse,loc) -> + let s_orig = Visitor_behavior.Get_orig.stmt self#behavior s' in + optim_if finfo keep_stmts s_orig s' (Some cond) bthen belse loc + | Switch (e,b,c,l) -> + let c' = List.filter (not $ (can_skip keep_stmts)) c in + s'.skind <- Switch(e,b,c',l) + | Block b -> + let loc = Stmt.loc s' in + (* must be performed after the optimisation + of the block itself (see comment in vblock) *) + Queue.add + (fun () -> + if b.bstmts = [] && b.battrs = [] then begin + List.iter self#remove_local_static_attr b.bstatics; + s'.skind <- (Instr (Skip loc)) + end) + self#get_filling_actions + | UnspecifiedSequence _ -> + let loc = Stmt.loc s' in + let visible_stmt = + let info = self#get_finfo () in + (fun s -> Info.inst_visible info !s) + in + Queue.add + (fun () -> + match s'.skind with + | UnspecifiedSequence l -> + let res = + List.filter (fun (s,_,_,_,_) -> not (is_skip s.skind)) l + in + let res = + List.map + (fun (s,m,w,r,c) -> + (s, + List.filter (visible_lval local_visible) m, + List.filter (visible_lval local_visible) w, + List.filter (visible_lval local_visible) r, + List.filter visible_stmt c + ) ) - ) - res - in - (match res with - [] -> s'.skind <- (Instr (Skip loc)) - | _ -> s'.skind <- UnspecifiedSequence res) - | _ -> ()) - self#get_filling_actions - | _ -> ()); + res + in + (match res with + [] -> s'.skind <- (Instr (Skip loc)) + | _ -> s'.skind <- UnspecifiedSequence res) + | _ -> ()) + self#get_filling_actions + | _ -> ()); debug "@[<hov 10>[process_visible_stmt] gives sid:%d@ @[%a@]@]@." s'.sid Printer.pp_stmt s'; s' @@ -672,7 +672,7 @@ end = struct | [] -> [] | l :: labs -> let keep = Info.label_visible finfo s l || self#is_our_label l in - debug "[filter_labels] %svisible %a@." + debug "[filter_labels] %svisible %a@." (if keep then "" else "in") Printer.pp_label l; if keep then l::(filter_labels labs) else filter_labels labs in @@ -708,7 +708,7 @@ end = struct keep_stmts <- Stmt.Set.empty; Varinfo.Hashtbl.clear local_visible; Varinfo.Hashtbl.add spec_table f.svar - (visitCilFunspec (self:>Cil.cilVisitor) + (visitCilFunspec (self:>Cil.cilVisitor) (Annotations.funspec ~populate:false (Extlib.the self#current_kf))); SkipChildren @@ -740,29 +740,29 @@ end = struct let ensure_visible (_,p) = Info.fun_postcond_visible finfo p.ip_content in b.b_post_cond <- filter_list ensure_visible (fun (k,p) -> k,self#visit_pred p) - b.b_post_cond; + b.b_post_cond; let allocates_visible a = Info.fun_allocates_visible finfo a in let frees_visible a = Info.fun_frees_visible finfo a in (match b.b_allocation with - FreeAllocAny -> () - | FreeAlloc(f,a) -> - try - let frees = filter_list frees_visible self#visit_identified_term f in - let allocates = filter_list allocates_visible self#visit_identified_term a in - b.b_allocation <- FreeAlloc (frees, allocates) - with Info.EraseAllocation -> b.b_allocation <- FreeAllocAny + FreeAllocAny -> () + | FreeAlloc(f,a) -> + try + let frees = filter_list frees_visible self#visit_identified_term f in + let allocates = filter_list allocates_visible self#visit_identified_term a in + b.b_allocation <- FreeAlloc (frees, allocates) + with Info.EraseAllocation -> b.b_allocation <- FreeAllocAny ); let from_visible a = Info.fun_assign_visible finfo a in let from_visit a = visitCilFrom (self:>Cil.cilVisitor) a in (match b.b_assigns with - WritesAny -> () - | Writes l -> - try - let assigns = filter_list from_visible from_visit l in - b.b_assigns <- Writes assigns - with Info.EraseAssigns -> b.b_assigns <- WritesAny + WritesAny -> () + | Writes l -> + try + let assigns = filter_list from_visible from_visit l in + b.b_assigns <- Writes assigns + with Info.EraseAssigns -> b.b_assigns <- WritesAny ); SkipChildren (* see the warning on [SkipChildren] in [vspec] ! *) @@ -779,7 +779,7 @@ end = struct | Some (t,n) -> if Info.fun_variant_visible finfo t then Some (visitCilTerm (self:>Cil.cilVisitor) t, n) else None - in + in spec.spec_variant <- new_variant ; let new_term = match spec.spec_terminates with @@ -797,7 +797,7 @@ end = struct has been visited above. we need to put links to the appropriate copies of variables (both pure C and logical ones) - *) + *) method private build_proto finfo loc = let kf = Extlib.the self#current_kf in @@ -805,70 +805,72 @@ end = struct let new_var = ff_var fun_vars kf finfo in (* we're building a prototype. *) if not (Varinfo.Hashtbl.mem fi_table new_var) then begin - new_var.vdefined <- false; - let new_kf = make_new_kf my_kf kf new_var in - Varinfo.Hashtbl.add fi_table new_var finfo; - debug "@[[build_cil_proto] -> %s@\n@]@." new_var.vname; - let action = - let (rt,args,va,attrs) = Cil.splitFunctionType new_var.vtype in - (match args with - | None -> () - | Some args -> - let old_formals = Kernel_function.get_formals kf in - let old_formals = filter_params finfo old_formals in - let args = filter_params finfo args in - let mytype = TFun(rt,Some args,va,attrs) in - let new_formals = List.map makeFormalsVarDecl args in - self#add_formals_bindings new_var new_formals; - Cil.update_var_type new_var mytype; - List.iter2 - (fun x y -> - Visitor_behavior.Set.varinfo self#behavior x y; - Visitor_behavior.Set_orig.varinfo self#behavior y x; - match x.vlogic_var_assoc with - None -> (); - | Some lv -> - let lv' = Cil.cvar_to_lvar y in - Visitor_behavior.Set.logic_var self#behavior lv lv'; - Visitor_behavior.Set_orig.logic_var self#behavior lv' lv) - old_formals - new_formals; - (* adds the new parameters to the formals decl table *) - Queue.add - (fun () -> Cil.unsafeSetFormalsDecl new_var new_formals) - self#get_filling_actions); - let res = - Cil.visitCilFunspec (self :> Cil.cilVisitor) - (Annotations.funspec ~populate:false kf) + new_var.vdefined <- false; + let new_kf = make_new_kf my_kf kf new_var in + Varinfo.Hashtbl.add fi_table new_var finfo; + debug "@[[build_cil_proto] -> %s@\n@]@." new_var.vname; + let action = + let (rt,args,va,attrs) = Cil.splitFunctionType new_var.vtype in + (match args with + | None -> () + | Some args -> + let old_formals = Kernel_function.get_formals kf in + let old_formals = filter_params finfo old_formals in + let args = filter_params finfo args in + let mytype = TFun(rt,Some args,va,attrs) in + let new_formals = List.map makeFormalsVarDecl args in + self#add_formals_bindings new_var new_formals; + Cil.update_var_type new_var mytype; + List.iter2 + (fun x y -> + Visitor_behavior.Set.varinfo self#behavior x y; + Visitor_behavior.Set_orig.varinfo self#behavior y x; + match x.vlogic_var_assoc with + None -> (); + | Some lv -> + let lv' = Cil.cvar_to_lvar y in + Visitor_behavior.Set.logic_var self#behavior lv lv'; + Visitor_behavior.Set_orig.logic_var self#behavior lv' lv) + old_formals + new_formals; + (* adds the new parameters to the formals decl table *) + Queue.add + (fun () -> Cil.unsafeSetFormalsDecl new_var new_formals) + self#get_filling_actions); + let res = + Cil.visitCilFunspec (self :> Cil.cilVisitor) + (Annotations.funspec ~populate:false kf) + in + let action () = + (* Replace the funspec copied by the default visitor, as + varinfo of formals would not be taken into account correctly + otherwise: everything would be mapped to the last set of + formals... *) + Queue.add + (fun () -> + new_kf.spec <- res; + Annotations.register_funspec ~force:true new_kf) + self#get_filling_actions + in + action in - let action () = - (* Replace the funspec copied by the default visitor, as - varinfo of formals would not be taken into account correctly - otherwise: everything would be mapped to the last set of - formals... *) - Queue.add - (fun () -> - new_kf.spec <- res; - Annotations.register_funspec ~force:true new_kf) - self#get_filling_actions - in - action - in - let orig_var = Ast_info.Function.get_vi kf.fundec in - (* The first copy is also the default one for varinfo that are not handled - by ff_var but directly by the visitor *) - if (Visitor_behavior.Get.varinfo self#behavior orig_var) == orig_var then - Visitor_behavior.Set.varinfo self#behavior orig_var new_var; - (* Set the new_var as an already known one, coming from the vi associated - to the current kf. - *) - Visitor_behavior.Set.varinfo self#behavior new_var new_var; - Visitor_behavior.Set_orig.varinfo self#behavior new_var orig_var; - Visitor_behavior.Set.kernel_function self#behavior kf new_kf; - Visitor_behavior.Set_orig.kernel_function self#behavior new_kf kf; - Queue.add - (fun () -> Globals.Functions.register new_kf) self#get_filling_actions; - GFunDecl (Cil.empty_funspec(), new_var, loc), action + let orig_var = Ast_info.Function.get_vi kf.fundec in + (* The first copy is also the default one for varinfo that are not handled + by ff_var but directly by the visitor *) + if (Visitor_behavior.Get.varinfo self#behavior orig_var) == orig_var + then + Visitor_behavior.Set.varinfo self#behavior orig_var new_var; + + (* Set the new_var as an already known one, coming from the vi associated + to the current kf. + *) + Visitor_behavior.Set.varinfo self#behavior new_var new_var; + Visitor_behavior.Set_orig.varinfo self#behavior new_var orig_var; + Visitor_behavior.Set.kernel_function self#behavior kf new_kf; + Visitor_behavior.Set_orig.kernel_function self#behavior new_kf kf; + Queue.add + (fun () -> Globals.Functions.register new_kf) self#get_filling_actions; + GFunDecl (Cil.empty_funspec(), new_var, loc), action end else begin let old_finfo = Varinfo.Hashtbl.find fi_table new_var in if not (finfo = old_finfo) then @@ -917,24 +919,24 @@ end = struct let action () = Queue.add (fun () -> - new_kf.spec <- Varinfo.Hashtbl.find spec_table new_fct_var; - Annotations.register_funspec ~force:true new_kf) + new_kf.spec <- Varinfo.Hashtbl.find spec_table new_fct_var; + Annotations.register_funspec ~force:true new_kf) self#get_filling_actions in let f = Kernel_function.get_definition new_kf in (* [JS 2009/03/23] do not call self#vfunc in the assertion; otherwise does not work whenever frama-c is compiled with -no-assert *) - let res = self#vfunc f in - assert (res = SkipChildren); + let res = self#vfunc f in + assert (res = SkipChildren); (* if this ever changes, we must do some work. *) - GFun (f,loc), action + GFun (f,loc), action end in (match List.filter Info.body_visible finfo_list with - | [ _ ] -> () - | [] | _ :: _ :: _ -> - let vars = static_from_kf kf in - List.iter self#remove_local_static_attr vars); + | [ _ ] -> () + | [] | _ :: _ :: _ -> + let vars = static_from_kf kf in + List.iter self#remove_local_static_attr vars); List.map do_f finfo_list method! vglob_aux g = diff --git a/src/kernel_services/ast_transformations/filter.mli b/src/kernel_services/ast_transformations/filter.mli index dc0616c892e..e41f394b6ea 100644 --- a/src/kernel_services/ast_transformations/filter.mli +++ b/src/kernel_services/ast_transformations/filter.mli @@ -33,13 +33,13 @@ module type RemoveInfo = sig (** exception that fun_assign_visible should raise to indicate that the corresponding assigns clause should be erased entirely - *) + *) exception EraseAssigns - (** exception that fun_frees_visible or fun_allocates_visible should - raise to indicate that the corresponding allocation clause should + (** exception that fun_frees_visible or fun_allocates_visible should + raise to indicate that the corresponding allocation clause should be erased entirely - *) + *) exception EraseAllocation (** some type for the whole project information *) @@ -49,22 +49,22 @@ module type RemoveInfo = sig type fct (** This function will be called for each function of the source program. - * A new function will be created for each element of the returned list. + * A new function will be created for each element of the returned list. *) val fct_info : proj -> kernel_function -> fct list (** useful when we want to have several functions in the result for one - * source function. If it is not the case, you can return [varinfo.vname]. - * It is the responsibility of the user to given different names to different - * function. *) + * source function. If it is not the case, you can return [varinfo.vname]. + * It is the responsibility of the user to given different names to different + * function. *) val fct_name : varinfo -> fct -> string (** tells if the n-th formal parameter is visible. *) val param_visible : fct -> int -> bool (** tells if the body of a function definition is visible. - * True is most cases, but can be defined to be false when we want to export - * only the declaration of a function instead of its definition *) + * True is most cases, but can be defined to be false when we want to export + * only the declaration of a function instead of its definition *) val body_visible : fct -> bool (** tells if the local variable is visible. *) @@ -87,35 +87,35 @@ module type RemoveInfo = sig val fun_allocates_visible : fct -> identified_term -> bool val fun_assign_visible : fct -> from -> bool - (** true if the assigned value (first component of the from) is visible - @raise EraseAssigns to indicate that the corresponding assigns clause - should be erased entirely (i.e. assigns everything. If it were to - just return false to all elements, this would result in assigns \nothing - *) + (** true if the assigned value (first component of the from) is visible + @raise EraseAssigns to indicate that the corresponding assigns clause + should be erased entirely (i.e. assigns everything. If it were to + just return false to all elements, this would result in assigns \nothing + *) val fun_deps_visible : fct -> identified_term -> bool - (** true if the corresponding functional dependency is visible. *) + (** true if the corresponding functional dependency is visible. *) (** [called_info] will be called only if the call statement is visible. - * If it returns [None], the source call will be visible, - * else it will use the returned [fct] to know if the return value and the - * arguments are visible. - * The input [fct] parameter is the one of the caller function. - * *) + * If it returns [None], the source call will be visible, + * else it will use the returned [fct] to know if the return value and the + * arguments are visible. + * The input [fct] parameter is the one of the caller function. + * *) val called_info : proj * fct -> stmt -> - (kernel_function * fct) option + (kernel_function * fct) option (** tells if the lvalue of the call has to be visible *) val res_call_visible : fct -> stmt -> bool (** tells if the function returns something or if the result is [void]. - * Notice that if this function returns [true] the function will have the same - * return type than the original function. So, if it was already [void], it - * makes no difference if this function returns true or false. - * - * - For a defined function, this should give the same result than - * [inst_visible fct_info (Kernel_function.find_return kf)]. - * - [res_call_visible] must return [false] - * if [result_visible] returns false on the called function. + * Notice that if this function returns [true] the function will have the same + * return type than the original function. So, if it was already [void], it + * makes no difference if this function returns true or false. + * + * - For a defined function, this should give the same result than + * [inst_visible fct_info (Kernel_function.find_return kf)]. + * - [res_call_visible] must return [false] + * if [result_visible] returns false on the called function. *) val result_visible : kernel_function -> fct -> bool @@ -128,7 +128,7 @@ module type RemoveInfo = sig end (** Given a module that match the module type described above, -* [F.build_cil_file] initializes a new project containing the slices + * [F.build_cil_file] initializes a new project containing the slices *) module F (Info : RemoveInfo) : sig -- GitLab From 4b7ec70813b1c9bd0d3fc0f056b1b4e2f9047d04 Mon Sep 17 00:00:00 2001 From: Virgile Prevosto <virgile.prevosto@m4x.org> Date: Wed, 1 Apr 2020 08:45:59 +0200 Subject: [PATCH 087/218] [slicing] more robust correspondance between function varinfos The varinfo used for occurences that were not handled directly by filter, but relied on standard visitor replacement was absolutely not synchronized with the the ones generated according to the finfo list. --- .../ast_transformations/filter.ml | 37 ++++++++++++------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/src/kernel_services/ast_transformations/filter.ml b/src/kernel_services/ast_transformations/filter.ml index 95bbf5768ae..caff6cef46e 100644 --- a/src/kernel_services/ast_transformations/filter.ml +++ b/src/kernel_services/ast_transformations/filter.ml @@ -799,7 +799,7 @@ end = struct variables (both pure C and logical ones) *) - method private build_proto finfo loc = + method private build_proto is_first finfo loc = let kf = Extlib.the self#current_kf in fi <- Some finfo; let new_var = ff_var fun_vars kf finfo in @@ -855,15 +855,12 @@ end = struct action in let orig_var = Ast_info.Function.get_vi kf.fundec in - (* The first copy is also the default one for varinfo that are not handled - by ff_var but directly by the visitor *) - if (Visitor_behavior.Get.varinfo self#behavior orig_var) == orig_var - then + (* The first copy is also the default one for varinfo + that are not handled by ff_var but directly by the visitor *) + if is_first then Visitor_behavior.Set.varinfo self#behavior orig_var new_var; - - (* Set the new_var as an already known one, coming from the vi associated - to the current kf. - *) + (* Set the new_var as an already known one, + coming from the vi associated to the current kf. *) Visitor_behavior.Set.varinfo self#behavior new_var new_var; Visitor_behavior.Set_orig.varinfo self#behavior new_var orig_var; Visitor_behavior.Set.kernel_function self#behavior kf new_kf; @@ -887,8 +884,15 @@ end = struct debug "@[[compute_fct_prototypes] for %a (x%d)@\n@]@." Kernel_function.pretty (Extlib.the self#current_kf) (List.length finfo_list); - let build_cil_proto finfo = self#build_proto finfo loc - in List.map build_cil_proto finfo_list + let build_cil_proto is_first finfo = + self#build_proto is_first finfo loc + in + match finfo_list with + | [] -> [] + | hd :: tl -> + let hd = build_cil_proto true hd in + let tl = List.map (build_cil_proto false) tl in + hd :: tl method private compute_fct_definitions f loc = let fvar = f.Cil_types.svar in @@ -896,9 +900,9 @@ end = struct let finfo_list = Info.fct_info pinfo kf in debug "@[[compute_fct_definitions] for %a (x%d)@\n@]@." Kernel_function.pretty kf (List.length finfo_list); - let do_f finfo = + let do_f is_first finfo = if not (Info.body_visible finfo) then - self#build_proto finfo loc + self#build_proto is_first finfo loc else begin let new_fct_var = ff_var fun_vars kf finfo in new_fct_var.vdefined <- true; @@ -937,7 +941,12 @@ end = struct | [] | _ :: _ :: _ -> let vars = static_from_kf kf in List.iter self#remove_local_static_attr vars); - List.map do_f finfo_list + match finfo_list with + | [] -> [] + | hd :: tl -> + let hd = do_f true hd in + let tl = List.map (do_f false) tl in + hd :: tl method! vglob_aux g = let post action g = -- GitLab From 9dbd1fbf100683ed1d0d047f075cdbaaeddade7b Mon Sep 17 00:00:00 2001 From: Virgile Prevosto <virgile.prevosto@m4x.org> Date: Wed, 1 Apr 2020 08:55:49 +0200 Subject: [PATCH 088/218] [tests] update test for #840 and set oracle --- tests/slicing/function_lvar.i | 2 +- tests/slicing/oracle/function_lvar.res.oracle | 57 +++++++++++++++++++ 2 files changed, 58 insertions(+), 1 deletion(-) create mode 100644 tests/slicing/oracle/function_lvar.res.oracle diff --git a/tests/slicing/function_lvar.i b/tests/slicing/function_lvar.i index c7d245c4528..05cc5c69a20 100644 --- a/tests/slicing/function_lvar.i +++ b/tests/slicing/function_lvar.i @@ -1,5 +1,5 @@ /* run.config* -OPT: -slice-pragma main +OPT: -slice-pragma main -then-last -print */ int g(int x) { return x; } diff --git a/tests/slicing/oracle/function_lvar.res.oracle b/tests/slicing/oracle/function_lvar.res.oracle new file mode 100644 index 00000000000..667a53c29a9 --- /dev/null +++ b/tests/slicing/oracle/function_lvar.res.oracle @@ -0,0 +1,57 @@ +[kernel] Parsing tests/slicing/function_lvar.i (no preprocessing) +[slicing] slicing requests in progress... +[eva] Analyzing a complete application starting at main +[eva] Computing initial state +[eva] Initial state computed +[eva:initial-state] Values of globals at initialization + +[eva] done for function main +[eva:summary] ====== ANALYSIS SUMMARY ====== + ---------------------------------------------------------------------------- + 2 functions analyzed (out of 2): 100% coverage. + In these functions, 5 statements reached (out of 5): 100% coverage. + ---------------------------------------------------------------------------- + No errors or warnings raised during the analysis. + ---------------------------------------------------------------------------- + 0 alarms generated by the analysis. + ---------------------------------------------------------------------------- + Evaluation of the logical properties reached by the analysis: + Assertions 1 valid 0 unknown 0 invalid 1 total + Preconditions 0 valid 0 unknown 0 invalid 0 total + 100% of the logical properties reached have been proven. + ---------------------------------------------------------------------------- +[slicing] initializing slicing ... +[slicing] interpreting slicing requests from the command line... +[pdg] computing for function main +[from] Computing for function g +[from] Done for function g +[pdg] done for function main +[slicing] applying all slicing requests... +[slicing] applying 0 actions... +[slicing] applying all slicing requests... +[slicing] applying 1 actions... +[slicing] applying actions: 1/1... +[pdg] computing for function g +[pdg] done for function g +[slicing] exporting project to 'Slicing export'... +[slicing] applying all slicing requests... +[slicing] applying 0 actions... +[sparecode] remove unused global declarations from project 'Slicing export tmp' +[sparecode] removed unused global declarations in new project 'Slicing export' +/* Generated by Frama-C */ +int g(int x); + +void g_slice_1(void) +{ + return; +} + +void main(void) +{ + /*@ assert &g ≡ &g; */ ; + /*@ slice pragma stmt; */ + g_slice_1(); + return; +} + + -- GitLab From 1850061b67211112a04e9a2996521b5c546801d6 Mon Sep 17 00:00:00 2001 From: Patrick Baudin <patrick.baudin@cea.fr> Date: Wed, 1 Apr 2020 09:30:00 +0200 Subject: [PATCH 089/218] Adds a comment about Cil.update_var_type --- src/kernel_services/ast_data/cil_types.mli | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/kernel_services/ast_data/cil_types.mli b/src/kernel_services/ast_data/cil_types.mli index 66327ce7d8c..4e590ae3297 100644 --- a/src/kernel_services/ast_data/cil_types.mli +++ b/src/kernel_services/ast_data/cil_types.mli @@ -540,7 +540,9 @@ and varinfo = { (** the original name of the variable. Need not be unique. *) mutable vtype: typ; - (** The declared type of the variable. *) + (** The declared type of the variable. For modifications of the field, + {!Cil.update_var_type} helps in synchronizing the type of the C + variable and the one of the associated logic variable. *) mutable vattr: attributes; (** A list of attributes associated with the variable.*) -- GitLab From de65a6c4150efca0d5b51c45a732c7058cc3db79 Mon Sep 17 00:00:00 2001 From: Virgile Prevosto <virgile.prevosto@m4x.org> Date: Wed, 1 Apr 2020 09:42:22 +0200 Subject: [PATCH 090/218] [tests] also tests should use Cil.update_var_type --- tests/cil/Change_formals.ml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/cil/Change_formals.ml b/tests/cil/Change_formals.ml index 218b1e4fe20..c311efe0728 100644 --- a/tests/cil/Change_formals.ml +++ b/tests/cil/Change_formals.ml @@ -40,7 +40,7 @@ class transform prj = object(_self) typ, Some (vtype @ [ "ok", Cil.intType, [] ]), varity, attr) in - vi.vtype <- new_fun_typ; + Cil.update_var_type vi new_fun_typ; Project.on prj (fun () -> Cil.setFormalsDecl vi new_fun_typ;) (); -- GitLab From e2bb33a05e95893afafa2a62096fb29d7040d932 Mon Sep 17 00:00:00 2001 From: Virgile Prevosto <virgile.prevosto@m4x.org> Date: Wed, 1 Apr 2020 09:55:51 +0200 Subject: [PATCH 091/218] [value] yet another missing Cil.update_var_type --- src/plugins/value/domains/cvalue/builtins_malloc.ml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/value/domains/cvalue/builtins_malloc.ml b/src/plugins/value/domains/cvalue/builtins_malloc.ml index 30c6755737c..727ef69ca50 100644 --- a/src/plugins/value/domains/cvalue/builtins_malloc.ml +++ b/src/plugins/value/domains/cvalue/builtins_malloc.ml @@ -454,7 +454,7 @@ let update_variable_validity ?(make_weak=false) base sizev = (* Mutating the type of a varinfo is not exactly a good idea. This is probably fine here, because the type of a malloced variable is almost never used. *) - vi.vtype <- weaken_type vi.vtype; + Cil.update_var_type vi (weaken_type vi.vtype); end; Base.update_variable_validity variable_v ~weak:make_weak ~min_alloc:min_sure_bits ~max_alloc:max_valid_bits; -- GitLab From 15d76c8e0de36f84103974f51a73d7b362f0f3b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20B=C3=BChler?= <david.buhler@cea.fr> Date: Wed, 1 Apr 2020 09:56:53 +0200 Subject: [PATCH 092/218] [Eva] Relaxes the check of builtin types for void pointers. When a builtin expects a void pointer (as argument or result), any pointer type is accepted. This allows allocation builtins to be used for more functions. --- src/plugins/value/domains/cvalue/builtins.ml | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/plugins/value/domains/cvalue/builtins.ml b/src/plugins/value/domains/cvalue/builtins.ml index 2558f8efefb..f992d2c0885 100644 --- a/src/plugins/value/domains/cvalue/builtins.ml +++ b/src/plugins/value/domains/cvalue/builtins.ml @@ -129,10 +129,15 @@ let inconsistent_builtin_typ kf = function let expected_result, expected_args = typ () in match Kernel_function.get_type kf with | TFun (result, args, _, _) -> + (* If a builtin expects a void pointer, then accept all pointer types. *) + let need_cast typ expected = + Cil.need_cast typ expected + && not (Cil.isVoidPtrType expected && Cil.isPointerType typ) + in let args = Cil.argsToList args in - Cil.need_cast result expected_result + need_cast result expected_result || List.length args <> List.length expected_args - || List.exists2 (fun (_, t, _) u -> Cil.need_cast t u) args expected_args + || List.exists2 (fun (_, t, _) u -> need_cast t u) args expected_args | _ -> assert false (* Warns if the builtin [bname] overrides the function definition [kf]. *) -- GitLab From af4ad89054b851a3bed38977400c48f9b1c51b28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Loi=CC=88c=20Correnson?= <loic.correnson@cea.fr> Date: Wed, 1 Apr 2020 10:19:24 +0200 Subject: [PATCH 093/218] [kernel] also coerce enum constants --- .../ast_queries/logic_utils.ml | 21 +++++++++---------- .../oracle/enum.res.oracle | 4 ++-- .../oracle/cast_enum_bts1546.0.res.oracle | 2 +- 3 files changed, 13 insertions(+), 14 deletions(-) diff --git a/src/kernel_services/ast_queries/logic_utils.ml b/src/kernel_services/ast_queries/logic_utils.ml index c08f9d6d6ae..9f0a5c558d9 100644 --- a/src/kernel_services/ast_queries/logic_utils.ml +++ b/src/kernel_services/ast_queries/logic_utils.ml @@ -227,13 +227,6 @@ let equal_ltype = Cil_datatype.Logic_type.equal let mk_cast ?loc ?(force=false) newt t = let newt = Cil.type_remove_attributes_for_logic_type newt in if equal_ltype (Ctype newt) t.term_type then t else - (* - let rec is_iconst e = match e.term_node with - | TCastE(ty,e) when Cil.isArithmeticOrPointerType ty -> is_iconst e - | TLogic_coerce(Linteger,e) -> is_iconst e - | TConst(Integer _) -> true - | _ -> false in - *) let rec unroll_cast e = match e.term_node with | TCastE(oldt,e) when (Cil.isPointerType newt && Cil.isPointerType oldt) @@ -248,8 +241,8 @@ let mk_cast ?loc ?(force=false) newt t = | _ -> e in let tres = if force then t else unroll_cast t in - let loc = match loc with None -> t.term_loc | Some loc -> loc in - Logic_const.term ~loc (TCastE (newt, tres)) (Ctype newt) + let loc = match loc with None -> t.term_loc | Some loc -> loc in + Logic_const.term ~loc (TCastE (newt, tres)) (Ctype newt) (* -------------------------------------------------------------------------- *) @@ -319,14 +312,20 @@ let numeric_coerce ltyp t = | TLogic_coerce(lt,e) when Cil.no_op_coerce lt e -> (* coercion hidden by the printer, but still present *) mk_coerce ltyp e - | TConst(Integer _) when ltyp = Linteger -> { t with term_type = Linteger } - | TConst(LReal _ ) when ltyp = Lreal -> { t with term_type = Lreal } + | TConst(LEnum _) | TConst(Integer _) when ltyp = Linteger + -> { t with term_type = Linteger } + | TConst(LReal _ ) when ltyp = Lreal -> + { t with term_type = Lreal } | TCastE(ty,e) -> begin match ltyp, Cil.unrollType ty, e.term_node with | Linteger, TInt(ik,_), TConst(Integer(v,_)) when Cil.fitsInInt ik v -> { e with term_type = Linteger } | Lreal, TFloat(fk,_), TConst(LReal r) when Cil.isFiniteFloat fk r.r_nearest -> { e with term_type = Lreal } + | Linteger, TInt(ik,_), TConst(LEnum { eival }) -> + ( match Cil.constFoldToInt eival with + | Some i when Cil.fitsInInt ik i -> { e with term_type = Linteger } + | _ -> mk_coerce ltyp t ) | _ -> mk_coerce ltyp t end | _ -> mk_coerce ltyp t diff --git a/tests/constant_propagation/oracle/enum.res.oracle b/tests/constant_propagation/oracle/enum.res.oracle index d7c4e9f6ea0..cbd71cd5823 100644 --- a/tests/constant_propagation/oracle/enum.res.oracle +++ b/tests/constant_propagation/oracle/enum.res.oracle @@ -14,7 +14,7 @@ [eva] Recording results for f [eva] Done for function f [eva:alarm] tests/constant_propagation/enum.i:13: Warning: - signed overflow. assert (int)B + c ≤ 2147483647; + signed overflow. assert B + c ≤ 2147483647; [eva:alarm] tests/constant_propagation/enum.i:15: Warning: signed overflow. assert (int)(y + z) + t ≤ 2147483647; [eva:alarm] tests/constant_propagation/enum.i:15: Warning: @@ -43,7 +43,7 @@ int main(int c, unsigned int u) enum E x = A; int y = f(0U); int z = f(D); - /*@ assert Eva: signed_overflow: (int)B + c ≤ 2147483647; */ + /*@ assert Eva: signed_overflow: B + c ≤ 2147483647; */ int t = B + c; int v = (int)(2U + u); /*@ assert Eva: signed_overflow: (int)(y + z) + t ≤ 2147483647; */ diff --git a/tests/spec/oracle/cast_enum_bts1546.0.res.oracle b/tests/spec/oracle/cast_enum_bts1546.0.res.oracle index 859426aa635..8a5f937eecd 100644 --- a/tests/spec/oracle/cast_enum_bts1546.0.res.oracle +++ b/tests/spec/oracle/cast_enum_bts1546.0.res.oracle @@ -39,7 +39,7 @@ enum e f(enum e x) return __retres; } -/*@ ensures P: \result ≡ (unsigned int)E0; */ +/*@ ensures P: \result ≡ E0; */ enum e g(enum e x) { enum e __retres; -- GitLab From ae6b6d2993a6d544fae92f48ca5d271b0ae67cc1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Loi=CC=88c=20Correnson?= <loic.correnson@cea.fr> Date: Wed, 1 Apr 2020 10:37:25 +0200 Subject: [PATCH 094/218] [kernel] more updated oracles with better casts --- tests/float/oracle/dr_infinity.res.oracle | 5 ++--- tests/float/oracle/nonlin.0.res.oracle | 2 +- tests/float/oracle/nonlin.3.res.oracle | 2 +- tests/misc/oracle/widen_hints_float.res.oracle | 4 ++-- tests/value/oracle/propagate_bottom.res.oracle | 6 +++--- 5 files changed, 9 insertions(+), 10 deletions(-) diff --git a/tests/float/oracle/dr_infinity.res.oracle b/tests/float/oracle/dr_infinity.res.oracle index 8d194475db5..04bd0c13b12 100644 --- a/tests/float/oracle/dr_infinity.res.oracle +++ b/tests/float/oracle/dr_infinity.res.oracle @@ -27,10 +27,9 @@ [eva:alarm] tests/float/dr_infinity.i:16: Warning: non-finite float value. assert \is_finite(\mul_float(x, x)); [eva:alarm] tests/float/dr_infinity.i:21: Warning: - non-finite double value. - assert \is_finite(\mul_double(d, (double)((int)10))); + non-finite double value. assert \is_finite(\mul_double(d, (double)10)); [eva:alarm] tests/float/dr_infinity.i:26: Warning: - non-finite double value. assert \is_finite(\div_double((double)((int)2), d)); + non-finite double value. assert \is_finite(\div_double((double)2, d)); [eva:alarm] tests/float/dr_infinity.i:31: Warning: non-finite double value. assert \is_finite(\div_double(d, (double)0.01)); [eva:alarm] tests/float/dr_infinity.i:36: Warning: diff --git a/tests/float/oracle/nonlin.0.res.oracle b/tests/float/oracle/nonlin.0.res.oracle index fc0648394e7..b3c87ee2078 100644 --- a/tests/float/oracle/nonlin.0.res.oracle +++ b/tests/float/oracle/nonlin.0.res.oracle @@ -195,7 +195,7 @@ [eva:alarm] tests/float/nonlin.c:77: Warning: non-finite double value. assert - \is_finite(\div_double((double)((int)1), + \is_finite(\div_double((double)1, \add_double(\mul_double((double)ff, (double)ff), (double)0.000000001))); [eva] Recording results for split_alarm diff --git a/tests/float/oracle/nonlin.3.res.oracle b/tests/float/oracle/nonlin.3.res.oracle index e6446859b39..b5f30cd1f74 100644 --- a/tests/float/oracle/nonlin.3.res.oracle +++ b/tests/float/oracle/nonlin.3.res.oracle @@ -195,7 +195,7 @@ [eva:alarm] tests/float/nonlin.c:77: Warning: non-finite double value. assert - \is_finite(\div_double((double)((int)1), + \is_finite(\div_double((double)1, \add_double(\mul_double((double)ff, (double)ff), (double)0.000000001))); [eva] Recording results for split_alarm diff --git a/tests/misc/oracle/widen_hints_float.res.oracle b/tests/misc/oracle/widen_hints_float.res.oracle index 0f168648e4d..9fad6f26134 100644 --- a/tests/misc/oracle/widen_hints_float.res.oracle +++ b/tests/misc/oracle/widen_hints_float.res.oracle @@ -37,8 +37,8 @@ [eva:alarm] tests/misc/widen_hints_float.c:34: Warning: non-finite double value. assert - \is_finite(\mul_double(\sub_double(f3, (double)((int)64)), - \sub_double(f3, (double)((int)64)))); + \is_finite(\mul_double(\sub_double(f3, (double)64), + \sub_double(f3, (double)64))); [eva] Recording results for parabola [eva] Done for function parabola [eva] computing for function trigo <- main. diff --git a/tests/value/oracle/propagate_bottom.res.oracle b/tests/value/oracle/propagate_bottom.res.oracle index f48513b4b78..84b9c0efca5 100644 --- a/tests/value/oracle/propagate_bottom.res.oracle +++ b/tests/value/oracle/propagate_bottom.res.oracle @@ -18,13 +18,13 @@ division by zero. assert 0 ≢ 0; [eva:alarm] tests/value/propagate_bottom.i:25: Warning: non-finite double value. - assert \is_finite(\div_double((double)1., (double)((int)0))); + assert \is_finite(\div_double((double)1., (double)0)); [eva:alarm] tests/value/propagate_bottom.i:28: Warning: non-finite double value. - assert \is_finite(\div_double((double)1., (double)((int)0))); + assert \is_finite(\div_double((double)1., (double)0)); [eva:alarm] tests/value/propagate_bottom.i:31: Warning: non-finite double value. - assert \is_finite(\div_double((double)1., (double)((int)0))); + assert \is_finite(\div_double((double)1., (double)0)); [eva:alarm] tests/value/propagate_bottom.i:34: Warning: non-finite double value. assert \is_finite(\div_double((double)1., (double)0.)); -- GitLab From 4adc74a02074519d57c4d369225192e6708c4b0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Loi=CC=88c=20Correnson?= <loic.correnson@cea.fr> Date: Wed, 1 Apr 2020 10:44:21 +0200 Subject: [PATCH 095/218] [kernel] confirm inserted cast in pointer-comparison Alarm at line 16 actually uses pointers casted into *signed* integers. Can not remove this cast. --- tests/value/oracle/pointer_comparison.0.res.oracle | 6 ++++-- tests/value/oracle/pointer_comparison.1.res.oracle | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/tests/value/oracle/pointer_comparison.0.res.oracle b/tests/value/oracle/pointer_comparison.0.res.oracle index 6ac5900dc2e..0202337ff61 100644 --- a/tests/value/oracle/pointer_comparison.0.res.oracle +++ b/tests/value/oracle/pointer_comparison.0.res.oracle @@ -194,7 +194,8 @@ [eva:alarm] tests/value/pointer_comparison.c:16: Warning: pointer downcast. assert (unsigned int)(&y) ≤ 2147483647; [eva:alarm] tests/value/pointer_comparison.c:16: Warning: - pointer comparison. assert \pointer_comparable((void *)p, (void *)(&y)); + pointer comparison. + assert \pointer_comparable((void *)((int)p), (void *)((int)(&y))); [eva] tests/value/pointer_comparison.c:16: Frama_C_show_each_5: {{ &x + {16} }} [eva] tests/value/pointer_comparison.c:17: Frama_C_show_each_5e: {{ &x + {16} }} [eva:alarm] tests/value/pointer_comparison.c:18: Warning: @@ -254,7 +255,8 @@ tried with Eva. [ - ] Assertion 'Eva,ptr_comparison' (file tests/value/pointer_comparison.c, line 16) assert - Eva: ptr_comparison: \pointer_comparable((void *)p, (void *)(&y)); + Eva: ptr_comparison: + \pointer_comparable((void *)((int)p), (void *)((int)(&y))); tried with Eva. [ - ] Assertion 'Eva,ptr_comparison' (file tests/value/pointer_comparison.c, line 18) assert diff --git a/tests/value/oracle/pointer_comparison.1.res.oracle b/tests/value/oracle/pointer_comparison.1.res.oracle index cd63714dccc..0f48c4ee7e0 100644 --- a/tests/value/oracle/pointer_comparison.1.res.oracle +++ b/tests/value/oracle/pointer_comparison.1.res.oracle @@ -221,7 +221,8 @@ [eva:alarm] tests/value/pointer_comparison.c:16: Warning: pointer downcast. assert (unsigned int)(&y) ≤ 2147483647; [eva:alarm] tests/value/pointer_comparison.c:16: Warning: - pointer comparison. assert \pointer_comparable((void *)p, (void *)(&y)); + pointer comparison. + assert \pointer_comparable((void *)((int)p), (void *)((int)(&y))); [eva] tests/value/pointer_comparison.c:16: Frama_C_show_each_5: {{ &x + {16} }} [eva] tests/value/pointer_comparison.c:17: Frama_C_show_each_5e: {{ &x + {16} }} [eva:alarm] tests/value/pointer_comparison.c:18: Warning: @@ -282,7 +283,8 @@ tried with Eva. [ - ] Assertion 'Eva,ptr_comparison' (file tests/value/pointer_comparison.c, line 16) assert - Eva: ptr_comparison: \pointer_comparable((void *)p, (void *)(&y)); + Eva: ptr_comparison: + \pointer_comparable((void *)((int)p), (void *)((int)(&y))); tried with Eva. [ - ] Assertion 'Eva,ptr_comparison' (file tests/value/pointer_comparison.c, line 18) assert -- GitLab From 51293d424dd6bf3678f57f5cce5e5934d928c466 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Loi=CC=88c=20Correnson?= <loic.correnson@cea.fr> Date: Wed, 1 Apr 2020 10:48:47 +0200 Subject: [PATCH 096/218] [kernel] update oracles for completely missed alarm Probably due to a missing cast in previously generated alarm. --- tests/value/oracle/const.res.oracle | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/value/oracle/const.res.oracle b/tests/value/oracle/const.res.oracle index 857b44485fb..5836c004bf9 100644 --- a/tests/value/oracle/const.res.oracle +++ b/tests/value/oracle/const.res.oracle @@ -141,6 +141,8 @@ [eva] done for function main [eva] tests/value/const.i:21: assertion 'Eva,mem_access' got final status invalid. +[eva] tests/value/const.i:26: + assertion 'Eva,mem_access' got final status invalid. [eva] ====== VALUES COMPUTED ====== [eva:final-states] Values at end of function aux_ret_const: __retres ∈ {1} -- GitLab From 2ccdaba2f0e4ae7e1dd3bf2ce47cd3daf53c1b76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Loi=CC=88c=20Correnson?= <loic.correnson@cea.fr> Date: Wed, 1 Apr 2020 11:52:35 +0200 Subject: [PATCH 097/218] [kernel] fix comparison of logic typedefs --- src/kernel_services/ast_queries/cil_datatype.ml | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/kernel_services/ast_queries/cil_datatype.ml b/src/kernel_services/ast_queries/cil_datatype.ml index 95ca68ae356..f68c4028809 100644 --- a/src/kernel_services/ast_queries/cil_datatype.ml +++ b/src/kernel_services/ast_queries/cil_datatype.ml @@ -1320,17 +1320,19 @@ let rec compare_logic_type config v1 v2 = | Ltype _ -> 4 | Larrow _ -> 5 in + let rec unroll = function + | Ltype({lt_def = Some (LTsyn t)},[]) -> unroll t + (*TODO: instanciate polymorphic types *) + | t -> t in + let v1 = if config.unroll then unroll v1 else v1 in + let v2 = if config.unroll then unroll v2 else v2 in let k1 = rank v1 in let k2 = rank v2 in - if k1 <> k2 then k1-k2 + if k1 <> k2 then + k1-k2 else match v1,v2 with | Ctype t1 , Ctype t2 -> compare_type config t1 t2 - | Ltype ({lt_def = Some (LTsyn t1)},ts1), - Ltype ({lt_def = Some (LTsyn t2)},ts2) when config.unroll -> - let c = compare_logic_type config t1 t2 in - if c <> 0 then c - else compare_list (compare_logic_type config) ts1 ts2 | Ltype(a,ts1), Ltype(b,ts2) -> let c = Logic_type_info.compare a b in if c <> 0 then c -- GitLab From 260cbf3deadf784d4196eaea5db67eaf61dc2773 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Loi=CC=88c=20Correnson?= <loic.correnson@cea.fr> Date: Wed, 1 Apr 2020 10:37:52 +0200 Subject: [PATCH 098/218] [tests] fix cpp-command FILTER for macos --- tests/syntax/cpp-command.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/syntax/cpp-command.c b/tests/syntax/cpp-command.c index 45fd2383388..41512d12b91 100644 --- a/tests/syntax/cpp-command.c +++ b/tests/syntax/cpp-command.c @@ -1,5 +1,5 @@ /* run.config* - FILTER: sed 's|/tmp/[^ ]*\.i|/tmp/FILE.i|g' + FILTER: sed 's:/\(tmp\|var\)/[^ ]*\.i:/tmp/FILE.i:g' OPT: -no-autoload-plugins -cpp-frama-c-compliant -cpp-command "echo [\$(basename '%1') \$(basename '%1') \$(basename '%i') \$(basename '%input')] ['%2' '%2' '%o' '%output'] ['%args']" OPT: -no-autoload-plugins -cpp-frama-c-compliant -cpp-command "echo %%1 = \$(basename '%1') %%2 = '%2' %%args = '%args'" OPT: -no-autoload-plugins -cpp-frama-c-compliant -cpp-command "printf \"%s\" \"using \\% has no effect : \$(basename \"\%input\")\"" -- GitLab From f9fe28ce15b2ca1f18374c08130daea89dd0f8c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Loi=CC=88c=20Correnson?= <loic.correnson@cea.fr> Date: Wed, 1 Apr 2020 12:11:09 +0200 Subject: [PATCH 099/218] [tests] fix includes in libc Does not work on macOS ; probably implicit path lookup is different than linux ? --- share/libc/netinet/in.h | 2 +- share/libc/sys/socket.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/share/libc/netinet/in.h b/share/libc/netinet/in.h index e63125c5678..6eb54f02eb0 100644 --- a/share/libc/netinet/in.h +++ b/share/libc/netinet/in.h @@ -25,7 +25,7 @@ #ifndef __FC_NETINET_IN #define __FC_NETINET_IN -#include "features.h" +#include "../features.h" __PUSH_FC_STDLIB #include "../__fc_inet.h" __POP_FC_STDLIB diff --git a/share/libc/sys/socket.h b/share/libc/sys/socket.h index bc155eeb8e7..4a6e6c21f4f 100644 --- a/share/libc/sys/socket.h +++ b/share/libc/sys/socket.h @@ -46,7 +46,7 @@ struct sockaddr_storage { sa_family_t ss_family; }; -#include "sys/uio.h" +#include "./uio.h" struct cmsghdr { socklen_t cmsg_len; -- GitLab From 58cca5b2d95b97e3f49d0458da71970c59439d6e Mon Sep 17 00:00:00 2001 From: Virgile Prevosto <virgile.prevosto@m4x.org> Date: Wed, 1 Apr 2020 13:32:14 +0200 Subject: [PATCH 100/218] [kernel] Use canonical Logic_utils.unroll_type for logic type unrolling --- src/kernel_services/ast_queries/cil_datatype.ml | 17 ++++++----------- .../ast_queries/cil_datatype.mli | 4 ++-- src/kernel_services/ast_queries/logic_utils.ml | 2 ++ 3 files changed, 10 insertions(+), 13 deletions(-) diff --git a/src/kernel_services/ast_queries/cil_datatype.ml b/src/kernel_services/ast_queries/cil_datatype.ml index f68c4028809..c9f743a32f6 100644 --- a/src/kernel_services/ast_queries/cil_datatype.ml +++ b/src/kernel_services/ast_queries/cil_datatype.ml @@ -386,12 +386,11 @@ let index_typ = function | TEnum _ -> 8 | TBuiltin_va_list _ -> 9 -let constfoldtoint = ref (fun _ -> failwith "constfoldtoint not yet defined") -let punrollType = - ref (fun _ -> failwith "punrollType not yet defined") +let constfoldtoint = Extlib.mk_fun "constfoldtoint" +let punrollType = Extlib.mk_fun "punrollType" +let punrollLogicType = Extlib.mk_fun "punrollLogicType" let drop_non_logic_attributes = ref (fun a -> a) -let compare_exp_struct_eq = - ref (fun _ -> failwith "compare_exp_struct_eq not yet defined") +let compare_exp_struct_eq = Extlib.mk_fun "compare_exp_struct_eq" type type_compare_config = { by_name : bool; @@ -1320,12 +1319,8 @@ let rec compare_logic_type config v1 v2 = | Ltype _ -> 4 | Larrow _ -> 5 in - let rec unroll = function - | Ltype({lt_def = Some (LTsyn t)},[]) -> unroll t - (*TODO: instanciate polymorphic types *) - | t -> t in - let v1 = if config.unroll then unroll v1 else v1 in - let v2 = if config.unroll then unroll v2 else v2 in + let v1 = if config.unroll then !punrollLogicType v1 else v1 in + let v2 = if config.unroll then !punrollLogicType v2 else v2 in let k1 = rank v1 in let k2 = rank v2 in if k1 <> k2 then diff --git a/src/kernel_services/ast_queries/cil_datatype.mli b/src/kernel_services/ast_queries/cil_datatype.mli index f1cf95ac209..52f914d8ebe 100644 --- a/src/kernel_services/ast_queries/cil_datatype.mli +++ b/src/kernel_services/ast_queries/cil_datatype.mli @@ -310,11 +310,11 @@ module Lexpr: S with type t = Logic_ptree.lexpr (** {2 Internal API} *) (* ****************************************************************************) -(* Forward declarations from Cil *) +(* Forward declarations from Cil et al. *) val drop_non_logic_attributes : (attributes -> attributes) ref val constfoldtoint : (exp -> Integer.t option) ref val punrollType: (typ -> typ) ref - +val punrollLogicType: (logic_type -> logic_type) ref val clear_caches: unit -> unit (**/**) diff --git a/src/kernel_services/ast_queries/logic_utils.ml b/src/kernel_services/ast_queries/logic_utils.ml index 9f0a5c558d9..973eb23feaf 100644 --- a/src/kernel_services/ast_queries/logic_utils.ml +++ b/src/kernel_services/ast_queries/logic_utils.ml @@ -2637,6 +2637,8 @@ class simplify_const_lval global_find_init = object (self) | _ -> Cil.DoChildren end +let () = Cil_datatype.punrollLogicType := unroll_type + (* ************************************************************************** *) (** {1 Deprecated} *) let instantiate = Logic_const.instantiate -- GitLab From e180d54c70cf011514f920648ffeb88b8e001fc6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Loi=CC=88c=20Correnson?= <loic.correnson@cea.fr> Date: Wed, 1 Apr 2020 13:52:26 +0200 Subject: [PATCH 101/218] [kernel] fix cast on non-exact floats --- src/kernel_services/ast_printing/cil_printer.ml | 3 ++- src/kernel_services/ast_queries/cil.ml | 4 ++++ src/kernel_services/ast_queries/cil.mli | 3 +++ src/kernel_services/ast_queries/logic_utils.ml | 2 +- 4 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/kernel_services/ast_printing/cil_printer.ml b/src/kernel_services/ast_printing/cil_printer.ml index 5baa9eb235d..6e9c4550927 100644 --- a/src/kernel_services/ast_printing/cil_printer.ml +++ b/src/kernel_services/ast_printing/cil_printer.ml @@ -2434,7 +2434,8 @@ class cil_printer () = object (self) | TCastE (ty,e) -> begin match ty, t.term_node with | TFloat(fk,_) , TConst(LReal r as cst) when - r.r_upper = r.r_lower && Cil.isFiniteFloat fk r.r_nearest -> + not Kernel.(is_debug_key_enabled dkey_print_logic_coercions) && + Cil.isExactFloat fk r -> self#logic_constant fmt cst | _ -> fprintf fmt "(%a)%a" (self#typ None) ty term e diff --git a/src/kernel_services/ast_queries/cil.ml b/src/kernel_services/ast_queries/cil.ml index fb67f20bba8..7fdc95e14d9 100644 --- a/src/kernel_services/ast_queries/cil.ml +++ b/src/kernel_services/ast_queries/cil.ml @@ -3070,6 +3070,10 @@ let isFiniteFloat fk v = | FFloat -> Floating_point.round_to_single_precision_float v | _ -> v + +let isExactFloat fk r = + r.r_upper = r.r_lower && isFiniteFloat fk r.r_nearest + (* Construct an integer constant with possible truncation if the kind is not specified *) let kinteger64 ~loc ?repr ?kind i = diff --git a/src/kernel_services/ast_queries/cil.mli b/src/kernel_services/ast_queries/cil.mli index 9e47d0eedd8..b3c39a06f89 100644 --- a/src/kernel_services/ast_queries/cil.mli +++ b/src/kernel_services/ast_queries/cil.mli @@ -2139,6 +2139,9 @@ val fitsInInt: ikind -> Integer.t -> bool (** True if the float is finite for the kind's range *) val isFiniteFloat: fkind -> float -> bool +(** True if the real constant is an exact float for the given type *) +val isExactFloat: fkind -> logic_real -> bool + exception Not_representable (** raised by {!intKindForValue}. *) diff --git a/src/kernel_services/ast_queries/logic_utils.ml b/src/kernel_services/ast_queries/logic_utils.ml index 973eb23feaf..859f27b27ac 100644 --- a/src/kernel_services/ast_queries/logic_utils.ml +++ b/src/kernel_services/ast_queries/logic_utils.ml @@ -321,7 +321,7 @@ let numeric_coerce ltyp t = | Linteger, TInt(ik,_), TConst(Integer(v,_)) when Cil.fitsInInt ik v -> { e with term_type = Linteger } | Lreal, TFloat(fk,_), TConst(LReal r) - when Cil.isFiniteFloat fk r.r_nearest -> { e with term_type = Lreal } + when Cil.isExactFloat fk r -> { e with term_type = Lreal } | Linteger, TInt(ik,_), TConst(LEnum { eival }) -> ( match Cil.constFoldToInt eival with | Some i when Cil.fitsInInt ik i -> { e with term_type = Linteger } -- GitLab From cb710519061b9eb485881eb2e5e866e890fc65f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20B=C3=BChler?= <david.buhler@cea.fr> Date: Wed, 1 Apr 2020 14:42:54 +0200 Subject: [PATCH 102/218] [cmdline] Fixes multiple_map parameters when a key is not bound to a value. For a Multiple_map paramater for an option "-option", build by the functor `Make_multiple_map (Key) (V)`: when a command line contains a key without a value ("-option key" instead of "-option key:v"), calls the function [V.of_string key None]. --- Changelog | 5 +- .../cmdline_parameters/parameter_builder.ml | 48 +++++++++++-------- 2 files changed, 31 insertions(+), 22 deletions(-) diff --git a/Changelog b/Changelog index dbefdf6029f..0c8955af999 100644 --- a/Changelog +++ b/Changelog @@ -17,6 +17,9 @@ Open Source Release <next-release> ################################## +- Kernel [2020/04/01] Report user errors when keys are not bound to a + value for command-line options that require pairs of key:value + as arguments. Such keys were silently ignored. *! Kernel [2020/03/30] Reject labels at end of blocks. - RTE [2020/03/30] Emits alarm on invalid pointers when option is on - Eva [2020/03/30] Emits alarm on invalid pointers when option is on @@ -31,7 +34,7 @@ Open Source Release <next-release> - Kernel [2020/03/20] Add option -cpp-extra-args-per-file -* Kernel [2020/03/18] Fixes #@823 (-load-module/-load-script now accept spaces in filename) --* Kernel [2020/03/18] Fixes #@818 (term generated for downcast alarms) +-* Kernel [2020/03/18] Fixes #@818 (term generated for downcast alarms) - Eva [2020/03/17] Supports the ACSL extended quantifiers \min and \max. - Eva [2020/03/17] deprecate options -eva-*-domain in favor of -eva-domains diff --git a/src/kernel_services/cmdline_parameters/parameter_builder.ml b/src/kernel_services/cmdline_parameters/parameter_builder.ml index 74ab79bec5a..3d6cefa192d 100644 --- a/src/kernel_services/cmdline_parameters/parameter_builder.ml +++ b/src/kernel_services/cmdline_parameters/parameter_builder.ml @@ -1577,31 +1577,37 @@ struct Text in the value returned by full_split *) assert false in + let apply_to_previous_pairing k f = + let keys = k_of_singleton_string k in + let key = ref None in + let prev = + try + K.Set.iter + (fun k -> + key := Some k; + (* choose any previous value, whatever it is: + don't know which clear semantics one would like *) + try raise (Found (!find_ref k)) with Not_found -> ()) + keys; + None + with Found v -> + Some v + in + match !key with + | None -> K.Set.empty, [] + | Some key -> keys, f ~key ~prev + in + let get_pairing k v l = + apply_to_previous_pairing k (parse_values k [] v l) + in fun s -> let (keys, values) = - let get_pairing k v l = - let keys = k_of_singleton_string k in - let key = ref None in - let prev = - try - K.Set.iter - (fun k -> - key := Some k; - (* choose any previous value, whatever it is: - don't know which clear semantics one would like *) - try raise (Found (!find_ref k)) with Not_found -> ()) - keys; - None - with Found v -> - Some v - in - match !key with - | None -> K.Set.empty, [] - | Some key -> keys, parse_values ~key k ~prev [] v l - in match Str.full_split r s with | [] -> cannot_build ("cannot interpret '" ^ s ^ "'") - | [Str.Text t] -> k_of_singleton_string t, [] + | [Str.Text t] -> + apply_to_previous_pairing t + (fun ~key ~prev -> + remove_none_and_rev [of_val ~key t ~prev None]) | Str.Delim d :: l -> let (f,s) = split_delim d in get_pairing f s l -- GitLab From 544344c972d442f7c7e1ad8d0a1dd4cf7b367052 Mon Sep 17 00:00:00 2001 From: Virgile Prevosto <virgile.prevosto@m4x.org> Date: Wed, 1 Apr 2020 15:13:51 +0200 Subject: [PATCH 103/218] [aorai] validate oracles --- .../aorai/tests/aorai/oracle/formals.res.oracle | 14 ++++++++------ .../aorai/tests/aorai/oracle/other.res.oracle | 10 ++++++++-- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/src/plugins/aorai/tests/aorai/oracle/formals.res.oracle b/src/plugins/aorai/tests/aorai/oracle/formals.res.oracle index 2e24eb7f8a7..b850086cbe9 100644 --- a/src/plugins/aorai/tests/aorai/oracle/formals.res.oracle +++ b/src/plugins/aorai/tests/aorai/oracle/formals.res.oracle @@ -581,24 +581,26 @@ int g(int y) ensures \at(aorai_CurStates ≡ init,Pre) ∧ aorai_CurStates ≡ aorai_reject ⇒ - aorai_x_0 ≡ \at(1,Pre) + 0 ∨ aorai_x_0 ≡ \at(aorai_x_0,Pre) + 0; + aorai_x_0 ≡ \at(aorai_x_0,Pre) + 0 ∨ + aorai_x_0 ≡ \at((int)1,Pre) + 0; ensures \at(aorai_CurStates ≡ init,Pre) ∧ aorai_CurStates ≡ aorai_reject ⇒ - aorai_y ≡ \at(2,Pre) + 0 ∨ aorai_y ≡ \at(aorai_y,Pre) + 0; + aorai_y ≡ \at(aorai_y,Pre) + 0 ∨ aorai_y ≡ \at((int)2,Pre) + 0; ensures \at(aorai_CurStates ≡ init,Pre) ∧ aorai_CurStates ≡ aorai_reject ⇒ - aorai_x ≡ \at(1,Pre) + 0 ∨ aorai_x ≡ \at(aorai_x,Pre) + 0; + aorai_x ≡ \at(aorai_x,Pre) + 0 ∨ aorai_x ≡ \at((int)1,Pre) + 0; ensures \at(aorai_CurStates ≡ init,Pre) ∧ aorai_CurStates ≡ OK ⇒ - aorai_x_0 ≡ \at(1,Pre) + 0 ∨ aorai_x_0 ≡ \at(aorai_x_0,Pre) + 0; + aorai_x_0 ≡ \at(aorai_x_0,Pre) + 0 ∨ + aorai_x_0 ≡ \at((int)1,Pre) + 0; ensures \at(aorai_CurStates ≡ init,Pre) ∧ aorai_CurStates ≡ OK ⇒ - aorai_y ≡ \at(2,Pre) + 0 ∨ aorai_y ≡ \at(aorai_y,Pre) + 0; + aorai_y ≡ \at(aorai_y,Pre) + 0 ∨ aorai_y ≡ \at((int)2,Pre) + 0; ensures \at(aorai_CurStates ≡ init,Pre) ∧ aorai_CurStates ≡ OK ⇒ - aorai_x ≡ \at(1,Pre) + 0 ∨ aorai_x ≡ \at(aorai_x,Pre) + 0; + aorai_x ≡ \at(aorai_x,Pre) + 0 ∨ aorai_x ≡ \at((int)1,Pre) + 0; */ int main(void) { diff --git a/src/plugins/aorai/tests/aorai/oracle/other.res.oracle b/src/plugins/aorai/tests/aorai/oracle/other.res.oracle index 91b4e2cc2ad..480cdbac3e3 100644 --- a/src/plugins/aorai/tests/aorai/oracle/other.res.oracle +++ b/src/plugins/aorai/tests/aorai/oracle/other.res.oracle @@ -525,7 +525,12 @@ void g(void) behavior buch_state_last_out: ensures 0 ≡ last; + behavior buch_state_step1_in: + assumes 1 ≡ init ∧ x ≡ 3; + ensures 1 ≡ step1; + behavior buch_state_step1_out: + assumes 0 ≡ init ∨ ¬(x ≡ 3); ensures 0 ≡ step1; @/ void main_pre_func(void) @@ -538,7 +543,9 @@ void g(void) init_tmp = init; last_tmp = last; step1_tmp = step1; - step1_tmp = 0; + if (init == 1) + if (x == 3) step1_tmp = 1; else step1_tmp = 0; + else step1_tmp = 0; last_tmp = 0; if (init == 1) if (x != 3) init_tmp = 1; else init_tmp = 0; @@ -644,7 +651,6 @@ void g(void) */ /*@ requires 1 ≡ init ∧ 0 ≡ last ∧ 0 ≡ step1; - requires 1 ≡ init ⇒ x ≢ 3; behavior aorai_acceptance: ensures 1 ≡ last; -- GitLab From e57504b7e2eb07f184ee4459a325fad7cb731eef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Loi=CC=88c=20Correnson?= <loic.correnson@cea.fr> Date: Wed, 1 Apr 2020 16:53:23 +0200 Subject: [PATCH 104/218] [kernel] preserve original types in expr-to-term --- src/kernel_services/ast_queries/logic_utils.ml | 16 +++++++++------- tests/rte/oracle/addsub_typedef.res.oracle | 3 ++- tests/rte/oracle/divmod_typedef.res.oracle | 2 +- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/src/kernel_services/ast_queries/logic_utils.ml b/src/kernel_services/ast_queries/logic_utils.ml index 859f27b27ac..d1bcc167969 100644 --- a/src/kernel_services/ast_queries/logic_utils.ml +++ b/src/kernel_services/ast_queries/logic_utils.ml @@ -404,7 +404,7 @@ let float_builtin prefix fkind = | _ -> Kernel.fatal "Missing or ambiguous builtin %S" name let get_float_binop op typ = - match typ, op with + match Cil.unrollType typ, op with | TFloat(fkind,_) , PlusA -> float_builtin "add" fkind | TFloat(fkind,_) , MinusA -> float_builtin "sub" fkind | TFloat(fkind,_) , Mult -> float_builtin "mul" fkind @@ -412,13 +412,13 @@ let get_float_binop op typ = | _ -> None let get_float_unop op typ = - match typ, op with + match Cil.unrollType typ, op with | TFloat(fkind,_) , Neg -> float_builtin "neg" fkind | _ -> None let rec expr_to_term ?(coerce=false) e = let loc = e.eloc in - let typ = Cil.unrollType (Cil.typeOf e) in + let typ = Cil.typeOf e in let ctyp = Ctype typ in let node,ltyp = match e.enode with @@ -468,10 +468,12 @@ let rec expr_to_term ?(coerce=false) e = t.term_node , t.term_type in let v = mk_cast ~loc typ @@ Logic_const.term ~loc node ltyp in - match typ with - | TInt _ when coerce -> numeric_coerce Linteger v - | TFloat _ when coerce -> numeric_coerce Lreal v - | _ -> v + if coerce then + match Cil.unrollType typ with + | TInt _ -> numeric_coerce Linteger v + | TFloat _ -> numeric_coerce Lreal v + | _ -> v + else v and lval_to_term_lval (host,offset) = host_to_term_lhost host, offset_to_term_offset offset diff --git a/tests/rte/oracle/addsub_typedef.res.oracle b/tests/rte/oracle/addsub_typedef.res.oracle index adf710ee1ac..8e0232c30ba 100644 --- a/tests/rte/oracle/addsub_typedef.res.oracle +++ b/tests/rte/oracle/addsub_typedef.res.oracle @@ -41,7 +41,8 @@ int main(void) /*@ assert rte: signed_overflow: -2147483648 ≤ (int)(-0x7ffffffc) - y; */ z = -0x7ffffffc - y; /*@ assert rte: signed_overflow: -2147483647 ≤ x; */ - /*@ assert rte: signed_overflow: -2147483648 ≤ (int)(-x) - 0x7ffffffc; */ + /*@ assert rte: signed_overflow: -2147483648 ≤ (tint)(-x) - 0x7ffffffc; + */ z = - x - 0x7ffffffc; /*@ assert rte: signed_overflow: 0x7ffffffc + y ≤ 2147483647; */ z = 0x7ffffffc + y; diff --git a/tests/rte/oracle/divmod_typedef.res.oracle b/tests/rte/oracle/divmod_typedef.res.oracle index 51b06e5796e..a965ff5054d 100644 --- a/tests/rte/oracle/divmod_typedef.res.oracle +++ b/tests/rte/oracle/divmod_typedef.res.oracle @@ -65,7 +65,7 @@ int main(void) uz = (unsigned int)((int)(0x80000000 / 0xffffffff)); /*@ assert rte: signed_overflow: -2147483648 ≤ x + y; */ /*@ assert rte: signed_overflow: x + y ≤ 2147483647; */ - /*@ assert rte: division_by_zero: (int)(x + y) ≢ 0; */ + /*@ assert rte: division_by_zero: (tint)(x + y) ≢ 0; */ z = 1 / (x + y); /*@ assert rte: signed_overflow: x / (int)(-1) ≤ 2147483647; */ z = x / -1; -- GitLab From 03afadb267d63abf76cbb6b9e31766cc67231b68 Mon Sep 17 00:00:00 2001 From: Virgile Prevosto <virgile.prevosto@m4x.org> Date: Wed, 1 Apr 2020 18:23:14 +0200 Subject: [PATCH 105/218] [debug] more robust bin/frama-c.debug script across OCaml versions - 4.08.0 messes up dynlink, which is needed by extlib for semi-good reasons: it is currently impossible to load the printers in this version. - 4.09.0 and upwards directly load dynlink, and will complain if we try to do that again. --- bin/frama-c.debug | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/bin/frama-c.debug b/bin/frama-c.debug index 89d9b58a603..39667bbb3b5 100755 --- a/bin/frama-c.debug +++ b/bin/frama-c.debug @@ -24,12 +24,29 @@ . $(dirname $0)/local_export.sh +if ! command -v ocamlc > /dev/null; then + echo "ocamlc not found" && exit 1; +fi +if ! command -v ocamldebug > /dev/null; then + echo "ocamldebug not found" && exit 1; +fi + +OCAML_VERSION=$(ocamlc -version) +case $OCAML_VERSION in +4.05*|4.06*|4.07*) DYNLINK='load_printer "dynlink.cma"';; +4.08*) + echo "impossible to load dynlink in ocamldebug for version $OCAML_VERSION"; + echo "pretty-printers will not be loaded"; + if test ! -e .ocamldebug; then GEN_OCAMLDEBUG=yes; touch .ocamldebug; fi;; +*) DYNLINK=;; +esac + if test ! -e .ocamldebug; then GEN_OCAMLDEBUG=yes; cat <<EOF > .ocamldebug; load_printer "str.cma" load_printer "zarith.cma" -load_printer "dynlink.cma" +$DYNLINK load_printer "extlib.cmo" load_printer "filepath.cmo" load_printer "integer.cmo" @@ -161,10 +178,11 @@ install_printer Cabs_debug.pp_attrs install_printer Cabs_debug.pp_file EOF else -GEN_OCAMLDEBUG=no; +GEN_OCAMLDEBUG=${GEN_OCAMLDEBUG:-no}; fi ocamldebug -I $(ocamlfind query zarith) -I $(ocamlfind query ocamlgraph) \ + -I $(ocamlfind query compiler-libs) \ -I $FRAMAC_LIB $BINDIR/toplevel.byte "$@" if test "$GEN_OCAMLDEBUG" = "yes"; then -- GitLab From ac00a6ecddf22bac391ac28f87d309c7d9cdfbad Mon Sep 17 00:00:00 2001 From: Allan Blanchard <allan.blanchard@cea.fr> Date: Thu, 26 Mar 2020 15:30:46 +0100 Subject: [PATCH 106/218] [Instantiate] Refacto in string modules --- src/plugins/instantiate/Makefile.in | 1 + src/plugins/instantiate/basic_blocks.ml | 11 ++ src/plugins/instantiate/basic_blocks.mli | 5 + src/plugins/instantiate/string/mem_utils.ml | 150 ++++++++++++++++++ src/plugins/instantiate/string/mem_utils.mli | 60 +++++++ src/plugins/instantiate/string/memcmp.ml | 83 ++-------- src/plugins/instantiate/string/memcpy.ml | 118 +++----------- src/plugins/instantiate/string/memmove.ml | 116 ++------------ .../oracle/ignore-functions.res.oracle | 10 +- .../options/oracle/only-functions.res.oracle | 10 +- .../tests/string/oracle/memcpy.res.oracle | 80 +++++----- 11 files changed, 332 insertions(+), 312 deletions(-) create mode 100644 src/plugins/instantiate/string/mem_utils.ml create mode 100644 src/plugins/instantiate/string/mem_utils.mli diff --git a/src/plugins/instantiate/Makefile.in b/src/plugins/instantiate/Makefile.in index 144f5c7128e..a8fc2764589 100644 --- a/src/plugins/instantiate/Makefile.in +++ b/src/plugins/instantiate/Makefile.in @@ -30,6 +30,7 @@ FRAMAC_LIBDIR :=$(shell frama-c-config -print-libpath) endif SRC_STRING:= \ + mem_utils \ memcmp \ memcpy \ memmove \ diff --git a/src/plugins/instantiate/basic_blocks.ml b/src/plugins/instantiate/basic_blocks.ml index 660db8c83c0..830911e482e 100644 --- a/src/plugins/instantiate/basic_blocks.ml +++ b/src/plugins/instantiate/basic_blocks.ml @@ -50,6 +50,17 @@ let call_function lval vi args = let args = List.map2 gen_arg args typs in Call(lval, (Cil.evar vi), args, loc) +let exp_type_of_pointed x = + let no_cast = Cil.stripCasts x in + if not (Cil.isPointerType (Cil.typeOf no_cast)) then + match Cil.constFoldToInt x with + | Some t when Integer.(equal t (of_int 0)) -> Some (Cil.typeOf x) + | _ -> None + else + let xt = Cil.unrollTypeDeep (Cil.typeOf no_cast) in + let xt = Cil.type_remove_qualifier_attributes_deep xt in + Some (Cil.typeOf_pointed xt) + let rec string_of_typ_aux = function | TVoid(_) -> "void" | TInt(IBool, _) -> "bool" diff --git a/src/plugins/instantiate/basic_blocks.mli b/src/plugins/instantiate/basic_blocks.mli index 8b22347ecc1..d8723d96765 100644 --- a/src/plugins/instantiate/basic_blocks.mli +++ b/src/plugins/instantiate/basic_blocks.mli @@ -42,6 +42,11 @@ val ttype_of_pointed: logic_type -> logic_type (** {2 C} *) +(** For an expression, return the type of the pointed data. + If the expression is not a pointer, returns None. +*) +val exp_type_of_pointed: exp -> typ option + (** For a type [T], returns [T*] *) val ptr_of: typ -> typ diff --git a/src/plugins/instantiate/string/mem_utils.ml b/src/plugins/instantiate/string/mem_utils.ml new file mode 100644 index 00000000000..71247c78162 --- /dev/null +++ b/src/plugins/instantiate/string/mem_utils.ml @@ -0,0 +1,150 @@ +(**************************************************************************) +(* *) +(* This file is part of Frama-C. *) +(* *) +(* Copyright (C) 2007-2020 *) +(* CEA (Commissariat à l'énergie atomique et aux énergies *) +(* alternatives) *) +(* *) +(* you can redistribute it and/or modify it under the terms of the GNU *) +(* Lesser General Public License as published by the Free Software *) +(* Foundation, version 2.1. *) +(* *) +(* It is distributed in the hope that it will be useful, *) +(* but WITHOUT ANY WARRANTY; without even the implied warranty of *) +(* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *) +(* GNU Lesser General Public License for more details. *) +(* *) +(* See the GNU Lesser General Public License version 2.1 *) +(* for more details (enclosed in the file licenses/LGPLv2.1). *) +(* *) +(**************************************************************************) + +open Basic_blocks +open Cil_types +open Logic_const + +type kind = CPtr | Ptr | Len | Int +type action = Strip | Id +type param = string * kind * action +type proto = kind * param list +type 'a spec_gen = location -> typ -> term -> term -> term -> 'a + +let unexpected = Options.fatal "Mem_utils: %s" + +let mem2s_typing _ = function + | [ dest ; src ; len ] -> + (Cil.isIntegralType len) && + (Cil_datatype.Typ.equal dest src) && + (not (Cil.isVoidType dest)) && + (Cil.isCompleteType dest) + | _ -> false + +let mem2s_spec ~requires ~assigns ~ensures _t { svar = vi } loc = + let (cdest, csrc, clen) = match Cil.getFormalsDecl vi with + | [ dest ; src ; len ] -> dest, src, len + | _ -> unexpected "ill-formed fundec in specification generation" + in + let t = cdest.vtype in + let dest = cvar_to_tvar cdest in + let src = cvar_to_tvar csrc in + let len = cvar_to_tvar clen in + let requires = requires loc t dest src len in + let assigns = assigns loc t dest src len in + let ensures = ensures loc t dest src len in + make_funspec [make_behavior ~requires ~assigns ~ensures ()] () + +let pcopied_len_bytes ?loc p1 p2 bytes_len = + plet_len_div_size ?loc p1.term_type bytes_len + (punfold_all_elems_eq ?loc p1 p2) + +let memcpy_memmove_common_requires loc _ dest src len = + List.map new_predicate [ + { (pcorrect_len_bytes ~loc dest.term_type len) + with pred_name = ["aligned_end"] } ; + { (pvalid_len_bytes ~loc here_label dest len) + with pred_name = ["valid_dest"] } ; + { (pvalid_read_len_bytes ~loc here_label src len) + with pred_name = ["valid_read_src"] } ; + ] + +let memcpy_memmove_common_assigns loc t dest src len = + let dest_range = new_identified_term (tunref_range_bytes_len ~loc dest len) in + let src_range = new_identified_term(tunref_range_bytes_len ~loc src len) in + let copy = dest_range, From [src_range] in + let result = new_identified_term (tresult t) in + let dest = new_identified_term dest in + let res = result, From [dest] in + Writes [ copy ; res ] + +let presult_dest ?loc t dest = + prel ?loc (Req, (tresult ?loc t), dest) + +let memcpy_memmove_common_ensures name loc t dest src len = + List.map (fun p -> Normal, new_predicate p) [ + { (pcopied_len_bytes ~loc dest src len) with pred_name = [name] } ; + { (presult_dest ~loc t dest) with pred_name = ["result"] } + ] + +module type Function = sig + val name: string + val prototype: proto + val well_typed: typ option -> typ list -> bool +end + +module Make (F: Function) = +struct + let generate_function_type t = + let to_type = function + | CPtr -> ptr_of (const_of t) + | Ptr -> ptr_of t + | Len -> size_t() + | Int -> Cil.intType + in + let ret, ps = F.prototype in + let ret = to_type ret in + let ps = List.map (fun (name, kind, _) -> name, (to_type kind), []) ps in + TFun(ret, Some ps, false, []) + + let generate_prototype t = + let ftype = generate_function_type t in + let name = F.name ^ "_" ^ (string_of_typ t) in + name, ftype + + let well_typed_call lval args = + let _, ps = F.prototype in + if List.length args <> List.length ps then false + else + let extract e = function + | _, (CPtr | Ptr), _ -> exp_type_of_pointed e + | _, (Len | Int), _ -> Some (Cil.typeOf e) + in + let lvt = Extlib.opt_map Cil.typeOfLval lval in + let pts = List.map2 extract args ps in + let is_none = function None -> true | _ -> false in + if List.exists is_none pts then false + else F.well_typed lvt (List.map (fun x -> Extlib.the x) pts) + + let retype_args _ args = + let _, ps = F.prototype in + if List.length args <> List.length ps then + unexpected "trying to retype arguments on an ill-typed call" + else + let retype x = function + | _, _, Strip -> Cil.stripCasts x + | _, _, Id -> x + in + List.map2 retype args ps + + let key_from_call _ret args = + let _, ps = F.prototype in + match ps, args with + | (_, (Ptr|CPtr), _)::ps, fst::args when List.(length ps = length args) -> + begin match exp_type_of_pointed fst with + | Some t -> t + | None -> + unexpected "Mem_utils: trying to get key on an ill-typed call" + end + | _ -> + unexpected "Mem_utils: trying to get key on an ill-typed call" +end diff --git a/src/plugins/instantiate/string/mem_utils.mli b/src/plugins/instantiate/string/mem_utils.mli new file mode 100644 index 00000000000..543e5b06bc1 --- /dev/null +++ b/src/plugins/instantiate/string/mem_utils.mli @@ -0,0 +1,60 @@ +(**************************************************************************) +(* *) +(* This file is part of Frama-C. *) +(* *) +(* Copyright (C) 2007-2020 *) +(* CEA (Commissariat à l'énergie atomique et aux énergies *) +(* alternatives) *) +(* *) +(* you can redistribute it and/or modify it under the terms of the GNU *) +(* Lesser General Public License as published by the Free Software *) +(* Foundation, version 2.1. *) +(* *) +(* It is distributed in the hope that it will be useful, *) +(* but WITHOUT ANY WARRANTY; without even the implied warranty of *) +(* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *) +(* GNU Lesser General Public License for more details. *) +(* *) +(* See the GNU Lesser General Public License version 2.1 *) +(* for more details (enclosed in the file licenses/LGPLv2.1). *) +(* *) +(**************************************************************************) + +open Cil_types + +type kind = CPtr | Ptr | Len | Int +type action = Strip | Id +type param = string * kind * action +type proto = kind * param list + +module type Function = sig + val name: string + val prototype: proto + val well_typed: typ option -> typ list -> bool +end + +module Make (F: Function) : sig + val generate_function_type : typ -> typ + val generate_prototype : typ -> string * typ + val well_typed_call : lval option -> exp list -> bool + val retype_args : 'a -> exp list -> exp list + val key_from_call : 'a -> exp list -> typ +end + +(** location -> key -> s1 -> s2 -> len -> spec_result *) +type 'a spec_gen = location -> typ -> term -> term -> term -> 'a + +val mem2s_spec: + requires: (identified_predicate list) spec_gen -> + assigns: assigns spec_gen -> + ensures: (termination_kind * identified_predicate) list spec_gen -> + typ -> fundec -> location -> funspec + +val mem2s_typing: typ option -> typ list -> bool + +val memcpy_memmove_common_requires: (identified_predicate list) spec_gen + +val memcpy_memmove_common_assigns: assigns spec_gen + +val memcpy_memmove_common_ensures: + string -> (termination_kind * identified_predicate) list spec_gen diff --git a/src/plugins/instantiate/string/memcmp.ml b/src/plugins/instantiate/string/memcmp.ml index 633294db95b..c8518480ed8 100644 --- a/src/plugins/instantiate/string/memcmp.ml +++ b/src/plugins/instantiate/string/memcmp.ml @@ -26,9 +26,7 @@ open Basic_blocks let function_name = "memcmp" -let unexpected = Options.fatal "String.Memcmp: unexpected: %s" - -let generate_requires loc s1 s2 len = +let requires loc _ s1 s2 len = List.map new_predicate [ { (pcorrect_len_bytes ~loc s1.term_type len) with pred_name = ["aligned_end"] } ; @@ -43,7 +41,7 @@ let presult_memcmp ?loc p1 p2 len = let res = prel ?loc (Req, (tresult ?loc Cil.intType), (tinteger ?loc 0)) in piff ?loc (res, eq) -let generate_assigns loc s1 s2 len = +let assigns loc _ s1 s2 len = let indirect_range loc s len = new_identified_term { (tunref_range_bytes_len ~loc s len) with term_name = ["indirect"] } @@ -57,78 +55,31 @@ let generate_assigns loc s1 s2 len = let presult_memcmp_len_bytes ?loc p1 p2 bytes_len = plet_len_div_size ?loc p1.term_type bytes_len (presult_memcmp ?loc p1 p2) -let generate_ensures loc s1 s2 len = +let ensures loc _ s1 s2 len = List.map (fun p -> Normal, new_predicate p) [ { (presult_memcmp_len_bytes ~loc s1 s2 len) with pred_name = [ "equals" ] } ] -let generate_spec _t { svar = vi } loc = - let (c_s1, c_s2, clen) = match Cil.getFormalsDecl vi with - | [ s1 ; s2 ; len ] -> s1, s2, len - | _ -> unexpected "ill-formed fundec in specification generation" - in - let s1 = cvar_to_tvar c_s1 in - let s2 = cvar_to_tvar c_s2 in - let len = cvar_to_tvar clen in - let requires = generate_requires loc s1 s2 len in - let assigns = generate_assigns loc s1 s2 len in - let ensures = generate_ensures loc s1 s2 len in - make_funspec [make_behavior ~requires ~assigns ~ensures ()] () - -let generate_function_type t = - let t = ptr_of (const_of t) in - let params = [ - ("s1", t, []) ; - ("s2", t, []) ; - ("len", size_t (), []) - ] in - TFun(Cil.intType, Some params, false, []) - -let generate_prototype t = - let fun_type = generate_function_type t in - let name = function_name ^ "_" ^ (string_of_typ t) in - name, fun_type - -let type_from_arg x = - let x = Cil.stripCasts x in - let xt = Cil.unrollTypeDeep (Cil.typeOf x) in - let xt = Cil.type_remove_qualifier_attributes_deep xt in - Cil.typeOf_pointed xt - -let well_typed_call _ret = function - | [ s1 ; s2 ; len ] -> - (Cil.isIntegralType (Cil.typeOf len)) && - (Cil_datatype.Typ.equal (type_from_arg s1) (type_from_arg s2)) && - (not (Cil.isVoidType (type_from_arg s1))) && - (Cil.isCompleteType (type_from_arg s1)) - | _ -> false - -let key_from_call _ret = function - | [ s1 ; _ ; _ ] -> type_from_arg s1 - | _ -> unexpected "trying to generate a key on an ill-typed call" - -let retype_args override_key = function - | [ s1 ; s2 ; len ] -> - let s1 = Cil.stripCasts s1 in - let s2 = Cil.stripCasts s2 in - assert ( - Cil_datatype.Typ.equal (type_from_arg s1) override_key && - Cil_datatype.Typ.equal (type_from_arg s2) override_key - ) ; - [ s1 ; s2 ; len ] - | _ -> unexpected "trying to retype arguments on an ill-typed call" +let generate_spec = Mem_utils.mem2s_spec ~requires ~assigns ~ensures -let args_for_original _t args = args +module Function = +struct + open Mem_utils + let name = function_name + let prototype = Int, [ ("s1",CPtr,Strip);("s2",CPtr,Strip);("len",Len,Id)] + let well_typed = Mem_utils.mem2s_typing +end +module Memcmp_base = Mem_utils.Make(Function) let () = Transform.register (module struct module Hashtbl = Cil_datatype.Typ.Hashtbl type override_key = typ let function_name = function_name - let well_typed_call = well_typed_call - let key_from_call = key_from_call - let retype_args = retype_args - let generate_prototype = generate_prototype + let well_typed_call = Memcmp_base.well_typed_call + let key_from_call = Memcmp_base.key_from_call + let retype_args = Memcmp_base.retype_args + let generate_prototype = Memcmp_base.generate_prototype let generate_spec = generate_spec - let args_for_original = args_for_original + let args_for_original _ = Extlib.id end) diff --git a/src/plugins/instantiate/string/memcpy.ml b/src/plugins/instantiate/string/memcpy.ml index d0db608eef1..b13a13067cb 100644 --- a/src/plugins/instantiate/string/memcpy.ml +++ b/src/plugins/instantiate/string/memcpy.ml @@ -23,118 +23,42 @@ open Cil_types open Logic_const open Basic_blocks +open Mem_utils let function_name = "memcpy" -let unexpected = Options.fatal "String.Memcpy: unexpected: %s" - let pseparated_memcpy_len_bytes ?loc p1 p2 bytes_len = let generate len = pseparated_memories ?loc p1 len p2 len in plet_len_div_size ?loc p1.term_type bytes_len generate -let pcopied_len_bytes ?loc p1 p2 bytes_len = - plet_len_div_size ?loc p1.term_type bytes_len - (punfold_all_elems_eq ?loc p1 p2) - -let presult_dest ?loc t dest = - prel ?loc (Req, (tresult ?loc t), dest) - -let generate_requires loc dest src len = - List.map new_predicate [ - { (pcorrect_len_bytes ~loc dest.term_type len) - with pred_name = ["aligned_end"] } ; - { (pvalid_len_bytes ~loc here_label dest len) - with pred_name = ["valid_dest"] } ; - { (pvalid_read_len_bytes ~loc here_label src len) - with pred_name = ["valid_read_src"] } ; - { (pseparated_memcpy_len_bytes ~loc dest src len) - with pred_name = ["separation"] } - ] - -let generate_assigns loc t dest src len = - let dest_range = new_identified_term (tunref_range_bytes_len ~loc dest len) in - let src_range = new_identified_term(tunref_range_bytes_len ~loc src len) in - let copy = dest_range, From [src_range] in - let result = new_identified_term (tresult t) in - let dest = new_identified_term dest in - let res = result, From [dest] in - Writes [ copy ; res ] - -let generate_ensures loc t dest src len = - List.map (fun p -> Normal, new_predicate p) [ - { (pcopied_len_bytes ~loc dest src len) with pred_name = [ "copied"] } ; - { (presult_dest ~loc t dest) with pred_name = [ "result"] } - ] - -let generate_spec _t { svar = vi } loc = - let (cdest, csrc, clen) = match Cil.getFormalsDecl vi with - | [ dest ; src ; len ] -> dest, src, len - | _ -> unexpected "ill-formed fundec in specification generation" +let requires loc t dest src len = + let separated = new_predicate + { (pseparated_memcpy_len_bytes ~loc dest src len) + with pred_name = ["separation"] } in - let t = cdest.vtype in - let dest = cvar_to_tvar cdest in - let src = cvar_to_tvar csrc in - let len = cvar_to_tvar clen in - let requires = generate_requires loc dest src len in - let assigns = generate_assigns loc t dest src len in - let ensures = generate_ensures loc t dest src len in - make_funspec [make_behavior ~requires ~assigns ~ensures ()] () - -let generate_function_type t = - let dt = ptr_of t in - let st = ptr_of (const_of t) in - let params = [ - ("dest", dt, []) ; - ("src", st, []) ; - ("len", size_t (), []) - ] in - TFun(dt, Some params, false, []) - -let generate_prototype t = - let fun_type = generate_function_type t in - let name = function_name ^ "_" ^ (string_of_typ t) in - name, fun_type - -let type_from_arg x = - let x = Cil.stripCasts x in - let xt = Cil.unrollTypeDeep (Cil.typeOf x) in - let xt = Cil.type_remove_qualifier_attributes_deep xt in - Cil.typeOf_pointed xt - -let well_typed_call _ret = function - | [ dest ; src ; len ] -> - (Cil.isIntegralType (Cil.typeOf len)) && - (Cil_datatype.Typ.equal (type_from_arg dest) (type_from_arg src)) && - (not (Cil.isVoidType (type_from_arg dest))) && - (Cil.isCompleteType (type_from_arg dest)) - | _ -> false - -let key_from_call _ret = function - | [ dest ; _ ; _ ] -> type_from_arg dest - | _ -> unexpected "trying to generate a key on an ill-typed call" + separated :: (memcpy_memmove_common_requires loc t dest src len) -let retype_args override_key = function - | [ dest ; src ; len ] -> - let dest = Cil.stripCasts dest in - let src = Cil.stripCasts src in - assert ( - Cil_datatype.Typ.equal (type_from_arg dest) override_key && - Cil_datatype.Typ.equal (type_from_arg src) override_key - ) ; - [ dest ; src ; len ] - | _ -> unexpected "trying to retype arguments on an ill-typed call" +let assigns = memcpy_memmove_common_assigns +let ensures = memcpy_memmove_common_ensures "copied" +let generate_spec = mem2s_spec ~requires ~assigns ~ensures -let args_for_original _t args = args +module Function = +struct + let name = function_name + let prototype = Ptr, [("dest",Ptr,Strip);("src",CPtr,Strip);("len",Len,Id)] + let well_typed = Mem_utils.mem2s_typing +end +module Memcpy_base = Mem_utils.Make(Function) let () = Transform.register (module struct module Hashtbl = Cil_datatype.Typ.Hashtbl type override_key = typ let function_name = function_name - let well_typed_call = well_typed_call - let key_from_call = key_from_call - let retype_args = retype_args - let generate_prototype = generate_prototype + let well_typed_call = Memcpy_base.well_typed_call + let key_from_call = Memcpy_base.key_from_call + let retype_args = Memcpy_base.retype_args + let generate_prototype = Memcpy_base.generate_prototype let generate_spec = generate_spec - let args_for_original = args_for_original + let args_for_original _ = Extlib.id end) diff --git a/src/plugins/instantiate/string/memmove.ml b/src/plugins/instantiate/string/memmove.ml index 6481c423a1f..0295236f2cd 100644 --- a/src/plugins/instantiate/string/memmove.ml +++ b/src/plugins/instantiate/string/memmove.ml @@ -21,114 +21,32 @@ (**************************************************************************) open Cil_types -open Logic_const -open Basic_blocks +open Mem_utils let function_name = "memmove" -let unexpected = Options.fatal "String.Memmove: unexpected: %s" +let requires = memcpy_memmove_common_requires +let assigns = memcpy_memmove_common_assigns +let ensures = memcpy_memmove_common_ensures "moved" +let generate_spec = mem2s_spec ~requires ~assigns ~ensures -let pmoved_len_bytes ?loc dest src bytes_len = - plet_len_div_size ?loc dest.term_type bytes_len - (punfold_all_elems_eq ?loc dest src) - -let presult_dest ?loc t dest = - prel ?loc (Req, (tresult ?loc t), dest) - -let generate_requires loc dest src len = - List.map new_predicate [ - { (pcorrect_len_bytes ~loc dest.term_type len) - with pred_name = ["aligned_end"] } ; - { (pvalid_len_bytes ~loc here_label dest len) - with pred_name = ["valid_dest"] } ; - { (pvalid_read_len_bytes ~loc here_label src len) - with pred_name = ["valid_read_src"] } ; - ] - -let generate_assigns loc t dest src len = - let dest_range = new_identified_term (tunref_range_bytes_len ~loc dest len) in - let src_range = new_identified_term(tunref_range_bytes_len ~loc src len) in - let copy = dest_range, From [src_range] in - let result = new_identified_term (tresult t) in - let dest = new_identified_term dest in - let res = result, From [dest] in - Writes [ copy ; res ] - -let generate_ensures loc t dest src len = - List.map (fun p -> Normal, new_predicate p) [ - { (pmoved_len_bytes ~loc dest src len) with pred_name = [ "moved"] } ; - { (presult_dest ~loc t dest) with pred_name = [ "result"] } - ] - -let generate_spec _t { svar = vi } loc = - let (cdest, csrc, clen) = match Cil.getFormalsDecl vi with - | [ dest ; src ; len ] -> dest, src, len - | _ -> unexpected "ill-formed fundec in specification generation" - in - let t = cdest.vtype in - let dest = cvar_to_tvar cdest in - let src = cvar_to_tvar csrc in - let len = cvar_to_tvar clen in - let requires = generate_requires loc dest src len in - let assigns = generate_assigns loc t dest src len in - let ensures = generate_ensures loc t dest src len in - make_funspec [make_behavior ~requires ~assigns ~ensures ()] () - -let generate_function_type t = - let dt = ptr_of t in - let st = ptr_of (const_of t) in - let params = [ - ("dest", dt, []) ; - ("src", st, []) ; - ("len", size_t (), []) - ] in - TFun(dt, Some params, false, []) - -let generate_prototype t = - let fun_type = generate_function_type t in - let name = function_name ^ "_" ^ (string_of_typ t) in - name, fun_type - -let type_from_arg x = - let x = Cil.stripCasts x in - let xt = Cil.unrollTypeDeep (Cil.typeOf x) in - let xt = Cil.type_remove_qualifier_attributes_deep xt in - Cil.typeOf_pointed xt - -let well_typed_call _ret = function - | [ dest ; src ; len ] -> - (Cil.isIntegralType (Cil.typeOf len)) && - (Cil_datatype.Typ.equal (type_from_arg dest) (type_from_arg src)) && - (not (Cil.isVoidType (type_from_arg dest))) && - (Cil.isCompleteType (type_from_arg dest)) - | _ -> false - -let key_from_call _ret = function - | [ dest ; _ ; _ ] -> type_from_arg dest - | _ -> unexpected "trying to generate a key on an ill-typed call" - -let retype_args override_key = function - | [ dest ; src ; len ] -> - let dest = Cil.stripCasts dest in - let src = Cil.stripCasts src in - assert ( - Cil_datatype.Typ.equal (type_from_arg dest) override_key && - Cil_datatype.Typ.equal (type_from_arg src) override_key - ) ; - [ dest ; src ; len ] - | _ -> unexpected "trying to retype arguments on an ill-typed call" - -let args_for_original _t args = args +module Function = +struct + let name = function_name + let prototype = Ptr, [("dest",Ptr,Strip);("src",CPtr,Strip);("len",Len,Id)] + let well_typed = Mem_utils.mem2s_typing +end +module Memmove_base = Mem_utils.Make(Function) let () = Transform.register (module struct module Hashtbl = Cil_datatype.Typ.Hashtbl type override_key = typ let function_name = function_name - let well_typed_call = well_typed_call - let key_from_call = key_from_call - let retype_args = retype_args - let generate_prototype = generate_prototype + let well_typed_call = Memmove_base.well_typed_call + let key_from_call = Memmove_base.key_from_call + let retype_args = Memmove_base.retype_args + let generate_prototype = Memmove_base.generate_prototype let generate_spec = generate_spec - let args_for_original = args_for_original + let args_for_original _ = Extlib.id end) diff --git a/src/plugins/instantiate/tests/options/oracle/ignore-functions.res.oracle b/src/plugins/instantiate/tests/options/oracle/ignore-functions.res.oracle index 8aacf1fa757..b260fc61afd 100644 --- a/src/plugins/instantiate/tests/options/oracle/ignore-functions.res.oracle +++ b/src/plugins/instantiate/tests/options/oracle/ignore-functions.res.oracle @@ -11,16 +11,16 @@ void foo(void) return; } -/*@ requires aligned_end: len % 4 ≡ 0; +/*@ requires + separation: + \let __fc_len = len / 4; + \separated(dest + (0 .. __fc_len - 1), src + (0 .. __fc_len - 1)); + requires aligned_end: len % 4 ≡ 0; requires valid_dest: \let __fc_len = len / 4; \valid(dest + (0 .. __fc_len - 1)); requires valid_read_src: \let __fc_len = len / 4; \valid_read(src + (0 .. __fc_len - 1)); - requires - separation: - \let __fc_len = len / 4; - \separated(dest + (0 .. __fc_len - 1), src + (0 .. __fc_len - 1)); ensures copied: \let __fc_len = len / 4; diff --git a/src/plugins/instantiate/tests/options/oracle/only-functions.res.oracle b/src/plugins/instantiate/tests/options/oracle/only-functions.res.oracle index cc08c601aac..d84cec92ebc 100644 --- a/src/plugins/instantiate/tests/options/oracle/only-functions.res.oracle +++ b/src/plugins/instantiate/tests/options/oracle/only-functions.res.oracle @@ -3,16 +3,16 @@ #include "stddef.h" #include "string.h" #include "strings.h" -/*@ requires aligned_end: len % 4 ≡ 0; +/*@ requires + separation: + \let __fc_len = len / 4; + \separated(dest + (0 .. __fc_len - 1), src + (0 .. __fc_len - 1)); + requires aligned_end: len % 4 ≡ 0; requires valid_dest: \let __fc_len = len / 4; \valid(dest + (0 .. __fc_len - 1)); requires valid_read_src: \let __fc_len = len / 4; \valid_read(src + (0 .. __fc_len - 1)); - requires - separation: - \let __fc_len = len / 4; - \separated(dest + (0 .. __fc_len - 1), src + (0 .. __fc_len - 1)); ensures copied: \let __fc_len = len / 4; diff --git a/src/plugins/instantiate/tests/string/oracle/memcpy.res.oracle b/src/plugins/instantiate/tests/string/oracle/memcpy.res.oracle index 05681aeb44e..78076d88eb1 100644 --- a/src/plugins/instantiate/tests/string/oracle/memcpy.res.oracle +++ b/src/plugins/instantiate/tests/string/oracle/memcpy.res.oracle @@ -13,16 +13,16 @@ struct X { }; typedef int named; struct incomplete; -/*@ requires aligned_end: len % 4 ≡ 0; +/*@ requires + separation: + \let __fc_len = len / 4; + \separated(dest + (0 .. __fc_len - 1), src + (0 .. __fc_len - 1)); + requires aligned_end: len % 4 ≡ 0; requires valid_dest: \let __fc_len = len / 4; \valid(dest + (0 .. __fc_len - 1)); requires valid_read_src: \let __fc_len = len / 4; \valid_read(src + (0 .. __fc_len - 1)); - requires - separation: - \let __fc_len = len / 4; - \separated(dest + (0 .. __fc_len - 1), src + (0 .. __fc_len - 1)); ensures copied: \let __fc_len = len / 4; @@ -53,16 +53,16 @@ void with_named(named * /*[10]*/ src, named * /*[10]*/ dest) return; } -/*@ requires aligned_end: len % 8 ≡ 0; +/*@ requires + separation: + \let __fc_len = len / 8; + \separated(dest + (0 .. __fc_len - 1), src + (0 .. __fc_len - 1)); + requires aligned_end: len % 8 ≡ 0; requires valid_dest: \let __fc_len = len / 8; \valid(dest + (0 .. __fc_len - 1)); requires valid_read_src: \let __fc_len = len / 8; \valid_read(src + (0 .. __fc_len - 1)); - requires - separation: - \let __fc_len = len / 8; - \separated(dest + (0 .. __fc_len - 1), src + (0 .. __fc_len - 1)); ensures copied: \let __fc_len = len / 8; @@ -86,16 +86,16 @@ void structure(struct X * /*[10]*/ src, struct X * /*[10]*/ dest) return; } -/*@ requires aligned_end: len % 4 ≡ 0; +/*@ requires + separation: + \let __fc_len = len / 4; + \separated(dest + (0 .. __fc_len - 1), src + (0 .. __fc_len - 1)); + requires aligned_end: len % 4 ≡ 0; requires valid_dest: \let __fc_len = len / 4; \valid(dest + (0 .. __fc_len - 1)); requires valid_read_src: \let __fc_len = len / 4; \valid_read(src + (0 .. __fc_len - 1)); - requires - separation: - \let __fc_len = len / 4; - \separated(dest + (0 .. __fc_len - 1), src + (0 .. __fc_len - 1)); ensures copied: \let __fc_len = len / 4; @@ -119,17 +119,17 @@ void pointers(int ** /*[10]*/ src, int ** /*[10]*/ dest) return; } -/*@ requires aligned_end: len % 40 ≡ 0; +/*@ requires + separation: + \let __fc_len = len / 40; + \separated(dest + (0 .. __fc_len - 1), src + (0 .. __fc_len - 1)); + requires aligned_end: len % 40 ≡ 0; requires valid_dest: \let __fc_len = len / 40; \valid(dest + (0 .. __fc_len - 1)); requires valid_read_src: \let __fc_len = len / 40; \valid_read(src + (0 .. __fc_len - 1)); - requires - separation: - \let __fc_len = len / 40; - \separated(dest + (0 .. __fc_len - 1), src + (0 .. __fc_len - 1)); ensures copied: \let __fc_len = len / 40; @@ -185,16 +185,16 @@ struct X { }; typedef int named; struct incomplete; -/*@ requires aligned_end: len % 4 ≡ 0; +/*@ requires + separation: + \let __fc_len = len / 4; + \separated(dest + (0 .. __fc_len - 1), src + (0 .. __fc_len - 1)); + requires aligned_end: len % 4 ≡ 0; requires valid_dest: \let __fc_len = len / 4; \valid(dest + (0 .. __fc_len - 1)); requires valid_read_src: \let __fc_len = len / 4; \valid_read(src + (0 .. __fc_len - 1)); - requires - separation: - \let __fc_len = len / 4; - \separated(dest + (0 .. __fc_len - 1), src + (0 .. __fc_len - 1)); ensures copied: \let __fc_len = \old(len) / 4; @@ -228,16 +228,16 @@ void with_named(named *src, named *dest) return; } -/*@ requires aligned_end: len % 8 ≡ 0; +/*@ requires + separation: + \let __fc_len = len / 8; + \separated(dest + (0 .. __fc_len - 1), src + (0 .. __fc_len - 1)); + requires aligned_end: len % 8 ≡ 0; requires valid_dest: \let __fc_len = len / 8; \valid(dest + (0 .. __fc_len - 1)); requires valid_read_src: \let __fc_len = len / 8; \valid_read(src + (0 .. __fc_len - 1)); - requires - separation: - \let __fc_len = len / 8; - \separated(dest + (0 .. __fc_len - 1), src + (0 .. __fc_len - 1)); ensures copied: \let __fc_len = \old(len) / 8; @@ -264,16 +264,16 @@ void structure(struct X *src, struct X *dest) return; } -/*@ requires aligned_end: len % 4 ≡ 0; +/*@ requires + separation: + \let __fc_len = len / 4; + \separated(dest + (0 .. __fc_len - 1), src + (0 .. __fc_len - 1)); + requires aligned_end: len % 4 ≡ 0; requires valid_dest: \let __fc_len = len / 4; \valid(dest + (0 .. __fc_len - 1)); requires valid_read_src: \let __fc_len = len / 4; \valid_read(src + (0 .. __fc_len - 1)); - requires - separation: - \let __fc_len = len / 4; - \separated(dest + (0 .. __fc_len - 1), src + (0 .. __fc_len - 1)); ensures copied: \let __fc_len = \old(len) / 4; @@ -299,17 +299,17 @@ void pointers(int **src, int **dest) return; } -/*@ requires aligned_end: len % 40 ≡ 0; +/*@ requires + separation: + \let __fc_len = len / 40; + \separated(dest + (0 .. __fc_len - 1), src + (0 .. __fc_len - 1)); + requires aligned_end: len % 40 ≡ 0; requires valid_dest: \let __fc_len = len / 40; \valid(dest + (0 .. __fc_len - 1)); requires valid_read_src: \let __fc_len = len / 40; \valid_read(src + (0 .. __fc_len - 1)); - requires - separation: - \let __fc_len = len / 40; - \separated(dest + (0 .. __fc_len - 1), src + (0 .. __fc_len - 1)); ensures copied: \let __fc_len = \old(len) / 40; -- GitLab From 49cd989a1c992317c000a608d462cf0b2ec3ff7f Mon Sep 17 00:00:00 2001 From: Allan Blanchard <allan.blanchard@cea.fr> Date: Thu, 26 Mar 2020 18:16:35 +0100 Subject: [PATCH 107/218] [Instantiate] Takes care of constants in Memset --- src/plugins/instantiate/basic_blocks.ml | 3 +- src/plugins/instantiate/string/memset.ml | 42 +++++++++++------------- 2 files changed, 22 insertions(+), 23 deletions(-) diff --git a/src/plugins/instantiate/basic_blocks.ml b/src/plugins/instantiate/basic_blocks.ml index 830911e482e..0fcd642c58f 100644 --- a/src/plugins/instantiate/basic_blocks.ml +++ b/src/plugins/instantiate/basic_blocks.ml @@ -54,7 +54,8 @@ let exp_type_of_pointed x = let no_cast = Cil.stripCasts x in if not (Cil.isPointerType (Cil.typeOf no_cast)) then match Cil.constFoldToInt x with - | Some t when Integer.(equal t (of_int 0)) -> Some (Cil.typeOf x) + | Some t when Integer.(equal t (of_int 0)) -> + Some (Cil.typeOf_pointed (Cil.typeOf x)) | _ -> None else let xt = Cil.unrollTypeDeep (Cil.typeOf no_cast) in diff --git a/src/plugins/instantiate/string/memset.ml b/src/plugins/instantiate/string/memset.ml index 393f6ae626b..3eef4cdd5b9 100644 --- a/src/plugins/instantiate/string/memset.ml +++ b/src/plugins/instantiate/string/memset.ml @@ -175,12 +175,6 @@ let generate_spec (_t, e) { svar = vi } loc = let ensures = generate_ensures e loc t ptr value len in make_funspec [make_behavior ~requires ~assigns ~ensures ()] () -let type_from_arg x = - let x = Cil.stripCasts x in - let xt = Cil.unrollTypeDeep (Cil.typeOf x) in - let xt = Cil.type_remove_qualifier_attributes_deep xt in - Cil.typeOf_pointed xt - let memset_value e = let ff = Integer.of_int 255 in match (Cil.constFold false e).enode with @@ -199,22 +193,25 @@ let rec contains_union_type t = | _ -> false let well_typed_call _ret = function - | [ ptr ; _ ; _ ] when any_char_composed_type (type_from_arg ptr) -> true - | [ ptr ; _ ; _ ] when contains_union_type (type_from_arg ptr) -> false - | [ ptr ; _ ; _ ] when Cil.isVoidType (type_from_arg ptr) -> false - | [ ptr ; _ ; _ ] when not (Cil.isCompleteType (type_from_arg ptr)) -> false - | [ _ ; value ; _ ] -> - begin match memset_value value with - | None -> false - | Some _ -> true + | [ ptr ; value ; _ ] -> + begin match exp_type_of_pointed ptr, memset_value value with + | None , _ -> false + | Some t, _ when any_char_composed_type t -> true + | Some t, _ when contains_union_type t -> false + | Some t, _ when Cil.isVoidType t -> false + | Some t, _ when not (Cil.isCompleteType t) -> false + | _, None -> false + | _, Some _ -> true end | _ -> false let key_from_call _ret = function - | [ ptr ; _ ; _ ] when any_char_composed_type (type_from_arg ptr) -> - (type_from_arg ptr), None - | [ ptr ; value ; _ ] when not (contains_union_type (type_from_arg ptr)) -> - (type_from_arg ptr), (memset_value value) + | [ ptr ; value ; _ ] -> + begin match exp_type_of_pointed ptr, memset_value value with + | Some t, _ when any_char_composed_type t -> t, None + | Some t, value when not (contains_union_type t) -> t, value + | _ , _ -> unexpected "trying to generate a key on an ill-typed call" + end | _ -> unexpected "trying to generate a key on an ill-typed call" let char_prototype t = @@ -246,17 +243,18 @@ let generate_prototype = function | _, _ -> unexpected "trying to generate a prototype on an ill-typed call" -let retype_args (t, e) args = +let retype_args (_t, e) args = match e, args with | None, [ ptr ; v ; n ] -> let ptr = Cil.stripCasts ptr in - assert (any_char_composed_type (type_from_arg ptr)) ; - let base_type = base_char_type (type_from_arg ptr) in + let base_type = match exp_type_of_pointed ptr with + | Some t -> base_char_type t + | None -> unexpected "trying to retype arguments on an ill-typed call" + in let v = Cil.mkCast (Cil.stripCasts v) base_type in [ ptr ; v ; n ] | Some fv, [ ptr ; v ; n ] -> let ptr = Cil.stripCasts ptr in - assert (Cil_datatype.Typ.equal (type_from_arg ptr) t) ; assert (match memset_value v with Some x when x = fv -> true | _ -> false) ; [ ptr ; n ] | _ -> -- GitLab From 00218f0d7c723057832731cd3353bffcc9a25eff Mon Sep 17 00:00:00 2001 From: Allan Blanchard <allan.blanchard@cea.fr> Date: Thu, 26 Mar 2020 18:17:20 +0100 Subject: [PATCH 108/218] [Instantiate] Value equality with Enums --- src/plugins/instantiate/stdlib/calloc.ml | 2 +- src/plugins/instantiate/string/memset.ml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/instantiate/stdlib/calloc.ml b/src/plugins/instantiate/stdlib/calloc.ml index 86eada6103d..1e064706c5b 100644 --- a/src/plugins/instantiate/stdlib/calloc.ml +++ b/src/plugins/instantiate/stdlib/calloc.ml @@ -34,7 +34,7 @@ let pset_len_to_zero ?loc alloc_type num size = let value = match Logic_utils.unroll_type t.term_type with | Ctype(TPtr(_)) -> term Tnull t.term_type | Ctype(TFloat(_)) -> treal ?loc 0. - | Ctype(TInt(_)) -> tinteger ?loc 0 + | Ctype(TInt(_) | TEnum (_)) -> tinteger ?loc 0 | _ -> unexpected "non atomic type during equality generation" in prel ?loc (Req, t, value) diff --git a/src/plugins/instantiate/string/memset.ml b/src/plugins/instantiate/string/memset.ml index 3eef4cdd5b9..a8fc72f07a5 100644 --- a/src/plugins/instantiate/string/memset.ml +++ b/src/plugins/instantiate/string/memset.ml @@ -68,7 +68,7 @@ let pset_len_bytes_to_zero ?loc ptr bytes_len = let value = match Logic_utils.unroll_type t.term_type with | Ctype(TPtr(_)) -> term Tnull t.term_type | Ctype(TFloat(_)) -> treal ?loc 0. - | Ctype(TInt(_)) -> tinteger ?loc 0 + | Ctype(TInt(_) | TEnum (_)) -> tinteger ?loc 0 | _ -> unexpected "non atomic type during equality generation" in prel ?loc (Req, t, value) -- GitLab From c67732283d828aa9f5ea795f14749210d2761bbd Mon Sep 17 00:00:00 2001 From: Allan Blanchard <allan.blanchard@cea.fr> Date: Fri, 27 Mar 2020 09:01:43 +0100 Subject: [PATCH 109/218] [Instantiate] Moves a not generic function from basic_blocks to mem_utils --- src/plugins/instantiate/basic_blocks.ml | 12 ----- src/plugins/instantiate/basic_blocks.mli | 5 -- src/plugins/instantiate/string/mem_utils.ml | 49 ++++++++++++++------ src/plugins/instantiate/string/mem_utils.mli | 19 +++++++- src/plugins/instantiate/string/memcmp.ml | 8 +++- src/plugins/instantiate/string/memcpy.ml | 8 +++- src/plugins/instantiate/string/memmove.ml | 8 +++- src/plugins/instantiate/string/memset.ml | 24 +++++----- 8 files changed, 85 insertions(+), 48 deletions(-) diff --git a/src/plugins/instantiate/basic_blocks.ml b/src/plugins/instantiate/basic_blocks.ml index 0fcd642c58f..660db8c83c0 100644 --- a/src/plugins/instantiate/basic_blocks.ml +++ b/src/plugins/instantiate/basic_blocks.ml @@ -50,18 +50,6 @@ let call_function lval vi args = let args = List.map2 gen_arg args typs in Call(lval, (Cil.evar vi), args, loc) -let exp_type_of_pointed x = - let no_cast = Cil.stripCasts x in - if not (Cil.isPointerType (Cil.typeOf no_cast)) then - match Cil.constFoldToInt x with - | Some t when Integer.(equal t (of_int 0)) -> - Some (Cil.typeOf_pointed (Cil.typeOf x)) - | _ -> None - else - let xt = Cil.unrollTypeDeep (Cil.typeOf no_cast) in - let xt = Cil.type_remove_qualifier_attributes_deep xt in - Some (Cil.typeOf_pointed xt) - let rec string_of_typ_aux = function | TVoid(_) -> "void" | TInt(IBool, _) -> "bool" diff --git a/src/plugins/instantiate/basic_blocks.mli b/src/plugins/instantiate/basic_blocks.mli index d8723d96765..8b22347ecc1 100644 --- a/src/plugins/instantiate/basic_blocks.mli +++ b/src/plugins/instantiate/basic_blocks.mli @@ -42,11 +42,6 @@ val ttype_of_pointed: logic_type -> logic_type (** {2 C} *) -(** For an expression, return the type of the pointed data. - If the expression is not a pointer, returns None. -*) -val exp_type_of_pointed: exp -> typ option - (** For a type [T], returns [T*] *) val ptr_of: typ -> typ diff --git a/src/plugins/instantiate/string/mem_utils.ml b/src/plugins/instantiate/string/mem_utils.ml index 71247c78162..9d88bb79b94 100644 --- a/src/plugins/instantiate/string/mem_utils.ml +++ b/src/plugins/instantiate/string/mem_utils.ml @@ -24,12 +24,30 @@ open Basic_blocks open Cil_types open Logic_const -type kind = CPtr | Ptr | Len | Int +type kind = CPtr | Ptr | Data of typ type action = Strip | Id type param = string * kind * action type proto = kind * param list type 'a spec_gen = location -> typ -> term -> term -> term -> 'a +type pointed_expr_type = + | Of_null of typ + | Value_of of typ + | No_pointed + +let exp_type_of_pointed x = + let no_cast = Cil.stripCasts x in + if not (Cil.isPointerType (Cil.typeOf no_cast)) then + match Cil.constFoldToInt x with + | Some t when Integer.(equal t (of_int 0)) -> + Of_null (Cil.typeOf_pointed (Cil.typeOf x)) + | _ -> + No_pointed + else + let xt = Cil.unrollTypeDeep (Cil.typeOf no_cast) in + let xt = Cil.type_remove_qualifier_attributes_deep xt in + Value_of (Cil.typeOf_pointed xt) + let unexpected = Options.fatal "Mem_utils: %s" let mem2s_typing _ = function @@ -88,7 +106,7 @@ let memcpy_memmove_common_ensures name loc t dest src len = module type Function = sig val name: string - val prototype: proto + val prototype: unit -> proto val well_typed: typ option -> typ list -> bool end @@ -98,10 +116,9 @@ struct let to_type = function | CPtr -> ptr_of (const_of t) | Ptr -> ptr_of t - | Len -> size_t() - | Int -> Cil.intType + | Data t -> t in - let ret, ps = F.prototype in + let ret, ps = F.prototype () in let ret = to_type ret in let ps = List.map (fun (name, kind, _) -> name, (to_type kind), []) ps in TFun(ret, Some ps, false, []) @@ -112,21 +129,25 @@ struct name, ftype let well_typed_call lval args = - let _, ps = F.prototype in + let _, ps = F.prototype () in if List.length args <> List.length ps then false else let extract e = function | _, (CPtr | Ptr), _ -> exp_type_of_pointed e - | _, (Len | Int), _ -> Some (Cil.typeOf e) + | _, Data _ , _ -> Value_of (Cil.typeOf e) in let lvt = Extlib.opt_map Cil.typeOfLval lval in let pts = List.map2 extract args ps in - let is_none = function None -> true | _ -> false in - if List.exists is_none pts then false - else F.well_typed lvt (List.map (fun x -> Extlib.the x) pts) + let is_no_pointed = function No_pointed -> true | _ -> false in + let the_typ = function + | No_pointed -> assert false + | Value_of t | Of_null t -> t + in + if List.exists is_no_pointed pts then false + else F.well_typed lvt (List.map the_typ pts) let retype_args _ args = - let _, ps = F.prototype in + let _, ps = F.prototype () in if List.length args <> List.length ps then unexpected "trying to retype arguments on an ill-typed call" else @@ -137,12 +158,12 @@ struct List.map2 retype args ps let key_from_call _ret args = - let _, ps = F.prototype in + let _, ps = F.prototype () in match ps, args with | (_, (Ptr|CPtr), _)::ps, fst::args when List.(length ps = length args) -> begin match exp_type_of_pointed fst with - | Some t -> t - | None -> + | Value_of t -> t + | _ -> unexpected "Mem_utils: trying to get key on an ill-typed call" end | _ -> diff --git a/src/plugins/instantiate/string/mem_utils.mli b/src/plugins/instantiate/string/mem_utils.mli index 543e5b06bc1..d4b205be01e 100644 --- a/src/plugins/instantiate/string/mem_utils.mli +++ b/src/plugins/instantiate/string/mem_utils.mli @@ -22,14 +22,22 @@ open Cil_types -type kind = CPtr | Ptr | Len | Int +type kind = CPtr | Ptr | Data of typ type action = Strip | Id type param = string * kind * action type proto = kind * param list module type Function = sig val name: string - val prototype: proto + + val prototype: unit -> proto + + (** receives the type of the lvalue and the types of the arguments recieved + for a call to the function and returns [true] iff they are correct. + The received types depend on the [prototype] of the module. + - if the kind is [Data t] -> it is the exact type of the expr/lvalue + - it the kind is [(C)Ptr] -> it is the pointed type of the expr/lvalue + *) val well_typed: typ option -> typ list -> bool end @@ -58,3 +66,10 @@ val memcpy_memmove_common_assigns: assigns spec_gen val memcpy_memmove_common_ensures: string -> (termination_kind * identified_predicate) list spec_gen + +type pointed_expr_type = + | Of_null of typ + | Value_of of typ + | No_pointed + +val exp_type_of_pointed: exp -> pointed_expr_type \ No newline at end of file diff --git a/src/plugins/instantiate/string/memcmp.ml b/src/plugins/instantiate/string/memcmp.ml index c8518480ed8..59969c7ddee 100644 --- a/src/plugins/instantiate/string/memcmp.ml +++ b/src/plugins/instantiate/string/memcmp.ml @@ -66,7 +66,13 @@ module Function = struct open Mem_utils let name = function_name - let prototype = Int, [ ("s1",CPtr,Strip);("s2",CPtr,Strip);("len",Len,Id)] + let prototype () = + Data Cil.intType, + [ + ("s1" , CPtr,Strip) ; + ("s2" , CPtr,Strip) ; + ("len", Data (size_t ()) ,Id) + ] let well_typed = Mem_utils.mem2s_typing end module Memcmp_base = Mem_utils.Make(Function) diff --git a/src/plugins/instantiate/string/memcpy.ml b/src/plugins/instantiate/string/memcpy.ml index b13a13067cb..e56778e6a57 100644 --- a/src/plugins/instantiate/string/memcpy.ml +++ b/src/plugins/instantiate/string/memcpy.ml @@ -45,7 +45,13 @@ let generate_spec = mem2s_spec ~requires ~assigns ~ensures module Function = struct let name = function_name - let prototype = Ptr, [("dest",Ptr,Strip);("src",CPtr,Strip);("len",Len,Id)] + let prototype () = + Ptr, + [ + ("dest", Ptr, Strip) ; + ("src", CPtr, Strip) ; + ("len", Data (size_t()), Id) + ] let well_typed = Mem_utils.mem2s_typing end module Memcpy_base = Mem_utils.Make(Function) diff --git a/src/plugins/instantiate/string/memmove.ml b/src/plugins/instantiate/string/memmove.ml index 0295236f2cd..9ce6d75b6bd 100644 --- a/src/plugins/instantiate/string/memmove.ml +++ b/src/plugins/instantiate/string/memmove.ml @@ -33,7 +33,13 @@ let generate_spec = mem2s_spec ~requires ~assigns ~ensures module Function = struct let name = function_name - let prototype = Ptr, [("dest",Ptr,Strip);("src",CPtr,Strip);("len",Len,Id)] + let prototype () = + Ptr, + [ + ("dest", Ptr, Strip); + ("src" , CPtr, Strip); + ("len", Data (Basic_blocks.size_t()), Id) + ] let well_typed = Mem_utils.mem2s_typing end module Memmove_base = Mem_utils.Make(Function) diff --git a/src/plugins/instantiate/string/memset.ml b/src/plugins/instantiate/string/memset.ml index a8fc72f07a5..f681aa0ef13 100644 --- a/src/plugins/instantiate/string/memset.ml +++ b/src/plugins/instantiate/string/memset.ml @@ -194,12 +194,12 @@ let rec contains_union_type t = let well_typed_call _ret = function | [ ptr ; value ; _ ] -> - begin match exp_type_of_pointed ptr, memset_value value with - | None , _ -> false - | Some t, _ when any_char_composed_type t -> true - | Some t, _ when contains_union_type t -> false - | Some t, _ when Cil.isVoidType t -> false - | Some t, _ when not (Cil.isCompleteType t) -> false + begin match Mem_utils.exp_type_of_pointed ptr, memset_value value with + | (No_pointed | Of_null _) , _ -> false + | Value_of t , _ when any_char_composed_type t -> true + | Value_of t , _ when contains_union_type t -> false + | Value_of t , _ when Cil.isVoidType t -> false + | Value_of t , _ when not (Cil.isCompleteType t) -> false | _, None -> false | _, Some _ -> true end @@ -207,9 +207,9 @@ let well_typed_call _ret = function let key_from_call _ret = function | [ ptr ; value ; _ ] -> - begin match exp_type_of_pointed ptr, memset_value value with - | Some t, _ when any_char_composed_type t -> t, None - | Some t, value when not (contains_union_type t) -> t, value + begin match Mem_utils.exp_type_of_pointed ptr, memset_value value with + | Value_of t, _ when any_char_composed_type t -> t, None + | Value_of t, value when not (contains_union_type t) -> t, value | _ , _ -> unexpected "trying to generate a key on an ill-typed call" end | _ -> unexpected "trying to generate a key on an ill-typed call" @@ -247,9 +247,9 @@ let retype_args (_t, e) args = match e, args with | None, [ ptr ; v ; n ] -> let ptr = Cil.stripCasts ptr in - let base_type = match exp_type_of_pointed ptr with - | Some t -> base_char_type t - | None -> unexpected "trying to retype arguments on an ill-typed call" + let base_type = match Mem_utils.exp_type_of_pointed ptr with + | Value_of t -> base_char_type t + | _ -> unexpected "trying to retype arguments on an ill-typed call" in let v = Cil.mkCast (Cil.stripCasts v) base_type in [ ptr ; v ; n ] -- GitLab From 778ba37f1cb383495ed1a7c3da82c2c3413e72aa Mon Sep 17 00:00:00 2001 From: Allan Blanchard <allan.blanchard@cea.fr> Date: Fri, 27 Mar 2020 09:17:49 +0100 Subject: [PATCH 110/218] [Instantiate] Test related to enums for memset/calloc --- src/plugins/instantiate/tests/stdlib/calloc.c | 3 + .../tests/stdlib/oracle/calloc.res.oracle | 91 ++++++++++++++++++- .../instantiate/tests/string/memset_0.c | 6 ++ .../instantiate/tests/string/memset_FF.c | 6 ++ .../instantiate/tests/string/memset_value.c | 6 ++ .../tests/string/oracle/memset_0.res.oracle | 66 +++++++++++++- .../tests/string/oracle/memset_FF.res.oracle | 66 +++++++++++++- .../string/oracle/memset_value.res.oracle | 42 +++++++-- 8 files changed, 273 insertions(+), 13 deletions(-) diff --git a/src/plugins/instantiate/tests/stdlib/calloc.c b/src/plugins/instantiate/tests/stdlib/calloc.c index 87b1f9338cc..d87508ad415 100644 --- a/src/plugins/instantiate/tests/stdlib/calloc.c +++ b/src/plugins/instantiate/tests/stdlib/calloc.c @@ -11,8 +11,11 @@ struct Flex { int f[] ; } ; +enum E { A, B, C }; + int main(void){ int* pi = calloc(10, sizeof(int)) ; + enum E* pe = calloc(10, sizeof(enum E)) ; float* pf = calloc(10, sizeof(float)) ; struct X* px = calloc(10, sizeof(struct X)) ; char* pc = calloc(10, sizeof(char)) ; diff --git a/src/plugins/instantiate/tests/stdlib/oracle/calloc.res.oracle b/src/plugins/instantiate/tests/stdlib/oracle/calloc.res.oracle index 28d42c036e3..cc72848fd62 100644 --- a/src/plugins/instantiate/tests/stdlib/oracle/calloc.res.oracle +++ b/src/plugins/instantiate/tests/stdlib/oracle/calloc.res.oracle @@ -1,6 +1,6 @@ [kernel] Parsing tests/stdlib/calloc.c (with preprocessing) -[instantiate] tests/stdlib/calloc.c:21: Warning: Ignore call: not well typed -[instantiate] tests/stdlib/calloc.c:22: Warning: Ignore call: not well typed +[instantiate] tests/stdlib/calloc.c:24: Warning: Ignore call: not well typed +[instantiate] tests/stdlib/calloc.c:25: Warning: Ignore call: not well typed /* Generated by Frama-C */ #include "stdlib.h" struct X { @@ -12,6 +12,11 @@ struct Flex { char c ; int f[] ; }; +enum E { + A = 0, + B = 1, + C = 2 +}; struct incomplete; /*@ requires correct_size: 0 ≤ size - 8 ∧ 0 ≡ (size - 8) % 4; requires only_one: num ≡ 1; @@ -216,6 +221,43 @@ float *calloc_float(size_t num, size_t size) return __retres; } +/*@ requires correct_size: 0 ≡ size % 4; + assigns \result, __fc_heap_status; + assigns \result \from __fc_heap_status, num, size; + assigns __fc_heap_status \from __fc_heap_status, num, size; + allocates \result; + + behavior allocation: + assumes allocable: is_allocable(num * size); + ensures fresh_result: \fresh{Old, Here}(\result,num * size); + ensures + zero_initialization: + ∀ ℤ j0; 0 ≤ j0 < num ⇒ *(\result + j0) ≡ 0; + ensures + initialization: + ∀ ℤ j0; 0 ≤ j0 < num ⇒ \initialized(\result + j0); + assigns \result, __fc_heap_status; + assigns \result \from __fc_heap_status, num, size; + assigns __fc_heap_status \from __fc_heap_status, num, size; + allocates \result; + + behavior no_allocation: + assumes allocable: ¬is_allocable(num * size); + ensures null_result: \result ≡ \null; + assigns \result; + assigns \result \from \nothing; + allocates \nothing; + + complete behaviors no_allocation, allocation; + disjoint behaviors no_allocation, allocation; + */ +enum E *calloc_e_E(size_t num, size_t size) +{ + enum E *__retres; + __retres = (enum E *)calloc(num,size); + return __retres; +} + /*@ requires correct_size: 0 ≡ size % 4; assigns \result, __fc_heap_status; assigns \result \from __fc_heap_status, num, size; @@ -257,6 +299,7 @@ int main(void) { int __retres; int *pi = calloc_int((unsigned int)10,sizeof(int)); + enum E *pe = calloc_e_E((unsigned int)10,sizeof(enum E)); float *pf = calloc_float((unsigned int)10,sizeof(float)); struct X *px = calloc_st_X((unsigned int)10,sizeof(struct X)); char *pc = calloc_char((unsigned int)10,sizeof(char)); @@ -283,6 +326,11 @@ struct Flex { char c ; int f[] ; }; +enum E { + A = 0, + B = 1, + C = 2 +}; struct incomplete; /*@ requires correct_size: 0 ≤ size - 8 ∧ 0 ≡ (size - 8) % 4; requires only_one: num ≡ 1; @@ -490,6 +538,44 @@ float *calloc_float(size_t num, size_t size) return __retres; } +/*@ requires correct_size: 0 ≡ size % 4; + assigns \result, __fc_heap_status; + assigns \result \from __fc_heap_status, num, size; + assigns __fc_heap_status \from __fc_heap_status, num, size; + allocates \result; + + behavior allocation: + assumes allocable: is_allocable(num * size); + ensures + fresh_result: \fresh{Old, Here}(\result,\old(num) * \old(size)); + ensures + zero_initialization: + ∀ ℤ j0; 0 ≤ j0 < \old(num) ⇒ *(\result + j0) ≡ 0; + ensures + initialization: + ∀ ℤ j0; 0 ≤ j0 < \old(num) ⇒ \initialized(\result + j0); + assigns \result, __fc_heap_status; + assigns \result \from __fc_heap_status, num, size; + assigns __fc_heap_status \from __fc_heap_status, num, size; + allocates \result; + + behavior no_allocation: + assumes allocable: ¬is_allocable(num * size); + ensures null_result: \result ≡ \null; + assigns \result; + assigns \result \from \nothing; + allocates \nothing; + + complete behaviors no_allocation, allocation; + disjoint behaviors no_allocation, allocation; + */ +enum E *calloc_e_E(size_t num, size_t size) +{ + enum E *__retres; + __retres = (enum E *)calloc(num,size); + return __retres; +} + /*@ requires correct_size: 0 ≡ size % 4; assigns \result, __fc_heap_status; assigns \result \from __fc_heap_status, num, size; @@ -532,6 +618,7 @@ int main(void) { int __retres; int *pi = calloc_int((unsigned int)10,sizeof(int)); + enum E *pe = calloc_e_E((unsigned int)10,sizeof(enum E)); float *pf = calloc_float((unsigned int)10,sizeof(float)); struct X *px = calloc_st_X((unsigned int)10,sizeof(struct X)); char *pc = calloc_char((unsigned int)10,sizeof(char)); diff --git a/src/plugins/instantiate/tests/string/memset_0.c b/src/plugins/instantiate/tests/string/memset_0.c index ffd73cad6a7..f87d8629005 100644 --- a/src/plugins/instantiate/tests/string/memset_0.c +++ b/src/plugins/instantiate/tests/string/memset_0.c @@ -27,6 +27,12 @@ void integer(int dest[10]){ memset(res, 0, 10 * sizeof(int)); } +enum E { A, B, C } ; +void with_enum(enum E dest[10]){ + enum E * res = memset(dest, 0, 10 * sizeof(enum E)); + memset(res, 0, 10 * sizeof(enum E)); +} + void floats(float dest[10]){ float * res = memset(dest, 0, 10 * sizeof(float)); memset(res, 0, 10 * sizeof(float)); diff --git a/src/plugins/instantiate/tests/string/memset_FF.c b/src/plugins/instantiate/tests/string/memset_FF.c index 17c8260b516..45b8e49cd11 100644 --- a/src/plugins/instantiate/tests/string/memset_FF.c +++ b/src/plugins/instantiate/tests/string/memset_FF.c @@ -27,6 +27,12 @@ void integer(int dest[10]){ memset(res, 0xFF, 10 * sizeof(int)); } +enum E { A, B, C } ; +void with_enum(enum E dest[10]){ + enum E * res = memset(dest, 0xFF, 10 * sizeof(enum E)); + memset(res, 0xFF, 10 * sizeof(enum E)); +} + void unsigned_integer(unsigned dest[10]){ unsigned * res = memset(dest, 0xFF, 10 * sizeof(unsigned)); memset(res, 0xFF, 10 * sizeof(unsigned)); diff --git a/src/plugins/instantiate/tests/string/memset_value.c b/src/plugins/instantiate/tests/string/memset_value.c index 432b8ed6a6d..654466dbc2f 100644 --- a/src/plugins/instantiate/tests/string/memset_value.c +++ b/src/plugins/instantiate/tests/string/memset_value.c @@ -27,6 +27,12 @@ void integer(int dest[10], int value){ memset(res, value, 10 * sizeof(int)); } +enum E { A, B, C } ; +void with_enum(enum E dest[10], int value){ + enum E * res = memset(dest, value, 10 * sizeof(enum E)); + memset(res, value, 10 * sizeof(enum E)); +} + void with_named(named dest[10], int value){ named * res = memset(dest, value, 10 * sizeof(named)); memset(res, value, 10 * sizeof(named)); diff --git a/src/plugins/instantiate/tests/string/oracle/memset_0.res.oracle b/src/plugins/instantiate/tests/string/oracle/memset_0.res.oracle index 1b7efe66ddf..368076b562a 100644 --- a/src/plugins/instantiate/tests/string/oracle/memset_0.res.oracle +++ b/src/plugins/instantiate/tests/string/oracle/memset_0.res.oracle @@ -1,6 +1,6 @@ [kernel] Parsing tests/string/memset_0.c (with preprocessing) -[instantiate] tests/string/memset_0.c:56: Warning: Ignore call: not well typed -[instantiate] tests/string/memset_0.c:57: Warning: Ignore call: not well typed +[instantiate] tests/string/memset_0.c:62: Warning: Ignore call: not well typed +[instantiate] tests/string/memset_0.c:63: Warning: Ignore call: not well typed /* Generated by Frama-C */ #include "stddef.h" #include "string.h" @@ -10,6 +10,11 @@ struct X { int y ; }; typedef int named; +enum E { + A = 0, + B = 1, + C = 2 +}; /*@ requires in_bounds_value: -128 ≤ value < 128; requires valid_dest: \valid(ptr + (0 .. len - 1)); ensures @@ -111,6 +116,32 @@ void integer(int * /*[10]*/ dest) return; } +/*@ requires aligned_end: len % 4 ≡ 0; + requires + valid_dest: \let __fc_len = len / 4; \valid(ptr + (0 .. __fc_len - 1)); + ensures + set_content: + \let __fc_len = len / 4; + ∀ ℤ j0; 0 ≤ j0 < __fc_len ⇒ *(ptr + j0) ≡ 0; + ensures result: \result ≡ ptr; + assigns *(ptr + (0 .. len / 4 - 1)), \result; + assigns *(ptr + (0 .. len / 4 - 1)) \from \nothing; + assigns \result \from ptr; + */ +enum E *memset_e_E_0(enum E *ptr, size_t len) +{ + enum E *__retres; + __retres = (enum E *)memset((void *)ptr,0,len); + return __retres; +} + +void with_enum(enum E * /*[10]*/ dest) +{ + enum E *res = memset_e_E_0(dest,(unsigned int)10 * sizeof(enum E)); + memset_e_E_0(res,(unsigned int)10 * sizeof(enum E)); + return; +} + /*@ requires aligned_end: len % 4 ≡ 0; requires valid_dest: \let __fc_len = len / 4; \valid(ptr + (0 .. __fc_len - 1)); @@ -244,6 +275,11 @@ struct X { int y ; }; typedef int named; +enum E { + A = 0, + B = 1, + C = 2 +}; /*@ requires in_bounds_value: -128 ≤ value < 128; requires valid_dest: \valid(ptr + (0 .. len - 1)); ensures @@ -350,6 +386,32 @@ void integer(int *dest) return; } +/*@ requires aligned_end: len % 4 ≡ 0; + requires + valid_dest: \let __fc_len = len / 4; \valid(ptr + (0 .. __fc_len - 1)); + ensures + set_content: + \let __fc_len = \old(len) / 4; + ∀ ℤ j0; 0 ≤ j0 < __fc_len ⇒ *(\old(ptr) + j0) ≡ 0; + ensures result: \result ≡ \old(ptr); + assigns *(ptr + (0 .. len / 4 - 1)), \result; + assigns *(ptr + (0 .. len / 4 - 1)) \from \nothing; + assigns \result \from ptr; + */ +enum E *memset_e_E_0(enum E *ptr, size_t len) +{ + enum E *__retres; + __retres = (enum E *)memset((void *)ptr,0,len); + return __retres; +} + +void with_enum(enum E *dest) +{ + enum E *res = memset_e_E_0(dest,(unsigned int)10 * sizeof(enum E)); + memset_e_E_0(res,(unsigned int)10 * sizeof(enum E)); + return; +} + /*@ requires aligned_end: len % 4 ≡ 0; requires valid_dest: \let __fc_len = len / 4; \valid(ptr + (0 .. __fc_len - 1)); diff --git a/src/plugins/instantiate/tests/string/oracle/memset_FF.res.oracle b/src/plugins/instantiate/tests/string/oracle/memset_FF.res.oracle index ffe160d7caa..7495743e8a2 100644 --- a/src/plugins/instantiate/tests/string/oracle/memset_FF.res.oracle +++ b/src/plugins/instantiate/tests/string/oracle/memset_FF.res.oracle @@ -1,6 +1,6 @@ [kernel] Parsing tests/string/memset_FF.c (with preprocessing) -[instantiate] tests/string/memset_FF.c:82: Warning: Ignore call: not well typed -[instantiate] tests/string/memset_FF.c:83: Warning: Ignore call: not well typed +[instantiate] tests/string/memset_FF.c:88: Warning: Ignore call: not well typed +[instantiate] tests/string/memset_FF.c:89: Warning: Ignore call: not well typed /* Generated by Frama-C */ #include "stddef.h" #include "string.h" @@ -10,6 +10,11 @@ struct X { int y ; }; typedef int named; +enum E { + A = 0, + B = 1, + C = 2 +}; /*@ requires in_bounds_value: -128 ≤ value < 128; requires valid_dest: \valid(ptr + (0 .. len - 1)); ensures @@ -112,6 +117,32 @@ void integer(int * /*[10]*/ dest) return; } +/*@ requires aligned_end: len % 4 ≡ 0; + requires + valid_dest: \let __fc_len = len / 4; \valid(ptr + (0 .. __fc_len - 1)); + ensures + set_content: + \let __fc_len = len / 4; + ∀ ℤ j0; 0 ≤ j0 < __fc_len ⇒ *(ptr + j0) ≡ 4294967295; + ensures result: \result ≡ ptr; + assigns *(ptr + (0 .. len / 4 - 1)), \result; + assigns *(ptr + (0 .. len / 4 - 1)) \from \nothing; + assigns \result \from ptr; + */ +enum E *memset_e_E_FF(enum E *ptr, size_t len) +{ + enum E *__retres; + __retres = (enum E *)memset((void *)ptr,255,len); + return __retres; +} + +void with_enum(enum E * /*[10]*/ dest) +{ + enum E *res = memset_e_E_FF(dest,(unsigned int)10 * sizeof(enum E)); + memset_e_E_FF(res,(unsigned int)10 * sizeof(enum E)); + return; +} + /*@ requires aligned_end: len % 4 ≡ 0; requires valid_dest: \let __fc_len = len / 4; \valid(ptr + (0 .. __fc_len - 1)); @@ -382,6 +413,11 @@ struct X { int y ; }; typedef int named; +enum E { + A = 0, + B = 1, + C = 2 +}; /*@ requires in_bounds_value: -128 ≤ value < 128; requires valid_dest: \valid(ptr + (0 .. len - 1)); ensures @@ -489,6 +525,32 @@ void integer(int *dest) return; } +/*@ requires aligned_end: len % 4 ≡ 0; + requires + valid_dest: \let __fc_len = len / 4; \valid(ptr + (0 .. __fc_len - 1)); + ensures + set_content: + \let __fc_len = \old(len) / 4; + ∀ ℤ j0; 0 ≤ j0 < __fc_len ⇒ *(\old(ptr) + j0) ≡ 4294967295; + ensures result: \result ≡ \old(ptr); + assigns *(ptr + (0 .. len / 4 - 1)), \result; + assigns *(ptr + (0 .. len / 4 - 1)) \from \nothing; + assigns \result \from ptr; + */ +enum E *memset_e_E_FF(enum E *ptr, size_t len) +{ + enum E *__retres; + __retres = (enum E *)memset((void *)ptr,255,len); + return __retres; +} + +void with_enum(enum E *dest) +{ + enum E *res = memset_e_E_FF(dest,(unsigned int)10 * sizeof(enum E)); + memset_e_E_FF(res,(unsigned int)10 * sizeof(enum E)); + return; +} + /*@ requires aligned_end: len % 4 ≡ 0; requires valid_dest: \let __fc_len = len / 4; \valid(ptr + (0 .. __fc_len - 1)); diff --git a/src/plugins/instantiate/tests/string/oracle/memset_value.res.oracle b/src/plugins/instantiate/tests/string/oracle/memset_value.res.oracle index 462fc372857..f68d49c8e42 100644 --- a/src/plugins/instantiate/tests/string/oracle/memset_value.res.oracle +++ b/src/plugins/instantiate/tests/string/oracle/memset_value.res.oracle @@ -3,30 +3,34 @@ Ignore call: not well typed [instantiate] tests/string/memset_value.c:27: Warning: Ignore call: not well typed -[instantiate] tests/string/memset_value.c:31: Warning: - Ignore call: not well typed [instantiate] tests/string/memset_value.c:32: Warning: Ignore call: not well typed -[instantiate] tests/string/memset_value.c:36: Warning: +[instantiate] tests/string/memset_value.c:33: Warning: Ignore call: not well typed [instantiate] tests/string/memset_value.c:37: Warning: Ignore call: not well typed -[instantiate] tests/string/memset_value.c:41: Warning: +[instantiate] tests/string/memset_value.c:38: Warning: Ignore call: not well typed [instantiate] tests/string/memset_value.c:42: Warning: Ignore call: not well typed -[instantiate] tests/string/memset_value.c:46: Warning: +[instantiate] tests/string/memset_value.c:43: Warning: Ignore call: not well typed [instantiate] tests/string/memset_value.c:47: Warning: Ignore call: not well typed -[instantiate] tests/string/memset_value.c:51: Warning: +[instantiate] tests/string/memset_value.c:48: Warning: Ignore call: not well typed [instantiate] tests/string/memset_value.c:52: Warning: Ignore call: not well typed -[instantiate] tests/string/memset_value.c:56: Warning: +[instantiate] tests/string/memset_value.c:53: Warning: Ignore call: not well typed [instantiate] tests/string/memset_value.c:57: Warning: Ignore call: not well typed +[instantiate] tests/string/memset_value.c:58: Warning: + Ignore call: not well typed +[instantiate] tests/string/memset_value.c:62: Warning: + Ignore call: not well typed +[instantiate] tests/string/memset_value.c:63: Warning: + Ignore call: not well typed /* Generated by Frama-C */ #include "stddef.h" #include "string.h" @@ -36,6 +40,11 @@ struct X { int y ; }; typedef int named; +enum E { + A = 0, + B = 1, + C = 2 +}; struct incomplete; /*@ requires in_bounds_value: -128 ≤ value < 128; requires valid_dest: \valid(ptr + (0 .. len - 1)); @@ -119,6 +128,13 @@ void integer(int * /*[10]*/ dest, int value) return; } +void with_enum(enum E * /*[10]*/ dest, int value) +{ + enum E *res = memset((void *)dest,value,(unsigned int)10 * sizeof(enum E)); + memset((void *)res,value,(unsigned int)10 * sizeof(enum E)); + return; +} + void with_named(named * /*[10]*/ dest, int value) { named *res = memset((void *)dest,value,(unsigned int)10 * sizeof(named)); @@ -174,6 +190,11 @@ struct X { int y ; }; typedef int named; +enum E { + A = 0, + B = 1, + C = 2 +}; struct incomplete; /*@ requires in_bounds_value: -128 ≤ value < 128; requires valid_dest: \valid(ptr + (0 .. len - 1)); @@ -262,6 +283,13 @@ void integer(int *dest, int value) return; } +void with_enum(enum E *dest, int value) +{ + enum E *res = memset((void *)dest,value,(unsigned int)10 * sizeof(enum E)); + memset((void *)res,value,(unsigned int)10 * sizeof(enum E)); + return; +} + void with_named(named *dest, int value) { named *res = memset((void *)dest,value,(unsigned int)10 * sizeof(named)); -- GitLab From 0217e3d94b4c472f30baa64262a3991d5cb6a36a Mon Sep 17 00:00:00 2001 From: Allan Blanchard <allan.blanchard@cea.fr> Date: Fri, 27 Mar 2020 09:56:10 +0100 Subject: [PATCH 111/218] [Instantiate] Fixes Memset for all bits to one --- src/plugins/instantiate/string/memset.ml | 13 +++++++---- .../tests/string/oracle/memset_FF.res.oracle | 23 +++++++++---------- 2 files changed, 19 insertions(+), 17 deletions(-) diff --git a/src/plugins/instantiate/string/memset.ml b/src/plugins/instantiate/string/memset.ml index f681aa0ef13..b62c37aa2ca 100644 --- a/src/plugins/instantiate/string/memset.ml +++ b/src/plugins/instantiate/string/memset.ml @@ -89,15 +89,18 @@ let pset_len_bytes_all_bits_to_one ?loc ptr bytes_len = papp ?loc ((find_nan_for_type t.term_type), [], [t]) | Ctype(TPtr(_)) -> pnot ?loc (pvalid_read ?loc (here_label, t)) - | Ctype(TInt(kind, _)) | Ctype(TEnum({ ekind = kind }, _)) -> + | Ctype((TInt(kind, _) | TEnum({ ekind = kind }, _)) as typ) -> let is_signed = Cil.isSigned kind in let bits = Cil.bitsSizeOfInt kind in - let value = if is_signed then - Cil.min_signed_number bits + let value = + if is_signed then + let zero = tinteger ?loc 0 in + let zero = Logic_utils.mk_cast ?loc typ zero in + term (TUnOp(BNot, zero)) t.term_type else - Cil.max_unsigned_number bits + let value = Cil.max_unsigned_number bits in + term ?loc (TConst (Integer (value,None))) Linteger in - let value = term ?loc (TConst (Integer (value,None))) Linteger in prel ?loc (Req, t, value) | _ -> unexpected "non atomic type during equality generation" diff --git a/src/plugins/instantiate/tests/string/oracle/memset_FF.res.oracle b/src/plugins/instantiate/tests/string/oracle/memset_FF.res.oracle index 7495743e8a2..0054f340577 100644 --- a/src/plugins/instantiate/tests/string/oracle/memset_FF.res.oracle +++ b/src/plugins/instantiate/tests/string/oracle/memset_FF.res.oracle @@ -97,7 +97,7 @@ void nested_chars(char (* /*[10]*/ dest)[10]) ensures set_content: \let __fc_len = len / 4; - ∀ ℤ j0; 0 ≤ j0 < __fc_len ⇒ *(ptr + j0) ≡ -2147483648; + ∀ ℤ j0; 0 ≤ j0 < __fc_len ⇒ *(ptr + j0) ≡ ~((int)0); ensures result: \result ≡ ptr; assigns *(ptr + (0 .. len / 4 - 1)), \result; assigns *(ptr + (0 .. len / 4 - 1)) \from \nothing; @@ -176,7 +176,7 @@ void unsigned_integer(unsigned int * /*[10]*/ dest) ensures set_content: \let __fc_len = len / 4; - ∀ ℤ j0; 0 ≤ j0 < __fc_len ⇒ *(ptr + j0) ≡ -2147483648; + ∀ ℤ j0; 0 ≤ j0 < __fc_len ⇒ *(ptr + j0) ≡ ~((long)0); ensures result: \result ≡ ptr; assigns *(ptr + (0 .. len / 4 - 1)), \result; assigns *(ptr + (0 .. len / 4 - 1)) \from \nothing; @@ -229,8 +229,7 @@ void unsigned_long_integer(unsigned long * /*[10]*/ dest) ensures set_content: \let __fc_len = len / 8; - ∀ ℤ j0; - 0 ≤ j0 < __fc_len ⇒ *(ptr + j0) ≡ -9223372036854775808; + ∀ ℤ j0; 0 ≤ j0 < __fc_len ⇒ *(ptr + j0) ≡ ~((long long)0); ensures result: \result ≡ ptr; assigns *(ptr + (0 .. len / 8 - 1)), \result; assigns *(ptr + (0 .. len / 8 - 1)) \from \nothing; @@ -320,7 +319,7 @@ void with_named(named * /*[10]*/ dest) \let __fc_len = len / 8; ∀ ℤ j0; 0 ≤ j0 < __fc_len ⇒ - (ptr + j0)->x ≡ -2147483648 ∧ (ptr + j0)->y ≡ -2147483648; + (ptr + j0)->x ≡ ~((int)0) ∧ (ptr + j0)->y ≡ ~((int)0); ensures result: \result ≡ ptr; assigns *(ptr + (0 .. len / 8 - 1)), \result; assigns *(ptr + (0 .. len / 8 - 1)) \from \nothing; @@ -374,7 +373,7 @@ void pointers(int ** /*[10]*/ dest) \let __fc_len = len / 40; ∀ ℤ j0; 0 ≤ j0 < __fc_len ⇒ - (∀ ℤ j1; 0 ≤ j1 < 10 ⇒ (*(ptr + j0))[j1] ≡ -2147483648); + (∀ ℤ j1; 0 ≤ j1 < 10 ⇒ (*(ptr + j0))[j1] ≡ ~((int)0)); ensures result: \result ≡ ptr; assigns (*(ptr + (0 .. len / 40 - 1)))[0 .. 10 - 1], \result; assigns (*(ptr + (0 .. len / 40 - 1)))[0 .. 10 - 1] \from \nothing; @@ -505,7 +504,7 @@ void nested_chars(char (*dest)[10]) ensures set_content: \let __fc_len = \old(len) / 4; - ∀ ℤ j0; 0 ≤ j0 < __fc_len ⇒ *(\old(ptr) + j0) ≡ -2147483648; + ∀ ℤ j0; 0 ≤ j0 < __fc_len ⇒ *(\old(ptr) + j0) ≡ ~((int)0); ensures result: \result ≡ \old(ptr); assigns *(ptr + (0 .. len / 4 - 1)), \result; assigns *(ptr + (0 .. len / 4 - 1)) \from \nothing; @@ -584,7 +583,7 @@ void unsigned_integer(unsigned int *dest) ensures set_content: \let __fc_len = \old(len) / 4; - ∀ ℤ j0; 0 ≤ j0 < __fc_len ⇒ *(\old(ptr) + j0) ≡ -2147483648; + ∀ ℤ j0; 0 ≤ j0 < __fc_len ⇒ *(\old(ptr) + j0) ≡ ~((long)0); ensures result: \result ≡ \old(ptr); assigns *(ptr + (0 .. len / 4 - 1)), \result; assigns *(ptr + (0 .. len / 4 - 1)) \from \nothing; @@ -638,7 +637,7 @@ void unsigned_long_integer(unsigned long *dest) set_content: \let __fc_len = \old(len) / 8; ∀ ℤ j0; - 0 ≤ j0 < __fc_len ⇒ *(\old(ptr) + j0) ≡ -9223372036854775808; + 0 ≤ j0 < __fc_len ⇒ *(\old(ptr) + j0) ≡ ~((long long)0); ensures result: \result ≡ \old(ptr); assigns *(ptr + (0 .. len / 8 - 1)), \result; assigns *(ptr + (0 .. len / 8 - 1)) \from \nothing; @@ -728,8 +727,8 @@ void with_named(named *dest) \let __fc_len = \old(len) / 8; ∀ ℤ j0; 0 ≤ j0 < __fc_len ⇒ - (\old(ptr) + j0)->x ≡ -2147483648 ∧ - (\old(ptr) + j0)->y ≡ -2147483648; + (\old(ptr) + j0)->x ≡ ~((int)0) ∧ + (\old(ptr) + j0)->y ≡ ~((int)0); ensures result: \result ≡ \old(ptr); assigns *(ptr + (0 .. len / 8 - 1)), \result; assigns *(ptr + (0 .. len / 8 - 1)) \from \nothing; @@ -784,7 +783,7 @@ void pointers(int **dest) ∀ ℤ j0; 0 ≤ j0 < __fc_len ⇒ (∀ ℤ j1; - 0 ≤ j1 < 10 ⇒ (*(\old(ptr) + j0))[j1] ≡ -2147483648); + 0 ≤ j1 < 10 ⇒ (*(\old(ptr) + j0))[j1] ≡ ~((int)0)); ensures result: \result ≡ \old(ptr); assigns (*(ptr + (0 .. len / 40 - 1)))[0 .. 10 - 1], \result; assigns (*(ptr + (0 .. len / 40 - 1)))[0 .. 10 - 1] \from \nothing; -- GitLab From 1b103b96a0b50636144458360922c99bff0ee2fa Mon Sep 17 00:00:00 2001 From: Allan Blanchard <allan.blanchard@cea.fr> Date: Fri, 27 Mar 2020 10:17:36 +0100 Subject: [PATCH 112/218] [Instantiate] Test for numeric constant as pointers --- src/plugins/instantiate/tests/string/memcmp.c | 9 ++++++- src/plugins/instantiate/tests/string/memcpy.c | 9 ++++++- .../instantiate/tests/string/memmove.c | 7 +++++ .../instantiate/tests/string/memset_0.c | 5 ++++ .../instantiate/tests/string/memset_FF.c | 5 ++++ .../instantiate/tests/string/memset_value.c | 7 ++++- .../tests/string/oracle/memcmp.res.oracle | 26 +++++++++++++++++++ .../tests/string/oracle/memcpy.res.oracle | 22 ++++++++++++++++ .../tests/string/oracle/memmove.res.oracle | 22 ++++++++++++++++ .../tests/string/oracle/memset_0.res.oracle | 16 ++++++++++++ .../tests/string/oracle/memset_FF.res.oracle | 16 ++++++++++++ .../string/oracle/memset_value.res.oracle | 18 +++++++++++++ 12 files changed, 159 insertions(+), 3 deletions(-) diff --git a/src/plugins/instantiate/tests/string/memcmp.c b/src/plugins/instantiate/tests/string/memcmp.c index 404692f9eb1..d8d958e45ed 100644 --- a/src/plugins/instantiate/tests/string/memcmp.c +++ b/src/plugins/instantiate/tests/string/memcmp.c @@ -34,4 +34,11 @@ int with_void(void *s1, void *s2, int n){ struct incomplete ; int with_incomplete(struct incomplete* s1, struct incomplete* s2, int n){ return memcmp(s1, s2, n); -} \ No newline at end of file +} + +void with_null_or_int(int p[10]){ + memcmp(NULL, p, 10 * sizeof(int)); + memcmp(p, NULL, 10 * sizeof(int)); + memcmp((int const*)42, p, 10 * sizeof(int)); + memcmp(p, (int const*)42, 10 * sizeof(int)); +} diff --git a/src/plugins/instantiate/tests/string/memcpy.c b/src/plugins/instantiate/tests/string/memcpy.c index f2c6c03d864..fda5fadb758 100644 --- a/src/plugins/instantiate/tests/string/memcpy.c +++ b/src/plugins/instantiate/tests/string/memcpy.c @@ -41,4 +41,11 @@ struct incomplete ; void with_incomplete(struct incomplete* src, struct incomplete* dest, int n){ struct incomplete* res = memcpy(dest, src, n); memcpy(src, res, n); -} \ No newline at end of file +} + +void with_null_or_int(int p[10]){ + memcpy(NULL, p, 10 * sizeof(int)); + memcpy(p, NULL, 10 * sizeof(int)); + memcpy((int*)42, p, 10 * sizeof(int)); + memcpy(p, (int*)42, 10 * sizeof(int)); +} diff --git a/src/plugins/instantiate/tests/string/memmove.c b/src/plugins/instantiate/tests/string/memmove.c index a40698297fd..72a5e891aee 100644 --- a/src/plugins/instantiate/tests/string/memmove.c +++ b/src/plugins/instantiate/tests/string/memmove.c @@ -42,3 +42,10 @@ void with_incomplete(struct incomplete *src, struct incomplete *dest, int n){ struct incomplete *res = memmove(dest, src, n); memmove(src, res, n); } + +void with_null_or_int(int p[10]){ + memmove(NULL, p, 10 * sizeof(int)); + memmove(p, NULL, 10 * sizeof(int)); + memmove((int*)42, p, 10 * sizeof(int)); + memmove(p, (int*)42, 10 * sizeof(int)); +} diff --git a/src/plugins/instantiate/tests/string/memset_0.c b/src/plugins/instantiate/tests/string/memset_0.c index f87d8629005..bb58f3d9c3a 100644 --- a/src/plugins/instantiate/tests/string/memset_0.c +++ b/src/plugins/instantiate/tests/string/memset_0.c @@ -62,3 +62,8 @@ void with_void(void* dest){ void* res = memset(dest, 0, 10); memset(res, 0, 10); } + +void with_null_or_int(void){ + memset(NULL, 0, 10); + memset((int*) 42, 0, 10); +} diff --git a/src/plugins/instantiate/tests/string/memset_FF.c b/src/plugins/instantiate/tests/string/memset_FF.c index 45b8e49cd11..68f3253fc58 100644 --- a/src/plugins/instantiate/tests/string/memset_FF.c +++ b/src/plugins/instantiate/tests/string/memset_FF.c @@ -88,3 +88,8 @@ void with_void(void* dest){ void* res = memset(dest, 0xFF, 10); memset(res, 0xFF, 10); } + +void with_null_or_int(void){ + memset(NULL, 0xFF, 10); + memset((int*) 42, 0xFF, 10); +} diff --git a/src/plugins/instantiate/tests/string/memset_value.c b/src/plugins/instantiate/tests/string/memset_value.c index 654466dbc2f..ad966713db9 100644 --- a/src/plugins/instantiate/tests/string/memset_value.c +++ b/src/plugins/instantiate/tests/string/memset_value.c @@ -61,4 +61,9 @@ void with_void(void* dest, int value){ void with_incomplete(struct incomplete* dest, int value){ struct incomplete * res = memset(dest, value, 10); memset(res, value, 10); -} \ No newline at end of file +} + +void with_null_or_int(int value){ + memset(NULL, value, 10); + memset((int*) 42, value, 10); +} diff --git a/src/plugins/instantiate/tests/string/oracle/memcmp.res.oracle b/src/plugins/instantiate/tests/string/oracle/memcmp.res.oracle index 18ada799c0a..856300f9ad0 100644 --- a/src/plugins/instantiate/tests/string/oracle/memcmp.res.oracle +++ b/src/plugins/instantiate/tests/string/oracle/memcmp.res.oracle @@ -1,6 +1,10 @@ [kernel] Parsing tests/string/memcmp.c (with preprocessing) [instantiate] tests/string/memcmp.c:31: Warning: Ignore call: not well typed [instantiate] tests/string/memcmp.c:36: Warning: Ignore call: not well typed +[instantiate] tests/string/memcmp.c:40: Warning: Ignore call: not well typed +[instantiate] tests/string/memcmp.c:41: Warning: Ignore call: not well typed +[instantiate] tests/string/memcmp.c:42: Warning: Ignore call: not well typed +[instantiate] tests/string/memcmp.c:43: Warning: Ignore call: not well typed /* Generated by Frama-C */ #include "stddef.h" #include "string.h" @@ -159,6 +163,17 @@ int with_incomplete(struct incomplete *s1, struct incomplete *s2, int n) return tmp; } +void with_null_or_int(int * /*[10]*/ p) +{ + memcmp((void const *)0,(void const *)p,(unsigned int)10 * sizeof(int)); + memcmp((void const *)p,(void const *)0,(unsigned int)10 * sizeof(int)); + memcmp((void const *)((int const *)42),(void const *)p, + (unsigned int)10 * sizeof(int)); + memcmp((void const *)p,(void const *)((int const *)42), + (unsigned int)10 * sizeof(int)); + return; +} + [kernel] Parsing tests/string/result/memcmp.c (with preprocessing) /* Generated by Frama-C */ @@ -328,4 +343,15 @@ int with_incomplete(struct incomplete *s1, struct incomplete *s2, int n) return tmp; } +void with_null_or_int(int *p) +{ + memcmp((void const *)0,(void const *)p,(unsigned int)10 * sizeof(int)); + memcmp((void const *)p,(void const *)0,(unsigned int)10 * sizeof(int)); + memcmp((void const *)((int const *)42),(void const *)p, + (unsigned int)10 * sizeof(int)); + memcmp((void const *)p,(void const *)((int const *)42), + (unsigned int)10 * sizeof(int)); + return; +} + diff --git a/src/plugins/instantiate/tests/string/oracle/memcpy.res.oracle b/src/plugins/instantiate/tests/string/oracle/memcpy.res.oracle index 78076d88eb1..35a4b88ca8f 100644 --- a/src/plugins/instantiate/tests/string/oracle/memcpy.res.oracle +++ b/src/plugins/instantiate/tests/string/oracle/memcpy.res.oracle @@ -3,6 +3,10 @@ [instantiate] tests/string/memcpy.c:37: Warning: Ignore call: not well typed [instantiate] tests/string/memcpy.c:42: Warning: Ignore call: not well typed [instantiate] tests/string/memcpy.c:43: Warning: Ignore call: not well typed +[instantiate] tests/string/memcpy.c:47: Warning: Ignore call: not well typed +[instantiate] tests/string/memcpy.c:48: Warning: Ignore call: not well typed +[instantiate] tests/string/memcpy.c:49: Warning: Ignore call: not well typed +[instantiate] tests/string/memcpy.c:50: Warning: Ignore call: not well typed /* Generated by Frama-C */ #include "stddef.h" #include "string.h" @@ -173,6 +177,15 @@ void with_incomplete(struct incomplete *src, struct incomplete *dest, int n) return; } +void with_null_or_int(int * /*[10]*/ p) +{ + memcpy((void *)0,(void const *)p,(unsigned int)10 * sizeof(int)); + memcpy((void *)p,(void const *)0,(unsigned int)10 * sizeof(int)); + memcpy((void *)((int *)42),(void const *)p,(unsigned int)10 * sizeof(int)); + memcpy((void *)p,(void const *)((int *)42),(unsigned int)10 * sizeof(int)); + return; +} + [kernel] Parsing tests/string/result/memcpy.c (with preprocessing) /* Generated by Frama-C */ @@ -356,4 +369,13 @@ void with_incomplete(struct incomplete *src, struct incomplete *dest, int n) return; } +void with_null_or_int(int *p) +{ + memcpy((void *)0,(void const *)p,(unsigned int)10 * sizeof(int)); + memcpy((void *)p,(void const *)0,(unsigned int)10 * sizeof(int)); + memcpy((void *)((int *)42),(void const *)p,(unsigned int)10 * sizeof(int)); + memcpy((void *)p,(void const *)((int *)42),(unsigned int)10 * sizeof(int)); + return; +} + diff --git a/src/plugins/instantiate/tests/string/oracle/memmove.res.oracle b/src/plugins/instantiate/tests/string/oracle/memmove.res.oracle index 15c80507c4a..b53227bdabf 100644 --- a/src/plugins/instantiate/tests/string/oracle/memmove.res.oracle +++ b/src/plugins/instantiate/tests/string/oracle/memmove.res.oracle @@ -3,6 +3,10 @@ [instantiate] tests/string/memmove.c:37: Warning: Ignore call: not well typed [instantiate] tests/string/memmove.c:42: Warning: Ignore call: not well typed [instantiate] tests/string/memmove.c:43: Warning: Ignore call: not well typed +[instantiate] tests/string/memmove.c:47: Warning: Ignore call: not well typed +[instantiate] tests/string/memmove.c:48: Warning: Ignore call: not well typed +[instantiate] tests/string/memmove.c:49: Warning: Ignore call: not well typed +[instantiate] tests/string/memmove.c:50: Warning: Ignore call: not well typed /* Generated by Frama-C */ #include "stddef.h" #include "string.h" @@ -157,6 +161,15 @@ void with_incomplete(struct incomplete *src, struct incomplete *dest, int n) return; } +void with_null_or_int(int * /*[10]*/ p) +{ + memmove((void *)0,(void const *)p,(unsigned int)10 * sizeof(int)); + memmove((void *)p,(void const *)0,(unsigned int)10 * sizeof(int)); + memmove((void *)((int *)42),(void const *)p,(unsigned int)10 * sizeof(int)); + memmove((void *)p,(void const *)((int *)42),(unsigned int)10 * sizeof(int)); + return; +} + [kernel] Parsing tests/string/result/memmove.c (with preprocessing) /* Generated by Frama-C */ @@ -324,4 +337,13 @@ void with_incomplete(struct incomplete *src, struct incomplete *dest, int n) return; } +void with_null_or_int(int *p) +{ + memmove((void *)0,(void const *)p,(unsigned int)10 * sizeof(int)); + memmove((void *)p,(void const *)0,(unsigned int)10 * sizeof(int)); + memmove((void *)((int *)42),(void const *)p,(unsigned int)10 * sizeof(int)); + memmove((void *)p,(void const *)((int *)42),(unsigned int)10 * sizeof(int)); + return; +} + diff --git a/src/plugins/instantiate/tests/string/oracle/memset_0.res.oracle b/src/plugins/instantiate/tests/string/oracle/memset_0.res.oracle index 368076b562a..af6a60f7c80 100644 --- a/src/plugins/instantiate/tests/string/oracle/memset_0.res.oracle +++ b/src/plugins/instantiate/tests/string/oracle/memset_0.res.oracle @@ -1,6 +1,8 @@ [kernel] Parsing tests/string/memset_0.c (with preprocessing) [instantiate] tests/string/memset_0.c:62: Warning: Ignore call: not well typed [instantiate] tests/string/memset_0.c:63: Warning: Ignore call: not well typed +[instantiate] tests/string/memset_0.c:67: Warning: Ignore call: not well typed +[instantiate] tests/string/memset_0.c:68: Warning: Ignore call: not well typed /* Generated by Frama-C */ #include "stddef.h" #include "string.h" @@ -264,6 +266,13 @@ void with_void(void *dest) return; } +void with_null_or_int(void) +{ + memset((void *)0,0,(unsigned int)10); + memset((void *)((int *)42),0,(unsigned int)10); + return; +} + [kernel] Parsing tests/string/result/memset_0.c (with preprocessing) /* Generated by Frama-C */ @@ -535,4 +544,11 @@ void with_void(void *dest) return; } +void with_null_or_int(void) +{ + memset((void *)0,0,(unsigned int)10); + memset((void *)((int *)42),0,(unsigned int)10); + return; +} + diff --git a/src/plugins/instantiate/tests/string/oracle/memset_FF.res.oracle b/src/plugins/instantiate/tests/string/oracle/memset_FF.res.oracle index 0054f340577..91a1e42f767 100644 --- a/src/plugins/instantiate/tests/string/oracle/memset_FF.res.oracle +++ b/src/plugins/instantiate/tests/string/oracle/memset_FF.res.oracle @@ -1,6 +1,8 @@ [kernel] Parsing tests/string/memset_FF.c (with preprocessing) [instantiate] tests/string/memset_FF.c:88: Warning: Ignore call: not well typed [instantiate] tests/string/memset_FF.c:89: Warning: Ignore call: not well typed +[instantiate] tests/string/memset_FF.c:93: Warning: Ignore call: not well typed +[instantiate] tests/string/memset_FF.c:94: Warning: Ignore call: not well typed /* Generated by Frama-C */ #include "stddef.h" #include "string.h" @@ -401,6 +403,13 @@ void with_void(void *dest) return; } +void with_null_or_int(void) +{ + memset((void *)0,0xFF,(unsigned int)10); + memset((void *)((int *)42),0xFF,(unsigned int)10); + return; +} + [kernel] Parsing tests/string/result/memset_FF.c (with preprocessing) /* Generated by Frama-C */ @@ -811,4 +820,11 @@ void with_void(void *dest) return; } +void with_null_or_int(void) +{ + memset((void *)0,0xFF,(unsigned int)10); + memset((void *)((int *)42),0xFF,(unsigned int)10); + return; +} + diff --git a/src/plugins/instantiate/tests/string/oracle/memset_value.res.oracle b/src/plugins/instantiate/tests/string/oracle/memset_value.res.oracle index f68d49c8e42..8609a955121 100644 --- a/src/plugins/instantiate/tests/string/oracle/memset_value.res.oracle +++ b/src/plugins/instantiate/tests/string/oracle/memset_value.res.oracle @@ -31,6 +31,10 @@ Ignore call: not well typed [instantiate] tests/string/memset_value.c:63: Warning: Ignore call: not well typed +[instantiate] tests/string/memset_value.c:67: Warning: + Ignore call: not well typed +[instantiate] tests/string/memset_value.c:68: Warning: + Ignore call: not well typed /* Generated by Frama-C */ #include "stddef.h" #include "string.h" @@ -179,6 +183,13 @@ void with_incomplete(struct incomplete *dest, int value) return; } +void with_null_or_int(int value) +{ + memset((void *)0,value,(unsigned int)10); + memset((void *)((int *)42),value,(unsigned int)10); + return; +} + [kernel] Parsing tests/string/result/memset_value.c (with preprocessing) /* Generated by Frama-C */ @@ -334,4 +345,11 @@ void with_incomplete(struct incomplete *dest, int value) return; } +void with_null_or_int(int value) +{ + memset((void *)0,value,(unsigned int)10); + memset((void *)((int *)42),value,(unsigned int)10); + return; +} + -- GitLab From 48356f3732fca021d9a4732f859d0f0c73b2cb92 Mon Sep 17 00:00:00 2001 From: Allan Blanchard <allan.blanchard@cea.fr> Date: Wed, 25 Mar 2020 17:13:14 +0100 Subject: [PATCH 113/218] [Instantiate] Simplifies internal tables management --- .../instantiate/instantiator_builder.ml | 19 ++++++++++--------- .../instantiate/instantiator_builder.mli | 5 ++--- .../instantiate/tests/plugin/ast_clear.c | 9 +++++++++ .../tests/plugin/oracle/ast_clear.res.oracle | 2 ++ src/plugins/instantiate/transform.ml | 15 ++++++++------- 5 files changed, 31 insertions(+), 19 deletions(-) create mode 100644 src/plugins/instantiate/tests/plugin/ast_clear.c create mode 100644 src/plugins/instantiate/tests/plugin/oracle/ast_clear.res.oracle diff --git a/src/plugins/instantiate/instantiator_builder.ml b/src/plugins/instantiate/instantiator_builder.ml index df9028d122d..6b98b3ad9d2 100644 --- a/src/plugins/instantiate/instantiator_builder.ml +++ b/src/plugins/instantiate/instantiator_builder.ml @@ -46,10 +46,9 @@ module type Instantiator = sig val retype_args: override_key -> exp list -> exp list val get_override: override_key -> fundec val get_kfs: unit -> kernel_function list - val mark_as_computed: ?project:Project.t -> unit -> unit + val clear: unit -> unit end - let build_body caller callee args_generator = let open Extlib in let loc = Cil_datatype.Location.unknown in @@ -68,12 +67,13 @@ let build_body caller callee args_generator = module Make_instantiator (G: Generator_sig) = struct include G module Enabled = Options.NewInstantiator (G) - module Cache = State_builder.Hashtbl (G.Hashtbl) (Cil_datatype.Fundec) - (struct - let size = 5 - let dependencies = [] - let name = "Instantiator." ^ G.function_name - end) + module Cache = struct + let tbl = G.Hashtbl.create 13 + let find = G.Hashtbl.find tbl + let add = G.Hashtbl.add tbl + let fold f = G.Hashtbl.fold f tbl + let clear () = G.Hashtbl.clear tbl + end let make_fundec key = let open Globals.Functions in @@ -113,5 +113,6 @@ module Make_instantiator (G: Generator_sig) = struct let get_kfs () = Cache.fold (fun _ fd l -> Globals.Functions.get fd.svar :: l) [] - let mark_as_computed = Cache.mark_as_computed + let clear () = + Cache.clear () end diff --git a/src/plugins/instantiate/instantiator_builder.mli b/src/plugins/instantiate/instantiator_builder.mli index e2432608275..87c268d2d49 100644 --- a/src/plugins/instantiate/instantiator_builder.mli +++ b/src/plugins/instantiate/instantiator_builder.mli @@ -123,10 +123,9 @@ module type Instantiator = sig *) val get_kfs: unit -> kernel_function list - (** [mark_as_computed ?project ()] applies the [mark_as_computed] on the - internal table. + (** [clear ()] clears the internal table of the instantiator. *) - val mark_as_computed: ?project:Project.t -> unit -> unit + val clear: unit -> unit end (** Generates a [Instantiator] from a [Generator_sig] adding all necessary stuff for diff --git a/src/plugins/instantiate/tests/plugin/ast_clear.c b/src/plugins/instantiate/tests/plugin/ast_clear.c new file mode 100644 index 00000000000..d3dfbb6ad2a --- /dev/null +++ b/src/plugins/instantiate/tests/plugin/ast_clear.c @@ -0,0 +1,9 @@ +/* run.config + OPT: -instantiate -then -pp-annot +*/ + +#include <string.h> + +int foo(char* s1, char* s2, size_t len){ + return memcmp(s1, s2, len) ; +} \ No newline at end of file diff --git a/src/plugins/instantiate/tests/plugin/oracle/ast_clear.res.oracle b/src/plugins/instantiate/tests/plugin/oracle/ast_clear.res.oracle new file mode 100644 index 00000000000..1a8c67bb4f4 --- /dev/null +++ b/src/plugins/instantiate/tests/plugin/oracle/ast_clear.res.oracle @@ -0,0 +1,2 @@ +[kernel] Parsing tests/plugin/ast_clear.c (with preprocessing) +[kernel] Parsing tests/plugin/ast_clear.c (with preprocessing) diff --git a/src/plugins/instantiate/transform.ml b/src/plugins/instantiate/transform.ml index 28f7a1ca811..c1f0f29d170 100644 --- a/src/plugins/instantiate/transform.ml +++ b/src/plugins/instantiate/transform.ml @@ -29,12 +29,6 @@ let register (module G: Generator_sig) = let module Instantiator = Make_instantiator(G) in Hashtbl.add base G.function_name (module Instantiator) -let mark_as_computed () = - let mark_as_computed _ instantiator = - let module I = (val instantiator: Instantiator) in I.mark_as_computed () - in - Hashtbl.iter mark_as_computed base - let get_kfs () = let get_kfs _ instantiator = let module I = (val instantiator: Instantiator) in @@ -43,6 +37,13 @@ let get_kfs () = in Hashtbl.fold (fun k v l -> (get_kfs k v) @ l) base [] +let clear () = + let clear _ instantiator = + let module I = (val instantiator: Instantiator) in + I.clear () + in + Hashtbl.iter clear base + module VISet = Cil_datatype.Varinfo.Hptset class transformer = object(self) @@ -55,7 +56,6 @@ class transformer = object(self) let post f = Ast.mark_as_changed () ; Ast.mark_as_grown () ; - mark_as_computed () ; f in Cil.DoChildrenPost post @@ -158,5 +158,6 @@ let compute_statuses_all_kfs () = List.iter compute_comp_disj_statuses kfs let transform file = + clear () ; Visitor.visitFramacFile (new transformer) file ; compute_statuses_all_kfs () -- GitLab From 91b9f160c66dc0c00abd37a51ac8c4f9e60778d0 Mon Sep 17 00:00:00 2001 From: Allan Blanchard <allan.blanchard@cea.fr> Date: Fri, 27 Mar 2020 12:10:44 +0100 Subject: [PATCH 114/218] [Instantiate] Adds the called function to typing function --- src/plugins/instantiate/Instantiate.mli | 15 ++++++++------- .../instantiate/instantiator_builder.ml | 8 ++++---- .../instantiate/instantiator_builder.mli | 19 ++++++++++--------- src/plugins/instantiate/stdlib/calloc.ml | 10 +++++----- src/plugins/instantiate/stdlib/free.ml | 8 ++++---- src/plugins/instantiate/stdlib/malloc.ml | 10 +++++----- src/plugins/instantiate/string/mem_utils.ml | 9 ++++++--- src/plugins/instantiate/string/mem_utils.mli | 6 +++--- src/plugins/instantiate/string/memset.ml | 8 ++++---- .../api/external_instantiator_registration.ml | 4 ++-- src/plugins/instantiate/transform.ml | 4 ++-- 11 files changed, 53 insertions(+), 48 deletions(-) diff --git a/src/plugins/instantiate/Instantiate.mli b/src/plugins/instantiate/Instantiate.mli index 061723344f1..d47de410b8f 100644 --- a/src/plugins/instantiate/Instantiate.mli +++ b/src/plugins/instantiate/Instantiate.mli @@ -41,19 +41,20 @@ module Instantiator_builder: sig (** Name of the implemented instantiator function *) val function_name: string - (** [well_typed_call ret args] must return true if and only if the + (** [well_typed_call ret fct args] must return true if and only if the corresponding call is well typed in the sens that the generator can produce a function override for the corresponding return value and parameters, according to their types and/or values. *) - val well_typed_call: lval option -> exp list -> bool + val well_typed_call: lval option -> varinfo -> exp list -> bool - (** [key_from_call ret args] must return an identifier for the corresponding - call. [key_from_call ret1 args1] and [key_from_call ret2 args2] must equal - if and only if the same override function can be used for both call. Any - call for which [well_typed_call] returns true must be able to give a key. + (** [key_from_call ret fct args] must return an identifier for the + corresponding call. [key_from_call ret1 fct1 args1] and + [key_from_call ret2 fct2 args2] must equal if and only if the same + override function can be used for both call. Any call for which + [well_typed_call] returns true must be able to give a key. *) - val key_from_call: lval option -> exp list -> override_key + val key_from_call: lval option -> varinfo -> exp list -> override_key (** [retype_args key args] must returns a new argument list compatible with the function identified by [override_key]. [args] is the list of arguments diff --git a/src/plugins/instantiate/instantiator_builder.ml b/src/plugins/instantiate/instantiator_builder.ml index 6b98b3ad9d2..74242ed7bb5 100644 --- a/src/plugins/instantiate/instantiator_builder.ml +++ b/src/plugins/instantiate/instantiator_builder.ml @@ -28,8 +28,8 @@ module type Generator_sig = sig type override_key = Hashtbl.key val function_name: string - val well_typed_call: lval option -> exp list -> bool - val key_from_call: lval option -> exp list -> override_key + val well_typed_call: lval option -> varinfo -> exp list -> bool + val key_from_call: lval option -> varinfo -> exp list -> override_key val retype_args: override_key -> exp list -> exp list val args_for_original: override_key -> exp list -> exp list val generate_prototype: override_key -> (string * typ) @@ -41,8 +41,8 @@ module type Instantiator = sig type override_key val function_name: string - val well_typed_call: lval option -> exp list -> bool - val key_from_call: lval option -> exp list -> override_key + val well_typed_call: lval option -> varinfo -> exp list -> bool + val key_from_call: lval option -> varinfo -> exp list -> override_key val retype_args: override_key -> exp list -> exp list val get_override: override_key -> fundec val get_kfs: unit -> kernel_function list diff --git a/src/plugins/instantiate/instantiator_builder.mli b/src/plugins/instantiate/instantiator_builder.mli index 87c268d2d49..b0eb2f79fcf 100644 --- a/src/plugins/instantiate/instantiator_builder.mli +++ b/src/plugins/instantiate/instantiator_builder.mli @@ -40,19 +40,20 @@ module type Generator_sig = sig (** Name of the implemented function *) val function_name: string - (** [well_typed_call ret args] must return true if and only if the + (** [well_typed_call ret fct args] must return true if and only if the corresponding call is well typed in the sens that the generator can produce a function override for the corresponding return value and parameters, according to their types and/or values. *) - val well_typed_call: lval option -> exp list -> bool + val well_typed_call: lval option -> varinfo -> exp list -> bool - (** [key_from_call ret args] must return an identifier for the corresponding - call. [key_from_call ret1 args1] and [key_from_call ret2 args2] must equal - if and only if the same override function can be used for both call. Any - call for which [well_typed_call] returns true must be able to give a key. + (** [key_from_call ret fct args] must return an identifier for the + corresponding call. [key_from_call ret1 fct1 args1] and + [key_from_call ret2 fct2 args2] must equal if and only if the same + override function can be used for both call. Any call for which + [well_typed_call] returns true must be able to give a key. *) - val key_from_call: lval option -> exp list -> override_key + val key_from_call: lval option -> varinfo -> exp list -> override_key (** [retype_args key args] must returns a new argument list compatible with the function identified by [override_key]. [args] is the list of arguments @@ -105,9 +106,9 @@ module type Instantiator = sig (** Same as [Generator_sig.override_key] *) val function_name: string (** Same as [Generator_sig.override_key] *) - val well_typed_call: lval option -> exp list -> bool + val well_typed_call: lval option -> varinfo -> exp list -> bool (** Same as [Generator_sig.override_key] *) - val key_from_call: lval option -> exp list -> override_key + val key_from_call: lval option -> varinfo -> exp list -> override_key (** Same as [Generator_sig.override_key] *) val retype_args: override_key -> exp list -> exp list diff --git a/src/plugins/instantiate/stdlib/calloc.ml b/src/plugins/instantiate/stdlib/calloc.ml index 1e064706c5b..89af52fd24d 100644 --- a/src/plugins/instantiate/stdlib/calloc.ml +++ b/src/plugins/instantiate/stdlib/calloc.ml @@ -131,21 +131,21 @@ let generate_prototype alloc_type = ] in name, (TFun((ptr_of alloc_type), Some params, false, [])) -let well_typed_call ret args = +let well_typed_call ret fct args = match ret, args with - | Some ret, [ _ ; _ ] -> + | Some ret, [ _ ; _ ] when Cil.hasAttribute "fc_stdlib" fct.vattr -> let t = Cil.typeOfLval ret in Cil.isPointerType t && not (Cil.isVoidPtrType t) && Cil.isCompleteType (Cil.typeOf_pointed t) | _ -> false -let key_from_call ret _ = +let key_from_call ret fct _ = match ret with - | Some ret -> + | Some ret when Cil.hasAttribute "fc_stdlib" fct.vattr -> let ret_t = Cil.unrollTypeDeep (Cil.typeOfLval ret) in let ret_t = Cil.type_remove_qualifier_attributes_deep ret_t in Cil.typeOf_pointed ret_t - | None -> unexpected "trying to generate a key on an ill-typed call" + | _ -> unexpected "trying to generate a key on an ill-typed call" let retype_args _typ args = args let args_for_original _typ args = args diff --git a/src/plugins/instantiate/stdlib/free.ml b/src/plugins/instantiate/stdlib/free.ml index 7ef4c509bb2..ec63f84f4aa 100644 --- a/src/plugins/instantiate/stdlib/free.ml +++ b/src/plugins/instantiate/stdlib/free.ml @@ -83,16 +83,16 @@ let generate_prototype alloc_t = ] in name, (TFun(Cil.voidType, Some params, false, [])) -let well_typed_call _ret args = +let well_typed_call _ret fct args = match args with - | [ ptr ] -> + | [ ptr ] when Cil.hasAttribute "fc_stdlib" fct.vattr -> let t = Cil.typeOf (Cil.stripCasts ptr) in Cil.isPointerType t && not (Cil.isVoidPtrType t) | _ -> false -let key_from_call _ret args = +let key_from_call _ret fct args = match args with - | [ ptr ] -> + | [ ptr ] when Cil.hasAttribute "fc_stdlib" fct.vattr -> let ptr = Cil.stripCasts ptr in let ptr_t = Cil.unrollTypeDeep (Cil.typeOf ptr) in let ptr_t = Cil.type_remove_qualifier_attributes_deep ptr_t in diff --git a/src/plugins/instantiate/stdlib/malloc.ml b/src/plugins/instantiate/stdlib/malloc.ml index 16521b530ae..fbf3374bcdd 100644 --- a/src/plugins/instantiate/stdlib/malloc.ml +++ b/src/plugins/instantiate/stdlib/malloc.ml @@ -70,21 +70,21 @@ let generate_prototype alloc_t = ] in name, (TFun((ptr_of alloc_t), Some params, false, [])) -let well_typed_call ret args = +let well_typed_call ret fct args = match ret, args with - | Some ret, [ _ ] -> + | Some ret, [ _ ] when Cil.hasAttribute "fc_stdlib" fct.vattr -> let t = Cil.typeOfLval ret in Cil.isPointerType t && not (Cil.isVoidPtrType t) && Cil.isCompleteType (Cil.typeOf_pointed t) | _ -> false -let key_from_call ret _ = +let key_from_call ret fct _ = match ret with - | Some ret -> + | Some ret when Cil.hasAttribute "fc_stdlib" fct.vattr -> let ret_t = Cil.unrollTypeDeep (Cil.typeOfLval ret) in let ret_t = Cil.type_remove_qualifier_attributes_deep ret_t in Cil.typeOf_pointed ret_t - | None -> unexpected "trying to generate a key on an ill-typed call" + | _ -> unexpected "trying to generate a key on an ill-typed call" let retype_args _typ args = args let args_for_original _typ args = args diff --git a/src/plugins/instantiate/string/mem_utils.ml b/src/plugins/instantiate/string/mem_utils.ml index 9d88bb79b94..02ccd376309 100644 --- a/src/plugins/instantiate/string/mem_utils.ml +++ b/src/plugins/instantiate/string/mem_utils.ml @@ -128,9 +128,10 @@ struct let name = F.name ^ "_" ^ (string_of_typ t) in name, ftype - let well_typed_call lval args = + let well_typed_call lval fct args = let _, ps = F.prototype () in if List.length args <> List.length ps then false + else if not (Cil.hasAttribute "fc_stdlib" fct.vattr) then false else let extract e = function | _, (CPtr | Ptr), _ -> exp_type_of_pointed e @@ -157,10 +158,12 @@ struct in List.map2 retype args ps - let key_from_call _ret args = + let key_from_call _ret fct args = let _, ps = F.prototype () in match ps, args with - | (_, (Ptr|CPtr), _)::ps, fst::args when List.(length ps = length args) -> + | (_, (Ptr|CPtr), _) :: ps, fst :: args + when List.(length ps = length args) + && Cil.hasAttribute "fc_stdlib" fct.vattr -> begin match exp_type_of_pointed fst with | Value_of t -> t | _ -> diff --git a/src/plugins/instantiate/string/mem_utils.mli b/src/plugins/instantiate/string/mem_utils.mli index d4b205be01e..fca57bd58d0 100644 --- a/src/plugins/instantiate/string/mem_utils.mli +++ b/src/plugins/instantiate/string/mem_utils.mli @@ -44,9 +44,9 @@ end module Make (F: Function) : sig val generate_function_type : typ -> typ val generate_prototype : typ -> string * typ - val well_typed_call : lval option -> exp list -> bool - val retype_args : 'a -> exp list -> exp list - val key_from_call : 'a -> exp list -> typ + val well_typed_call : lval option -> varinfo -> exp list -> bool + val retype_args : typ -> exp list -> exp list + val key_from_call : lval option -> varinfo -> exp list -> typ end (** location -> key -> s1 -> s2 -> len -> spec_result *) diff --git a/src/plugins/instantiate/string/memset.ml b/src/plugins/instantiate/string/memset.ml index b62c37aa2ca..21e44be2106 100644 --- a/src/plugins/instantiate/string/memset.ml +++ b/src/plugins/instantiate/string/memset.ml @@ -195,8 +195,8 @@ let rec contains_union_type t = contains_union_type t | _ -> false -let well_typed_call _ret = function - | [ ptr ; value ; _ ] -> +let well_typed_call _ret fct = function + | [ ptr ; value ; _ ] when Cil.hasAttribute "fc_stdlib" fct.vattr -> begin match Mem_utils.exp_type_of_pointed ptr, memset_value value with | (No_pointed | Of_null _) , _ -> false | Value_of t , _ when any_char_composed_type t -> true @@ -208,8 +208,8 @@ let well_typed_call _ret = function end | _ -> false -let key_from_call _ret = function - | [ ptr ; value ; _ ] -> +let key_from_call _ret fct = function + | [ ptr ; value ; _ ] when Cil.hasAttribute "fc_stdlib" fct.vattr -> begin match Mem_utils.exp_type_of_pointed ptr, memset_value value with | Value_of t, _ when any_char_composed_type t -> t, None | Value_of t, value when not (contains_union_type t) -> t, value diff --git a/src/plugins/instantiate/tests/api/external_instantiator_registration.ml b/src/plugins/instantiate/tests/api/external_instantiator_registration.ml index b800bd1efbd..aa3c9b5c6a4 100644 --- a/src/plugins/instantiate/tests/api/external_instantiator_registration.ml +++ b/src/plugins/instantiate/tests/api/external_instantiator_registration.ml @@ -1,12 +1,12 @@ let function_name = "mine" -let well_typed_call _ = function +let well_typed_call _ _ = function | [ e ] -> let t = Cil.typeOf(Cil.stripCasts e) in not (Cil.isVoidPtrType t) && Cil.isPointerType t | _ -> false -let key_from_call _ = function +let key_from_call _ _ = function | [ e ] -> let t = Cil.typeOf(Cil.stripCasts e) in Cil.typeOf_pointed t diff --git a/src/plugins/instantiate/transform.ml b/src/plugins/instantiate/transform.ml index c1f0f29d170..4970a5913e2 100644 --- a/src/plugins/instantiate/transform.ml +++ b/src/plugins/instantiate/transform.ml @@ -90,8 +90,8 @@ class transformer = object(self) method private replace_call (lval, fct, args) = try let module I = (val (self#find_enabled_instantiator fct): Instantiator) in - if I.well_typed_call lval args then - let key = I.key_from_call lval args in + if I.well_typed_call lval fct args then + let key = I.key_from_call lval fct args in let fundec = I.get_override key in let new_args = I.retype_args key args in Queue.add fundec used_instantiator_last_kf ; -- GitLab From 638dca648dba9c79e2bd52869645b756f58311d5 Mon Sep 17 00:00:00 2001 From: Allan Blanchard <allan.blanchard@cea.fr> Date: Fri, 27 Mar 2020 16:41:28 +0100 Subject: [PATCH 115/218] [Instantiate] Introduces globals variables table --- src/plugins/instantiate/Instantiate.mli | 11 +++ src/plugins/instantiate/Makefile.in | 4 +- src/plugins/instantiate/global_vars.ml | 40 ++++++++++ src/plugins/instantiate/global_vars.mli | 42 +++++++++++ src/plugins/instantiate/stdlib/basic_alloc.ml | 4 +- .../instantiate/tests/plugin/needs_global.i | 14 ++++ .../instantiate/tests/plugin/needs_globals.ml | 75 +++++++++++++++++++ .../plugin/oracle/needs_global.res.oracle | 34 +++++++++ src/plugins/instantiate/transform.ml | 2 + 9 files changed, 223 insertions(+), 3 deletions(-) create mode 100644 src/plugins/instantiate/global_vars.ml create mode 100644 src/plugins/instantiate/global_vars.mli create mode 100644 src/plugins/instantiate/tests/plugin/needs_global.i create mode 100644 src/plugins/instantiate/tests/plugin/needs_globals.ml create mode 100644 src/plugins/instantiate/tests/plugin/oracle/needs_global.res.oracle diff --git a/src/plugins/instantiate/Instantiate.mli b/src/plugins/instantiate/Instantiate.mli index d47de410b8f..4af9d03fc53 100644 --- a/src/plugins/instantiate/Instantiate.mli +++ b/src/plugins/instantiate/Instantiate.mli @@ -100,3 +100,14 @@ module Transform: sig *) val register: (module Instantiator_builder.Generator_sig) -> unit end + +module Global_vars:sig + (** [get t ghost storage name] searches for an existing variable [name]. If this + variable does not exists, it is created with the specified type [t], [ghost] + status and [storage]. + + The obtained varinfo does not need to be registered, it will be done by the + transformation. + *) + val get: typ -> bool -> storage -> string -> varinfo +end \ No newline at end of file diff --git a/src/plugins/instantiate/Makefile.in b/src/plugins/instantiate/Makefile.in index a8fc2764589..97c0b467e45 100644 --- a/src/plugins/instantiate/Makefile.in +++ b/src/plugins/instantiate/Makefile.in @@ -56,7 +56,9 @@ PLUGIN_EXTRA_DIRS:=\ stdlib PLUGIN_CMI := PLUGIN_CMO := \ - options basic_blocks instantiator_builder transform register \ + options basic_blocks \ + global_vars instantiator_builder \ + transform register \ $(SRC_STRING) \ $(SRC_STDLIB) diff --git a/src/plugins/instantiate/global_vars.ml b/src/plugins/instantiate/global_vars.ml new file mode 100644 index 00000000000..379443e789b --- /dev/null +++ b/src/plugins/instantiate/global_vars.ml @@ -0,0 +1,40 @@ +(**************************************************************************) +(* *) +(* This file is part of Frama-C. *) +(* *) +(* Copyright (C) 2007-2020 *) +(* CEA (Commissariat à l'énergie atomique et aux énergies *) +(* alternatives) *) +(* *) +(* you can redistribute it and/or modify it under the terms of the GNU *) +(* Lesser General Public License as published by the Free Software *) +(* Foundation, version 2.1. *) +(* *) +(* It is distributed in the hope that it will be useful, *) +(* but WITHOUT ANY WARRANTY; without even the implied warranty of *) +(* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *) +(* GNU Lesser General Public License for more details. *) +(* *) +(* See the GNU Lesser General Public License version 2.1 *) +(* for more details (enclosed in the file licenses/LGPLv2.1). *) +(* *) +(**************************************************************************) + +module Table = Datatype.String.Hashtbl +let table = Table.create 13 + +let get typ ghost storage name = + if Table.mem table name then Table.find table name + else begin + try Globals.Vars.find_from_astinfo name VGlobal + with Not_found -> + let vi = Cil.makeVarinfo ~ghost true false name typ in + vi.vstorage <- storage ; + Table.add table name vi ; + vi + end + +let clear () = Table.clear table + +let globals loc = + Table.fold (fun _ x l -> Cil_types.GVarDecl(x, loc) :: l) table [] diff --git a/src/plugins/instantiate/global_vars.mli b/src/plugins/instantiate/global_vars.mli new file mode 100644 index 00000000000..88b711593ce --- /dev/null +++ b/src/plugins/instantiate/global_vars.mli @@ -0,0 +1,42 @@ +(**************************************************************************) +(* *) +(* This file is part of Frama-C. *) +(* *) +(* Copyright (C) 2007-2020 *) +(* CEA (Commissariat à l'énergie atomique et aux énergies *) +(* alternatives) *) +(* *) +(* you can redistribute it and/or modify it under the terms of the GNU *) +(* Lesser General Public License as published by the Free Software *) +(* Foundation, version 2.1. *) +(* *) +(* It is distributed in the hope that it will be useful, *) +(* but WITHOUT ANY WARRANTY; without even the implied warranty of *) +(* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *) +(* GNU Lesser General Public License for more details. *) +(* *) +(* See the GNU Lesser General Public License version 2.1 *) +(* for more details (enclosed in the file licenses/LGPLv2.1). *) +(* *) +(**************************************************************************) + +open Cil_types + +(** The purpose of this module is to create global variables when it is needed + by instantiation modules. +*) + +(** [get t ghost storage name] searches for an existing variable [name]. If this + variable does not exists, it is created with the specified type [t], [ghost] + status and [storage]. + + The obtained varinfo does not need to be registered, it will be done by the + transformation. +*) +val get: typ -> bool -> storage -> string -> varinfo + +(** Clears internal tables *) +val clear: unit -> unit + +(** Creates a list of global for the variables that have been created *) +val globals: location -> global list diff --git a/src/plugins/instantiate/stdlib/basic_alloc.ml b/src/plugins/instantiate/stdlib/basic_alloc.ml index 41679ef1d11..d2bb11bd72d 100644 --- a/src/plugins/instantiate/stdlib/basic_alloc.ml +++ b/src/plugins/instantiate/stdlib/basic_alloc.ml @@ -61,8 +61,8 @@ let isnt_allocable ?loc size = new_predicate { p with pred_name = [ "allocable" ]} let heap_status () = - let heap_status = Globals.Vars.find_from_astinfo "__fc_heap_status" VGlobal in - Basic_blocks.cvar_to_tvar (heap_status) + let vi = Global_vars.get Cil.intType true Extern "__fc_heap_status" in + Basic_blocks.cvar_to_tvar vi let assigns_result ?loc typ deps = let heap_status = new_identified_term (heap_status ()) in diff --git a/src/plugins/instantiate/tests/plugin/needs_global.i b/src/plugins/instantiate/tests/plugin/needs_global.i new file mode 100644 index 00000000000..dfd53797477 --- /dev/null +++ b/src/plugins/instantiate/tests/plugin/needs_global.i @@ -0,0 +1,14 @@ +/* run.config + OPT: -load-script tests/plugin/needs_globals.ml -instantiate -check -print +*/ + +int i ; // needed for already_one specifciation +void already_one(void* parameter) ; + +void needs_new(void* parameter) ; + +void foo(void){ + int *i ; + already_one(i); + needs_new(i); +} diff --git a/src/plugins/instantiate/tests/plugin/needs_globals.ml b/src/plugins/instantiate/tests/plugin/needs_globals.ml new file mode 100644 index 00000000000..c76373900f5 --- /dev/null +++ b/src/plugins/instantiate/tests/plugin/needs_globals.ml @@ -0,0 +1,75 @@ +let well_typed_call _ _ = function + | [ e ] -> + let t = Cil.typeOf(Cil.stripCasts e) in + not (Cil.isVoidPtrType t) && Cil.isPointerType t + | _ -> false + +let key_from_call _ _ = function + | [ e ] -> Cil.typeOf_pointed (Cil.typeOf(Cil.stripCasts e)) + | _ -> assert false + +let retype_args _ = function + | [ e ] -> [ Cil.stripCasts e ] + | _ -> assert false + +let generate_function_type t = + let params = [("x", Cil_types.TPtr(t, []), [])] in + Cil_types.TFun(Cil.voidType, Some params, false, []) + +let generate_prototype function_name t = + let fun_type = generate_function_type t in + let name = function_name ^ "_" ^ match t with + | Cil_types.TInt(_) -> "int" + | _ -> assert false (* nothing else in our test *) + in + name, fun_type + +let generate_spec needed _ _ _ = + let open Cil_types in + let open Logic_const in + let open Instantiate.Global_vars in + let vi = get Cil.floatType true Cil_types.Extern needed in + let t = tvar (Cil.cvar_to_lvar vi) in + let assigns = + Cil_types.Writes [ Logic_const.new_identified_term t, From [] ] + in { + spec_behavior = [ { + b_name = Cil.default_behavior_name ; + b_requires = [] ; + b_assumes = [] ; + b_post_cond = [] ; + b_assigns = assigns ; + b_allocation = FreeAllocAny ; + b_extended = [] + } ] ; + spec_variant = None ; + spec_terminates = None ; + spec_complete_behaviors = [] ; + spec_disjoint_behaviors = [] ; + } + +let () = Instantiate.Transform.register (module struct + module Hashtbl = Cil_datatype.Typ.Hashtbl + type override_key = Hashtbl.key + + let function_name = "already_one" + let well_typed_call = well_typed_call + let key_from_call = key_from_call + let retype_args = retype_args + let generate_prototype = generate_prototype function_name + let generate_spec = generate_spec "i" + let args_for_original _ = Extlib.id + end) + +let () = Instantiate.Transform.register (module struct + module Hashtbl = Cil_datatype.Typ.Hashtbl + type override_key = Hashtbl.key + + let function_name = "needs_new" + let well_typed_call = well_typed_call + let key_from_call = key_from_call + let retype_args = retype_args + let generate_prototype = generate_prototype function_name + let generate_spec = generate_spec "j" + let args_for_original _ = Extlib.id + end) diff --git a/src/plugins/instantiate/tests/plugin/oracle/needs_global.res.oracle b/src/plugins/instantiate/tests/plugin/oracle/needs_global.res.oracle new file mode 100644 index 00000000000..0b7e5b4ccb7 --- /dev/null +++ b/src/plugins/instantiate/tests/plugin/oracle/needs_global.res.oracle @@ -0,0 +1,34 @@ +[kernel] Parsing tests/plugin/needs_global.i (no preprocessing) +/* Generated by Frama-C */ +/*@ ghost extern float j; */ + +int i; +void already_one(void *parameter); + +void needs_new(void *parameter); + +/*@ assigns j; + assigns j \from \nothing; */ +void needs_new_int(int *x) +{ + needs_new((void *)x); + return; +} + +/*@ assigns i; + assigns i \from \nothing; */ +void already_one_int(int *x) +{ + already_one((void *)x); + return; +} + +void foo(void) +{ + int *i_0; + already_one_int(i_0); + needs_new_int(i_0); + return; +} + + diff --git a/src/plugins/instantiate/transform.ml b/src/plugins/instantiate/transform.ml index 4970a5913e2..8b0f9ece40e 100644 --- a/src/plugins/instantiate/transform.ml +++ b/src/plugins/instantiate/transform.ml @@ -38,6 +38,7 @@ let get_kfs () = Hashtbl.fold (fun k v l -> (get_kfs k v) @ l) base [] let clear () = + Global_vars.clear () ; let clear _ instantiator = let module I = (val instantiator: Instantiator) in I.clear () @@ -54,6 +55,7 @@ class transformer = object(self) method! vfile _ = let post f = + f.globals <- (Global_vars.globals (Cil.CurrentLoc.get())) @ f.globals ; Ast.mark_as_changed () ; Ast.mark_as_grown () ; f -- GitLab From 7b96b98b4d12a448c6f5fbd6928dba899da23c9a Mon Sep 17 00:00:00 2001 From: Allan Blanchard <allan.blanchard@cea.fr> Date: Fri, 27 Mar 2020 16:42:16 +0100 Subject: [PATCH 116/218] [Instantiate] No more frama_c_stdlib restriction --- src/plugins/instantiate/stdlib/calloc.ml | 8 ++++---- src/plugins/instantiate/stdlib/free.ml | 8 ++++---- src/plugins/instantiate/stdlib/malloc.ml | 8 ++++---- src/plugins/instantiate/string/mem_utils.ml | 8 +++----- src/plugins/instantiate/string/memset.ml | 8 ++++---- 5 files changed, 19 insertions(+), 21 deletions(-) diff --git a/src/plugins/instantiate/stdlib/calloc.ml b/src/plugins/instantiate/stdlib/calloc.ml index 89af52fd24d..cebc53197c9 100644 --- a/src/plugins/instantiate/stdlib/calloc.ml +++ b/src/plugins/instantiate/stdlib/calloc.ml @@ -131,17 +131,17 @@ let generate_prototype alloc_type = ] in name, (TFun((ptr_of alloc_type), Some params, false, [])) -let well_typed_call ret fct args = +let well_typed_call ret _fct args = match ret, args with - | Some ret, [ _ ; _ ] when Cil.hasAttribute "fc_stdlib" fct.vattr -> + | Some ret, [ _ ; _ ] -> let t = Cil.typeOfLval ret in Cil.isPointerType t && not (Cil.isVoidPtrType t) && Cil.isCompleteType (Cil.typeOf_pointed t) | _ -> false -let key_from_call ret fct _ = +let key_from_call ret _fct _ = match ret with - | Some ret when Cil.hasAttribute "fc_stdlib" fct.vattr -> + | Some ret -> let ret_t = Cil.unrollTypeDeep (Cil.typeOfLval ret) in let ret_t = Cil.type_remove_qualifier_attributes_deep ret_t in Cil.typeOf_pointed ret_t diff --git a/src/plugins/instantiate/stdlib/free.ml b/src/plugins/instantiate/stdlib/free.ml index ec63f84f4aa..b1adaae34a3 100644 --- a/src/plugins/instantiate/stdlib/free.ml +++ b/src/plugins/instantiate/stdlib/free.ml @@ -83,16 +83,16 @@ let generate_prototype alloc_t = ] in name, (TFun(Cil.voidType, Some params, false, [])) -let well_typed_call _ret fct args = +let well_typed_call _ret _fct args = match args with - | [ ptr ] when Cil.hasAttribute "fc_stdlib" fct.vattr -> + | [ ptr ] -> let t = Cil.typeOf (Cil.stripCasts ptr) in Cil.isPointerType t && not (Cil.isVoidPtrType t) | _ -> false -let key_from_call _ret fct args = +let key_from_call _ret _fct args = match args with - | [ ptr ] when Cil.hasAttribute "fc_stdlib" fct.vattr -> + | [ ptr ] -> let ptr = Cil.stripCasts ptr in let ptr_t = Cil.unrollTypeDeep (Cil.typeOf ptr) in let ptr_t = Cil.type_remove_qualifier_attributes_deep ptr_t in diff --git a/src/plugins/instantiate/stdlib/malloc.ml b/src/plugins/instantiate/stdlib/malloc.ml index fbf3374bcdd..f7b3e9f3b0d 100644 --- a/src/plugins/instantiate/stdlib/malloc.ml +++ b/src/plugins/instantiate/stdlib/malloc.ml @@ -70,17 +70,17 @@ let generate_prototype alloc_t = ] in name, (TFun((ptr_of alloc_t), Some params, false, [])) -let well_typed_call ret fct args = +let well_typed_call ret _fct args = match ret, args with - | Some ret, [ _ ] when Cil.hasAttribute "fc_stdlib" fct.vattr -> + | Some ret, [ _ ] -> let t = Cil.typeOfLval ret in Cil.isPointerType t && not (Cil.isVoidPtrType t) && Cil.isCompleteType (Cil.typeOf_pointed t) | _ -> false -let key_from_call ret fct _ = +let key_from_call ret _fct _ = match ret with - | Some ret when Cil.hasAttribute "fc_stdlib" fct.vattr -> + | Some ret -> let ret_t = Cil.unrollTypeDeep (Cil.typeOfLval ret) in let ret_t = Cil.type_remove_qualifier_attributes_deep ret_t in Cil.typeOf_pointed ret_t diff --git a/src/plugins/instantiate/string/mem_utils.ml b/src/plugins/instantiate/string/mem_utils.ml index 02ccd376309..de076b1e3c0 100644 --- a/src/plugins/instantiate/string/mem_utils.ml +++ b/src/plugins/instantiate/string/mem_utils.ml @@ -128,10 +128,9 @@ struct let name = F.name ^ "_" ^ (string_of_typ t) in name, ftype - let well_typed_call lval fct args = + let well_typed_call lval _fct args = let _, ps = F.prototype () in if List.length args <> List.length ps then false - else if not (Cil.hasAttribute "fc_stdlib" fct.vattr) then false else let extract e = function | _, (CPtr | Ptr), _ -> exp_type_of_pointed e @@ -158,12 +157,11 @@ struct in List.map2 retype args ps - let key_from_call _ret fct args = + let key_from_call _ret _fct args = let _, ps = F.prototype () in match ps, args with | (_, (Ptr|CPtr), _) :: ps, fst :: args - when List.(length ps = length args) - && Cil.hasAttribute "fc_stdlib" fct.vattr -> + when List.(length ps = length args) -> begin match exp_type_of_pointed fst with | Value_of t -> t | _ -> diff --git a/src/plugins/instantiate/string/memset.ml b/src/plugins/instantiate/string/memset.ml index 21e44be2106..1538ba32be0 100644 --- a/src/plugins/instantiate/string/memset.ml +++ b/src/plugins/instantiate/string/memset.ml @@ -195,8 +195,8 @@ let rec contains_union_type t = contains_union_type t | _ -> false -let well_typed_call _ret fct = function - | [ ptr ; value ; _ ] when Cil.hasAttribute "fc_stdlib" fct.vattr -> +let well_typed_call _ret _fct = function + | [ ptr ; value ; _ ] -> begin match Mem_utils.exp_type_of_pointed ptr, memset_value value with | (No_pointed | Of_null _) , _ -> false | Value_of t , _ when any_char_composed_type t -> true @@ -208,8 +208,8 @@ let well_typed_call _ret fct = function end | _ -> false -let key_from_call _ret fct = function - | [ ptr ; value ; _ ] when Cil.hasAttribute "fc_stdlib" fct.vattr -> +let key_from_call _ret _fct = function + | [ ptr ; value ; _ ] -> begin match Mem_utils.exp_type_of_pointed ptr, memset_value value with | Value_of t, _ when any_char_composed_type t -> t, None | Value_of t, value when not (contains_union_type t) -> t, value -- GitLab From 854550083ceb53df2977d6e52b821a9aecbfbda5 Mon Sep 17 00:00:00 2001 From: Allan Blanchard <allan.blanchard@cea.fr> Date: Fri, 27 Mar 2020 17:12:57 +0100 Subject: [PATCH 117/218] [test] Adds missing 'must_recompte_cfg' in ast_init test --- tests/syntax/ast_init.ml | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/syntax/ast_init.ml b/tests/syntax/ast_init.ml index b0520cc04b9..f0e57935a23 100644 --- a/tests/syntax/ast_init.ml +++ b/tests/syntax/ast_init.ml @@ -8,6 +8,7 @@ let apply _ = (fun b -> b.bstmts <- Cil.mkStmtOneInstr (Skip (Cil_datatype.Stmt.loc s)) :: b.bstmts) l; + File.must_recompute_cfg (Kernel_function.get_definition f) ; Ast.mark_as_grown () let () = Ast.apply_after_computed apply -- GitLab From daeed27eba8cab04b59b324374dfa0fca08cbd61 Mon Sep 17 00:00:00 2001 From: Allan Blanchard <allan.blanchard@cea.fr> Date: Fri, 27 Mar 2020 17:35:38 +0100 Subject: [PATCH 118/218] [Instantiate] Changes error when can't instantiate --- src/plugins/instantiate/Instantiate.mli | 2 +- src/plugins/instantiate/string/mem_utils.mli | 2 +- .../tests/stdlib/oracle/calloc.res.oracle | 6 ++-- .../tests/stdlib/oracle/free.res.oracle | 3 +- .../tests/stdlib/oracle/malloc.res.oracle | 6 ++-- .../tests/string/oracle/memcmp.res.oracle | 18 ++++++---- .../tests/string/oracle/memcpy.res.oracle | 24 ++++++++----- .../tests/string/oracle/memmove.res.oracle | 24 ++++++++----- .../tests/string/oracle/memset_0.res.oracle | 12 ++++--- .../tests/string/oracle/memset_FF.res.oracle | 12 ++++--- .../oracle/memset_nested_union.res.oracle | 2 +- .../string/oracle/memset_value.res.oracle | 36 +++++++++---------- src/plugins/instantiate/transform.ml | 3 +- 13 files changed, 93 insertions(+), 57 deletions(-) diff --git a/src/plugins/instantiate/Instantiate.mli b/src/plugins/instantiate/Instantiate.mli index 4af9d03fc53..aaddb8131d0 100644 --- a/src/plugins/instantiate/Instantiate.mli +++ b/src/plugins/instantiate/Instantiate.mli @@ -110,4 +110,4 @@ module Global_vars:sig transformation. *) val get: typ -> bool -> storage -> string -> varinfo -end \ No newline at end of file +end diff --git a/src/plugins/instantiate/string/mem_utils.mli b/src/plugins/instantiate/string/mem_utils.mli index fca57bd58d0..a6bbb923b7c 100644 --- a/src/plugins/instantiate/string/mem_utils.mli +++ b/src/plugins/instantiate/string/mem_utils.mli @@ -72,4 +72,4 @@ type pointed_expr_type = | Value_of of typ | No_pointed -val exp_type_of_pointed: exp -> pointed_expr_type \ No newline at end of file +val exp_type_of_pointed: exp -> pointed_expr_type diff --git a/src/plugins/instantiate/tests/stdlib/oracle/calloc.res.oracle b/src/plugins/instantiate/tests/stdlib/oracle/calloc.res.oracle index cc72848fd62..16706418268 100644 --- a/src/plugins/instantiate/tests/stdlib/oracle/calloc.res.oracle +++ b/src/plugins/instantiate/tests/stdlib/oracle/calloc.res.oracle @@ -1,6 +1,8 @@ [kernel] Parsing tests/stdlib/calloc.c (with preprocessing) -[instantiate] tests/stdlib/calloc.c:24: Warning: Ignore call: not well typed -[instantiate] tests/stdlib/calloc.c:25: Warning: Ignore call: not well typed +[instantiate] tests/stdlib/calloc.c:24: Warning: + calloc instantiator cannot replace call +[instantiate] tests/stdlib/calloc.c:25: Warning: + calloc instantiator cannot replace call /* Generated by Frama-C */ #include "stdlib.h" struct X { diff --git a/src/plugins/instantiate/tests/stdlib/oracle/free.res.oracle b/src/plugins/instantiate/tests/stdlib/oracle/free.res.oracle index cfdb769ed8d..a0671fe0bc8 100644 --- a/src/plugins/instantiate/tests/stdlib/oracle/free.res.oracle +++ b/src/plugins/instantiate/tests/stdlib/oracle/free.res.oracle @@ -1,5 +1,6 @@ [kernel] Parsing tests/stdlib/free.c (with preprocessing) -[instantiate] tests/stdlib/free.c:13: Warning: Ignore call: not well typed +[instantiate] tests/stdlib/free.c:13: Warning: + free instantiator cannot replace call /* Generated by Frama-C */ #include "stdlib.h" struct incomplete; diff --git a/src/plugins/instantiate/tests/stdlib/oracle/malloc.res.oracle b/src/plugins/instantiate/tests/stdlib/oracle/malloc.res.oracle index 6cec0abadff..9aff502467c 100644 --- a/src/plugins/instantiate/tests/stdlib/oracle/malloc.res.oracle +++ b/src/plugins/instantiate/tests/stdlib/oracle/malloc.res.oracle @@ -1,6 +1,8 @@ [kernel] Parsing tests/stdlib/malloc.c (with preprocessing) -[instantiate] tests/stdlib/malloc.c:23: Warning: Ignore call: not well typed -[instantiate] tests/stdlib/malloc.c:24: Warning: Ignore call: not well typed +[instantiate] tests/stdlib/malloc.c:23: Warning: + malloc instantiator cannot replace call +[instantiate] tests/stdlib/malloc.c:24: Warning: + malloc instantiator cannot replace call /* Generated by Frama-C */ #include "stdlib.h" struct X { diff --git a/src/plugins/instantiate/tests/string/oracle/memcmp.res.oracle b/src/plugins/instantiate/tests/string/oracle/memcmp.res.oracle index 856300f9ad0..1f82bcd57b0 100644 --- a/src/plugins/instantiate/tests/string/oracle/memcmp.res.oracle +++ b/src/plugins/instantiate/tests/string/oracle/memcmp.res.oracle @@ -1,10 +1,16 @@ [kernel] Parsing tests/string/memcmp.c (with preprocessing) -[instantiate] tests/string/memcmp.c:31: Warning: Ignore call: not well typed -[instantiate] tests/string/memcmp.c:36: Warning: Ignore call: not well typed -[instantiate] tests/string/memcmp.c:40: Warning: Ignore call: not well typed -[instantiate] tests/string/memcmp.c:41: Warning: Ignore call: not well typed -[instantiate] tests/string/memcmp.c:42: Warning: Ignore call: not well typed -[instantiate] tests/string/memcmp.c:43: Warning: Ignore call: not well typed +[instantiate] tests/string/memcmp.c:31: Warning: + memcmp instantiator cannot replace call +[instantiate] tests/string/memcmp.c:36: Warning: + memcmp instantiator cannot replace call +[instantiate] tests/string/memcmp.c:40: Warning: + memcmp instantiator cannot replace call +[instantiate] tests/string/memcmp.c:41: Warning: + memcmp instantiator cannot replace call +[instantiate] tests/string/memcmp.c:42: Warning: + memcmp instantiator cannot replace call +[instantiate] tests/string/memcmp.c:43: Warning: + memcmp instantiator cannot replace call /* Generated by Frama-C */ #include "stddef.h" #include "string.h" diff --git a/src/plugins/instantiate/tests/string/oracle/memcpy.res.oracle b/src/plugins/instantiate/tests/string/oracle/memcpy.res.oracle index 35a4b88ca8f..899dd8afefc 100644 --- a/src/plugins/instantiate/tests/string/oracle/memcpy.res.oracle +++ b/src/plugins/instantiate/tests/string/oracle/memcpy.res.oracle @@ -1,12 +1,20 @@ [kernel] Parsing tests/string/memcpy.c (with preprocessing) -[instantiate] tests/string/memcpy.c:36: Warning: Ignore call: not well typed -[instantiate] tests/string/memcpy.c:37: Warning: Ignore call: not well typed -[instantiate] tests/string/memcpy.c:42: Warning: Ignore call: not well typed -[instantiate] tests/string/memcpy.c:43: Warning: Ignore call: not well typed -[instantiate] tests/string/memcpy.c:47: Warning: Ignore call: not well typed -[instantiate] tests/string/memcpy.c:48: Warning: Ignore call: not well typed -[instantiate] tests/string/memcpy.c:49: Warning: Ignore call: not well typed -[instantiate] tests/string/memcpy.c:50: Warning: Ignore call: not well typed +[instantiate] tests/string/memcpy.c:36: Warning: + memcpy instantiator cannot replace call +[instantiate] tests/string/memcpy.c:37: Warning: + memcpy instantiator cannot replace call +[instantiate] tests/string/memcpy.c:42: Warning: + memcpy instantiator cannot replace call +[instantiate] tests/string/memcpy.c:43: Warning: + memcpy instantiator cannot replace call +[instantiate] tests/string/memcpy.c:47: Warning: + memcpy instantiator cannot replace call +[instantiate] tests/string/memcpy.c:48: Warning: + memcpy instantiator cannot replace call +[instantiate] tests/string/memcpy.c:49: Warning: + memcpy instantiator cannot replace call +[instantiate] tests/string/memcpy.c:50: Warning: + memcpy instantiator cannot replace call /* Generated by Frama-C */ #include "stddef.h" #include "string.h" diff --git a/src/plugins/instantiate/tests/string/oracle/memmove.res.oracle b/src/plugins/instantiate/tests/string/oracle/memmove.res.oracle index b53227bdabf..f327581499b 100644 --- a/src/plugins/instantiate/tests/string/oracle/memmove.res.oracle +++ b/src/plugins/instantiate/tests/string/oracle/memmove.res.oracle @@ -1,12 +1,20 @@ [kernel] Parsing tests/string/memmove.c (with preprocessing) -[instantiate] tests/string/memmove.c:36: Warning: Ignore call: not well typed -[instantiate] tests/string/memmove.c:37: Warning: Ignore call: not well typed -[instantiate] tests/string/memmove.c:42: Warning: Ignore call: not well typed -[instantiate] tests/string/memmove.c:43: Warning: Ignore call: not well typed -[instantiate] tests/string/memmove.c:47: Warning: Ignore call: not well typed -[instantiate] tests/string/memmove.c:48: Warning: Ignore call: not well typed -[instantiate] tests/string/memmove.c:49: Warning: Ignore call: not well typed -[instantiate] tests/string/memmove.c:50: Warning: Ignore call: not well typed +[instantiate] tests/string/memmove.c:36: Warning: + memmove instantiator cannot replace call +[instantiate] tests/string/memmove.c:37: Warning: + memmove instantiator cannot replace call +[instantiate] tests/string/memmove.c:42: Warning: + memmove instantiator cannot replace call +[instantiate] tests/string/memmove.c:43: Warning: + memmove instantiator cannot replace call +[instantiate] tests/string/memmove.c:47: Warning: + memmove instantiator cannot replace call +[instantiate] tests/string/memmove.c:48: Warning: + memmove instantiator cannot replace call +[instantiate] tests/string/memmove.c:49: Warning: + memmove instantiator cannot replace call +[instantiate] tests/string/memmove.c:50: Warning: + memmove instantiator cannot replace call /* Generated by Frama-C */ #include "stddef.h" #include "string.h" diff --git a/src/plugins/instantiate/tests/string/oracle/memset_0.res.oracle b/src/plugins/instantiate/tests/string/oracle/memset_0.res.oracle index af6a60f7c80..dae2db7eba3 100644 --- a/src/plugins/instantiate/tests/string/oracle/memset_0.res.oracle +++ b/src/plugins/instantiate/tests/string/oracle/memset_0.res.oracle @@ -1,8 +1,12 @@ [kernel] Parsing tests/string/memset_0.c (with preprocessing) -[instantiate] tests/string/memset_0.c:62: Warning: Ignore call: not well typed -[instantiate] tests/string/memset_0.c:63: Warning: Ignore call: not well typed -[instantiate] tests/string/memset_0.c:67: Warning: Ignore call: not well typed -[instantiate] tests/string/memset_0.c:68: Warning: Ignore call: not well typed +[instantiate] tests/string/memset_0.c:62: Warning: + memset instantiator cannot replace call +[instantiate] tests/string/memset_0.c:63: Warning: + memset instantiator cannot replace call +[instantiate] tests/string/memset_0.c:67: Warning: + memset instantiator cannot replace call +[instantiate] tests/string/memset_0.c:68: Warning: + memset instantiator cannot replace call /* Generated by Frama-C */ #include "stddef.h" #include "string.h" diff --git a/src/plugins/instantiate/tests/string/oracle/memset_FF.res.oracle b/src/plugins/instantiate/tests/string/oracle/memset_FF.res.oracle index 91a1e42f767..137dd1c21a0 100644 --- a/src/plugins/instantiate/tests/string/oracle/memset_FF.res.oracle +++ b/src/plugins/instantiate/tests/string/oracle/memset_FF.res.oracle @@ -1,8 +1,12 @@ [kernel] Parsing tests/string/memset_FF.c (with preprocessing) -[instantiate] tests/string/memset_FF.c:88: Warning: Ignore call: not well typed -[instantiate] tests/string/memset_FF.c:89: Warning: Ignore call: not well typed -[instantiate] tests/string/memset_FF.c:93: Warning: Ignore call: not well typed -[instantiate] tests/string/memset_FF.c:94: Warning: Ignore call: not well typed +[instantiate] tests/string/memset_FF.c:88: Warning: + memset instantiator cannot replace call +[instantiate] tests/string/memset_FF.c:89: Warning: + memset instantiator cannot replace call +[instantiate] tests/string/memset_FF.c:93: Warning: + memset instantiator cannot replace call +[instantiate] tests/string/memset_FF.c:94: Warning: + memset instantiator cannot replace call /* Generated by Frama-C */ #include "stddef.h" #include "string.h" diff --git a/src/plugins/instantiate/tests/string/oracle/memset_nested_union.res.oracle b/src/plugins/instantiate/tests/string/oracle/memset_nested_union.res.oracle index f71268da3aa..7185fe7a665 100644 --- a/src/plugins/instantiate/tests/string/oracle/memset_nested_union.res.oracle +++ b/src/plugins/instantiate/tests/string/oracle/memset_nested_union.res.oracle @@ -1,6 +1,6 @@ [kernel] Parsing tests/string/memset_nested_union.c (with preprocessing) [instantiate] tests/string/memset_nested_union.c:10: Warning: - Ignore call: not well typed + memset instantiator cannot replace call /* Generated by Frama-C */ #include "stddef.h" #include "string.h" diff --git a/src/plugins/instantiate/tests/string/oracle/memset_value.res.oracle b/src/plugins/instantiate/tests/string/oracle/memset_value.res.oracle index 8609a955121..5ece8370f6b 100644 --- a/src/plugins/instantiate/tests/string/oracle/memset_value.res.oracle +++ b/src/plugins/instantiate/tests/string/oracle/memset_value.res.oracle @@ -1,40 +1,40 @@ [kernel] Parsing tests/string/memset_value.c (with preprocessing) [instantiate] tests/string/memset_value.c:26: Warning: - Ignore call: not well typed + memset instantiator cannot replace call [instantiate] tests/string/memset_value.c:27: Warning: - Ignore call: not well typed + memset instantiator cannot replace call [instantiate] tests/string/memset_value.c:32: Warning: - Ignore call: not well typed + memset instantiator cannot replace call [instantiate] tests/string/memset_value.c:33: Warning: - Ignore call: not well typed + memset instantiator cannot replace call [instantiate] tests/string/memset_value.c:37: Warning: - Ignore call: not well typed + memset instantiator cannot replace call [instantiate] tests/string/memset_value.c:38: Warning: - Ignore call: not well typed + memset instantiator cannot replace call [instantiate] tests/string/memset_value.c:42: Warning: - Ignore call: not well typed + memset instantiator cannot replace call [instantiate] tests/string/memset_value.c:43: Warning: - Ignore call: not well typed + memset instantiator cannot replace call [instantiate] tests/string/memset_value.c:47: Warning: - Ignore call: not well typed + memset instantiator cannot replace call [instantiate] tests/string/memset_value.c:48: Warning: - Ignore call: not well typed + memset instantiator cannot replace call [instantiate] tests/string/memset_value.c:52: Warning: - Ignore call: not well typed + memset instantiator cannot replace call [instantiate] tests/string/memset_value.c:53: Warning: - Ignore call: not well typed + memset instantiator cannot replace call [instantiate] tests/string/memset_value.c:57: Warning: - Ignore call: not well typed + memset instantiator cannot replace call [instantiate] tests/string/memset_value.c:58: Warning: - Ignore call: not well typed + memset instantiator cannot replace call [instantiate] tests/string/memset_value.c:62: Warning: - Ignore call: not well typed + memset instantiator cannot replace call [instantiate] tests/string/memset_value.c:63: Warning: - Ignore call: not well typed + memset instantiator cannot replace call [instantiate] tests/string/memset_value.c:67: Warning: - Ignore call: not well typed + memset instantiator cannot replace call [instantiate] tests/string/memset_value.c:68: Warning: - Ignore call: not well typed + memset instantiator cannot replace call /* Generated by Frama-C */ #include "stddef.h" #include "string.h" diff --git a/src/plugins/instantiate/transform.ml b/src/plugins/instantiate/transform.ml index 8b0f9ece40e..7dda9a46b99 100644 --- a/src/plugins/instantiate/transform.ml +++ b/src/plugins/instantiate/transform.ml @@ -99,7 +99,8 @@ class transformer = object(self) Queue.add fundec used_instantiator_last_kf ; (fundec.svar), new_args else begin - Options.warning ~current:true "Ignore call: not well typed" ; + Options.warning + ~current:true "%s instantiator cannot replace call" fct.vname ; (fct, args) end with -- GitLab From 41cf212fdd87bd870622c6dabe6bd65e39a282d5 Mon Sep 17 00:00:00 2001 From: Allan Blanchard <allan.blanchard@cea.fr> Date: Fri, 27 Mar 2020 17:42:46 +0100 Subject: [PATCH 119/218] [Instantiate] Adds files to header-check --- headers/header_spec.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/headers/header_spec.txt b/headers/header_spec.txt index 2ada5971dd2..d9acf0cdd50 100644 --- a/headers/header_spec.txt +++ b/headers/header_spec.txt @@ -945,6 +945,8 @@ src/plugins/occurrence/register_gui.ml: CEA_LGPL_OR_PROPRIETARY src/plugins/occurrence/register_gui.mli: CEA_LGPL_OR_PROPRIETARY src/plugins/instantiate/basic_blocks.ml: CEA_LGPL_OR_PROPRIETARY src/plugins/instantiate/basic_blocks.mli: CEA_LGPL_OR_PROPRIETARY +src/plugins/instantiate/global_vars.ml: CEA_LGPL_OR_PROPRIETARY +src/plugins/instantiate/global_vars.mli: CEA_LGPL_OR_PROPRIETARY src/plugins/instantiate/Instantiate.mli: CEA_LGPL_OR_PROPRIETARY src/plugins/instantiate/instantiator_builder.ml: CEA_LGPL_OR_PROPRIETARY src/plugins/instantiate/instantiator_builder.mli: CEA_LGPL_OR_PROPRIETARY @@ -958,6 +960,8 @@ src/plugins/instantiate/stdlib/free.ml: CEA_LGPL_OR_PROPRIETARY src/plugins/instantiate/stdlib/free.mli: CEA_LGPL_OR_PROPRIETARY src/plugins/instantiate/stdlib/malloc.ml: CEA_LGPL_OR_PROPRIETARY src/plugins/instantiate/stdlib/malloc.mli: CEA_LGPL_OR_PROPRIETARY +src/plugins/instantiate/string/mem_utils.ml: CEA_LGPL_OR_PROPRIETARY +src/plugins/instantiate/string/mem_utils.mli: CEA_LGPL_OR_PROPRIETARY src/plugins/instantiate/string/memcmp.ml: CEA_LGPL_OR_PROPRIETARY src/plugins/instantiate/string/memcmp.mli: CEA_LGPL_OR_PROPRIETARY src/plugins/instantiate/string/memcpy.ml: CEA_LGPL_OR_PROPRIETARY -- GitLab From 9c1304aa872f1a13bc0631acdbba1af36bb18e98 Mon Sep 17 00:00:00 2001 From: Andre Maroneze <andre.oliveiramaroneze@cea.fr> Date: Tue, 31 Mar 2020 11:21:42 +0200 Subject: [PATCH 120/218] [Doc] Revamp userman's chapter on reporting errors (BTS -> Gitlab) --- doc/userman/gitlab-bug-report.png | Bin 0 -> 115193 bytes doc/userman/gitlab-login.png | Bin 0 -> 54301 bytes doc/userman/user-errors.tex | 108 +++++++++--------------------- doc/userman/user-intro.tex | 4 +- 4 files changed, 35 insertions(+), 77 deletions(-) create mode 100644 doc/userman/gitlab-bug-report.png create mode 100644 doc/userman/gitlab-login.png diff --git a/doc/userman/gitlab-bug-report.png b/doc/userman/gitlab-bug-report.png new file mode 100644 index 0000000000000000000000000000000000000000..1a5e0d9baeab646e9de16382061072b6224b2566 GIT binary patch literal 115193 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�LFk(FBc;kRg`C_lR+HAjgPO?XGvf8MMT8>cqhbXv5QA9jLf!b z%ScKV+Kh)qM0^W3E51s`C|n7F%pE<wIb^kbD{{cCt2P=n7emzo-cVL|(6HqbDU|As zjg}DpfGPy}-e_8*zDu~E6YOKUD`;F;Nr+K$M9XwxI$#HM5W-%Ul^--{*WmGvq37~g zMjb>pMMVNmOnkRLKL=h3Fr&v&&;^G%+Fi$v!MF<U+?hRzYZAY5zT?OtG@;lt?0bYj zhUVidz+fn4))1``4i-Xz9u*Z8sk%d=t@)bN=$KkvrlX(`t_TR%-1ajGxFV1=hTPLM z5C}*fm&-p7W!tQo%W@~)DnGh9NYjI29^0e=9?MQo2iizx`LYPrD8NLVp9YB4w6sJ9 zf#*ndp9+0q-GL<i8}554=jvS6enVvg>)V&Jhc_0ve`GEv;qaExWK^1qbeLS8lI1#S z@+MJ{g}lVSdH@A+Nsbqg#kjz?L}AimR8cd9uOrFU9Zz4-wLAQ9`=mIQyk1?TR8Qqr zqLQk!NGV>pv*yNgKMZ2$4Jo#l^T)y8d!0Y7lA92xbcDKlw!M$?k?ejwC{(`dyBrcB zuPZ9@%bSr9+4iZdHSm;9kg2J>kMb>)@unr>H^(-OP!6me>~o*^PGPX7x??5I+^(=? zu6C2&YRR2<G3s9irbx~b2|&UMlMZ|EbH|*5FvIe-E{%%v^Sdfx$w4R5M&{#fYA#`! z;rDJQ{q~oy;jO|yvOA6FyCJvp3im_8OvzbCk77$cZwDpi$f&Be(ffg^g)5)*er~~Y z<AEd1=kb7-8{xkv!%O-8cxZed9w|wU$;>=>b7O>f|8<Bppo*35^G7{M2)|iML#*~! z&dk5f=l-6s{XOLR>&N%SJ|e{9TAcsl8|)5Dz!){yCPqgCst3-IgTLmj%ybX{{TEiN zox~d%;iWX(SHIsKT0aPnP{jRG*OhKOCY7y1yg{?jU<-~BwtleP$~-A?bA)iBV#6jd zsAQSAkL}Y85RQIH)_4}#cNIVA{*3<?GW4i8W02a(`Tpe=$uJ0BoAv57!ZuZh8T3Wx zA7#jrl@d0fo)%}`agL1e@$UDWiLs3>cU?ZE>9K?3U25DB1F7>NH}$w+O<6?|Lf&{? zCCMw@SCjC&L@PY$2bzD%a~6Czlr>R`vzD`JyU5Wl8{w_GLy85bj^b~Ux#wH{8s*Yl z82u{AuV~EA$!B3;qILO*fhJfk@2$FJjZ@-+%wCH9nfOMX+b<`<5>oD(EX>vORc-j@ z%g{R{CRCr5EU6d<aQXUMTeYGUH(q}2dESnIg9!}ONn6yGtrMI%WtWAG`A#uRy|g1v zS(Rl8%yi+AOB}ekL>S%@O%95mSKJY@uB5JHSj?iVy!({5TI9>Q9KOmjm-iwm0)cvE zEPu@-UE<%k8WfTT$Ly`I&%Wl+5`Ah)R!XR{EG5a;aO0I%$j_0~l)Lh49C^hx@HNu< zEhDwjx^cvxG47h=;^Pr9&Gpf1JXU&CqGAQiK^t#?Xrb{n4eJ)sb!V!4()|zDC^w!; zTu6o2Y-p{s|JdBhCKuCV8~><c;p42}y_T_Wj&sYAjVW=d_W8!I90OlZjb42C=h=LM z&1Ab63%ED_;Ns_K!GW0Tw_Y~<nPe}1iji8kRo!Z_5&S^ZPiep8l9+dQ*k`ZpG~o}f NUX~V36~6KCzX05!Lsb9( literal 0 HcmV?d00001 diff --git a/doc/userman/gitlab-login.png b/doc/userman/gitlab-login.png new file mode 100644 index 0000000000000000000000000000000000000000..3fa9c4ec6f130ed30c10bc70756807dcc10dbb32 GIT binary patch literal 54301 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 F{txL9rknr( literal 0 HcmV?d00001 diff --git a/doc/userman/user-errors.tex b/doc/userman/user-errors.tex index 6174a79f7e4..68370154cf4 100644 --- a/doc/userman/user-errors.tex +++ b/doc/userman/user-errors.tex @@ -1,94 +1,52 @@ \chapter{Reporting Errors} \label{user-errors} -If \FramaC crashes or behaves abnormally, you are invited to report a bug \via -the \FramaC Bugs Tracking System (BTS) located at -\url{http://bts.frama-c.com}. +If \FramaC crashes or behaves abnormally, you are invited to report an issue +\via the \FramaC Gitlab repository, located at \url{https://git.frama-c.com}. +The {\em New Issue} page (\url{https://git.frama-c.com/pub/frama-c/issues/new}) +allows creating a new report, but you will need an account. \begin{important} -Opening a BTS account is required for such a task. + Unless you have an account provided by the \FramaC team, you need to sign in + using a Github account, as shown in Figure~\ref{fig:gitlab-login}. \end{important} -Bug reports can be marked as public or private. -Public bug reports can be read by anyone and are indexed by search -engines. Private bug reports are only shown to \FramaC developers. - -Reporting a new issue opens a webpage similar to the one shown in -Figure~\ref{fig:bts}. \begin{figure}[htbp] \begin{center} -\includegraphics[width=\textwidth]{bts.pdf} +\includegraphics[width=\textwidth]{gitlab-login.png} \end{center} -\caption{The BTS Bugs Reporting Page} -\label{fig:bts} +\caption{The \FramaC Gitlab login page. Note that no direct account creation + is possible; you need to sign in via Github unless the \FramaC team + provided you an account.} +\label{fig:gitlab-login} \end{figure} -This page also has a link to an advanced bugs reporting page that allows you to -write a more detailed report. The different fields of these forms shall be -filled \emph{in English}\footnote{French is also a possible language choice for private entries.} -as precisely as possible, in order for the maintenance team to understand and -track the problem down easily. - -Below are some recommendations for this purpose\footnote{You can also have a - look at the associated \FramaC wiki: - \url{http://bts.frama-c.com/dokuwiki/doku.php?id=mantis:frama-c:start}.}: - -\begin{description} - -\item[Category:] select as appropriate. - -\item[Reproducibility:] select as appropriate. - -\item[Severity:] select the level of severity. Levels are shown in increasing - order of severity. - -\item[Profile or Platform, OS and OS Version:] enter your hardware and OS - characteristics. - -\item[Product Version and Product Build] this can be obtained with the - command \texttt{frama-c -version}\optionidx{-}{version}, see - Section~\ref{sec:version}. - -\item[Summary:] give a brief one line description of the nature of your bug. -\item[Description:] first, explain the \textit{actual behavior}, that is what - you actually observe on your system. Then, describe your \textit{expected - behavior} of \FramaC, that is the results you expect instead. A ``bug'' is - sometimes due to a misunderstanding of the tool's behaviour or a - misunderstanding of its results, so providing both behaviors is an essential - part of the report. Please do clearly separate both parts in the description. +When creating a new issue, choose the \texttt{bug\_report} template next to +{\em Title}, then enter the title and fill the template. -\item[Steps to reproduce:] provide everything necessary for a maintainer to - reproduce the bug: input files, commands used, sequence of actions, \etc. If - the bug appears through the \FramaC GUI, it may be useful to attach the - generated journal (see Section~\ref{sec:journal}). Beware that this journal - \textbf{does not} replace nor contain the input files, that must be added to - the bug report too (see below). +Bug reports can be marked as public or confidential. +Public bug reports can be read by anyone and may be indexed by search +engines. Confidential bug reports are only shown to \FramaC developers. -\item[Additional Information:] any extra information that might help the - maintainer. - -\item[Industrial:] set it to \texttt{true} if you have a maintenance contract - with the \FramaC development team. - -\item[Upload File:] click on the \texttt{Browse} button to select a file for - uploading. Typically, this is an archive that contains all files necessary - for reproducing your problem. It can include \C source files, shell scripts - to run \FramaC with your options and environment, a \FramaC journal, - \etc. Please check the size of the archive in order to keep it manageable: - leave out any object code or executable files that can be easily rebuilt - automatically (by a shell script for instance). - -\item[View Status:] set it to \texttt{private} if your bug should not be - visible by others users. Only yourself and the \FramaC developers will be - able to see your bug report. - -\item[Report Stay:] tick if this report shall remain open for further - additions. +Reporting a new issue opens a webpage similar to the one shown in +Figure~\ref{fig:gitlab-bug-report}. +\begin{figure}[htbp] +\begin{center} +\includegraphics[width=\textwidth]{gitlab-bug-report.png} +\end{center} +\caption{The Gitlab new issue page, with the \texttt{bug\_report} template. + The checkbox at the bottom enables marking the issue as private, so that + only \FramaC developers can see it.} +\label{fig:gitlab-bug-report} +\end{figure} -\end{description} +Please fill the template as precisely as possible, +\emph{in English}\footnote{French is also a possible language choice for + private entries.}, which helps the \FramaC team more quickly understand, +reproduce and respond to the issue. The form uses Markdown syntax and you can +attach source files and screenshots to the issue. -After submitting the report you will be notified by e-mail about its progress -and enter interactive mode on the BTS if necessary. +Replies and updates concerning your issue are sent by e-mail by Gitlab. %% Local Variables: %% compile-command: "make" diff --git a/doc/userman/user-intro.tex b/doc/userman/user-intro.tex index 9dc8991c369..c0245ee5977 100644 --- a/doc/userman/user-intro.tex +++ b/doc/userman/user-intro.tex @@ -53,6 +53,6 @@ The remainder of this manual is organized in several chapters. the platform. \item[Chapter~\ref{user-gui}] gives a detailed description of the graphical user interface of \FramaC. -\item[Chapter~\ref{user-errors}] explains how to report errors \via the - \FramaC's Bug Tracking System. +\item[Chapter~\ref{user-errors}] explains how to report errors \via \FramaC's + public Gitlab repository. \end{description} -- GitLab From ddd9af48f6348902b4e8ae5cf4603ee72936d044 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Loi=CC=88c=20Correnson?= <loic.correnson@cea.fr> Date: Thu, 2 Apr 2020 11:47:26 +0200 Subject: [PATCH 121/218] [kernel] recursively coerce t-sets Visible impact on Genassigns plug-in --- .../ast_queries/logic_utils.ml | 65 ++++++++++++------- .../ast_queries/logic_utils.mli | 13 ++-- 2 files changed, 51 insertions(+), 27 deletions(-) diff --git a/src/kernel_services/ast_queries/logic_utils.ml b/src/kernel_services/ast_queries/logic_utils.ml index d1bcc167969..242feb6c6a0 100644 --- a/src/kernel_services/ast_queries/logic_utils.ml +++ b/src/kernel_services/ast_queries/logic_utils.ml @@ -305,30 +305,49 @@ let parse_float ?loc literal = let mk_coerce ltyp t = Logic_const.term ~loc:t.term_loc (TLogic_coerce(ltyp, t)) ltyp -let numeric_coerce ltyp t = +let rec numeric_coerce ltyp t = let oldt = unroll_type t.term_type in - if Cil_datatype.Logic_type.equal oldt ltyp then t - else match t.term_node with - | TLogic_coerce(lt,e) when Cil.no_op_coerce lt e -> - (* coercion hidden by the printer, but still present *) - mk_coerce ltyp e - | TConst(LEnum _) | TConst(Integer _) when ltyp = Linteger - -> { t with term_type = Linteger } - | TConst(LReal _ ) when ltyp = Lreal -> - { t with term_type = Lreal } - | TCastE(ty,e) -> - begin match ltyp, Cil.unrollType ty, e.term_node with - | Linteger, TInt(ik,_), TConst(Integer(v,_)) - when Cil.fitsInInt ik v -> { e with term_type = Linteger } - | Lreal, TFloat(fk,_), TConst(LReal r) - when Cil.isExactFloat fk r -> { e with term_type = Lreal } - | Linteger, TInt(ik,_), TConst(LEnum { eival }) -> - ( match Cil.constFoldToInt eival with - | Some i when Cil.fitsInInt ik i -> { e with term_type = Linteger } - | _ -> mk_coerce ltyp t ) - | _ -> mk_coerce ltyp t - end - | _ -> mk_coerce ltyp t + match t.term_node with + | TLogic_coerce(lt,e) when Cil.no_op_coerce lt e -> + (* coercion hidden by the printer, but still present *) + numeric_coerce ltyp e + | TConst(LEnum _) | TConst(Integer _) when ltyp = Linteger + -> { t with term_type = Linteger } + | TConst(LReal _ ) when ltyp = Lreal -> + { t with term_type = Lreal } + | TCastE(ty,e) -> + begin match ltyp, Cil.unrollType ty, e.term_node with + | Linteger, TInt(ik,_), TConst(Integer(v,_)) + when Cil.fitsInInt ik v -> { e with term_type = Linteger } + | Lreal, TFloat(fk,_), TConst(LReal r) + when Cil.isExactFloat fk r -> { e with term_type = Lreal } + | Linteger, TInt(ik,_), TConst(LEnum { eival }) -> + ( match Cil.constFoldToInt eival with + | Some i when Cil.fitsInInt ik i -> { e with term_type = Linteger } + | _ -> mk_coerce ltyp t ) + | _ -> mk_coerce ltyp t + end + | Trange(a,b) -> + let ra = numeric_bound ltyp a in + let rb = numeric_bound ltyp b in + { t with term_node = Trange(ra,rb) ; + term_type = Logic_const.make_set_type ltyp } + | Tunion ts -> + { t with term_node = Tunion (List.map (numeric_coerce ltyp) ts) ; + term_type = Logic_const.make_set_type ltyp } + | Tinter ts -> + { t with term_node = Tinter (List.map (numeric_coerce ltyp) ts) ; + term_type = Logic_const.make_set_type ltyp } + | Tcomprehension(t,qs,cond) -> + { t with term_node = Tcomprehension (numeric_coerce ltyp t,qs,cond) ; + term_type = Logic_const.make_set_type ltyp } + | _ -> + if Cil_datatype.Logic_type.equal oldt ltyp then t + else mk_coerce ltyp t + +and numeric_bound ltyp = function + | None -> None + | Some a -> Some (numeric_coerce ltyp a) (* Don't forget to keep is_zero_comparable and scalar_term_to_predicate in sync. *) diff --git a/src/kernel_services/ast_queries/logic_utils.mli b/src/kernel_services/ast_queries/logic_utils.mli index 81a7c454d54..6817dfd9371 100644 --- a/src/kernel_services/ast_queries/logic_utils.mli +++ b/src/kernel_services/ast_queries/logic_utils.mli @@ -85,7 +85,9 @@ val logicCType : logic_type -> typ (** transforms an array into pointer. *) val array_to_ptr : logic_type -> logic_type -(** C type to logic type, with implicit conversion for arithmetic types. *) +(** C type to logic type, with implicit conversion for arithmetic types. + @since Frama-C+dev +*) val coerce_type : typ -> logic_type (** {2 Predicates} *) @@ -122,9 +124,7 @@ val mk_logic_pointer_or_StartOf : term -> term be inserted. Otherwise (which is the default), [mk_cast typ t] will return [t] if it is already of type [typ] - @modify Aluminium-20160501 added [force] optional argument - -*) + @modify Aluminium-20160501 added [force] optional argument *) val mk_cast: ?loc:location -> ?force:bool -> typ -> term -> term @@ -141,7 +141,12 @@ val remove_logic_coerce: term -> term in [t]. In particular, [numeric_coerce (int)cst Linteger], where [cst] fits in int will be directly [cst], without any coercion. + Also coerce recursively the sub-terms of t-set expressions + (range, union, inter and comprehension) and lift the associated + set type. + @since Magnesium-20151001 + @modify Frama-C+dev *) val numeric_coerce: logic_type -> term -> term -- GitLab From f7a58f21c39bf1d81af576d6d533af6fe63ae4b2 Mon Sep 17 00:00:00 2001 From: Basile Desloges <basile.desloges@cea.fr> Date: Thu, 19 Mar 2020 09:43:58 +0100 Subject: [PATCH 122/218] =?UTF-8?q?[eacsl:doc]=C2=A0Fix=20paths=20for=20do?= =?UTF-8?q?xygen=20generation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/plugins/e-acsl/doc/doxygen/doxygen.cfg.in | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/plugins/e-acsl/doc/doxygen/doxygen.cfg.in b/src/plugins/e-acsl/doc/doxygen/doxygen.cfg.in index 5d8a49c0b4e..ff2a3f4d7eb 100644 --- a/src/plugins/e-acsl/doc/doxygen/doxygen.cfg.in +++ b/src/plugins/e-acsl/doc/doxygen/doxygen.cfg.in @@ -423,7 +423,7 @@ WARN_FORMAT = # and error messages should be written. If left blank the output is written # to stderr. -WARN_LOGFILE = @abs_top_srcdir@/doc/doxygen/warn.log +WARN_LOGFILE = @abs_top_builddir@/doc/doxygen/warn.log #--------------------------------------------------------------------------- # configuration options related to the input files @@ -434,9 +434,10 @@ WARN_LOGFILE = @abs_top_srcdir@/doc/doxygen/warn.log # directories like "/usr/src/myproject". Separate the files or directories # with spaces. -INPUT = @abs_top_srcdir@/share/e-acsl \ - @abs_top_srcdir@/share/e-acsl/segment_model \ - @abs_top_srcdir@/share/e-acsl/bittree_model +INPUT = @abs_top_srcdir@/src/plugins/e-acsl/share/e-acsl \ + @abs_top_srcdir@/src/plugins/e-acsl/share/e-acsl/segment_model \ + @abs_top_srcdir@/src/plugins/e-acsl/share/e-acsl/bittree_model \ + @abs_top_srcdir@/src/plugins/e-acsl/share/e-acsl/instrumentation_model # If the value of the INPUT tag contains directories, you can use the # FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp -- GitLab From 232774051d64a22ddfa4afcbc81f5d01c1c9993c Mon Sep 17 00:00:00 2001 From: Basile Desloges <basile.desloges@cea.fr> Date: Wed, 25 Mar 2020 09:40:07 +0100 Subject: [PATCH 123/218] =?UTF-8?q?[eacsl:doc]=C2=A0Fix=20tab=20in=20Chang?= =?UTF-8?q?elog?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/plugins/e-acsl/doc/Changelog | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/e-acsl/doc/Changelog b/src/plugins/e-acsl/doc/Changelog index 5c3fedbea06..1eeeb2ac090 100644 --- a/src/plugins/e-acsl/doc/Changelog +++ b/src/plugins/e-acsl/doc/Changelog @@ -21,7 +21,7 @@ -* E-ACSL [2020/03/24] Fix automatic deactivation of plug-in Variadic when E-ACSL is directly called from Frama-C without using - e-acsl-gcc.sh. + e-acsl-gcc.sh. - E-ACSL [2020/03/10] Call E-ACSL's free functions for globals in a separate function at the end of main. - E-ACSL [2020/03/10] Call `__e_acsl_memory_init` only if the memory -- GitLab From e57aaa3fe78520ccf5b86eda9d201a61b2ca82b8 Mon Sep 17 00:00:00 2001 From: Basile Desloges <basile.desloges@cea.fr> Date: Mon, 23 Mar 2020 16:16:29 +0100 Subject: [PATCH 124/218] =?UTF-8?q?[doc]=C2=A0Fix=20module=20path=20to=20m?= =?UTF-8?q?kCompInfo=20and=20copyCompInfo=20in=20doc=20comment?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/kernel_services/ast_data/cil_types.mli | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/kernel_services/ast_data/cil_types.mli b/src/kernel_services/ast_data/cil_types.mli index 4e590ae3297..9ad9fdb7a76 100644 --- a/src/kernel_services/ast_data/cil_types.mli +++ b/src/kernel_services/ast_data/cil_types.mli @@ -360,9 +360,9 @@ and compinfo = { of a comp (along with the struct or union) *) mutable ckey: int; - (** A unique integer. This is assigned by {!Cil.mkCompInfo} using a global + (** A unique integer. This is assigned by {!Cil_const.mkCompInfo} using a global variable in the Cil module. Thus two identical structs in two different - files might have different keys. Use {!Cil.copyCompInfo} to copy + files might have different keys. Use {!Cil_const.copyCompInfo} to copy structures so that a new key is assigned. *) mutable cfields: fieldinfo list; -- GitLab From aba903a6bcc530019888e953cbbd732c33f2bdfa Mon Sep 17 00:00:00 2001 From: Basile Desloges <basile.desloges@cea.fr> Date: Thu, 26 Mar 2020 14:51:10 +0100 Subject: [PATCH 125/218] [eacsl:doc] Update E-ACSL reference manual - Function contracts: remove abrupt clauses from the list of exceptions - Statement contracts: remove abrupt clauses from the list of exceptions - Add grammar for abrupt termination - Update list of contributors --- src/plugins/e-acsl/doc/refman/Makefile | 2 +- src/plugins/e-acsl/doc/refman/abrupt.tex | 15 +++++++ .../e-acsl/doc/refman/changes_modern.tex | 9 +++- src/plugins/e-acsl/doc/refman/fn_behavior.tex | 5 ++- .../e-acsl/doc/refman/intro_modern.tex | 7 +-- src/plugins/e-acsl/doc/refman/main.tex | 1 + .../e-acsl/doc/refman/speclang_modern.tex | 44 +++++++++++-------- .../e-acsl/doc/refman/st_contracts.tex | 4 +- 8 files changed, 60 insertions(+), 27 deletions(-) create mode 100644 src/plugins/e-acsl/doc/refman/abrupt.tex diff --git a/src/plugins/e-acsl/doc/refman/Makefile b/src/plugins/e-acsl/doc/refman/Makefile index 3462abe5fba..282220d94f0 100644 --- a/src/plugins/e-acsl/doc/refman/Makefile +++ b/src/plugins/e-acsl/doc/refman/Makefile @@ -15,7 +15,7 @@ DEPS_MODERN=macros_modern.tex eacslversion.tex biblio.bib \ assertions_modern.bnf loops_modern.bnf st_contracts_modern.bnf \ logic_modern.bnf data_invariants_modern.bnf model_modern.bnf \ ghost_modern.bnf generalinvariants_modern.bnf iterator_modern.bnf \ - bsearch.c bsearch2.c link.c + abrupt_modern.bnf bsearch.c bsearch2.c link.c ############## # Main rules # diff --git a/src/plugins/e-acsl/doc/refman/abrupt.tex b/src/plugins/e-acsl/doc/refman/abrupt.tex new file mode 100644 index 00000000000..5fe8ef4e916 --- /dev/null +++ b/src/plugins/e-acsl/doc/refman/abrupt.tex @@ -0,0 +1,15 @@ +\begin{syntax} + { abrupt-clause } ::= { exits-clause } + \ + { exits-clause } ::= { "exits" pred ";" } + \ + { abrupt-clause-stmt } ::= { breaks-clause } | { continues-clause } | { returns-clause } + \ + { breaks-clause } ::= { "breaks" pred ";" } + \ + { continues-clause } ::= { "continues" pred ";" } + \ + { returns-clause } ::= { "returns" pred ";" } + \ + { term } ::= { "\exit_status" } + \end{syntax} diff --git a/src/plugins/e-acsl/doc/refman/changes_modern.tex b/src/plugins/e-acsl/doc/refman/changes_modern.tex index ee30a79f7e0..70b99aa30c0 100644 --- a/src/plugins/e-acsl/doc/refman/changes_modern.tex +++ b/src/plugins/e-acsl/doc/refman/changes_modern.tex @@ -61,7 +61,7 @@ \item \changeinsection{typing}{no user-defined types} \item \changeinsection{builtinconstructs}{no more implementation issue for \lstinline|\\old|} -\item \changeinsection{at}{more restrictive scoping rule for label references +\item \changeinsection{at}{more restrictive scoping rule for label references in \lstinline|\\at|} \end{itemize} @@ -84,7 +84,7 @@ in \lstinline|\\at|} \item \changeinsection{expressions}{remove laziness of operator \lstinline|<==>|} \item \changeinsection{expressions}{restrict guarded quantifications to integer} -\item \changeinsection{expressions}{add iterator quantifications} +\item \changeinsection{expressions}{add iterator quantifications} \item \changeinsection{expressions}{extend unguarded quantifications to char} \item \changeinsection{locations}{extend syntax of set comprehensions} \item \changeinsection{loop_annot}{simplify explanations for loop invariants and @@ -128,6 +128,11 @@ in \lstinline|\\at|} \begin{itemize} \item \changeinsection{reals}{support of rational numbers and operations} +\item \changeinsection{fn-behavior}{remove abrupt clauses from the list of + exceptions} +\item \changeinsection{statement_contract}{remove abrupt clauses from the list + of exceptions} +\item \changeinsection{abrupt}{add grammar for abrupt termination} \end{itemize} \subsection*{Version Potassium-19} diff --git a/src/plugins/e-acsl/doc/refman/fn_behavior.tex b/src/plugins/e-acsl/doc/refman/fn_behavior.tex index 4cd97341aa5..cf6a3ebb981 100644 --- a/src/plugins/e-acsl/doc/refman/fn_behavior.tex +++ b/src/plugins/e-acsl/doc/refman/fn_behavior.tex @@ -1,6 +1,6 @@ \begin{syntax} - [ function-contract ] ::= requires-clause*; - { decreases-clause? } simple-clause*; + [ function-contract ] ::= requires-clause* + { decreases-clause? } simple-clause* named-behavior* { completeness-clause* } \ requires-clause ::= "requires" pred ";" @@ -8,6 +8,7 @@ { decreases-clause } ::= { "decreases" term ("for" id)? ";" } \ [ simple-clause ] ::= { assigns-clause } | ensures-clause + | { allocation-clause} | { abrupt-clause } \ { assigns-clause } ::= { "assigns" locations ";" } \ diff --git a/src/plugins/e-acsl/doc/refman/intro_modern.tex b/src/plugins/e-acsl/doc/refman/intro_modern.tex index a3bcb11f398..472b6cf40aa 100644 --- a/src/plugins/e-acsl/doc/refman/intro_modern.tex +++ b/src/plugins/e-acsl/doc/refman/intro_modern.tex @@ -43,7 +43,7 @@ currently implemented into the \framac's \eacsl plug-in. \begin{center} \begin{tabular}{|l|l|} \hline - typing + typing & mathematical reals \\ \hline terms @@ -52,7 +52,7 @@ currently implemented into the \framac's \eacsl plug-in. & let binding \\ & t-sets \\ \hline - predicates + predicates & exclusive or operator \\ % \lstinline|^^| & let bindings \\ & quantifications over non-integer types \\ @@ -60,7 +60,7 @@ currently implemented into the \framac's \eacsl plug-in. & \lstinline|\\specified| \\ \hline - annotations + annotations & behavior-specific annotations \\ & loop assigns \\ & loop variants \\ @@ -69,6 +69,7 @@ currently implemented into the \framac's \eacsl plug-in. \hline behavior clauses & assigns \\ + & allocates \\ & decreases \\ & abrupt termination \\ & complete and disjoint behaviors diff --git a/src/plugins/e-acsl/doc/refman/main.tex b/src/plugins/e-acsl/doc/refman/main.tex index 88c2665b313..8f53a75d66c 100644 --- a/src/plugins/e-acsl/doc/refman/main.tex +++ b/src/plugins/e-acsl/doc/refman/main.tex @@ -82,6 +82,7 @@ Patrick Baudin, Bernard Botella, Lo\"ic Correnson, Pascal Cuoq, +Basile Desloges, Johannes Kanig, Fonenantsoa Maurica, David Mentr\'e, diff --git a/src/plugins/e-acsl/doc/refman/speclang_modern.tex b/src/plugins/e-acsl/doc/refman/speclang_modern.tex index c1482c0d65c..7c5b0e5a8ff 100644 --- a/src/plugins/e-acsl/doc/refman/speclang_modern.tex +++ b/src/plugins/e-acsl/doc/refman/speclang_modern.tex @@ -196,7 +196,7 @@ one is valid: \item \lstinline|\exists integer x, 1 <= x <= 0 && -1 <= 1/x <= 1| \end{itemize} In particular, the second one is invalid since the quantification is in fact an -enumeration over a finite number of elements, it amounts to +enumeration over a finite number of elements, it amounts to \lstinline|1/-1 > 0 && 1/0 > 0 && 1/1 > 0|. The first atomic proposition is invalid, so the rest of the conjunction (and in particular 1/0) is not evaluated. The fourth one is invalid since it is an existential quantification @@ -294,13 +294,12 @@ It is not possible to define logic types introduced by the specification writer \label{sec:fn-behavior} \index{function contract}\index{contract} -\except{no \lstinline|terminates| and \lstinline|abrupt| clauses} +\except{no \lstinline|terminates|} Figure~\ref{fig:gram:contracts} shows grammar of function contracts. This is a simplified version of \acsl one without -\lstinline|terminates| and \lstinline|abrupt| -clauses. Section~\ref{sec:termination} (resp.~\ref{sec:abrupt}) explains why -\eacsl has no \lstinline|terminates| (resp. \lstinline|abrupt|) clause. +\lstinline|terminates| clauses. Section~\ref{sec:termination} explains why +\eacsl has no \lstinline|terminates| clause. \begin{figure}[htbp] \begin{cadre} @@ -370,7 +369,7 @@ members easily identifiable. \begin{notimplementedenv} \begin{example}\label{ex:tset} -The set \lstinlineµ{ x | integer x; 0 <= x <= 9 || 20 <= x <= 29 }µ denotes the +The set \lstinlineµ{ x | integer x; 0 <= x <= 9 || 20 <= x <= 29 }µ denotes the set of all integers between 0 and 9 and between 20 and 29. \end{example} \end{notimplementedenv} @@ -422,7 +421,7 @@ Figure~\ref{fig:gram:assertions} summarizes grammar for assertions. \except{loop invariants lose their inductive nature} Figure~\ref{fig:gram:loops} shows grammar for loop annotations. There is no -syntactic difference with \acsl. +syntactic difference with \acsl. \begin{figure}[htbp] \begin{cadre} \input{loops_modern.bnf} @@ -453,7 +452,7 @@ In \eacsl, the same loop invariant $I$ is valid if and only if: \begin{itemize} \item $I$ holds before entering the loop; and \item if execution of the loop body in that state ends normally at the end of - the body or with a "continue" statement, $I$ is true in the resulting state. + the body or with a "continue" statement, $I$ is true in the resulting state. \end{itemize} Thus the only difference with \acsl is that \eacsl does not assume that the @@ -543,11 +542,9 @@ definition of its upper bound. \label{sec:statement_contract} \index{statement contract}\index{contract} -\except{no \lstinline|abrupt| clauses} +\nodiff -Figure~\ref{fig:gram:contracts} shows grammar of statement contracts. Like -function contracts, this is a simplified version of \acsl with no -\lstinline|abrupt| clauses. All other constructs are unchanged. +Figure~\ref{fig:gram:stcontracts} shows grammar of statement contracts. \begin{figure}[htbp] \begin{cadre} @@ -706,7 +703,7 @@ predicates which are related to memory location. \nodiff \difficultswhy{\lstinline|\\base\_addr|, - \lstinline|\\block\_length|, \lstinline|\\valid|, + \lstinline|\\block\_length|, \lstinline|\\valid|, \lstinline|\\valid_read| and \lstinline|\\offset|}{the implementation of a memory model} @@ -723,9 +720,7 @@ predicates which are related to memory location. \subsection{Allocation and deallocation} \difficultswhy{All these constructs}{the implementation of a memory model} \label{sec:alloc-dealloc} - -\mywarning{this section is still almost experimental in \acsl. Thus it might still -evolve in the future.} +\nodiff %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -753,8 +748,21 @@ Figure~\ref{fig:gram:list} shows the notations for built-in lists. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\section{Abrupt termination}\label{sec:abrupt} -\absentexperimental +\section{\notimplemented{Abrupt termination}} +\label{sec:abrupt} +\index{abrupt termination} + +\nodiff + +Figure~\ref{fig:gram:abrupt} shows grammar of abrupt termination. + +\begin{figure}[htbp] + \begin{cadre} + \input{abrupt_modern.bnf} + \end{cadre} + \caption{Grammar of contracts about abrupt terminations} + \label{fig:gram:abrupt} +\end{figure} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% diff --git a/src/plugins/e-acsl/doc/refman/st_contracts.tex b/src/plugins/e-acsl/doc/refman/st_contracts.tex index 498e9a73899..8aefcbe9f32 100644 --- a/src/plugins/e-acsl/doc/refman/st_contracts.tex +++ b/src/plugins/e-acsl/doc/refman/st_contracts.tex @@ -2,9 +2,11 @@ statement ::= "/*@" statement-contract "*/" statement \ [ statement-contract ] ::= {("for" id ("," id)* ":")?} requires-clause* ; - simple-clause* named-behavior-stmt* ; + simple-clause-stmt* named-behavior-stmt* ; completeness-clause* \ + simple-clause-stmt ::= simple-clause | { abrupt-clause-stmt } + \ named-behavior-stmt ::= "behavior" id ":" behavior-body-stmt \ behavior-body-stmt ::= assumes-clause* ; -- GitLab From d0c15bc9a92c37ee8646a5dea58cd60ad9de4226 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Loi=CC=88c=20Correnson?= <loic.correnson@cea.fr> Date: Thu, 2 Apr 2020 15:59:10 +0200 Subject: [PATCH 126/218] [eacsl:test] Update test oracles --- .../at_on-purely-logic-variables.res.oracle | 24 +++++++------ .../gen_at_on-purely-logic-variables.c | 36 ++++++++++++------- .../tests/arith/oracle_ci/gen_rationals.c | 4 +-- .../oracle_ci/gen_functions_contiki.c | 2 +- .../tests/memory/oracle_ci/gen_memsize.c | 18 +++++----- 5 files changed, 50 insertions(+), 34 deletions(-) diff --git a/src/plugins/e-acsl/tests/arith/oracle_ci/at_on-purely-logic-variables.res.oracle b/src/plugins/e-acsl/tests/arith/oracle_ci/at_on-purely-logic-variables.res.oracle index 0b02e09b98b..ceb8eed7a93 100644 --- a/src/plugins/e-acsl/tests/arith/oracle_ci/at_on-purely-logic-variables.res.oracle +++ b/src/plugins/e-acsl/tests/arith/oracle_ci/at_on-purely-logic-variables.res.oracle @@ -13,7 +13,7 @@ assertion got status unknown. [eva:alarm] tests/arith/at_on-purely-logic-variables.c:29: Warning: accessing uninitialized left-value. - assert \initialized(__gen_e_acsl_at_2 + (__gen_e_acsl_j - 2)); + assert \initialized(__gen_e_acsl_at_2 + (int)(__gen_e_acsl_j - 2)); [eva:alarm] tests/arith/at_on-purely-logic-variables.c:29: Warning: function __e_acsl_assert: precondition got status unknown. [eva:alarm] tests/arith/at_on-purely-logic-variables.c:29: Warning: @@ -24,7 +24,8 @@ accessing uninitialized left-value. assert \initialized(__gen_e_acsl_at_3 + - ((__gen_e_acsl_u - 9) * 11 + ((__gen_e_acsl_v - -5) - 1))); + (int)((int)((int)(__gen_e_acsl_u - 9) * 11) + + (int)((int)(__gen_e_acsl_v - -5) - 1))); [eva:alarm] tests/arith/at_on-purely-logic-variables.c:34: Warning: function __e_acsl_assert: precondition got status unknown. [eva:alarm] tests/arith/at_on-purely-logic-variables.c:31: Warning: @@ -33,7 +34,8 @@ assertion got status unknown. [eva:alarm] tests/arith/at_on-purely-logic-variables.c:41: Warning: accessing uninitialized left-value. - assert \initialized(__gen_e_acsl_at_5 + ((__gen_e_acsl_k_3 - -9) - 1)); + assert + \initialized(__gen_e_acsl_at_5 + (int)((int)(__gen_e_acsl_k_3 - -9) - 1)); [eva:alarm] tests/arith/at_on-purely-logic-variables.c:41: Warning: function __e_acsl_assert: precondition got status unknown. [eva:alarm] tests/arith/at_on-purely-logic-variables.c:41: Warning: @@ -44,17 +46,19 @@ accessing uninitialized left-value. assert \initialized(__gen_e_acsl_at_6 + - ((__gen_e_acsl_u_3 - 9) * 32 + ((__gen_e_acsl_v_3 - -5) - 1))); + (int)((int)((int)(__gen_e_acsl_u_3 - 9) * 32) + + (int)((int)(__gen_e_acsl_v_3 - -5) - 1))); [eva:alarm] tests/arith/at_on-purely-logic-variables.c:45: Warning: function __e_acsl_assert: precondition got status unknown. [eva:alarm] tests/arith/at_on-purely-logic-variables.c:43: Warning: assertion got status unknown. [eva:alarm] tests/arith/at_on-purely-logic-variables.c:7: Warning: accessing uninitialized left-value. - assert \initialized(__gen_e_acsl_at + ((__gen_e_acsl_n - 1) - 1)); + assert \initialized(__gen_e_acsl_at + (int)((int)(__gen_e_acsl_n - 1) - 1)); [eva:alarm] tests/arith/at_on-purely-logic-variables.c:7: Warning: accessing uninitialized left-value. - assert \initialized(__gen_e_acsl_at_2 + ((__gen_e_acsl_n - 1) - 1)); + assert + \initialized(__gen_e_acsl_at_2 + (int)((int)(__gen_e_acsl_n - 1) - 1)); [eva:alarm] tests/arith/at_on-purely-logic-variables.c:7: Warning: function __e_acsl_assert: precondition got status unknown. [eva:alarm] tests/arith/at_on-purely-logic-variables.c:7: Warning: @@ -63,7 +67,7 @@ function __gen_e_acsl_f: postcondition got status unknown. [eva:alarm] tests/arith/at_on-purely-logic-variables.c:16: Warning: accessing uninitialized left-value. - assert \initialized(__gen_e_acsl_at + (__gen_e_acsl_w - 3)); + assert \initialized(__gen_e_acsl_at + (int)(__gen_e_acsl_w - 3)); [eva:alarm] tests/arith/at_on-purely-logic-variables.c:16: Warning: function __e_acsl_assert: precondition got status unknown. [eva:alarm] tests/arith/at_on-purely-logic-variables.c:16: Warning: @@ -74,9 +78,9 @@ accessing uninitialized left-value. assert \initialized(__gen_e_acsl_at_7 + - ((__gen_e_acsl_u_5 - 10) * 300 + - (((__gen_e_acsl_v_5 - -10) - 1) * 100 + - ((__gen_e_acsl_w - 100) - 1)))); + (int)((int)((int)(__gen_e_acsl_u_5 - 10) * 300) + + (int)((int)((int)((int)(__gen_e_acsl_v_5 - -10) - 1) * 100) + + (int)((int)(__gen_e_acsl_w - 100) - 1)))); [eva:alarm] tests/arith/at_on-purely-logic-variables.c:54: Warning: assertion got status unknown. [eva:alarm] tests/arith/at_on-purely-logic-variables.c:63: Warning: diff --git a/src/plugins/e-acsl/tests/arith/oracle_ci/gen_at_on-purely-logic-variables.c b/src/plugins/e-acsl/tests/arith/oracle_ci/gen_at_on-purely-logic-variables.c index 007bc6daa68..17dee710545 100644 --- a/src/plugins/e-acsl/tests/arith/oracle_ci/gen_at_on-purely-logic-variables.c +++ b/src/plugins/e-acsl/tests/arith/oracle_ci/gen_at_on-purely-logic-variables.c @@ -56,7 +56,7 @@ void g(void) "tests/arith/at_on-purely-logic-variables.c",16); /*@ assert Eva: initialization: - \initialized(__gen_e_acsl_at + (__gen_e_acsl_w - 3)); + \initialized(__gen_e_acsl_at + (int)(__gen_e_acsl_w - 3)); */ if (! *(__gen_e_acsl_at + (__gen_e_acsl_w - 3))) ; else { @@ -240,7 +240,7 @@ int main(void) "tests/arith/at_on-purely-logic-variables.c",29); /*@ assert Eva: initialization: - \initialized(__gen_e_acsl_at_2 + (__gen_e_acsl_j - 2)); + \initialized(__gen_e_acsl_at_2 + (int)(__gen_e_acsl_j - 2)); */ if (! *(__gen_e_acsl_at_2 + (__gen_e_acsl_j - 2))) ; else { @@ -289,8 +289,8 @@ int main(void) /*@ assert Eva: initialization: \initialized(__gen_e_acsl_at_3 + - ((__gen_e_acsl_u - 9) * 11 + - ((__gen_e_acsl_v - -5) - 1))); + (int)((int)((int)(__gen_e_acsl_u - 9) * 11) + + (int)((int)(__gen_e_acsl_v - -5) - 1))); */ if (*(__gen_e_acsl_at_3 + ((__gen_e_acsl_u - 9) * 11 + (( __gen_e_acsl_v - -5) - 1)))) @@ -374,7 +374,8 @@ int main(void) "tests/arith/at_on-purely-logic-variables.c",41); /*@ assert Eva: initialization: - \initialized(__gen_e_acsl_at_5 + ((__gen_e_acsl_k_3 - -9) - 1)); + \initialized(__gen_e_acsl_at_5 + + (int)((int)(__gen_e_acsl_k_3 - -9) - 1)); */ if (! (*(__gen_e_acsl_at_5 + ((__gen_e_acsl_k_3 - -9) - 1)) == 0L)) ; @@ -427,8 +428,9 @@ int main(void) /*@ assert Eva: initialization: \initialized(__gen_e_acsl_at_6 + - ((__gen_e_acsl_u_3 - 9) * 32 + - ((__gen_e_acsl_v_3 - -5) - 1))); + (int)((int)((int)(__gen_e_acsl_u_3 - 9) * 32) + + + (int)((int)(__gen_e_acsl_v_3 - -5) - 1))); */ if (*(__gen_e_acsl_at_6 + ((__gen_e_acsl_u_3 - 9) * 32 + ( (__gen_e_acsl_v_3 - -5) - 1)))) @@ -514,9 +516,17 @@ int main(void) /*@ assert Eva: initialization: \initialized(__gen_e_acsl_at_7 + - ((__gen_e_acsl_u_5 - 10) * 300 + - (((__gen_e_acsl_v_5 - -10) - 1) * 100 + - ((__gen_e_acsl_w - 100) - 1)))); + (int)((int)((int)(__gen_e_acsl_u_5 - 10) * + 300) + + + (int)((int)((int)((int)(__gen_e_acsl_v_5 + - -10) + - 1) + * 100) + + + (int)((int)(__gen_e_acsl_w - + 100) + - 1)))); */ if (! *(__gen_e_acsl_at_7 + ((__gen_e_acsl_u_5 - 10) * 300 + ( ((__gen_e_acsl_v_5 - -10) - 1) * 100 + ( @@ -650,7 +660,8 @@ void __gen_e_acsl_f(int *t) "tests/arith/at_on-purely-logic-variables.c",7); /*@ assert Eva: initialization: - \initialized(__gen_e_acsl_at + ((__gen_e_acsl_n - 1) - 1)); + \initialized(__gen_e_acsl_at + + (int)((int)(__gen_e_acsl_n - 1) - 1)); */ if (*(__gen_e_acsl_at + ((__gen_e_acsl_n - 1) - 1))) { int __gen_e_acsl_valid_read_2; @@ -665,7 +676,8 @@ void __gen_e_acsl_f(int *t) "tests/arith/at_on-purely-logic-variables.c",7); /*@ assert Eva: initialization: - \initialized(__gen_e_acsl_at_2 + ((__gen_e_acsl_n - 1) - 1)); + \initialized(__gen_e_acsl_at_2 + + (int)((int)(__gen_e_acsl_n - 1) - 1)); */ __gen_e_acsl_and = *(__gen_e_acsl_at_2 + ((__gen_e_acsl_n - 1) - 1)); } diff --git a/src/plugins/e-acsl/tests/arith/oracle_ci/gen_rationals.c b/src/plugins/e-acsl/tests/arith/oracle_ci/gen_rationals.c index bd22a341b9b..7943b9907d6 100644 --- a/src/plugins/e-acsl/tests/arith/oracle_ci/gen_rationals.c +++ b/src/plugins/e-acsl/tests/arith/oracle_ci/gen_rationals.c @@ -57,9 +57,9 @@ int main(void) __gmpq_clear(__gen_e_acsl__4); } /*@ assert 0.1 ≡ 0.1; */ ; - __e_acsl_assert(1,"Assertion","main","(double)1.0 == 1.0", + __e_acsl_assert(1,"Assertion","main","1.0 == 1.0", "tests/arith/rationals.c",14); - /*@ assert (double)1.0 ≡ 1.0; */ ; + /*@ assert 1.0 ≡ 1.0; */ ; { __e_acsl_mpq_t __gen_e_acsl__5; double __gen_e_acsl__6; diff --git a/src/plugins/e-acsl/tests/examples/oracle_ci/gen_functions_contiki.c b/src/plugins/e-acsl/tests/examples/oracle_ci/gen_functions_contiki.c index 259afb2e7cf..47e55d3fc12 100644 --- a/src/plugins/e-acsl/tests/examples/oracle_ci/gen_functions_contiki.c +++ b/src/plugins/e-acsl/tests/examples/oracle_ci/gen_functions_contiki.c @@ -8,7 +8,7 @@ struct list { /*@ logic ℤ length_aux{L}(struct list *l, ℤ n) = \at(n < 0? -1: - (l ≡ (struct list *)((void *)0)? n: + (l ≡ (struct list *)0? n: (n < 2147483647? length_aux(l->next, n + 1): -1)), L); */ diff --git a/src/plugins/e-acsl/tests/memory/oracle_ci/gen_memsize.c b/src/plugins/e-acsl/tests/memory/oracle_ci/gen_memsize.c index a7e98e9b929..60fc5642381 100644 --- a/src/plugins/e-acsl/tests/memory/oracle_ci/gen_memsize.c +++ b/src/plugins/e-acsl/tests/memory/oracle_ci/gen_memsize.c @@ -57,25 +57,25 @@ int main(int argc, char **argv) "__e_acsl_heap_allocation_size == 16", "tests/memory/memsize.c",50); /*@ assert __e_acsl_heap_allocation_size ≡ 16; */ ; - __e_acsl_assert(b == (char *)0,"Assertion","main", - "b == (char *)((void *)0)","tests/memory/memsize.c",51); - /*@ assert b ≡ (char *)((void *)0); */ ; + __e_acsl_assert(b == (char *)0,"Assertion","main","b == (char *)0", + "tests/memory/memsize.c",51); + /*@ assert b ≡ (char *)0; */ ; b = (char *)calloc(18446744073709551615UL,18446744073709551615UL); __e_acsl_assert(__e_acsl_heap_allocation_size == 16UL,"Assertion","main", "__e_acsl_heap_allocation_size == 16", "tests/memory/memsize.c",55); /*@ assert __e_acsl_heap_allocation_size ≡ 16; */ ; - __e_acsl_assert(b == (char *)0,"Assertion","main", - "b == (char *)((void *)0)","tests/memory/memsize.c",56); - /*@ assert b ≡ (char *)((void *)0); */ ; + __e_acsl_assert(b == (char *)0,"Assertion","main","b == (char *)0", + "tests/memory/memsize.c",56); + /*@ assert b ≡ (char *)0; */ ; b = (char *)malloc(18446744073709551615UL); __e_acsl_assert(__e_acsl_heap_allocation_size == 16UL,"Assertion","main", "__e_acsl_heap_allocation_size == 16", "tests/memory/memsize.c",60); /*@ assert __e_acsl_heap_allocation_size ≡ 16; */ ; - __e_acsl_assert(b == (char *)0,"Assertion","main", - "b == (char *)((void *)0)","tests/memory/memsize.c",61); - /*@ assert b ≡ (char *)((void *)0); */ ; + __e_acsl_assert(b == (char *)0,"Assertion","main","b == (char *)0", + "tests/memory/memsize.c",61); + /*@ assert b ≡ (char *)0; */ ; __retres = 0; __e_acsl_memory_clean(); return __retres; -- GitLab From 319e6d2f0b75911094d5cd182be9355a08777fc5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Loi=CC=88c=20Correnson?= <loic.correnson@cea.fr> Date: Thu, 2 Apr 2020 16:53:58 +0200 Subject: [PATCH 127/218] [logic-interp] avoid creating non-supported long-double ops --- src/kernel_services/analysis/logic_interp.ml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kernel_services/analysis/logic_interp.ml b/src/kernel_services/analysis/logic_interp.ml index 99fd4b2c8a7..ca8044ead8d 100644 --- a/src/kernel_services/analysis/logic_interp.ml +++ b/src/kernel_services/analysis/logic_interp.ml @@ -200,7 +200,7 @@ let rec logic_type_to_typ = function | Ctype typ -> typ | Linteger -> TInt(ILongLong,[]) (*TODO: to have an unlimited integer type in the logic interpretation*) - | Lreal -> TFloat(FLongDouble,[]) (* TODO: handle reals, not floats... *) + | Lreal -> TFloat(FDouble,[]) (* TODO: handle reals, not floats... *) | Ltype({lt_name = name},[]) when name = Utf8_logic.boolean -> TInt(ILongLong,[]) | Ltype({lt_name = "set"},[t]) -> logic_type_to_typ t -- GitLab From 90fddb3dbad1a2cc2cb34cda03d1a8a8d2410151 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20B=C3=BChler?= <david.buhler@cea.fr> Date: Fri, 27 Mar 2020 11:32:37 +0100 Subject: [PATCH 128/218] [Kernel] Documents new options -warn-invalid-pointer and -warn-pointer-downcast. In the user manual and in the man page. --- doc/userman/user-analysis.tex | 27 +++++++++++++++++++++++++++ doc/userman/user-changes.tex | 2 ++ man/frama-c.1.md | 7 +++++++ 3 files changed, 36 insertions(+) diff --git a/doc/userman/user-analysis.tex b/doc/userman/user-analysis.tex index d82d08717a8..89fdc0a9b59 100644 --- a/doc/userman/user-analysis.tex +++ b/doc/userman/user-analysis.tex @@ -152,6 +152,23 @@ With \texttt{-safe-arrays}, the two accesses to \lstinline|v| are considered invalid. (Accessing \lstinline|v.b[-2]| or \lstinline|v.b[3]| remains incorrect, regardless of the value of the option.) +\item \optiondef{-}{warn-invalid-pointer} may be used to check that the code + does not perform illegal pointer arithmetics, creating pointers that do not + point inside an object or one past an object. + This option is disabled by default, allowing the creation of such invalid + pointers without alarm — but the dereference of an invalid pointer + \emph{always} generate an alarm. + + For instance, no error is detected by default in the following example, as + the dereference is correct. However, if option \texttt{-warn-invalid-pointer} + is enabled, an error is detected at line 4. + \begin{ccode} + int x; + int *p = &x; + p++; // valid + p++; // undefined behavior + *(p-2) = 1; + \end{ccode} \item \optiondef{-}{unspecified-access} may be used to check when the evaluation of an expression depends on the order in which its sub-expressions @@ -179,6 +196,16 @@ Here, the \texttt{x} might be incremented by \texttt{g} before or after the call to \texttt{f}, but since the two write accesses occur in different functions, \texttt{-unspecified-access} does not detect that. +\item \optiondef{-}{warn-pointer-downcast} may be used to check that the code + does not downcast a pointer to an integer type. This option is set by default. + In the following example, analyzers report by default an error on the third + line. Disabling the option removes this verification. + \begin{ccode} + int x; + uintptr_t addr = &x; + int a = &x; + \end{ccode} + \item \optiondef{-}{warn-signed-downcast} may be used to check that the analyzed code does not downcast an integer to a signed integer type. This option is \emph{not} set by default. Without it, the analyzers do not perform such a diff --git a/doc/userman/user-changes.tex b/doc/userman/user-changes.tex index 75f767128b9..262793fefb0 100644 --- a/doc/userman/user-changes.tex +++ b/doc/userman/user-changes.tex @@ -8,6 +8,8 @@ release. First we list changes of the last release. \begin{itemize} \item \textbf{Preparing the Sources:} added option \texttt{-cpp-extra-args-per-file}. +\item \textbf{Customizing Analyzers:} added options + \texttt{-warn-invalid-pointer} and \texttt{-warn-pointer-downcast} \end{itemize} \section*{20.0 (Calcium)} diff --git a/man/frama-c.1.md b/man/frama-c.1.md index c5835e67eb2..319c04fc20a 100644 --- a/man/frama-c.1.md +++ b/man/frama-c.1.md @@ -450,12 +450,19 @@ the case (this is the default). **Deprecated**: use **-kernel-warn-key parser:decimal-float=once** (and variants) instead. +[-no]-warn-invalid-pointer +: generate alarms for invalid pointer arithmetic. Defaults to no. + [-no]-warn-left-shift-negative : generate alarms for signed left shifts on negative values. Defaults to yes. [-no]-warn-right-shift-negative : generate alarms for signed right shifts on negative values. Defaults to no. +[-no]-warn-pointer-downcast +: generates alarms when the downcast of a pointer may exceed the destination +range. Defaults to yes. + [-no]-warn-signed-downcast : generates alarms when signed downcasts may exceed the destination range. Defaults to no. -- GitLab From b2e0f84158143ede0594181e4f115837f6355f08 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20B=C3=BChler?= <david.buhler@cea.fr> Date: Fri, 27 Mar 2020 11:42:03 +0100 Subject: [PATCH 129/218] [Eva] Documents new option -warn-invalid-pointer and -warn-pointer-downcast. --- doc/value/examples/alarms/pointer_arith.c | 5 ++ .../examples/alarms/pointer_conversion.c | 7 +++ doc/value/main.tex | 58 +++++++++++++++++++ 3 files changed, 70 insertions(+) create mode 100644 doc/value/examples/alarms/pointer_arith.c create mode 100644 doc/value/examples/alarms/pointer_conversion.c diff --git a/doc/value/examples/alarms/pointer_arith.c b/doc/value/examples/alarms/pointer_arith.c new file mode 100644 index 00000000000..2f66edd726d --- /dev/null +++ b/doc/value/examples/alarms/pointer_arith.c @@ -0,0 +1,5 @@ +void main () { + int x, *p = &x; + p++; + p++; +} diff --git a/doc/value/examples/alarms/pointer_conversion.c b/doc/value/examples/alarms/pointer_conversion.c new file mode 100644 index 00000000000..599a1f8645c --- /dev/null +++ b/doc/value/examples/alarms/pointer_conversion.c @@ -0,0 +1,7 @@ +#include <stdint.h> +void main () { + char c; + uintptr_t a = &c; + char *p = (char *) (a + 1); + char *q = (char *) (a + 2); +} diff --git a/doc/value/main.tex b/doc/value/main.tex index 6a79827826a..3da22e9e828 100644 --- a/doc/value/main.tex +++ b/doc/value/main.tex @@ -1460,6 +1460,58 @@ to the attitude described in \ref{norme_pratique}. An option to warn about these lines could happen if there was demand for this feature. +\subsubsection{Invalid pointer arithmetic} + +By default, \Eva{} does \emph{not} emit alarms on invalid pointer arithmetic: +alarms are only emitted when an invalid pointer is dereferenced or wrongly used +in a comparison, not at the creation of such pointers. + +However, if the \lstinline|-warn-invalid-pointer| option is enabled, +\Eva{} emits an alarm when an operation may create a pointer that does +not point inside an object or one past an object, +even if this pointer is not used afterward. + +This may happen on: +\begin{itemize} +\item addition (or subtraction) of an integer from a pointer, when the analysis + is unable to prove that the resulting pointer points inside, or one past, + the same object pointed to by the initial pointer. + In this case, the emitted alarm reports a possible undefined behavior. +\item conversion of an integer into a pointer. Except for the constant~0, + such a conversion is always an implementation-defined behavior + according to the ISO C99 standard. However, a footnote also explains that + conversion between pointers and integers is ``\emph{intended to + be consistent with the addressing structure of the execution environment}''. + This is why Eva also also authorizes conversion of integers: + \begin{itemize} + \item in the range of valid absolute addresses + (according to \texttt{absolute-valid-range}) + \item computed from the address of an object \lstinline|o| such that the + resulting pointer points inside or one past the object \lstinline|o|. + \end{itemize} + In all other cases, an alarm is emitted, which reports the possible + implementation-defined behavior mentionned above. +\end{itemize} + +In the example below, the first increment of the pointer \lstinline|p| is valid, +although the resulting pointer should not be dereferenced. The second increment +leads to an invalid alarm when option \lstinline|-warn-invalid-pointer| is on. +\listinginput{1}{examples/alarms/pointer_arith.c} +\begin{logs} + [eva:alarm] pointer_arith.c:4: Warning: + invalid pointer creation. assert \object_pointer(p + 1); +\end{logs} + +In the same way, in the example below, the first conversion at line~5 +does not generate an alarm, but the second conversion leads to an invalid alarm +with option \lstinline|-warn-invalid-pointer|. + +\listinginput{1}{examples/alarms/pointer_conversion.c} +\begin{logs} + [eva:alarm] pointer_arith.c:6: Warning: + invalid pointer creation. assert \object_pointer((char *)(a + 2)); +\end{logs} + \subsubsection{Division by zero} When dividing by an expression that the analysis @@ -1540,6 +1592,12 @@ defined semantics according to the ISO/IEC 9899:1999 standard. If one wishes to signal and prevent such unsigned overflows, option \verb+-warn-unsigned-overflow+ can be used. +By default, Eva emits alarms for downcasts of pointer values to (signed +or unsigned) integer types. Such downcasts are indeed undefined behavior +according to section 6.3.2.3, §6 of the ISO/IE 9899:1999 standard. +However, option \lstinline|-no-warn-pointer-downcast| can be used to disable +these alarms. + Finally, by default, no alarm is emitted for downcasts to signed or unsigned integers. In the signed case, the least significant bits of the original value are used, and are interpreted according -- GitLab From bebf6337c9d99a29cdb864e42c9273f7f4822d33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20B=C3=BChler?= <david.buhler@cea.fr> Date: Thu, 2 Apr 2020 16:53:29 +0200 Subject: [PATCH 130/218] [rte] Documents new option -warn-invalid-pointer and -warn-pointer-downcast. --- doc/rte/rte.tex | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/doc/rte/rte.tex b/doc/rte/rte.tex index 260b1e10663..8db61fe2d61 100644 --- a/doc/rte/rte.tex +++ b/doc/rte/rte.tex @@ -805,6 +805,9 @@ signed overflows \\ \lstinline|-warn-signed-downcast| & boolean (false) & Generate annotations for signed integer downcast \\ \hline +\lstinline|-warn-pointer-downcast| & boolean (true) & Generate annotations for +downcast of pointer values \\ +\hline \lstinline|-warn-left-shift-negative| & boolean (true) & Generate annotations for left shift on negative values \\ \hline @@ -817,6 +820,9 @@ right shift on negative values \\ \lstinline|-warn-special-float| & string: \lstinline|non-finite|, (\lstinline|nan|) or \lstinline|none| & generate annotations when special floats are produced: infinite floats or NaN (by default), only on NaN or never. \\ \hline +\lstinline|-warn-invalid-pointer| & boolean (false) & Generate annotations for +invalid pointer arithmetic \\ +\hline \end{tabular} \caption{\framac kernel options, impacting \rte{}} \label{kernel} \end{center} -- GitLab From 6af7ddfeec6b18fb685e521863ffc5224989e0aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20B=C3=BChler?= <david.buhler@cea.fr> Date: Thu, 2 Apr 2020 16:55:05 +0200 Subject: [PATCH 131/218] [rte] Doc: fixes the default value of option -warn-special-float. --- doc/rte/rte.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/rte/rte.tex b/doc/rte/rte.tex index 8db61fe2d61..228c049928b 100644 --- a/doc/rte/rte.tex +++ b/doc/rte/rte.tex @@ -817,7 +817,7 @@ right shift on negative values \\ \lstinline|-warn-invalid-bool| & boolean (true) & Generate annotations for \lstinline|_Bool| trap representations \\ \hline -\lstinline|-warn-special-float| & string: \lstinline|non-finite|, (\lstinline|nan|) or \lstinline|none| & generate annotations when +\lstinline|-warn-special-float| & string: (\lstinline|non-finite|), \lstinline|nan| or \lstinline|none| & generate annotations when special floats are produced: infinite floats or NaN (by default), only on NaN or never. \\ \hline \lstinline|-warn-invalid-pointer| & boolean (false) & Generate annotations for -- GitLab From 4e43f5ccbffd6d9d6953248afa72510611a96bff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20B=C3=BChler?= <david.buhler@cea.fr> Date: Thu, 2 Apr 2020 17:54:16 +0200 Subject: [PATCH 132/218] [Eva] Fixes the user manuel: Eva warns on indeterminate copies by default. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since 2016… --- doc/value/main.tex | 37 +++++++++++++++++++------------------ 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/doc/value/main.tex b/doc/value/main.tex index 6a79827826a..7db1b55844c 100644 --- a/doc/value/main.tex +++ b/doc/value/main.tex @@ -1628,13 +1628,25 @@ uninitialized.c:13: ... accessing left-value that contains escaping addresses. assert !\dangling(&p); \end{logs} -By default, \Eva{} does not emit an alarm for a copy from memory -to memory when the copied values include dangling addresses or uninitialized -contents. This behavior is safe because \Eva{} warns later, as soon -as an unsafe value is used in a computation --either directly or -after having been copied from another location. -The copy operations for which alarms are not emitted are assignments -from lvalues to lvalues (\lstinline|lv1 = lv2;|), passing lvalues +By default, \Eva{} emits an alarm as soon as a value that may be uninitialized +or a dangling address is read, even if this value is not used in any computation. + +However, it may be normal for some fields in a struct or union to contain +such dangerous contents in some cases. +Thus, \Eva{} \emph{never} emits an alarm for a copy from memory to memory +of a struct or an union containing dangling addresses or uninitialized contents. +This behavior is safe because \Eva{} warns later, as soon as an unsafe value is +used in a computation --either directly or after having been copied from another +location. + +This relaxed behavior on structs and unions can be extended to scalar variables +with the option \lstinline|-eva-warn-copy-indeterminate|. +Specifying \lstinline|-eva-warn-copy-indeterminate=-f| on the command-line +will cause the analyzer to not emit alarms on copy operations occurring in +function \lstinline|f|. The syntax \lstinline|-@all| can also be used to +activate this behavior for all functions. +In this mode, the copy operations for which alarms are not emitted are +assignments from lvalues to lvalues (\lstinline|lv1 = lv2;|), passing lvalues as arguments to functions (\lstinline|f(lv1);|), and returning lvalues (\lstinline|return lv1;|). An exception is made for lvalues passed as arguments to library functions: in this case, @@ -1642,17 +1654,6 @@ because the function's code is missing, there is no chance to catch the undefined access later; the analyzer emits an alarm at the point of the call. -The behavior documented above was implemented to avoid spurious warnings where -the copied lvalues are structs or unions. In some cases, it may be normal -for some fields in a struct or union to contain such dangerous contents. - -Option \lstinline|-eva-warn-copy-indeterminate| can be used to obtain a -more aggressive behavior on scalar variables. Specifying \lstinline|-eva-warn-copy-indeterminate f| -on the command-line will cause the analyzer to also emit an alarm on -all dangerous copy operations occurring in function \lstinline|f|, as long as -the copied lvalues are not structs or unions. The syntax \lstinline|@all| -can also be used to activate this behavior for all functions. - \subsubsection{Trap representations of \_Bool values} By default, \Eva{} emits an alarm whenever a trap representation might be read -- GitLab From f758c84b18a939d365ca3b0e0db46ad1775ec8c8 Mon Sep 17 00:00:00 2001 From: Andre Maroneze <andre.oliveiramaroneze@cea.fr> Date: Thu, 2 Apr 2020 18:43:53 +0200 Subject: [PATCH 133/218] [doc] Minor fixes after review --- doc/userman/user-analysis.tex | 8 ++++---- doc/value/main.tex | 4 ++-- man/frama-c.1 | 15 ++++++++++++++- man/frama-c.1.header | 2 +- 4 files changed, 21 insertions(+), 8 deletions(-) diff --git a/doc/userman/user-analysis.tex b/doc/userman/user-analysis.tex index 89fdc0a9b59..926fc9eecd7 100644 --- a/doc/userman/user-analysis.tex +++ b/doc/userman/user-analysis.tex @@ -156,12 +156,12 @@ regardless of the value of the option.) does not perform illegal pointer arithmetics, creating pointers that do not point inside an object or one past an object. This option is disabled by default, allowing the creation of such invalid - pointers without alarm — but the dereference of an invalid pointer - \emph{always} generate an alarm. + pointers without alarm — but the dereferencing of an invalid pointer + \emph{always} generates an alarm. For instance, no error is detected by default in the following example, as - the dereference is correct. However, if option \texttt{-warn-invalid-pointer} - is enabled, an error is detected at line 4. + the dereferencing is correct. However, if option + \texttt{-warn-invalid-pointer} is enabled, an error is detected at line 4. \begin{ccode} int x; int *p = &x; diff --git a/doc/value/main.tex b/doc/value/main.tex index 3da22e9e828..045d671af55 100644 --- a/doc/value/main.tex +++ b/doc/value/main.tex @@ -1490,7 +1490,7 @@ This may happen on: resulting pointer points inside or one past the object \lstinline|o|. \end{itemize} In all other cases, an alarm is emitted, which reports the possible - implementation-defined behavior mentionned above. + implementation-defined behavior mentioned above. \end{itemize} In the example below, the first increment of the pointer \lstinline|p| is valid, @@ -1594,7 +1594,7 @@ option \verb+-warn-unsigned-overflow+ can be used. By default, Eva emits alarms for downcasts of pointer values to (signed or unsigned) integer types. Such downcasts are indeed undefined behavior -according to section 6.3.2.3, §6 of the ISO/IE 9899:1999 standard. +according to section 6.3.2.3, §6 of the ISO/IEC 9899:1999 standard. However, option \lstinline|-no-warn-pointer-downcast| can be used to disable these alarms. diff --git a/man/frama-c.1 b/man/frama-c.1 index 706d54135e1..0fa77b175c6 100644 --- a/man/frama-c.1 +++ b/man/frama-c.1 @@ -25,7 +25,7 @@ .\" using pandoc 2.0 or newer. To modify this file, edit the Markdown file .\" and run `make man/frama-c.1`. -.TH FRAMA-C 1 2020-03-05 +.TH FRAMA-C 1 2020-04-02 .SH NAME .PP frama\-c[.byte] \- a static analyzer for C programs @@ -737,6 +737,12 @@ parser:decimal\-float=once\f[] (and variants) instead. .RS .RE .TP +.B [\-no]\-warn\-invalid\-pointer +generate alarms for invalid pointer arithmetic. +Defaults to no. +.RS +.RE +.TP .B [\-no]\-warn\-left\-shift\-negative generate alarms for signed left shifts on negative values. Defaults to yes. @@ -749,6 +755,13 @@ Defaults to no. .RS .RE .TP +.B [\-no]\-warn\-pointer\-downcast +generates alarms when the downcast of a pointer may exceed the +destination range. +Defaults to yes. +.RS +.RE +.TP .B [\-no]\-warn\-signed\-downcast generates alarms when signed downcasts may exceed the destination range. Defaults to no. diff --git a/man/frama-c.1.header b/man/frama-c.1.header index ce56197c3e9..23512489405 100644 --- a/man/frama-c.1.header +++ b/man/frama-c.1.header @@ -25,4 +25,4 @@ .\" using pandoc 2.0 or newer. To modify this file, edit the Markdown file .\" and run `make man/frama-c.1`. -.TH FRAMA-C 1 2020-03-05 +.TH FRAMA-C 1 2020-04-02 -- GitLab From bdc15d16708c9ae9bbe2dda2d7d965b73e66f2b4 Mon Sep 17 00:00:00 2001 From: Allan Blanchard <allan.blanchard@cea.fr> Date: Fri, 3 Apr 2020 10:02:10 +0200 Subject: [PATCH 134/218] [Instantiate] Global_vars renamed Global_context --- headers/header_spec.txt | 4 ++-- src/plugins/instantiate/Instantiate.mli | 13 ++++++------- src/plugins/instantiate/Makefile.in | 2 +- .../{global_vars.ml => global_context.ml} | 5 ++--- .../{global_vars.mli => global_context.mli} | 13 ++++++------- src/plugins/instantiate/stdlib/basic_alloc.ml | 8 +++++++- .../instantiate/tests/plugin/needs_globals.ml | 9 +++++++-- src/plugins/instantiate/transform.ml | 5 +++-- 8 files changed, 34 insertions(+), 25 deletions(-) rename src/plugins/instantiate/{global_vars.ml => global_context.ml} (94%) rename src/plugins/instantiate/{global_vars.mli => global_context.mli} (81%) diff --git a/headers/header_spec.txt b/headers/header_spec.txt index d9acf0cdd50..91d9557fd95 100644 --- a/headers/header_spec.txt +++ b/headers/header_spec.txt @@ -945,8 +945,8 @@ src/plugins/occurrence/register_gui.ml: CEA_LGPL_OR_PROPRIETARY src/plugins/occurrence/register_gui.mli: CEA_LGPL_OR_PROPRIETARY src/plugins/instantiate/basic_blocks.ml: CEA_LGPL_OR_PROPRIETARY src/plugins/instantiate/basic_blocks.mli: CEA_LGPL_OR_PROPRIETARY -src/plugins/instantiate/global_vars.ml: CEA_LGPL_OR_PROPRIETARY -src/plugins/instantiate/global_vars.mli: CEA_LGPL_OR_PROPRIETARY +src/plugins/instantiate/global_context.ml: CEA_LGPL_OR_PROPRIETARY +src/plugins/instantiate/global_context.mli: CEA_LGPL_OR_PROPRIETARY src/plugins/instantiate/Instantiate.mli: CEA_LGPL_OR_PROPRIETARY src/plugins/instantiate/instantiator_builder.ml: CEA_LGPL_OR_PROPRIETARY src/plugins/instantiate/instantiator_builder.mli: CEA_LGPL_OR_PROPRIETARY diff --git a/src/plugins/instantiate/Instantiate.mli b/src/plugins/instantiate/Instantiate.mli index aaddb8131d0..4444dd5d95b 100644 --- a/src/plugins/instantiate/Instantiate.mli +++ b/src/plugins/instantiate/Instantiate.mli @@ -101,13 +101,12 @@ module Transform: sig val register: (module Instantiator_builder.Generator_sig) -> unit end -module Global_vars:sig - (** [get t ghost storage name] searches for an existing variable [name]. If this - variable does not exists, it is created with the specified type [t], [ghost] - status and [storage]. +module Global_context:sig + (** [get_variable name f] searches for an existing variable [name]. If this + variable does not exists, it is created using [f]. - The obtained varinfo does not need to be registered, it will be done by the - transformation. + The obtained varinfo does not need to be registered, nor [f] needs to + perform the registration, it will be done by the transformation. *) - val get: typ -> bool -> storage -> string -> varinfo + val get_variable: string -> (unit -> varinfo) -> varinfo end diff --git a/src/plugins/instantiate/Makefile.in b/src/plugins/instantiate/Makefile.in index 97c0b467e45..8635d3bace9 100644 --- a/src/plugins/instantiate/Makefile.in +++ b/src/plugins/instantiate/Makefile.in @@ -57,7 +57,7 @@ PLUGIN_EXTRA_DIRS:=\ PLUGIN_CMI := PLUGIN_CMO := \ options basic_blocks \ - global_vars instantiator_builder \ + global_context instantiator_builder \ transform register \ $(SRC_STRING) \ $(SRC_STDLIB) diff --git a/src/plugins/instantiate/global_vars.ml b/src/plugins/instantiate/global_context.ml similarity index 94% rename from src/plugins/instantiate/global_vars.ml rename to src/plugins/instantiate/global_context.ml index 379443e789b..d28b409a52f 100644 --- a/src/plugins/instantiate/global_vars.ml +++ b/src/plugins/instantiate/global_context.ml @@ -23,13 +23,12 @@ module Table = Datatype.String.Hashtbl let table = Table.create 13 -let get typ ghost storage name = +let get_variable name make = if Table.mem table name then Table.find table name else begin try Globals.Vars.find_from_astinfo name VGlobal with Not_found -> - let vi = Cil.makeVarinfo ~ghost true false name typ in - vi.vstorage <- storage ; + let vi = make () in Table.add table name vi ; vi end diff --git a/src/plugins/instantiate/global_vars.mli b/src/plugins/instantiate/global_context.mli similarity index 81% rename from src/plugins/instantiate/global_vars.mli rename to src/plugins/instantiate/global_context.mli index 88b711593ce..66e60036195 100644 --- a/src/plugins/instantiate/global_vars.mli +++ b/src/plugins/instantiate/global_context.mli @@ -26,17 +26,16 @@ open Cil_types by instantiation modules. *) -(** [get t ghost storage name] searches for an existing variable [name]. If this - variable does not exists, it is created with the specified type [t], [ghost] - status and [storage]. +(** [get_variable name f] searches for an existing variable [name]. If this + variable does not exists, it is created using [f]. - The obtained varinfo does not need to be registered, it will be done by the - transformation. + The obtained varinfo does not need to be registered, nor [f] needs to + perform the registration, it will be done by the transformation. *) -val get: typ -> bool -> storage -> string -> varinfo +val get_variable: string -> (unit -> varinfo) -> varinfo (** Clears internal tables *) val clear: unit -> unit -(** Creates a list of global for the variables that have been created *) +(** Creates a list of global for the elements that have been created *) val globals: location -> global list diff --git a/src/plugins/instantiate/stdlib/basic_alloc.ml b/src/plugins/instantiate/stdlib/basic_alloc.ml index d2bb11bd72d..ec54907d18f 100644 --- a/src/plugins/instantiate/stdlib/basic_alloc.ml +++ b/src/plugins/instantiate/stdlib/basic_alloc.ml @@ -61,7 +61,13 @@ let isnt_allocable ?loc size = new_predicate { p with pred_name = [ "allocable" ]} let heap_status () = - let vi = Global_vars.get Cil.intType true Extern "__fc_heap_status" in + let name = "__fc_heap_status" in + let make () = + let vi = Cil.makeVarinfo ~ghost:true true false name Cil.intType in + vi.vstorage <- Extern ; + vi + in + let vi = Global_context.get_variable name make in Basic_blocks.cvar_to_tvar vi let assigns_result ?loc typ deps = diff --git a/src/plugins/instantiate/tests/plugin/needs_globals.ml b/src/plugins/instantiate/tests/plugin/needs_globals.ml index c76373900f5..506da455fdb 100644 --- a/src/plugins/instantiate/tests/plugin/needs_globals.ml +++ b/src/plugins/instantiate/tests/plugin/needs_globals.ml @@ -27,8 +27,13 @@ let generate_prototype function_name t = let generate_spec needed _ _ _ = let open Cil_types in let open Logic_const in - let open Instantiate.Global_vars in - let vi = get Cil.floatType true Cil_types.Extern needed in + let open Instantiate.Global_context in + let make () = + let vi = Cil.makeVarinfo ~ghost:true true false needed Cil.floatType in + vi.vstorage <- Extern ; + vi + in + let vi = get_variable needed make in let t = tvar (Cil.cvar_to_lvar vi) in let assigns = Cil_types.Writes [ Logic_const.new_identified_term t, From [] ] diff --git a/src/plugins/instantiate/transform.ml b/src/plugins/instantiate/transform.ml index 7dda9a46b99..590ee506dbd 100644 --- a/src/plugins/instantiate/transform.ml +++ b/src/plugins/instantiate/transform.ml @@ -38,7 +38,7 @@ let get_kfs () = Hashtbl.fold (fun k v l -> (get_kfs k v) @ l) base [] let clear () = - Global_vars.clear () ; + Global_context.clear () ; let clear _ instantiator = let module I = (val instantiator: Instantiator) in I.clear () @@ -55,7 +55,7 @@ class transformer = object(self) method! vfile _ = let post f = - f.globals <- (Global_vars.globals (Cil.CurrentLoc.get())) @ f.globals ; + f.globals <- (Global_context.globals (Cil.CurrentLoc.get())) @ f.globals ; Ast.mark_as_changed () ; Ast.mark_as_grown () ; f @@ -163,4 +163,5 @@ let compute_statuses_all_kfs () = let transform file = clear () ; Visitor.visitFramacFile (new transformer) file ; + File.reorder_ast () ; compute_statuses_all_kfs () -- GitLab From ee8fa60969ede0e2d922c657b8a53f56efaba549 Mon Sep 17 00:00:00 2001 From: Andre Maroneze <andre.oliveiramaroneze@cea.fr> Date: Tue, 4 Jun 2019 19:19:24 +0200 Subject: [PATCH 135/218] [Eva] very imprecise (but fast) builtins for memory allocation --- .../value/domains/cvalue/builtins_malloc.ml | 148 +++++++++++++++++- tests/builtins/calloc.c | 2 +- tests/builtins/malloc.c | 7 +- tests/builtins/oracle/calloc.5.res.oracle | 57 +++++++ tests/builtins/oracle/malloc.res.oracle | 20 +++ .../oracle/realloc_imprecise.res.oracle | 65 ++++++++ tests/builtins/realloc_imprecise.c | 18 +++ 7 files changed, 310 insertions(+), 7 deletions(-) create mode 100644 tests/builtins/oracle/calloc.5.res.oracle create mode 100644 tests/builtins/oracle/realloc_imprecise.res.oracle create mode 100644 tests/builtins/realloc_imprecise.c diff --git a/src/plugins/value/domains/cvalue/builtins_malloc.ml b/src/plugins/value/domains/cvalue/builtins_malloc.ml index 727ef69ca50..c8588932c9f 100644 --- a/src/plugins/value/domains/cvalue/builtins_malloc.ml +++ b/src/plugins/value/domains/cvalue/builtins_malloc.ml @@ -30,6 +30,9 @@ let dkey = Value_parameters.register_category "malloc" let wkey_weak_alloc = Value_parameters.register_warn_category "malloc:weak" let () = Value_parameters.set_warn_status wkey_weak_alloc Log.Winactive +let wkey_imprecise_alloc = Value_parameters.register_warn_category + "malloc:imprecise" + (** {1 Dynamically allocated bases} *) module Base_hptmap = Hptmap.Make @@ -363,12 +366,103 @@ let () = (alloc_fresh Weak Base.Malloc) ~typ:(fun () -> (Cil.voidPtrType, [Cil.theMachine.Cil.typeOfSizeOf])) +(* Extremely aggressive and imprecise allocation: a single weak base for each + region. *) +module MallocedSingleMalloc = + State_builder.Option_ref(Base.Base) + (struct + let name = "Value.Builtins_malloc.MallocedSingleMalloc" + let dependencies = [Ast.self] + end) +let () = Ast.add_monotonic_state MallocedSingleMalloc.self + +module MallocedSingleVLA = + State_builder.Option_ref(Base.Base) + (struct + let name = "Value.Builtins_malloc.MallocedSingleVLA" + let dependencies = [Ast.self] + end) +let () = Ast.add_monotonic_state MallocedSingleVLA.self + +module MallocedSingleAlloca = + State_builder.Option_ref(Base.Base) + (struct + let name = "Value.Builtins_malloc.MallocedSingleAlloca" + let dependencies = [Ast.self] + end) +let () = Ast.add_monotonic_state MallocedSingleAlloca.self + +let string_of_region = function + | Base.Malloc -> "via malloc/calloc/realloc" + | Base.VLA -> "related to variable-length arrays" + | Base.Alloca -> "via alloca" + +(* Only called when the 'weakest base' needs to be allocated. *) +let alloc_imprecise_weakest_alloc region _stack _prefix _sizev _state = + let stack = [ fst (Globals.entry_point ()), Kglobal ] in + let type_base = + TArray (Cil.charType, None, Cil.empty_size_cache (), []) + in + let var = create_new_var stack "alloc" type_base Weak in + Value_parameters.warning ~wkey:wkey_imprecise_alloc ~current:true ~once:true + "@[warning: allocating a single weak variable for ALL dynamic allocations %s: %a@]" + (string_of_region region) Printer.pp_varinfo var; + let variable_v = Base.create_variable_validity ~weak:true + ~min_alloc:Int.minus_one ~max_alloc:(Bit_utils.max_bit_address ()) in + let new_base = Base.register_allocated_var var region (Base.Variable variable_v) in + register_malloced_base ~stack new_base; + new_base, Bit_utils.max_bit_address () + +(* used by calloc_abstract *) +let alloc_imprecise_weakest_abstract region _stack _prefix _sizev state = + let datatype_get_option, datatype_set = + match region with + | Base.Malloc -> MallocedSingleMalloc.get_option, MallocedSingleMalloc.set + | Base.VLA -> MallocedSingleVLA.get_option, MallocedSingleVLA.set + | Base.Alloca -> MallocedSingleAlloca.get_option, MallocedSingleAlloca.set + in + match datatype_get_option () with + | None -> + let new_base, _ as r = + alloc_imprecise_weakest_alloc region _stack _prefix _sizev state + in + datatype_set new_base; + r + | Some base -> base, Bit_utils.max_bit_address () + +let alloc_imprecise_weakest_aux region _stack _prefix _sizev state = + let new_base, _ = alloc_imprecise_weakest_abstract region _stack _prefix _sizev state in + let new_state = + add_uninitialized state new_base (Bit_utils.max_bit_address ()) + in + let ret = V.inject new_base Ival.zero in + ret, new_state + +let alloc_imprecise_weakest region state actuals = + match actuals with + | [_, _size, _] -> + begin + let ret, new_state = alloc_imprecise_weakest_aux region [] "" _size state in + let c_values = wrap_fallible_alloc ret state new_state in + { Value_types.c_values = c_values ; + c_clobbered = Base.SetLattice.bottom; + c_cacheable = Value_types.NoCacheCallers; + c_from = None; + } + end + | _ -> raise (Builtins.Invalid_nb_of_args 1) + +let () = Builtins.register_builtin + "Frama_C_malloc_imprecise_weakest" (alloc_imprecise_weakest Base.Malloc) + ~typ:(fun () -> (Cil.voidPtrType, [Cil.theMachine.Cil.typeOfSizeOf])) + +let zero_to_max_bytes () = Ival.inject_range + (Some Integer.zero) (Some (Bit_utils.max_byte_size ())) + let alloc_size_ok intended_size = try let size = Cvalue.V.project_ival intended_size in - let ok_size = - Ival.inject_range (Some Integer.zero) (Some (Bit_utils.max_byte_size ())) - in + let ok_size = zero_to_max_bytes () in if Ival.is_included size ok_size then Alarmset.True else if Ival.intersects size ok_size then Alarmset.Unknown else Alarmset.False @@ -376,8 +470,7 @@ let alloc_size_ok intended_size = (* Generic function used both by [calloc_size] and [calloc_by_stack]. [calloc_f] is the actual function used (calloc_size or calloc_by_stack). *) -let calloc_abstract calloc_f state actuals = - let stack = call_stack_no_wrappers () in +let calloc_abstract calloc_f ?(stack=call_stack_no_wrappers ()) ?(override_size=false) state actuals = let nmemb, sizev = match actuals with | [(_exp, nmemb, _); (_, size, _)] -> nmemb, size @@ -395,6 +488,7 @@ let calloc_abstract calloc_f state actuals = c_from = None; } else + let alloc_size = if override_size then Cvalue.V.inject_ival (zero_to_max_bytes ()) else alloc_size in let base, max_valid = calloc_f stack "calloc" alloc_size state in let new_state = add_zeroes state base max_valid in let returns_null = if size_ok = Alarmset.Unknown then Some true else None in @@ -510,10 +604,18 @@ let () = Builtins.register_builtin ~replace:"__fc_vla_alloc" "Frama_C_vla_alloc_by_stack" (alloc_by_stack Base.VLA ~returns_null:false) ~typ:(fun () -> (Cil.voidPtrType, [Cil.theMachine.Cil.typeOfSizeOf])) +let () = Builtins.register_builtin + "Frama_C_vla_alloc_imprecise_weakest" + (alloc_imprecise_weakest Base.VLA) + ~typ:(fun () -> (Cil.voidPtrType, [Cil.theMachine.Cil.typeOfSizeOf])) let () = Builtins.register_builtin ~replace:"alloca" "Frama_C_alloca" (alloc_by_stack ~prefix:"alloca" Base.Alloca ~returns_null:false) ~typ:(fun () -> (Cil.voidPtrType, [Cil.theMachine.Cil.typeOfSizeOf])) +let () = Builtins.register_builtin + "Frama_C_alloca_imprecise_weakest" + (alloc_imprecise_weakest Base.Alloca) + ~typ:(fun () -> (Cil.voidPtrType, [Cil.theMachine.Cil.typeOfSizeOf])) (* Equivalent to [alloc_by_stack], but for [calloc]. *) let calloc_by_stack : Db.Value.builtin = fun state actuals -> @@ -524,6 +626,15 @@ let () = Builtins.register_builtin ~typ:(fun () -> (Cil.voidPtrType, [Cil.theMachine.Cil.typeOfSizeOf; Cil.theMachine.Cil.typeOfSizeOf])) +(* Equivalent to [malloc_imprecise_weakest], but for [calloc]. *) +let calloc_imprecise_weakest : Db.Value.builtin = fun state actuals -> + calloc_abstract (alloc_imprecise_weakest_abstract Base.Malloc) state actuals + +let () = Builtins.register_builtin + "Frama_C_calloc_imprecise_weakest" calloc_imprecise_weakest + ~typ:(fun () -> (Cil.voidPtrType, [Cil.theMachine.Cil.typeOfSizeOf; + Cil.theMachine.Cil.typeOfSizeOf])) + (** {1 Free} *) (* Change all references to bases into ESCAPINGADDR into the given state, @@ -819,6 +930,33 @@ let () = Builtins.register_builtin ~typ:(fun () -> (Cil.voidPtrType, [Cil.voidPtrType; Cil.theMachine.Cil.typeOfSizeOf])) +let realloc_imprecise_weakest state args = match args with + | [ (_,ptr,_); (_,_size,_) ] -> + let (bases, card_ok, _null) = resolve_bases_to_free ptr in + if card_ok > 0 then + let orig_state = state in + let ret, state = alloc_imprecise_weakest_aux Base.Malloc [] "" _size state in + (* free old bases. *) + let state, changed = free_aux state ~strong:false bases in + let c_values = wrap_fallible_alloc ret orig_state state in + { Value_types.c_values; + c_clobbered = Builtins.clobbered_set_from_ret state ret; + c_cacheable = Value_types.NoCacheCallers; + c_from = Some changed; + } + else (* Invalid call. *) + { Value_types.c_values = [] ; + c_clobbered = Base.SetLattice.bottom; + c_cacheable = Value_types.NoCacheCallers; + c_from = None; + } + | _ -> raise (Builtins.Invalid_nb_of_args 2) + +let () = Builtins.register_builtin + "Frama_C_realloc_imprecise_weakest" realloc_imprecise_weakest + ~typ:(fun () -> (Cil.voidPtrType, [Cil.voidPtrType; + Cil.theMachine.Cil.typeOfSizeOf])) + (** {1 Leak detection} *) (* Experimental, not to be released, leak detection built-in. *) diff --git a/tests/builtins/calloc.c b/tests/builtins/calloc.c index 648a4b4af03..a2fed462f6c 100644 --- a/tests/builtins/calloc.c +++ b/tests/builtins/calloc.c @@ -4,8 +4,8 @@ STDOPT: #"-eva-no-builtins-auto -eva-alloc-returns-null -eva-builtin calloc:Frama_C_calloc_by_stack" STDOPT: #"-eva-no-builtins-auto -eva-no-alloc-returns-null -eva-builtin calloc:Frama_C_calloc_fresh" STDOPT: #"-eva-no-builtins-auto -eva-no-alloc-returns-null -eva-builtin calloc:Frama_C_calloc_by_stack" + STDOPT: #"-eva-no-builtins-auto -eva-no-alloc-returns-null -eva-builtin calloc:Frama_C_calloc_imprecise_weakest" */ - #include <stdlib.h> #include <stdint.h> diff --git a/tests/builtins/malloc.c b/tests/builtins/malloc.c index c62203fa9dd..e208af715ad 100644 --- a/tests/builtins/malloc.c +++ b/tests/builtins/malloc.c @@ -4,7 +4,7 @@ #include <stddef.h> void *Frama_C_malloc_by_stack(size_t i); void *Frama_C_malloc_fresh(size_t i); - +void *Frama_C_malloc_imprecise_weakest(size_t i); void main(int c) { int x; int *s; @@ -30,5 +30,10 @@ void main(int c) { *r = 1; *(r+2) = 3; + int *mw = Frama_C_malloc_imprecise_weakest(42); + *mw = 1; + int *mw2 = Frama_C_malloc_imprecise_weakest(42); + *mw2 = 1; + // *s = 1; } diff --git a/tests/builtins/oracle/calloc.5.res.oracle b/tests/builtins/oracle/calloc.5.res.oracle new file mode 100644 index 00000000000..6d2516fe5ed --- /dev/null +++ b/tests/builtins/oracle/calloc.5.res.oracle @@ -0,0 +1,57 @@ +[kernel] Parsing tests/builtins/calloc.c (with preprocessing) +[eva] Analyzing a complete application starting at main +[eva] Computing initial state +[eva] Initial state computed +[eva:initial-state] Values of globals at initialization + nondet ∈ [--..--] +[eva] tests/builtins/calloc.c:14: + Call to builtin Frama_C_calloc_imprecise_weakest for function calloc +[eva:malloc:imprecise] tests/builtins/calloc.c:14: Warning: + warning: allocating a single weak variable for ALL dynamic allocations via malloc/calloc/realloc: __alloc_w_main +[eva] tests/builtins/calloc.c:17: + Call to builtin Frama_C_calloc_imprecise_weakest for function calloc +[eva] tests/builtins/calloc.c:20: + Call to builtin Frama_C_calloc_imprecise_weakest for function calloc +[eva] tests/builtins/calloc.c:23: + Call to builtin Frama_C_calloc_imprecise_weakest for function calloc +[eva:alarm] tests/builtins/calloc.c:26: Warning: assertion got status unknown. +[eva:alarm] tests/builtins/calloc.c:27: Warning: assertion got status unknown. +[eva] tests/builtins/calloc.c:30: + Call to builtin Frama_C_calloc_imprecise_weakest for function calloc +[eva:alarm] tests/builtins/calloc.c:33: Warning: assertion got status unknown. +[eva:alarm] tests/builtins/calloc.c:34: Warning: assertion got status unknown. +[eva:alarm] tests/builtins/calloc.c:35: Warning: assertion got status unknown. +[eva] tests/builtins/calloc.c:38: + Call to builtin Frama_C_calloc_imprecise_weakest for function calloc +[eva] tests/builtins/calloc.c:38: Warning: + calloc out of bounds: assert(nmemb * size <= SIZE_MAX) +[eva] tests/builtins/calloc.c:40: assertion got status valid. +[eva] Recording results for main +[eva] done for function main +[eva] ====== VALUES COMPUTED ====== +[eva:final-states] Values at end of function main: + __fc_heap_status ∈ [--..--] + p1 ∈ {{ &__alloc_w_main[0] }} + p2 ∈ {{ &__alloc_w_main[0] }} + p3 ∈ {{ &__alloc_w_main[0] }} + p4 ∈ {{ &__alloc_w_main[0] }} + p5 ∈ {{ (int *)&__alloc_w_main }} + p9001 ∈ {0} + __retres ∈ {0} +[from] Computing for function main +[from] Computing for function calloc <-main +[from] Done for function calloc +[from] Done for function main +[from] ====== DEPENDENCIES COMPUTED ====== + These dependencies hold at termination for the executions that terminate: +[from] Function calloc: + __fc_heap_status FROM __fc_heap_status; nmemb; size (and SELF) + \result FROM __fc_heap_status; nmemb; size +[from] Function main: + __fc_heap_status FROM __fc_heap_status (and SELF) + \result FROM __fc_heap_status +[from] ====== END OF DEPENDENCIES ====== +[inout] Out (internal) for function main: + __fc_heap_status; p1; p2; p3; p4; p5; p9001; __retres +[inout] Inputs for function main: + __fc_heap_status; nondet diff --git a/tests/builtins/oracle/malloc.res.oracle b/tests/builtins/oracle/malloc.res.oracle index ba9de96ef12..558c4562447 100644 --- a/tests/builtins/oracle/malloc.res.oracle +++ b/tests/builtins/oracle/malloc.res.oracle @@ -1,6 +1,8 @@ [kernel] Parsing tests/builtins/malloc.c (with preprocessing) [kernel:annot:missing-spec] tests/builtins/malloc.c:8: Warning: Neither code nor specification for function Frama_C_malloc_fresh, generating default assigns from the prototype +[kernel:annot:missing-spec] tests/builtins/malloc.c:8: Warning: + Neither code nor specification for function Frama_C_malloc_imprecise_weakest, generating default assigns from the prototype [kernel:annot:missing-spec] tests/builtins/malloc.c:8: Warning: Neither code nor specification for function Frama_C_malloc_by_stack, generating default assigns from the prototype [eva] Analyzing a complete application starting at main @@ -32,6 +34,20 @@ Frama_C_show_each: {{ &__malloc_main_l20 + {8} }} [eva] tests/builtins/malloc.c:27: Frama_C_show_each: {{ &__malloc_main_l20 + {8} }} +[eva] tests/builtins/malloc.c:33: + Call to builtin Frama_C_malloc_imprecise_weakest +[eva:malloc:imprecise] tests/builtins/malloc.c:33: Warning: + warning: allocating a single weak variable for ALL dynamic allocations via malloc/calloc/realloc: __alloc_w_main +[eva] tests/builtins/malloc.c:33: + Call to builtin Frama_C_malloc_imprecise_weakest +[eva:alarm] tests/builtins/malloc.c:34: Warning: + out of bounds write. assert \valid(mw); +[eva] tests/builtins/malloc.c:35: + Call to builtin Frama_C_malloc_imprecise_weakest +[eva] tests/builtins/malloc.c:35: + Call to builtin Frama_C_malloc_imprecise_weakest +[eva:alarm] tests/builtins/malloc.c:36: Warning: + out of bounds write. assert \valid(mw2); [eva] Recording results for main [eva] done for function main [eva] ====== VALUES COMPUTED ====== @@ -41,6 +57,8 @@ p ∈ {{ (int *)&__malloc_main_l19 }} q ∈ {{ &__malloc_main_l20[0] }} r ∈ {{ &__malloc_main_l21[0] ; &__malloc_main_l21_0[0] }} + mw ∈ {{ (int *)&__alloc_w_main }} + mw2 ∈ {{ (int *)&__alloc_w_main }} __malloc_main_l19[bits 0 to 31] ∈ {1} [4..7] ∈ UNINITIALIZED [bits 64 to 95] ∈ {3} @@ -58,3 +76,5 @@ [1] ∈ UNINITIALIZED [2] ∈ {3} [3..24] ∈ UNINITIALIZED + __alloc_w_main[bits 0 to 31] ∈ {1} or UNINITIALIZED + [4..4294967295] ∈ UNINITIALIZED diff --git a/tests/builtins/oracle/realloc_imprecise.res.oracle b/tests/builtins/oracle/realloc_imprecise.res.oracle new file mode 100644 index 00000000000..05f617bdea1 --- /dev/null +++ b/tests/builtins/oracle/realloc_imprecise.res.oracle @@ -0,0 +1,65 @@ +[kernel] Parsing tests/builtins/realloc_imprecise.c (with preprocessing) +[eva] Analyzing a complete application starting at main +[eva] Computing initial state +[eva] Initial state computed +[eva:initial-state] Values of globals at initialization + v ∈ [--..--] +[eva] tests/builtins/realloc_imprecise.c:10: + Call to builtin Frama_C_malloc_imprecise_weakest for function malloc +[eva:malloc:imprecise] tests/builtins/realloc_imprecise.c:10: Warning: + warning: allocating a single weak variable for ALL dynamic allocations via malloc/calloc/realloc: __alloc_w_main +[eva:alarm] tests/builtins/realloc_imprecise.c:11: Warning: + out of bounds write. assert \valid(p); +[eva] tests/builtins/realloc_imprecise.c:13: + Call to builtin Frama_C_realloc_imprecise_weakest for function realloc +[eva] tests/builtins/realloc_imprecise.c:13: + function realloc: precondition 'freeable' got status valid. +[eva:malloc] tests/builtins/realloc_imprecise.c:13: + weak free on bases: {__alloc_w_main} +[eva] tests/builtins/realloc_imprecise.c:15: + Call to builtin Frama_C_realloc_imprecise_weakest for function realloc +[eva] tests/builtins/realloc_imprecise.c:15: + function realloc: precondition 'freeable' got status valid. +[eva:malloc] tests/builtins/realloc_imprecise.c:15: + weak free on bases: {__alloc_w_main} +[eva] tests/builtins/realloc_imprecise.c:16: Call to builtin free +[eva] tests/builtins/realloc_imprecise.c:16: + function free: precondition 'freeable' got status valid. +[eva:malloc] tests/builtins/realloc_imprecise.c:16: + weak free on bases: {__alloc_w_main} +[eva] Recording results for main +[eva] done for function main +[eva] ====== VALUES COMPUTED ====== +[eva:final-states] Values at end of function main: + __fc_heap_status ∈ [--..--] + p ∈ {{ (int *)&__alloc_w_main }} or ESCAPINGADDR + pp ∈ {{ (int *)&__alloc_w_main }} or ESCAPINGADDR + q ∈ {{ (int *)&__alloc_w_main }} or ESCAPINGADDR + __alloc_w_main[bits 0 to 31] ∈ {17} or UNINITIALIZED + [4..4294967295] ∈ UNINITIALIZED +[from] Computing for function main +[from] Computing for function malloc <-main +[from] Done for function malloc +[from] Computing for function realloc <-main +[from] Done for function realloc +[from] Computing for function free <-main +[from] Done for function free +[from] Done for function main +[from] ====== DEPENDENCIES COMPUTED ====== + These dependencies hold at termination for the executions that terminate: +[from] Function free: + __fc_heap_status FROM __fc_heap_status (and SELF) +[from] Function malloc: + __fc_heap_status FROM __fc_heap_status; size (and SELF) + \result FROM __fc_heap_status; size +[from] Function realloc: + __fc_heap_status FROM __fc_heap_status (and SELF) + \result FROM __fc_heap_status; ptr; size +[from] Function main: + __fc_heap_status FROM __fc_heap_status; v (and SELF) + __alloc_w_main[0..3] FROM __fc_heap_status (and SELF) +[from] ====== END OF DEPENDENCIES ====== +[inout] Out (internal) for function main: + __fc_heap_status; p; pp; q; r; __alloc_w_main[0..3] +[inout] Inputs for function main: + __fc_heap_status; v diff --git a/tests/builtins/realloc_imprecise.c b/tests/builtins/realloc_imprecise.c new file mode 100644 index 00000000000..3a943140d53 --- /dev/null +++ b/tests/builtins/realloc_imprecise.c @@ -0,0 +1,18 @@ +/* run.config* + STDOPT: +"-eva-builtin malloc:Frama_C_malloc_imprecise_weakest,realloc:Frama_C_realloc_imprecise_weakest" +*/ + +#include <stdlib.h> + +volatile int v; + +void main() { + int *p = malloc(sizeof(int)); + *p = 17; + int *pp = p; + int *q = realloc(p, 2 * sizeof(int)); + if (v) { + int *r = realloc(q, sizeof(int)); + free(r); + } +} -- GitLab From 1ce80086247d41810333b96cb7403cb3fd05416d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20B=C3=BChler?= <david.buhler@cea.fr> Date: Wed, 1 Apr 2020 14:41:52 +0200 Subject: [PATCH 136/218] [Eva] Fixes a warning warning message. --- src/plugins/value/domains/cvalue/builtins_malloc.ml | 2 +- tests/builtins/oracle/calloc.5.res.oracle | 2 +- tests/builtins/oracle/malloc.res.oracle | 2 +- tests/builtins/oracle/realloc_imprecise.res.oracle | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/plugins/value/domains/cvalue/builtins_malloc.ml b/src/plugins/value/domains/cvalue/builtins_malloc.ml index c8588932c9f..283c8dd8384 100644 --- a/src/plugins/value/domains/cvalue/builtins_malloc.ml +++ b/src/plugins/value/domains/cvalue/builtins_malloc.ml @@ -405,7 +405,7 @@ let alloc_imprecise_weakest_alloc region _stack _prefix _sizev _state = in let var = create_new_var stack "alloc" type_base Weak in Value_parameters.warning ~wkey:wkey_imprecise_alloc ~current:true ~once:true - "@[warning: allocating a single weak variable for ALL dynamic allocations %s: %a@]" + "allocating a single weak variable for ALL dynamic allocations %s: %a" (string_of_region region) Printer.pp_varinfo var; let variable_v = Base.create_variable_validity ~weak:true ~min_alloc:Int.minus_one ~max_alloc:(Bit_utils.max_bit_address ()) in diff --git a/tests/builtins/oracle/calloc.5.res.oracle b/tests/builtins/oracle/calloc.5.res.oracle index 6d2516fe5ed..31723119f89 100644 --- a/tests/builtins/oracle/calloc.5.res.oracle +++ b/tests/builtins/oracle/calloc.5.res.oracle @@ -7,7 +7,7 @@ [eva] tests/builtins/calloc.c:14: Call to builtin Frama_C_calloc_imprecise_weakest for function calloc [eva:malloc:imprecise] tests/builtins/calloc.c:14: Warning: - warning: allocating a single weak variable for ALL dynamic allocations via malloc/calloc/realloc: __alloc_w_main + allocating a single weak variable for ALL dynamic allocations via malloc/calloc/realloc: __alloc_w_main [eva] tests/builtins/calloc.c:17: Call to builtin Frama_C_calloc_imprecise_weakest for function calloc [eva] tests/builtins/calloc.c:20: diff --git a/tests/builtins/oracle/malloc.res.oracle b/tests/builtins/oracle/malloc.res.oracle index 558c4562447..0fd1847bc24 100644 --- a/tests/builtins/oracle/malloc.res.oracle +++ b/tests/builtins/oracle/malloc.res.oracle @@ -37,7 +37,7 @@ [eva] tests/builtins/malloc.c:33: Call to builtin Frama_C_malloc_imprecise_weakest [eva:malloc:imprecise] tests/builtins/malloc.c:33: Warning: - warning: allocating a single weak variable for ALL dynamic allocations via malloc/calloc/realloc: __alloc_w_main + allocating a single weak variable for ALL dynamic allocations via malloc/calloc/realloc: __alloc_w_main [eva] tests/builtins/malloc.c:33: Call to builtin Frama_C_malloc_imprecise_weakest [eva:alarm] tests/builtins/malloc.c:34: Warning: diff --git a/tests/builtins/oracle/realloc_imprecise.res.oracle b/tests/builtins/oracle/realloc_imprecise.res.oracle index 05f617bdea1..7bb0194ab39 100644 --- a/tests/builtins/oracle/realloc_imprecise.res.oracle +++ b/tests/builtins/oracle/realloc_imprecise.res.oracle @@ -7,7 +7,7 @@ [eva] tests/builtins/realloc_imprecise.c:10: Call to builtin Frama_C_malloc_imprecise_weakest for function malloc [eva:malloc:imprecise] tests/builtins/realloc_imprecise.c:10: Warning: - warning: allocating a single weak variable for ALL dynamic allocations via malloc/calloc/realloc: __alloc_w_main + allocating a single weak variable for ALL dynamic allocations via malloc/calloc/realloc: __alloc_w_main [eva:alarm] tests/builtins/realloc_imprecise.c:11: Warning: out of bounds write. assert \valid(p); [eva] tests/builtins/realloc_imprecise.c:13: -- GitLab From 7e48ec3a516de5bdd4ae9b056c947728a489c8b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20B=C3=BChler?= <david.buhler@cea.fr> Date: Tue, 31 Mar 2020 17:36:41 +0200 Subject: [PATCH 137/218] [Eva] Allocation builtin: minor improvement to the imprecise malloc builtin. Uses [memo] from State_builder.Option_ref. Also stores the maximum size of the allocated bases once for all, instead of calling [Bit_utils.max_bit_adddress] in various places. --- .../value/domains/cvalue/builtins_malloc.ml | 51 +++++++++---------- 1 file changed, 25 insertions(+), 26 deletions(-) diff --git a/src/plugins/value/domains/cvalue/builtins_malloc.ml b/src/plugins/value/domains/cvalue/builtins_malloc.ml index 283c8dd8384..8f3cdbaa2b2 100644 --- a/src/plugins/value/domains/cvalue/builtins_malloc.ml +++ b/src/plugins/value/domains/cvalue/builtins_malloc.ml @@ -366,10 +366,12 @@ let () = (alloc_fresh Weak Base.Malloc) ~typ:(fun () -> (Cil.voidPtrType, [Cil.theMachine.Cil.typeOfSizeOf])) +module Base_with_Size = Datatype.Pair (Base.Base) (Datatype.Integer) + (* Extremely aggressive and imprecise allocation: a single weak base for each region. *) module MallocedSingleMalloc = - State_builder.Option_ref(Base.Base) + State_builder.Option_ref (Base_with_Size) (struct let name = "Value.Builtins_malloc.MallocedSingleMalloc" let dependencies = [Ast.self] @@ -377,7 +379,7 @@ module MallocedSingleMalloc = let () = Ast.add_monotonic_state MallocedSingleMalloc.self module MallocedSingleVLA = - State_builder.Option_ref(Base.Base) + State_builder.Option_ref (Base_with_Size) (struct let name = "Value.Builtins_malloc.MallocedSingleVLA" let dependencies = [Ast.self] @@ -385,7 +387,7 @@ module MallocedSingleVLA = let () = Ast.add_monotonic_state MallocedSingleVLA.self module MallocedSingleAlloca = - State_builder.Option_ref(Base.Base) + State_builder.Option_ref (Base_with_Size) (struct let name = "Value.Builtins_malloc.MallocedSingleAlloca" let dependencies = [Ast.self] @@ -398,7 +400,7 @@ let string_of_region = function | Base.Alloca -> "via alloca" (* Only called when the 'weakest base' needs to be allocated. *) -let alloc_imprecise_weakest_alloc region _stack _prefix _sizev _state = +let alloc_imprecise_weakest_alloc region = let stack = [ fst (Globals.entry_point ()), Kglobal ] in let type_base = TArray (Cil.charType, None, Cil.empty_size_cache (), []) @@ -407,34 +409,28 @@ let alloc_imprecise_weakest_alloc region _stack _prefix _sizev _state = Value_parameters.warning ~wkey:wkey_imprecise_alloc ~current:true ~once:true "allocating a single weak variable for ALL dynamic allocations %s: %a" (string_of_region region) Printer.pp_varinfo var; - let variable_v = Base.create_variable_validity ~weak:true - ~min_alloc:Int.minus_one ~max_alloc:(Bit_utils.max_bit_address ()) in + let min_alloc = Int.minus_one in + let max_alloc = Bit_utils.max_bit_address () in + let variable_v = + Base.create_variable_validity ~weak:true ~min_alloc ~max_alloc + in let new_base = Base.register_allocated_var var region (Base.Variable variable_v) in register_malloced_base ~stack new_base; - new_base, Bit_utils.max_bit_address () + new_base, max_alloc (* used by calloc_abstract *) -let alloc_imprecise_weakest_abstract region _stack _prefix _sizev state = - let datatype_get_option, datatype_set = +let alloc_imprecise_weakest_abstract region = + let memo = match region with - | Base.Malloc -> MallocedSingleMalloc.get_option, MallocedSingleMalloc.set - | Base.VLA -> MallocedSingleVLA.get_option, MallocedSingleVLA.set - | Base.Alloca -> MallocedSingleAlloca.get_option, MallocedSingleAlloca.set + | Base.Malloc -> MallocedSingleMalloc.memo + | Base.VLA -> MallocedSingleVLA.memo + | Base.Alloca -> MallocedSingleAlloca.memo in - match datatype_get_option () with - | None -> - let new_base, _ as r = - alloc_imprecise_weakest_alloc region _stack _prefix _sizev state - in - datatype_set new_base; - r - | Some base -> base, Bit_utils.max_bit_address () + memo (fun () -> alloc_imprecise_weakest_alloc region) let alloc_imprecise_weakest_aux region _stack _prefix _sizev state = - let new_base, _ = alloc_imprecise_weakest_abstract region _stack _prefix _sizev state in - let new_state = - add_uninitialized state new_base (Bit_utils.max_bit_address ()) - in + let new_base, max_alloc = alloc_imprecise_weakest_abstract region in + let new_state = add_uninitialized state new_base max_alloc in let ret = V.inject new_base Ival.zero in ret, new_state @@ -516,7 +512,7 @@ let () = (* Variables that have been returned by a call to an allocation function at this callstack. The first allocated variable is at the top of the stack. Currently, the callstacks are truncated according to - [-val-malloc-functions]. *) + [-eva-alloc-functions]. *) module MallocedByStack = (* varinfo list Callstack.hashtbl *) State_builder.Hashtbl(Value_types.Callstack.Hashtbl) (Datatype.List(Base)) @@ -628,7 +624,10 @@ let () = Builtins.register_builtin (* Equivalent to [malloc_imprecise_weakest], but for [calloc]. *) let calloc_imprecise_weakest : Db.Value.builtin = fun state actuals -> - calloc_abstract (alloc_imprecise_weakest_abstract Base.Malloc) state actuals + let calloc_f _stack _prefix _sizev _state = + alloc_imprecise_weakest_abstract Base.Malloc + in + calloc_abstract calloc_f state actuals let () = Builtins.register_builtin "Frama_C_calloc_imprecise_weakest" calloc_imprecise_weakest -- GitLab From 271b5b9a3d54886ce6519a18f93d55000ea6e5ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20B=C3=BChler?= <david.buhler@cea.fr> Date: Thu, 2 Apr 2020 12:33:12 +0200 Subject: [PATCH 138/218] [Eva] Imprecise builtins for alloca and vla_alloc do not return null. --- src/plugins/value/domains/cvalue/builtins_malloc.ml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/plugins/value/domains/cvalue/builtins_malloc.ml b/src/plugins/value/domains/cvalue/builtins_malloc.ml index 8f3cdbaa2b2..aac96421d2d 100644 --- a/src/plugins/value/domains/cvalue/builtins_malloc.ml +++ b/src/plugins/value/domains/cvalue/builtins_malloc.ml @@ -434,12 +434,12 @@ let alloc_imprecise_weakest_aux region _stack _prefix _sizev state = let ret = V.inject new_base Ival.zero in ret, new_state -let alloc_imprecise_weakest region state actuals = +let alloc_imprecise_weakest ?returns_null region state actuals = match actuals with | [_, _size, _] -> begin let ret, new_state = alloc_imprecise_weakest_aux region [] "" _size state in - let c_values = wrap_fallible_alloc ret state new_state in + let c_values = wrap_fallible_alloc ?returns_null ret state new_state in { Value_types.c_values = c_values ; c_clobbered = Base.SetLattice.bottom; c_cacheable = Value_types.NoCacheCallers; @@ -602,7 +602,7 @@ let () = Builtins.register_builtin ~typ:(fun () -> (Cil.voidPtrType, [Cil.theMachine.Cil.typeOfSizeOf])) let () = Builtins.register_builtin "Frama_C_vla_alloc_imprecise_weakest" - (alloc_imprecise_weakest Base.VLA) + (alloc_imprecise_weakest Base.VLA ~returns_null:false) ~typ:(fun () -> (Cil.voidPtrType, [Cil.theMachine.Cil.typeOfSizeOf])) let () = Builtins.register_builtin ~replace:"alloca" "Frama_C_alloca" @@ -610,7 +610,7 @@ let () = Builtins.register_builtin ~typ:(fun () -> (Cil.voidPtrType, [Cil.theMachine.Cil.typeOfSizeOf])) let () = Builtins.register_builtin "Frama_C_alloca_imprecise_weakest" - (alloc_imprecise_weakest Base.Alloca) + (alloc_imprecise_weakest Base.Alloca ~returns_null:false) ~typ:(fun () -> (Cil.voidPtrType, [Cil.theMachine.Cil.typeOfSizeOf])) (* Equivalent to [alloc_by_stack], but for [calloc]. *) -- GitLab From 83bf91d90caf475b170ac8b640413cf1616ea189 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20B=C3=BChler?= <david.buhler@cea.fr> Date: Fri, 3 Apr 2020 10:15:46 +0200 Subject: [PATCH 139/218] [Eva] Renames allocation builtins *_imprecise_weakest into *_imprecise. --- .../value/domains/cvalue/builtins_malloc.ml | 10 +++++----- tests/builtins/calloc.c | 2 +- tests/builtins/malloc.c | 6 +++--- tests/builtins/oracle/calloc.5.res.oracle | 12 ++++++------ tests/builtins/oracle/malloc.res.oracle | 16 ++++++---------- .../builtins/oracle/realloc_imprecise.res.oracle | 6 +++--- tests/builtins/realloc_imprecise.c | 2 +- 7 files changed, 25 insertions(+), 29 deletions(-) diff --git a/src/plugins/value/domains/cvalue/builtins_malloc.ml b/src/plugins/value/domains/cvalue/builtins_malloc.ml index aac96421d2d..2d24e1062e3 100644 --- a/src/plugins/value/domains/cvalue/builtins_malloc.ml +++ b/src/plugins/value/domains/cvalue/builtins_malloc.ml @@ -449,7 +449,7 @@ let alloc_imprecise_weakest ?returns_null region state actuals = | _ -> raise (Builtins.Invalid_nb_of_args 1) let () = Builtins.register_builtin - "Frama_C_malloc_imprecise_weakest" (alloc_imprecise_weakest Base.Malloc) + "Frama_C_malloc_imprecise" (alloc_imprecise_weakest Base.Malloc) ~typ:(fun () -> (Cil.voidPtrType, [Cil.theMachine.Cil.typeOfSizeOf])) let zero_to_max_bytes () = Ival.inject_range @@ -601,7 +601,7 @@ let () = Builtins.register_builtin (alloc_by_stack Base.VLA ~returns_null:false) ~typ:(fun () -> (Cil.voidPtrType, [Cil.theMachine.Cil.typeOfSizeOf])) let () = Builtins.register_builtin - "Frama_C_vla_alloc_imprecise_weakest" + "Frama_C_vla_alloc_imprecise" (alloc_imprecise_weakest Base.VLA ~returns_null:false) ~typ:(fun () -> (Cil.voidPtrType, [Cil.theMachine.Cil.typeOfSizeOf])) let () = Builtins.register_builtin @@ -609,7 +609,7 @@ let () = Builtins.register_builtin (alloc_by_stack ~prefix:"alloca" Base.Alloca ~returns_null:false) ~typ:(fun () -> (Cil.voidPtrType, [Cil.theMachine.Cil.typeOfSizeOf])) let () = Builtins.register_builtin - "Frama_C_alloca_imprecise_weakest" + "Frama_C_alloca_imprecise" (alloc_imprecise_weakest Base.Alloca ~returns_null:false) ~typ:(fun () -> (Cil.voidPtrType, [Cil.theMachine.Cil.typeOfSizeOf])) @@ -630,7 +630,7 @@ let calloc_imprecise_weakest : Db.Value.builtin = fun state actuals -> calloc_abstract calloc_f state actuals let () = Builtins.register_builtin - "Frama_C_calloc_imprecise_weakest" calloc_imprecise_weakest + "Frama_C_calloc_imprecise" calloc_imprecise_weakest ~typ:(fun () -> (Cil.voidPtrType, [Cil.theMachine.Cil.typeOfSizeOf; Cil.theMachine.Cil.typeOfSizeOf])) @@ -952,7 +952,7 @@ let realloc_imprecise_weakest state args = match args with | _ -> raise (Builtins.Invalid_nb_of_args 2) let () = Builtins.register_builtin - "Frama_C_realloc_imprecise_weakest" realloc_imprecise_weakest + "Frama_C_realloc_imprecise" realloc_imprecise_weakest ~typ:(fun () -> (Cil.voidPtrType, [Cil.voidPtrType; Cil.theMachine.Cil.typeOfSizeOf])) diff --git a/tests/builtins/calloc.c b/tests/builtins/calloc.c index a2fed462f6c..391526efc85 100644 --- a/tests/builtins/calloc.c +++ b/tests/builtins/calloc.c @@ -4,7 +4,7 @@ STDOPT: #"-eva-no-builtins-auto -eva-alloc-returns-null -eva-builtin calloc:Frama_C_calloc_by_stack" STDOPT: #"-eva-no-builtins-auto -eva-no-alloc-returns-null -eva-builtin calloc:Frama_C_calloc_fresh" STDOPT: #"-eva-no-builtins-auto -eva-no-alloc-returns-null -eva-builtin calloc:Frama_C_calloc_by_stack" - STDOPT: #"-eva-no-builtins-auto -eva-no-alloc-returns-null -eva-builtin calloc:Frama_C_calloc_imprecise_weakest" + STDOPT: #"-eva-no-builtins-auto -eva-no-alloc-returns-null -eva-builtin calloc:Frama_C_calloc_imprecise" */ #include <stdlib.h> #include <stdint.h> diff --git a/tests/builtins/malloc.c b/tests/builtins/malloc.c index e208af715ad..af7f6c2470d 100644 --- a/tests/builtins/malloc.c +++ b/tests/builtins/malloc.c @@ -4,7 +4,7 @@ #include <stddef.h> void *Frama_C_malloc_by_stack(size_t i); void *Frama_C_malloc_fresh(size_t i); -void *Frama_C_malloc_imprecise_weakest(size_t i); +void *Frama_C_malloc_imprecise(size_t i); void main(int c) { int x; int *s; @@ -30,9 +30,9 @@ void main(int c) { *r = 1; *(r+2) = 3; - int *mw = Frama_C_malloc_imprecise_weakest(42); + int *mw = Frama_C_malloc_imprecise(42); *mw = 1; - int *mw2 = Frama_C_malloc_imprecise_weakest(42); + int *mw2 = Frama_C_malloc_imprecise(42); *mw2 = 1; // *s = 1; diff --git a/tests/builtins/oracle/calloc.5.res.oracle b/tests/builtins/oracle/calloc.5.res.oracle index 31723119f89..679c1f964b2 100644 --- a/tests/builtins/oracle/calloc.5.res.oracle +++ b/tests/builtins/oracle/calloc.5.res.oracle @@ -5,24 +5,24 @@ [eva:initial-state] Values of globals at initialization nondet ∈ [--..--] [eva] tests/builtins/calloc.c:14: - Call to builtin Frama_C_calloc_imprecise_weakest for function calloc + Call to builtin Frama_C_calloc_imprecise for function calloc [eva:malloc:imprecise] tests/builtins/calloc.c:14: Warning: allocating a single weak variable for ALL dynamic allocations via malloc/calloc/realloc: __alloc_w_main [eva] tests/builtins/calloc.c:17: - Call to builtin Frama_C_calloc_imprecise_weakest for function calloc + Call to builtin Frama_C_calloc_imprecise for function calloc [eva] tests/builtins/calloc.c:20: - Call to builtin Frama_C_calloc_imprecise_weakest for function calloc + Call to builtin Frama_C_calloc_imprecise for function calloc [eva] tests/builtins/calloc.c:23: - Call to builtin Frama_C_calloc_imprecise_weakest for function calloc + Call to builtin Frama_C_calloc_imprecise for function calloc [eva:alarm] tests/builtins/calloc.c:26: Warning: assertion got status unknown. [eva:alarm] tests/builtins/calloc.c:27: Warning: assertion got status unknown. [eva] tests/builtins/calloc.c:30: - Call to builtin Frama_C_calloc_imprecise_weakest for function calloc + Call to builtin Frama_C_calloc_imprecise for function calloc [eva:alarm] tests/builtins/calloc.c:33: Warning: assertion got status unknown. [eva:alarm] tests/builtins/calloc.c:34: Warning: assertion got status unknown. [eva:alarm] tests/builtins/calloc.c:35: Warning: assertion got status unknown. [eva] tests/builtins/calloc.c:38: - Call to builtin Frama_C_calloc_imprecise_weakest for function calloc + Call to builtin Frama_C_calloc_imprecise for function calloc [eva] tests/builtins/calloc.c:38: Warning: calloc out of bounds: assert(nmemb * size <= SIZE_MAX) [eva] tests/builtins/calloc.c:40: assertion got status valid. diff --git a/tests/builtins/oracle/malloc.res.oracle b/tests/builtins/oracle/malloc.res.oracle index 0fd1847bc24..b9dd7712077 100644 --- a/tests/builtins/oracle/malloc.res.oracle +++ b/tests/builtins/oracle/malloc.res.oracle @@ -1,10 +1,10 @@ [kernel] Parsing tests/builtins/malloc.c (with preprocessing) [kernel:annot:missing-spec] tests/builtins/malloc.c:8: Warning: Neither code nor specification for function Frama_C_malloc_fresh, generating default assigns from the prototype -[kernel:annot:missing-spec] tests/builtins/malloc.c:8: Warning: - Neither code nor specification for function Frama_C_malloc_imprecise_weakest, generating default assigns from the prototype [kernel:annot:missing-spec] tests/builtins/malloc.c:8: Warning: Neither code nor specification for function Frama_C_malloc_by_stack, generating default assigns from the prototype +[kernel:annot:missing-spec] tests/builtins/malloc.c:8: Warning: + Neither code nor specification for function Frama_C_malloc_imprecise, generating default assigns from the prototype [eva] Analyzing a complete application starting at main [eva] Computing initial state [eva] Initial state computed @@ -34,18 +34,14 @@ Frama_C_show_each: {{ &__malloc_main_l20 + {8} }} [eva] tests/builtins/malloc.c:27: Frama_C_show_each: {{ &__malloc_main_l20 + {8} }} -[eva] tests/builtins/malloc.c:33: - Call to builtin Frama_C_malloc_imprecise_weakest +[eva] tests/builtins/malloc.c:33: Call to builtin Frama_C_malloc_imprecise [eva:malloc:imprecise] tests/builtins/malloc.c:33: Warning: allocating a single weak variable for ALL dynamic allocations via malloc/calloc/realloc: __alloc_w_main -[eva] tests/builtins/malloc.c:33: - Call to builtin Frama_C_malloc_imprecise_weakest +[eva] tests/builtins/malloc.c:33: Call to builtin Frama_C_malloc_imprecise [eva:alarm] tests/builtins/malloc.c:34: Warning: out of bounds write. assert \valid(mw); -[eva] tests/builtins/malloc.c:35: - Call to builtin Frama_C_malloc_imprecise_weakest -[eva] tests/builtins/malloc.c:35: - Call to builtin Frama_C_malloc_imprecise_weakest +[eva] tests/builtins/malloc.c:35: Call to builtin Frama_C_malloc_imprecise +[eva] tests/builtins/malloc.c:35: Call to builtin Frama_C_malloc_imprecise [eva:alarm] tests/builtins/malloc.c:36: Warning: out of bounds write. assert \valid(mw2); [eva] Recording results for main diff --git a/tests/builtins/oracle/realloc_imprecise.res.oracle b/tests/builtins/oracle/realloc_imprecise.res.oracle index 7bb0194ab39..346a55355c0 100644 --- a/tests/builtins/oracle/realloc_imprecise.res.oracle +++ b/tests/builtins/oracle/realloc_imprecise.res.oracle @@ -5,19 +5,19 @@ [eva:initial-state] Values of globals at initialization v ∈ [--..--] [eva] tests/builtins/realloc_imprecise.c:10: - Call to builtin Frama_C_malloc_imprecise_weakest for function malloc + Call to builtin Frama_C_malloc_imprecise for function malloc [eva:malloc:imprecise] tests/builtins/realloc_imprecise.c:10: Warning: allocating a single weak variable for ALL dynamic allocations via malloc/calloc/realloc: __alloc_w_main [eva:alarm] tests/builtins/realloc_imprecise.c:11: Warning: out of bounds write. assert \valid(p); [eva] tests/builtins/realloc_imprecise.c:13: - Call to builtin Frama_C_realloc_imprecise_weakest for function realloc + Call to builtin Frama_C_realloc_imprecise for function realloc [eva] tests/builtins/realloc_imprecise.c:13: function realloc: precondition 'freeable' got status valid. [eva:malloc] tests/builtins/realloc_imprecise.c:13: weak free on bases: {__alloc_w_main} [eva] tests/builtins/realloc_imprecise.c:15: - Call to builtin Frama_C_realloc_imprecise_weakest for function realloc + Call to builtin Frama_C_realloc_imprecise for function realloc [eva] tests/builtins/realloc_imprecise.c:15: function realloc: precondition 'freeable' got status valid. [eva:malloc] tests/builtins/realloc_imprecise.c:15: diff --git a/tests/builtins/realloc_imprecise.c b/tests/builtins/realloc_imprecise.c index 3a943140d53..bd9e002b64b 100644 --- a/tests/builtins/realloc_imprecise.c +++ b/tests/builtins/realloc_imprecise.c @@ -1,5 +1,5 @@ /* run.config* - STDOPT: +"-eva-builtin malloc:Frama_C_malloc_imprecise_weakest,realloc:Frama_C_realloc_imprecise_weakest" + STDOPT: +"-eva-builtin malloc:Frama_C_malloc_imprecise,realloc:Frama_C_realloc_imprecise" */ #include <stdlib.h> -- GitLab From 210d963ee84c8d01701ff95d14db70a9d7395861 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20B=C3=BChler?= <david.buhler@cea.fr> Date: Thu, 2 Apr 2020 12:33:57 +0200 Subject: [PATCH 140/218] [Eva] In the malloc test, tests that the base for the imprecise builtin is weak. --- tests/builtins/malloc.c | 2 +- tests/builtins/oracle/malloc.res.oracle | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/builtins/malloc.c b/tests/builtins/malloc.c index af7f6c2470d..af2dbc58d5b 100644 --- a/tests/builtins/malloc.c +++ b/tests/builtins/malloc.c @@ -33,7 +33,7 @@ void main(int c) { int *mw = Frama_C_malloc_imprecise(42); *mw = 1; int *mw2 = Frama_C_malloc_imprecise(42); - *mw2 = 1; + *mw2 = 2; // *s = 1; } diff --git a/tests/builtins/oracle/malloc.res.oracle b/tests/builtins/oracle/malloc.res.oracle index b9dd7712077..6bfbf908188 100644 --- a/tests/builtins/oracle/malloc.res.oracle +++ b/tests/builtins/oracle/malloc.res.oracle @@ -72,5 +72,5 @@ [1] ∈ UNINITIALIZED [2] ∈ {3} [3..24] ∈ UNINITIALIZED - __alloc_w_main[bits 0 to 31] ∈ {1} or UNINITIALIZED + __alloc_w_main[bits 0 to 31] ∈ {1; 2} or UNINITIALIZED [4..4294967295] ∈ UNINITIALIZED -- GitLab From 5320508459371d958f89f499a125b534bc129145 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20B=C3=BChler?= <david.buhler@cea.fr> Date: Fri, 3 Apr 2020 11:32:21 +0200 Subject: [PATCH 141/218] [Eva] Builtin: reverts an unused modification in function [calloc_abstract]. --- src/plugins/value/domains/cvalue/builtins_malloc.ml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/value/domains/cvalue/builtins_malloc.ml b/src/plugins/value/domains/cvalue/builtins_malloc.ml index 2d24e1062e3..dee1382281c 100644 --- a/src/plugins/value/domains/cvalue/builtins_malloc.ml +++ b/src/plugins/value/domains/cvalue/builtins_malloc.ml @@ -466,7 +466,8 @@ let alloc_size_ok intended_size = (* Generic function used both by [calloc_size] and [calloc_by_stack]. [calloc_f] is the actual function used (calloc_size or calloc_by_stack). *) -let calloc_abstract calloc_f ?(stack=call_stack_no_wrappers ()) ?(override_size=false) state actuals = +let calloc_abstract calloc_f state actuals = + let stack = call_stack_no_wrappers () in let nmemb, sizev = match actuals with | [(_exp, nmemb, _); (_, size, _)] -> nmemb, size @@ -484,7 +485,6 @@ let calloc_abstract calloc_f ?(stack=call_stack_no_wrappers ()) ?(override_size= c_from = None; } else - let alloc_size = if override_size then Cvalue.V.inject_ival (zero_to_max_bytes ()) else alloc_size in let base, max_valid = calloc_f stack "calloc" alloc_size state in let new_state = add_zeroes state base max_valid in let returns_null = if size_ok = Alarmset.Unknown then Some true else None in -- GitLab From c6424c46ccae6818b8175898f4999e4d761680e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20B=C3=BChler?= <david.buhler@cea.fr> Date: Fri, 3 Apr 2020 12:55:41 +0200 Subject: [PATCH 142/218] Updates the Changelog for MR !2309. --- Changelog | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Changelog b/Changelog index 0c8955af999..1d2fb8f1988 100644 --- a/Changelog +++ b/Changelog @@ -17,6 +17,8 @@ Open Source Release <next-release> ################################## +- Eva [2020/04/03] New experimental builtins for dynamic allocation + Frama_C_*alloc_imprecise: faster convergence, but very imprecise. - Kernel [2020/04/01] Report user errors when keys are not bound to a value for command-line options that require pairs of key:value as arguments. Such keys were silently ignored. -- GitLab From d9ca6cfe125d839f3239f4fd108840648df89868 Mon Sep 17 00:00:00 2001 From: Allan Blanchard <allan.blanchard@cea.fr> Date: Fri, 3 Apr 2020 13:10:38 +0200 Subject: [PATCH 143/218] [Instantiate] Fixes stdlib builtins when frama-c libc is not here --- src/plugins/instantiate/global_context.ml | 61 ++++- src/plugins/instantiate/global_context.mli | 28 +- src/plugins/instantiate/stdlib/basic_alloc.ml | 62 ++++- src/plugins/instantiate/string/mem_utils.mli | 2 +- .../instantiate/tests/stdlib/no_fc_stdlib.c | 12 + .../stdlib/oracle/no_fc_stdlib.res.oracle | 253 ++++++++++++++++++ 6 files changed, 397 insertions(+), 21 deletions(-) create mode 100644 src/plugins/instantiate/tests/stdlib/no_fc_stdlib.c create mode 100644 src/plugins/instantiate/tests/stdlib/oracle/no_fc_stdlib.res.oracle diff --git a/src/plugins/instantiate/global_context.ml b/src/plugins/instantiate/global_context.ml index d28b409a52f..9a6d4ff32d6 100644 --- a/src/plugins/instantiate/global_context.ml +++ b/src/plugins/instantiate/global_context.ml @@ -21,19 +21,70 @@ (**************************************************************************) module Table = Datatype.String.Hashtbl -let table = Table.create 13 + +let varinfos = Table.create 13 +let logic_functions = Table.create 13 +let axiomatics = Table.create 13 let get_variable name make = - if Table.mem table name then Table.find table name + if Table.mem varinfos name then Table.find varinfos name else begin try Globals.Vars.find_from_astinfo name VGlobal with Not_found -> let vi = make () in - Table.add table name vi ; + Table.add varinfos name vi ; vi end -let clear () = Table.clear table +let get_logic_function name make = + if Table.mem logic_functions name then Table.find logic_functions name + else begin + match Logic_env.find_all_logic_functions name with + | [] -> + let li = make () in + Table.add logic_functions name li ; + Logic_utils.add_logic_function li ; + li + | [x] -> x + | _ :: _ -> Options.not_yet_implemented "Logic function overloading" + end + +let in_axiomatic_functions = Table.create 13 + +let get_logic_function_in_axiomatic name make = + if Table.mem in_axiomatic_functions name then + Table.find in_axiomatic_functions name + else begin + let make_then_find name = + let open Cil_types in + let (ax_name, ax_list), functions = make () in + List.iter + (fun f -> + Table.add in_axiomatic_functions f.l_var_info.lv_name f ; + Logic_utils.add_logic_function f) + functions ; + Table.add axiomatics ax_name ax_list ; + Table.find in_axiomatic_functions name + in + try match Logic_env.find_all_logic_functions name with + | [] -> make_then_find name + | [x] -> x + | _ :: _ -> Options.not_yet_implemented "Logic function overloading" + with Not_found -> + Options.fatal "Failed to build %s" name + end + +let clear () = Table.clear varinfos let globals loc = - Table.fold (fun _ x l -> Cil_types.GVarDecl(x, loc) :: l) table [] + let open Cil_types in + let l = [] in + let l = + Table.fold (fun _ x l -> GVarDecl(x, loc) :: l) varinfos l + in + let annot x loc = GAnnot(x, loc) in + let fun_or_pred x loc = annot (Dfun_or_pred (x, loc)) loc in + let axiomatic name list loc = annot(Daxiomatic(name, list, [], loc)) loc in + let l = Table.fold (fun _ x l -> fun_or_pred x loc :: l) logic_functions l in + let l = Table.fold (fun n x l -> axiomatic n x loc :: l) axiomatics l in + l \ No newline at end of file diff --git a/src/plugins/instantiate/global_context.mli b/src/plugins/instantiate/global_context.mli index 66e60036195..89f3a212449 100644 --- a/src/plugins/instantiate/global_context.mli +++ b/src/plugins/instantiate/global_context.mli @@ -22,8 +22,8 @@ open Cil_types -(** The purpose of this module is to create global variables when it is needed - by instantiation modules. +(** The purpose of this module global definitions when it is needed by + instantiation modules. *) (** [get_variable name f] searches for an existing variable [name]. If this @@ -34,6 +34,30 @@ open Cil_types *) val get_variable: string -> (unit -> varinfo) -> varinfo +(** [get_logic_function name f] searches for an existing logic function [name]. + If this function does not exists, it is created using [f]. If the logic + function must be part of an axiomatic block **DO NOT** use this function, + use [get_logic_function_in_axiomatic]. + + Note that function overloading is not supported. +*) +val get_logic_function: string -> (unit -> logic_info) -> logic_info + +(** [get_logic_function_in_axiomatic name f] searches for an existing logic + function [name]. If this function does not exists, an axiomatic definition + is created using [f]. + + [f] must return: + - the axiomatic in a form [name, list of the defintions (incl. functions)] + - all functions that are part of the axiomatic definition + + Note that function overloading is not supported. +*) +val get_logic_function_in_axiomatic: + string -> + (unit -> (string * global_annotation list) * logic_info list) -> + logic_info + (** Clears internal tables *) val clear: unit -> unit diff --git a/src/plugins/instantiate/stdlib/basic_alloc.ml b/src/plugins/instantiate/stdlib/basic_alloc.ml index ec54907d18f..3f9ced7c231 100644 --- a/src/plugins/instantiate/stdlib/basic_alloc.ml +++ b/src/plugins/instantiate/stdlib/basic_alloc.ml @@ -47,19 +47,6 @@ let valid_size ?loc typ size = in new_predicate { p with pred_name = ["correct_size"] } -let pis_allocable ?loc size = - let is_allocable = Logic_env.find_all_logic_functions "is_allocable" in - let is_allocable = as_singleton is_allocable in - papp ?loc (is_allocable, [here_label], [size]) - -let is_allocable ?loc size = - let p = pis_allocable ?loc size in - new_predicate { p with pred_name = [ "allocable" ]} - -let isnt_allocable ?loc size = - let p = pnot ?loc (pis_allocable ?loc size) in - new_predicate { p with pred_name = [ "allocable" ]} - let heap_status () = let name = "__fc_heap_status" in let make () = @@ -70,6 +57,55 @@ let heap_status () = let vi = Global_context.get_variable name make in Basic_blocks.cvar_to_tvar vi +let make_is_allocable () = + let name = "is_allocable" in + { + l_var_info = Cil_const.make_logic_var_global name (Ctype Cil.voidType) ; + l_type = None ; + l_tparams = []; + l_labels = [FormalLabel("L")]; + l_profile = [Cil_const.make_logic_var_formal "i" Linteger] ; + l_body = LBreads [new_identified_term (heap_status())]; + } + +let make_axiomatic_is_allocable loc () = + let is_allocable = make_is_allocable () in + let lv_i = Cil_const.make_logic_var_quant "i" Linteger in + let t_i = tvar lv_i in + let zero = tinteger 0 in + let max = + tinteger + (Integer.to_int + (Cil.max_unsigned_number (Cil.bitsSizeOf (size_t ())))) + in + let label = FormalLabel("L") in + let cond = pand (prel (Rlt, t_i, zero), prel (Rgt, t_i, max)) in + let app = pnot (papp (is_allocable,[label],[t_i])) in + let prop = pforall ([lv_i], pimplies (cond, app)) in + let gfun = Dfun_or_pred(is_allocable, loc) in + let axiom = Dlemma("never_allocable", true, [label],[],prop,[], loc) in + ("dynamic_allocation", [gfun ; axiom]), [is_allocable] + +let get_is_allocable loc = + Global_context.get_logic_function_in_axiomatic + "is_allocable" (make_axiomatic_is_allocable loc) + +let pis_allocable ?loc size = + let loc = match loc with + | None -> Cil_datatype.Location.unknown + | Some l -> l + in + let is_allocable = get_is_allocable loc in + papp ~loc (is_allocable, [here_label], [size]) + +let is_allocable ?loc size = + let p = pis_allocable ?loc size in + new_predicate { p with pred_name = [ "allocable" ]} + +let isnt_allocable ?loc size = + let p = pnot ?loc (pis_allocable ?loc size) in + new_predicate { p with pred_name = [ "allocable" ]} + let assigns_result ?loc typ deps = let heap_status = new_identified_term (heap_status ()) in let deps = match deps with diff --git a/src/plugins/instantiate/string/mem_utils.mli b/src/plugins/instantiate/string/mem_utils.mli index a6bbb923b7c..2a580c48732 100644 --- a/src/plugins/instantiate/string/mem_utils.mli +++ b/src/plugins/instantiate/string/mem_utils.mli @@ -32,7 +32,7 @@ module type Function = sig val prototype: unit -> proto - (** receives the type of the lvalue and the types of the arguments recieved + (** receives the type of the lvalue and the types of the arguments received for a call to the function and returns [true] iff they are correct. The received types depend on the [prototype] of the module. - if the kind is [Data t] -> it is the exact type of the expr/lvalue diff --git a/src/plugins/instantiate/tests/stdlib/no_fc_stdlib.c b/src/plugins/instantiate/tests/stdlib/no_fc_stdlib.c new file mode 100644 index 00000000000..21498c2ef2b --- /dev/null +++ b/src/plugins/instantiate/tests/stdlib/no_fc_stdlib.c @@ -0,0 +1,12 @@ +#include <stddef.h> + +void* malloc(size_t s); +void* calloc(size_t num, size_t size); +void free(void* ptr); + +void foo(void){ + int * p = malloc(sizeof(int)); + int * q = calloc(2, sizeof(int)); + free(p); + free(q); +} \ No newline at end of file diff --git a/src/plugins/instantiate/tests/stdlib/oracle/no_fc_stdlib.res.oracle b/src/plugins/instantiate/tests/stdlib/oracle/no_fc_stdlib.res.oracle new file mode 100644 index 00000000000..baa036c870f --- /dev/null +++ b/src/plugins/instantiate/tests/stdlib/oracle/no_fc_stdlib.res.oracle @@ -0,0 +1,253 @@ +[kernel] Parsing tests/stdlib/no_fc_stdlib.c (with preprocessing) +/* Generated by Frama-C */ +#include "stddef.h" +/*@ ghost extern int __fc_heap_status; */ + +/*@ +axiomatic dynamic_allocation { + predicate is_allocable{L}(ℤ i) + reads __fc_heap_status; + + axiom never_allocable{L}: + ∀ ℤ i; i < 0 ∧ i > 4294967295 ⇒ ¬is_allocable(i); + + } + +*/ +void *malloc(size_t s); + +void *calloc(size_t num, size_t size); + +void free(void *ptr); + +/*@ requires freeable: ptr ≡ \null ∨ \freeable(ptr); + assigns __fc_heap_status; + assigns __fc_heap_status \from __fc_heap_status, ptr; + frees ptr; + + behavior allocation: + assumes ptr ≢ \null; + ensures freed: \allocable(ptr); + assigns __fc_heap_status; + assigns __fc_heap_status \from __fc_heap_status, ptr; + frees ptr; + + behavior no_allocation: + assumes ptr ≡ \null; + assigns \nothing; + allocates \nothing; + + complete behaviors no_allocation, allocation; + disjoint behaviors no_allocation, allocation; + */ +void free_int(int *ptr) +{ + free((void *)ptr); + return; +} + +/*@ requires correct_size: 0 ≡ size % 4; + assigns \result, __fc_heap_status; + assigns \result \from __fc_heap_status, num, size; + assigns __fc_heap_status \from __fc_heap_status, num, size; + allocates \result; + + behavior allocation: + assumes allocable: is_allocable(num * size); + ensures fresh_result: \fresh{Old, Here}(\result,num * size); + ensures + zero_initialization: + ∀ ℤ j0; 0 ≤ j0 < num ⇒ *(\result + j0) ≡ 0; + ensures + initialization: + ∀ ℤ j0; 0 ≤ j0 < num ⇒ \initialized(\result + j0); + assigns \result, __fc_heap_status; + assigns \result \from __fc_heap_status, num, size; + assigns __fc_heap_status \from __fc_heap_status, num, size; + allocates \result; + + behavior no_allocation: + assumes allocable: ¬is_allocable(num * size); + ensures null_result: \result ≡ \null; + assigns \result; + assigns \result \from \nothing; + allocates \nothing; + + complete behaviors no_allocation, allocation; + disjoint behaviors no_allocation, allocation; + */ +int *calloc_int(size_t num, size_t size) +{ + int *__retres; + __retres = (int *)calloc(num,size); + return __retres; +} + +/*@ requires correct_size: 0 ≡ size % 4; + assigns \result, __fc_heap_status; + assigns \result \from __fc_heap_status, size; + assigns __fc_heap_status \from __fc_heap_status, size; + allocates \result; + + behavior allocation: + assumes allocable: is_allocable(size); + ensures fresh_result: \fresh{Old, Here}(\result,size); + assigns \result, __fc_heap_status; + assigns \result \from __fc_heap_status, size; + assigns __fc_heap_status \from __fc_heap_status, size; + allocates \result; + + behavior no_allocation: + assumes allocable: ¬is_allocable(size); + ensures null_result: \result ≡ \null; + assigns \result; + assigns \result \from \nothing; + allocates \nothing; + + complete behaviors no_allocation, allocation; + disjoint behaviors no_allocation, allocation; + */ +int *malloc_int(size_t size) +{ + int *__retres; + __retres = (int *)malloc(size); + return __retres; +} + +void foo(void) +{ + int *p = malloc_int(sizeof(int)); + int *q = calloc_int((unsigned int)2,sizeof(int)); + free_int(p); + free_int(q); + return; +} + + +[kernel] Parsing tests/stdlib/result/no_fc_stdlib.c (with preprocessing) +/* Generated by Frama-C */ +#include "stddef.h" +/*@ ghost extern int __fc_heap_status; */ + +/*@ +axiomatic dynamic_allocation { + predicate is_allocable{L}(ℤ i) + reads __fc_heap_status; + + axiom never_allocable{L}: + ∀ ℤ i; i < 0 ∧ i > 4294967295 ⇒ ¬is_allocable(i); + + } + +*/ +void *malloc(size_t s); + +void *calloc(size_t num, size_t size); + +void free(void *ptr); + +/*@ requires freeable: ptr ≡ \null ∨ \freeable(ptr); + assigns __fc_heap_status; + assigns __fc_heap_status \from __fc_heap_status, ptr; + frees ptr; + + behavior allocation: + assumes ptr ≢ \null; + ensures freed: \allocable(\old(ptr)); + assigns __fc_heap_status; + assigns __fc_heap_status \from __fc_heap_status, ptr; + frees ptr; + + behavior no_allocation: + assumes ptr ≡ \null; + assigns \nothing; + allocates \nothing; + + complete behaviors no_allocation, allocation; + disjoint behaviors no_allocation, allocation; + */ +void free_int(int *ptr) +{ + free((void *)ptr); + return; +} + +/*@ requires correct_size: 0 ≡ size % 4; + assigns \result, __fc_heap_status; + assigns \result \from __fc_heap_status, num, size; + assigns __fc_heap_status \from __fc_heap_status, num, size; + allocates \result; + + behavior allocation: + assumes allocable: is_allocable(num * size); + ensures + fresh_result: \fresh{Old, Here}(\result,\old(num) * \old(size)); + ensures + zero_initialization: + ∀ ℤ j0; 0 ≤ j0 < \old(num) ⇒ *(\result + j0) ≡ 0; + ensures + initialization: + ∀ ℤ j0; 0 ≤ j0 < \old(num) ⇒ \initialized(\result + j0); + assigns \result, __fc_heap_status; + assigns \result \from __fc_heap_status, num, size; + assigns __fc_heap_status \from __fc_heap_status, num, size; + allocates \result; + + behavior no_allocation: + assumes allocable: ¬is_allocable(num * size); + ensures null_result: \result ≡ \null; + assigns \result; + assigns \result \from \nothing; + allocates \nothing; + + complete behaviors no_allocation, allocation; + disjoint behaviors no_allocation, allocation; + */ +int *calloc_int(size_t num, size_t size) +{ + int *__retres; + __retres = (int *)calloc(num,size); + return __retres; +} + +/*@ requires correct_size: 0 ≡ size % 4; + assigns \result, __fc_heap_status; + assigns \result \from __fc_heap_status, size; + assigns __fc_heap_status \from __fc_heap_status, size; + allocates \result; + + behavior allocation: + assumes allocable: is_allocable(size); + ensures fresh_result: \fresh{Old, Here}(\result,\old(size)); + assigns \result, __fc_heap_status; + assigns \result \from __fc_heap_status, size; + assigns __fc_heap_status \from __fc_heap_status, size; + allocates \result; + + behavior no_allocation: + assumes allocable: ¬is_allocable(size); + ensures null_result: \result ≡ \null; + assigns \result; + assigns \result \from \nothing; + allocates \nothing; + + complete behaviors no_allocation, allocation; + disjoint behaviors no_allocation, allocation; + */ +int *malloc_int(size_t size) +{ + int *__retres; + __retres = (int *)malloc(size); + return __retres; +} + +void foo(void) +{ + int *p = malloc_int(sizeof(int)); + int *q = calloc_int((unsigned int)2,sizeof(int)); + free_int(p); + free_int(q); + return; +} + + -- GitLab From afae560037fb15a91e44acc19c0a144617cccb53 Mon Sep 17 00:00:00 2001 From: Allan Blanchard <allan.blanchard@cea.fr> Date: Fri, 3 Apr 2020 13:50:09 +0200 Subject: [PATCH 144/218] [Instantiate] Lint --- src/plugins/instantiate/global_context.ml | 2 +- src/plugins/instantiate/global_context.mli | 6 +++--- src/plugins/instantiate/stdlib/basic_alloc.ml | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/plugins/instantiate/global_context.ml b/src/plugins/instantiate/global_context.ml index 9a6d4ff32d6..9791a78d529 100644 --- a/src/plugins/instantiate/global_context.ml +++ b/src/plugins/instantiate/global_context.ml @@ -87,4 +87,4 @@ let globals loc = let axiomatic name list loc = annot(Daxiomatic(name, list, [], loc)) loc in let l = Table.fold (fun _ x l -> fun_or_pred x loc :: l) logic_functions l in let l = Table.fold (fun n x l -> axiomatic n x loc :: l) axiomatics l in - l \ No newline at end of file + l diff --git a/src/plugins/instantiate/global_context.mli b/src/plugins/instantiate/global_context.mli index 89f3a212449..9a1456ff0bb 100644 --- a/src/plugins/instantiate/global_context.mli +++ b/src/plugins/instantiate/global_context.mli @@ -54,9 +54,9 @@ val get_logic_function: string -> (unit -> logic_info) -> logic_info Note that function overloading is not supported. *) val get_logic_function_in_axiomatic: - string -> - (unit -> (string * global_annotation list) * logic_info list) -> - logic_info + string -> + (unit -> (string * global_annotation list) * logic_info list) -> + logic_info (** Clears internal tables *) val clear: unit -> unit diff --git a/src/plugins/instantiate/stdlib/basic_alloc.ml b/src/plugins/instantiate/stdlib/basic_alloc.ml index 3f9ced7c231..a35a97b53e3 100644 --- a/src/plugins/instantiate/stdlib/basic_alloc.ml +++ b/src/plugins/instantiate/stdlib/basic_alloc.ml @@ -76,7 +76,7 @@ let make_axiomatic_is_allocable loc () = let max = tinteger (Integer.to_int - (Cil.max_unsigned_number (Cil.bitsSizeOf (size_t ())))) + (Cil.max_unsigned_number (Cil.bitsSizeOf (size_t ())))) in let label = FormalLabel("L") in let cond = pand (prel (Rlt, t_i, zero), prel (Rgt, t_i, max)) in -- GitLab From d36f20d0632d3fabefb48d9d75781a6c59851c15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Loi=CC=88c=20Correnson?= <loic.correnson@cea.fr> Date: Mon, 6 Apr 2020 09:55:51 +0200 Subject: [PATCH 145/218] [libs] lint floating-point utils --- .Makefile.lint | 2 - src/libraries/utils/floating_point.ml | 284 ++++++++++++------------- src/libraries/utils/floating_point.mli | 8 +- 3 files changed, 146 insertions(+), 148 deletions(-) diff --git a/.Makefile.lint b/.Makefile.lint index 140545ce013..43b7afd7d9e 100644 --- a/.Makefile.lint +++ b/.Makefile.lint @@ -145,8 +145,6 @@ ML_LINT_KO+=src/libraries/utils/command.ml ML_LINT_KO+=src/libraries/utils/command.mli ML_LINT_KO+=src/libraries/utils/escape.mli ML_LINT_KO+=src/libraries/utils/filepath.ml -ML_LINT_KO+=src/libraries/utils/floating_point.ml -ML_LINT_KO+=src/libraries/utils/floating_point.mli ML_LINT_KO+=src/libraries/utils/hook.ml ML_LINT_KO+=src/libraries/utils/hook.mli ML_LINT_KO+=src/libraries/utils/hptmap.ml diff --git a/src/libraries/utils/floating_point.ml b/src/libraries/utils/floating_point.ml index 1b4d343a4de..8311b3e6449 100644 --- a/src/libraries/utils/floating_point.ml +++ b/src/libraries/utils/floating_point.ml @@ -41,10 +41,10 @@ external set_rounding_mode: c_rounding_mode -> unit = "set_rounding_mode" "noall [@@@ warning "+3"] -external round_to_single_precision_float: float -> float = "round_to_float" -external sys_single_precision_of_string: string -> float = - "single_precision_of_string" -(* TODO two functions above: declare "float", +external round_to_single_precision_float: float -> float = "round_to_float" +external sys_single_precision_of_string: string -> float = + "single_precision_of_string" +(* TODO two functions above: declare "float", must have separate version for bytecode, see OCaml manual *) let max_single_precision_float = Int32.float_of_bits 0x7f7fffffl @@ -56,16 +56,16 @@ type parsed_float = { f_upper : float ; } -let inf ~man_size ~max_exp = +let inf ~man_size ~max_exp = let biggest_not_inf = ldexp (2.0 -. ldexp 1.0 (~- man_size)) max_exp in - { + { f_lower = biggest_not_inf ; f_nearest = infinity ; f_upper = infinity ; } (* [s = num * 2^exp / den] hold *) -let make_float ~num ~den ~exp ~man_size ~min_exp ~max_exp = +let make_float ~num ~den ~exp ~man_size ~min_exp ~max_exp = assert (Integer.gt num Integer.zero); assert (Integer.gt den Integer.zero); (* @@ -78,7 +78,7 @@ let make_float ~num ~den ~exp ~man_size ~min_exp ~max_exp = let den = ref den in let exp = ref exp in - while + while Integer.ge num (Integer.shift_left !den ssize_bi) || !exp < min_exp do @@ -88,7 +88,7 @@ let make_float ~num ~den ~exp ~man_size ~min_exp ~max_exp = let den = !den in let shifted_den = Integer.shift_left den size_bi in let num = ref num in - while + while Integer.lt !num shifted_den && !exp > min_exp do num := Integer.shift_left !num Integer.one; @@ -96,7 +96,7 @@ let make_float ~num ~den ~exp ~man_size ~min_exp ~max_exp = done; let num = !num in let exp = !exp in -(* +(* Format.printf "make_float2: num den exp:@\n%a@\n@\n%a@\n@\n%d@." Datatype.Integer.pretty num Datatype.Integer.pretty den exp; *) @@ -107,9 +107,9 @@ let make_float ~num ~den ~exp ~man_size ~min_exp ~max_exp = Integer.shift_left rem Integer.one in let man = Integer.to_int64 man in -(* Format.printf "pre-round: num den man rem:@\n%a@\n@\n%a@\n@\n%Ld@\n@\n%a@." - Datatype.Integer.pretty num Datatype.Integer.pretty den - man Datatype.Integer.pretty rem; *) + (* Format.printf "pre-round: num den man rem:@\n%a@\n@\n%a@\n@\n%Ld@\n@\n%a@." + Datatype.Integer.pretty num Datatype.Integer.pretty den + man Datatype.Integer.pretty rem; *) let lowb = ldexp (Int64.to_float man) exp in if Integer.is_zero rem2 then { f_lower = lowb ; @@ -118,16 +118,16 @@ let make_float ~num ~den ~exp ~man_size ~min_exp ~max_exp = } else let upb = ldexp (Int64.to_float (Int64.succ man)) exp in if Integer.lt rem2 den || - (Integer.equal rem2 den && (Int64.logand man Int64.one) = 0L) + (Integer.equal rem2 den && (Int64.logand man Int64.one) = 0L) then { - f_lower = lowb ; - f_nearest = lowb ; - f_upper = upb ; + f_lower = lowb ; + f_nearest = lowb ; + f_upper = upb ; } else { - f_lower = lowb ; - f_nearest = upb ; - f_upper = upb ; + f_lower = lowb ; + f_nearest = upb ; + f_upper = upb ; } let reg_exp = "[eE][+]?\\(-?[0-9]+\\)" @@ -154,66 +154,66 @@ let parse_float ~man_size ~min_exp ~max_exp s = with Failure _ -> (* Format.printf "Error in exponent: %s@." s; *) if s.[0] = '-' - then raise (Shortcut { - f_lower = 0.0 ; - f_nearest = 0.0 ; - f_upper = ldexp 1.0 (min_exp - man_size) ; - }) + then raise (Shortcut { + f_lower = 0.0 ; + f_nearest = 0.0 ; + f_upper = ldexp 1.0 (min_exp - man_size) ; + }) else raise (Shortcut (inf ~man_size ~max_exp)) in - try - (* At the end of the function, [s = num * 2^exp / den] *) - let num, den, exp = - if Str.string_match numdotfracexp s 0 - then - let n = Str.matched_group 1 s in - let frac = Str.matched_group 2 s in - let len_frac = String.length frac in - let num = Integer.of_string (n ^ frac) in - let den = Integer.power_int_positive_int 5 len_frac in - if Integer.is_zero num then raise (Shortcut zero); - let exp10 = match_exp 3 - in - if exp10 >= 0 - then - Integer.mul num (Integer.power_int_positive_int 5 exp10), - den, - exp10 - len_frac - else - num, - Integer.mul den (Integer.power_int_positive_int 5 (~- exp10)), - exp10 - len_frac - else if Str.string_match numdotfrac s 0 - then - let n = Str.matched_group 1 s in - let frac = Str.matched_group 2 s in - let len_frac = String.length frac in - Integer.of_string (n ^ frac), - Integer.power_int_positive_int 5 len_frac, - ~- len_frac - else if Str.string_match numexp s 0 - then - let n = Str.matched_group 1 s in - let num = Integer.of_string n in - if Integer.is_zero num then raise (Shortcut zero); - let exp10 = match_exp 2 in - if exp10 >= 0 - then - Integer.mul num (Integer.power_int_positive_int 5 exp10), - Integer.one, - exp10 - else - num, - (Integer.power_int_positive_int 5 (~- exp10)), - exp10 - else (Format.printf "Could not parse floating point number %S@." s; - assert false) - in - if Integer.is_zero num - then zero - else - make_float ~num ~den ~exp ~man_size ~min_exp ~max_exp - with Shortcut r -> r + try + (* At the end of the function, [s = num * 2^exp / den] *) + let num, den, exp = + if Str.string_match numdotfracexp s 0 + then + let n = Str.matched_group 1 s in + let frac = Str.matched_group 2 s in + let len_frac = String.length frac in + let num = Integer.of_string (n ^ frac) in + let den = Integer.power_int_positive_int 5 len_frac in + if Integer.is_zero num then raise (Shortcut zero); + let exp10 = match_exp 3 + in + if exp10 >= 0 + then + Integer.mul num (Integer.power_int_positive_int 5 exp10), + den, + exp10 - len_frac + else + num, + Integer.mul den (Integer.power_int_positive_int 5 (~- exp10)), + exp10 - len_frac + else if Str.string_match numdotfrac s 0 + then + let n = Str.matched_group 1 s in + let frac = Str.matched_group 2 s in + let len_frac = String.length frac in + Integer.of_string (n ^ frac), + Integer.power_int_positive_int 5 len_frac, + ~- len_frac + else if Str.string_match numexp s 0 + then + let n = Str.matched_group 1 s in + let num = Integer.of_string n in + if Integer.is_zero num then raise (Shortcut zero); + let exp10 = match_exp 2 in + if exp10 >= 0 + then + Integer.mul num (Integer.power_int_positive_int 5 exp10), + Integer.one, + exp10 + else + num, + (Integer.power_int_positive_int 5 (~- exp10)), + exp10 + else (Format.printf "Could not parse floating point number %S@." s; + assert false) + in + if Integer.is_zero num + then zero + else + make_float ~num ~den ~exp ~man_size ~min_exp ~max_exp + with Shortcut r -> r let is_hex s = let l = String.length s in @@ -224,7 +224,7 @@ let opp_parse_float f = let rec single_precision_of_string s = if s.[0] = '-' then - opp_parse_float (single_precision_of_string (String.sub s 1 (String.length s - 1))) + opp_parse_float (single_precision_of_string (String.sub s 1 (String.length s - 1))) else if is_hex s then try @@ -236,11 +236,11 @@ let rec single_precision_of_string s = parse_float ~man_size:23 ~min_exp:(-126) ~max_exp:127 s (* May raise Failure("float_of_string"). *) -let rec double_precision_of_string s = +let rec double_precision_of_string s = if s.[0] = '-' then opp_parse_float (double_precision_of_string (String.sub s 1 (String.length s - 1))) else if is_hex s - then + then let f = float_of_string s in { f_lower = f ; f_nearest = f ; f_upper = f } else (* decimal *) @@ -285,62 +285,62 @@ let pretty_normal ~use_hex fmt f = let s = if s then "-" else "" in if exp = 2047 then begin - if man = 0L - then - Format.fprintf fmt "%sinf" s - else - Format.fprintf fmt "NaN" - end + if man = 0L + then + Format.fprintf fmt "%sinf" s + else + Format.fprintf fmt "NaN" + end else - let firstdigit, exp = - if exp <> 0 - then 1, (exp - 1023) - else 0, if f = 0. then 0 else -1022 - in - if not use_hex - then begin + let firstdigit, exp = + if exp <> 0 + then 1, (exp - 1023) + else 0, if f = 0. then 0 else -1022 + in + if not use_hex + then begin let firstdigit, man, exp = - if 0 < exp && exp <= 12 - then begin - Int64.to_int - (Int64.shift_right_logical - (Int64.logor man double_norm) - (52 - exp)), - Int64.logand (Int64.shift_left man exp) double_mask, - 0 - end - else firstdigit, man, exp + if 0 < exp && exp <= 12 + then begin + Int64.to_int + (Int64.shift_right_logical + (Int64.logor man double_norm) + (52 - exp)), + Int64.logand (Int64.shift_left man exp) double_mask, + 0 + end + else firstdigit, man, exp in let d = - Int64.float_of_bits - (Int64.logor 0x3ff0000000000000L man) + Int64.float_of_bits + (Int64.logor 0x3ff0000000000000L man) in let d, re = - if d >= 1.5 - then d -. 1.5, 5000000000000000L - else d -. 1.0, 0L + if d >= 1.5 + then d -. 1.5, 5000000000000000L + else d -. 1.0, 0L in let d = d *. 1e16 in let decdigits = Int64.add re (Int64.of_float d) in if exp = 0 || (firstdigit = 0 && decdigits = 0L && exp = -1022) then - Format.fprintf fmt "%s%d.%016Ld" - s - firstdigit - decdigits + Format.fprintf fmt "%s%d.%016Ld" + s + firstdigit + decdigits else - Format.fprintf fmt "%s%d.%016Ld*2^%d" - s - firstdigit - decdigits - exp + Format.fprintf fmt "%s%d.%016Ld*2^%d" + s + firstdigit + decdigits + exp end - else - Format.fprintf fmt "%s0x%d.%013Lxp%d" - s - firstdigit - man - exp + else + Format.fprintf fmt "%s0x%d.%013Lxp%d" + s + firstdigit + man + exp let pretty fmt f = let use_hex = Kernel.FloatHex.get() in @@ -354,15 +354,15 @@ let pretty fmt f = then pretty_normal ~use_hex fmt f else begin - let r = Format.sprintf "%.*g" 12 f in - if (String.contains r '.' || String.contains r 'e' || - String.contains r 'E') - || (match classify_float f with - | FP_normal | FP_subnormal | FP_zero -> false - | FP_infinite | FP_nan -> true) - then Format.pp_print_string fmt r - else Format.fprintf fmt "%s." r - end + let r = Format.sprintf "%.*g" 12 f in + if (String.contains r '.' || String.contains r 'e' || + String.contains r 'E') + || (match classify_float f with + | FP_normal | FP_subnormal | FP_zero -> false + | FP_infinite | FP_nan -> true) + then Format.pp_print_string fmt r + else Format.fprintf fmt "%s." r + end type sign = Neg | Pos @@ -373,12 +373,12 @@ exception Float_Non_representable_as_Int64 of sign raise Float_Non_representable_as_Int64. This is the most reasonable as a floating-point number may represent an exponentially large integer. *) let truncate_to_integer = - let min_64_float = -9.22337203685477581e+18 - (* Int64.to_float (-0x8000000000000000L) *) + let min_64_float = -9.22337203685477581e+18 + (* Int64.to_float (-0x8000000000000000L) *) in - let max_64_float = 9.22337203685477478e+18 -(* let open Int64 in - float_of_bits (pred (bits_of_float (to_float max_int))) *) + let max_64_float = 9.22337203685477478e+18 + (* let open Int64 in + float_of_bits (pred (bits_of_float (to_float max_int))) *) in fun x -> let max_64_float = Extlib.id max_64_float in @@ -388,10 +388,10 @@ let truncate_to_integer = then raise (Float_Non_representable_as_Int64 Pos); if x <= max_64_float then Integer.of_int64 (Int64.of_float x) - else - Integer.add - (Integer.of_int64 (Int64.of_float (x +. min_64_float))) - (Integer.two_power_of_int 63) + else + Integer.add + (Integer.of_int64 (Int64.of_float (x +. min_64_float))) + (Integer.two_power_of_int 63) let bits_of_max_double = Integer.of_int64 (Int64.bits_of_float max_float) diff --git a/src/libraries/utils/floating_point.mli b/src/libraries/utils/floating_point.mli index 27a4bbbe39e..6588bd2367c 100644 --- a/src/libraries/utils/floating_point.mli +++ b/src/libraries/utils/floating_point.mli @@ -30,8 +30,8 @@ val string_of_c_rounding_mode : c_rounding_mode -> string external set_round_downward : unit -> unit = "set_round_downward" [@@noalloc] external set_round_upward : unit -> unit = "set_round_upward" [@@noalloc] -external set_round_nearest_even : unit -> unit = - "set_round_nearest_even" [@@noalloc] +external set_round_nearest_even : unit -> unit = + "set_round_nearest_even" [@@noalloc] external set_round_toward_zero : unit -> unit = "set_round_toward_zero" [@@noalloc] external get_rounding_mode: unit -> c_rounding_mode = @@ -49,8 +49,8 @@ val neg_min_denormal: float val min_single_precision_denormal: float val neg_min_single_precision_denormal: float -external sys_single_precision_of_string: string -> float = - "single_precision_of_string" +external sys_single_precision_of_string: string -> float = + "single_precision_of_string" (** If [s] is parsed as [(n, l, u)], then [n] is the nearest approximation of -- GitLab From 49c521b20f85e2ea97f0f293c3110ee664029bfd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Loi=CC=88c=20Correnson?= <loic.correnson@cea.fr> Date: Mon, 6 Apr 2020 10:16:49 +0200 Subject: [PATCH 146/218] [printer] fix logic float printing --- src/kernel_services/ast_printing/cil_printer.ml | 2 +- src/libraries/utils/floating_point.ml | 8 ++++++++ src/libraries/utils/floating_point.mli | 4 ++++ 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/kernel_services/ast_printing/cil_printer.ml b/src/kernel_services/ast_printing/cil_printer.ml index 6e9c4550927..fbfc904dc2a 100644 --- a/src/kernel_services/ast_printing/cil_printer.ml +++ b/src/kernel_services/ast_printing/cil_printer.ml @@ -2435,7 +2435,7 @@ class cil_printer () = object (self) begin match ty, t.term_node with | TFloat(fk,_) , TConst(LReal r as cst) when not Kernel.(is_debug_key_enabled dkey_print_logic_coercions) && - Cil.isExactFloat fk r -> + Floating_point.has_suffix fk r.r_literal -> self#logic_constant fmt cst | _ -> fprintf fmt "(%a)%a" (self#typ None) ty term e diff --git a/src/libraries/utils/floating_point.ml b/src/libraries/utils/floating_point.ml index 8311b3e6449..13227afdd5d 100644 --- a/src/libraries/utils/floating_point.ml +++ b/src/libraries/utils/floating_point.ml @@ -274,6 +274,14 @@ let parse string = Kernel.fatal ~current:true "Unexpected error parsing floating-point constant: %s." string +let has_suffix fk lit = + let s = match fk with + | Cil_types.FFloat -> 'F' + | Cil_types.FDouble -> 'D' + | Cil_types.FLongDouble -> 'L' in + let ln = String.length lit in + ln > 0 && Char.uppercase_ascii lit.[ln-1] = s + let pretty_normal ~use_hex fmt f = let double_norm = Int64.shift_left 1L 52 in let double_mask = Int64.pred double_norm in diff --git a/src/libraries/utils/floating_point.mli b/src/libraries/utils/floating_point.mli index 6588bd2367c..599d4770d1c 100644 --- a/src/libraries/utils/floating_point.mli +++ b/src/libraries/utils/floating_point.mli @@ -69,6 +69,10 @@ type parsed_float = { with no suffix are parsed as double. *) val parse: string -> Cil_types.fkind * parsed_float +(** Checks if the (uppercased) string ends with an explicit `F|D|L` + suffix for the given float kind. *) +val has_suffix: Cil_types.fkind -> string -> bool + val pretty_normal : use_hex : bool -> Format.formatter -> float -> unit val pretty : Format.formatter -> float -> unit -- GitLab From 97d4fb497baeb7e34a8773cfcec006799044e166 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Loi=CC=88c=20Correnson?= <loic.correnson@cea.fr> Date: Mon, 6 Apr 2020 11:16:29 +0200 Subject: [PATCH 147/218] [doc] typos --- src/kernel_services/ast_queries/logic_utils.mli | 10 +++++----- src/libraries/utils/floating_point.mli | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/kernel_services/ast_queries/logic_utils.mli b/src/kernel_services/ast_queries/logic_utils.mli index 6817dfd9371..c147282eea5 100644 --- a/src/kernel_services/ast_queries/logic_utils.mli +++ b/src/kernel_services/ast_queries/logic_utils.mli @@ -187,7 +187,7 @@ val expr_to_predicate: exp -> predicate of the original C-expression. This is different from [expr_to_term e |> scalar_term_to_predicate] - since it directly translate C-relations into logic ones. + since C-relations are translated into logic ones. @raise Fatal error if the expression is not a comparison and cannot be compared to zero. @@ -212,7 +212,7 @@ val expr_to_boolean: exp -> term of the original C-expression. This is different from [expr_to_term e |> scalar_term_to_predicate] - since it directly translate C-relations into logic ones. + since C-relations are translated into logic ones. @raise Fatal error if the expression is not a comparison and cannot be compared to zero. @@ -256,9 +256,9 @@ val lconstant_to_constant: logic_constant-> constant The returned term is either a real constant or real constant casted into a C-float type. - Unsuffised constants are considered as real numbers. - Literals suffixed by ['f'] or ['d'] are - considered as float constants. *) + Unsuffixed literals are considered as real numbers. + Literals suffixed by [f|d|l] or [F|D|L] are considered + as float constants of the associated kind. *) val parse_float : ?loc:location -> string -> term (** {2 Various Utilities} *) diff --git a/src/libraries/utils/floating_point.mli b/src/libraries/utils/floating_point.mli index 599d4770d1c..d698d950308 100644 --- a/src/libraries/utils/floating_point.mli +++ b/src/libraries/utils/floating_point.mli @@ -69,7 +69,7 @@ type parsed_float = { with no suffix are parsed as double. *) val parse: string -> Cil_types.fkind * parsed_float -(** Checks if the (uppercased) string ends with an explicit `F|D|L` +(** Checks if the (uppercased) string ends with an explicit [F|D|L] suffix for the given float kind. *) val has_suffix: Cil_types.fkind -> string -> bool -- GitLab From fc33bf23c3a30fb03eb093257757655f6fc680b0 Mon Sep 17 00:00:00 2001 From: Andre Maroneze <andre.oliveiramaroneze@cea.fr> Date: Mon, 6 Apr 2020 13:48:43 +0200 Subject: [PATCH 148/218] [doc] normalize references to ISO C99 --- doc/value/main.tex | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/doc/value/main.tex b/doc/value/main.tex index 045d671af55..d9a08cc3af8 100644 --- a/doc/value/main.tex +++ b/doc/value/main.tex @@ -31,6 +31,7 @@ \newcommand{\framacversion}% {\input{../../VERSION} (\input{../../VERSION_CODENAME}\unskip)} +\newcommand{\isoc}{\textsf{C99}} \newcommand{\Eva}{\textsf{Eva}} @@ -630,7 +631,7 @@ no run-time error could happen when running the program. The alarm means that \Eva{} could not prove that the value \verb|ks[i]| accessed in \verb|skein_block.c:69| was definitely initialized before being read. Reading an initialized value is an undefined behavior according to the -ISO C99 standard (and can even lead to security vulnerabilities). +\isoc{} standard (and can even lead to security vulnerabilities). As is often the case, this alarm is related to the approximation introduced in \verb|skein_block.c:56|, which is the loop responsible for initializing @@ -1479,7 +1480,7 @@ This may happen on: In this case, the emitted alarm reports a possible undefined behavior. \item conversion of an integer into a pointer. Except for the constant~0, such a conversion is always an implementation-defined behavior - according to the ISO C99 standard. However, a footnote also explains that + according to the \isoc{} standard. However, a footnote also explains that conversion between pointers and integers is ``\emph{intended to be consistent with the addressing structure of the execution environment}''. This is why Eva also also authorizes conversion of integers: @@ -1546,7 +1547,7 @@ simpler than this one. Do not be surprised by them. Another arithmetic alarm is the alarm emitted for logical shift operations on integers where the second operand may be larger than the size in bits of the first operand's type. -Such an operation is left undefined by the ISO/IEC 9899:1999 standard, and +Such an operation is left undefined by the \isoc{} standard, and indeed, processors are often built in a way that such an operation does not produce the \lstinline|0| or \lstinline|-1| result that could have been expected. Here is an example @@ -1558,7 +1559,7 @@ shift.c:4: ... invalid RHS operand for shift. assert 0 <= c < 32; \Eva{} also detects shifts on negative integers. Left-shifting a negative integer is an undefined behavior according to the -ISO C99 standard, and leads to an alarm by default. +\isoc{} standard, and leads to an alarm by default. These alarms can be disabled by using the option \lstinline|-no-warn-left-shift-negative|. Right-shifting a negative integer is an implementation-defined operation, @@ -1577,7 +1578,7 @@ By default, \Eva{} emits alarms for --- and reduces the sets of possible results of --- signed arithmetic computations where the possibility of an overflow exists. Indeed, such overflows have an undefined behavior according to -paragraph 6.5.5 of the ISO/IEC 9899:1999 standard. +paragraph 6.5.5 of the \isoc{} standard. % If useful, it is also possible to assume that signed integers overflow according to a 2's complement representation. The option @@ -1588,13 +1589,13 @@ as potentially overflowing. This warning can also be disabled by option By default, no alarm is emitted for arithmetic operations on unsigned integers for which an overflow may happen, since such operations have -defined semantics according to the ISO/IEC 9899:1999 standard. +defined semantics according to the \isoc{} standard. If one wishes to signal and prevent such unsigned overflows, option \verb+-warn-unsigned-overflow+ can be used. By default, Eva emits alarms for downcasts of pointer values to (signed or unsigned) integer types. Such downcasts are indeed undefined behavior -according to section 6.3.2.3, §6 of the ISO/IEC 9899:1999 standard. +according to section 6.3.2.3, §6 of the \isoc{} standard. However, option \lstinline|-no-warn-pointer-downcast| can be used to disable these alarms. @@ -1715,7 +1716,7 @@ can also be used to activate this behavior for all functions. By default, \Eva{} emits an alarm whenever a trap representation might be read from an lvalue of type \texttt{\_Bool}. -According to the ISO/IEC 9899:1999 standard, the \texttt{\_Bool} type contains +According to the \isoc{} standard, the \texttt{\_Bool} type contains the values 0 and 1, but any other value might be a trap representation, that is, an object representation that does not represent a valid value of the type. Trap representations can be created through unions or pointer casts. @@ -1867,7 +1868,7 @@ compiler, if we may ask such a rhetorical question, is right? They all are, because the program is undefined. When function \lstinline|copy()| is called from \lstinline|main()|, the assignment \lstinline|*p = *q;| breaks -C99's 6.5.16.1:3 rule. This rule states that +\isoc{}'s 6.5.16.1:3 rule. This rule states that in an assignment from lvalue to lvalue, the left and right lvalues must overlap either exactly or not at all. @@ -2173,7 +2174,7 @@ limited form, but imprecisions may accumulate quickly \Eva{} does not check all the properties that could be expected of it\footnote{There are 245 unspecified or undefined - behaviors in Annex J of the ISO C99 standard.}. Support for each of + behaviors in Annex J of the \isoc{} standard.}. Support for each of these missing features could arrive if the need was expressed. Below are some of the existing limitations. -- GitLab From a2c983f12a866f38bca8f95ab9f243ef27753a04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20B=C3=BChler?= <david.buhler@cea.fr> Date: Mon, 10 Feb 2020 13:53:08 +0100 Subject: [PATCH 149/218] [Eva] In abstract domains, slightly changes the queries signature. Queries return an origin option instead of an origin. Domains not using the origin simply return None, and no longer need to define the origin type. --- src/plugins/value/domains/abstract_domain.mli | 7 ++++--- src/plugins/value/domains/apron/apron_domain.ml | 6 +++--- src/plugins/value/domains/cvalue/cvalue_domain.ml | 2 +- src/plugins/value/domains/cvalue/cvalue_transfer.ml | 4 ++-- .../value/domains/cvalue/cvalue_transfer.mli | 2 +- src/plugins/value/domains/domain_builder.ml | 13 ++++++++----- src/plugins/value/domains/domain_product.ml | 8 ++++---- .../value/domains/equality/equality_domain.ml | 6 +++--- src/plugins/value/domains/gauges/gauges_domain.ml | 6 +++--- src/plugins/value/domains/inout_domain.ml | 4 ++-- src/plugins/value/domains/octagons.ml | 6 +++--- src/plugins/value/domains/offsm_domain.ml | 10 +++++----- src/plugins/value/domains/simple_memory.ml | 6 +++--- src/plugins/value/domains/symbolic_locs.ml | 8 ++++---- src/plugins/value/domains/traces_domain.ml | 4 ++-- src/plugins/value/domains/unit_domain.ml | 4 ++-- src/plugins/value/engine/evaluation.ml | 4 +--- 17 files changed, 51 insertions(+), 49 deletions(-) diff --git a/src/plugins/value/domains/abstract_domain.mli b/src/plugins/value/domains/abstract_domain.mli index df7e17c543e..b1b06f70f1d 100644 --- a/src/plugins/value/domains/abstract_domain.mli +++ b/src/plugins/value/domains/abstract_domain.mli @@ -134,7 +134,8 @@ module type Queries = sig - a value for the expression, which can be: – `Bottom if its evaluation is infeasible; – `Value (v, o) where [v] is an over-approximation of the abstract - value of the expression [exp], and [o] is the origin of the value. *) + value of the expression [exp], and [o] is the origin of the value, + which can be None. *) (** Query function for compound expressions: [eval oracle t exp] returns the known value of [exp] by the state [t]. @@ -143,14 +144,14 @@ module type Queries = sig No recursive evaluation should be done by this function. *) val extract_expr : (exp -> value evaluated) -> - state -> exp -> (value * origin) evaluated + state -> exp -> (value * origin option) evaluated (** Query function for lvalues: [find oracle t lval typ loc] returns the known value stored at the location [loc] of the left value [lval] of type [typ]. *) val extract_lval : (exp -> value evaluated) -> - state -> lval -> typ -> location -> (value * origin) evaluated + state -> lval -> typ -> location -> (value * origin option) evaluated (** [backward_location state lval typ loc v] reduces the location [loc] of the lvalue [lval] of type [typ], so that only the locations that may have value diff --git a/src/plugins/value/domains/apron/apron_domain.ml b/src/plugins/value/domains/apron/apron_domain.ml index 8915d40c396..c9fd86075f1 100644 --- a/src/plugins/value/domains/apron/apron_domain.ml +++ b/src/plugins/value/domains/apron/apron_domain.ml @@ -360,7 +360,7 @@ module Make (Man : Input) = struct type state = Man.t Abstract1.t type value = Main_values.Interval.t type location = Precise_locs.precise_location - type origin = unit + type origin let man = Man.manager let log_category = dkey @@ -463,7 +463,7 @@ module Make (Man : Input) = struct let dummy_oracle _ exn = raise exn let compute state expr typ = - let top = `Value (None, ()), Alarmset.all in + let top = `Value (None, None), Alarmset.all in if not (is_relevant expr) then top else @@ -476,7 +476,7 @@ module Make (Man : Input) = struct let value = if Interval.is_bottom interval then `Bottom - else `Value (interval_to_ival interval, ()) + else `Value (interval_to_ival interval, None) in (* TODO: remove alarms if computation does not overflow *) value, Alarmset.all diff --git a/src/plugins/value/domains/cvalue/cvalue_domain.ml b/src/plugins/value/domains/cvalue/cvalue_domain.ml index 811a00dd6b0..b5a165f3189 100644 --- a/src/plugins/value/domains/cvalue/cvalue_domain.ml +++ b/src/plugins/value/domains/cvalue/cvalue_domain.ml @@ -38,7 +38,7 @@ module Model = struct lvalue can be incomparable. The origin is then used to store the value from the state, to later choose which value to keep. This is done by the update function in cvalue_transfer. *) - type origin = value option + type origin = value let extract_expr _ _ _ = `Value (Cvalue.V.top, None), Alarmset.all diff --git a/src/plugins/value/domains/cvalue/cvalue_transfer.ml b/src/plugins/value/domains/cvalue/cvalue_transfer.ml index 540f2ec4bd4..94bb435e101 100644 --- a/src/plugins/value/domains/cvalue/cvalue_transfer.ml +++ b/src/plugins/value/domains/cvalue/cvalue_transfer.ml @@ -25,7 +25,7 @@ open Eval open Cvalue.Model type value = Main_values.CVal.t -type origin = value option +type origin = value type location = Main_locations.PLoc.location let unbottomize = function @@ -71,7 +71,7 @@ let update valuation t = included in the other). We use some notion of cardinality of abstract values to choose the best value to keep. *) match record.origin with - | Some (Some previous_v) -> + | Some previous_v -> let typ = Cil.typeOfLval lv in if is_smaller_value typ v previous_v then v else previous_v | _ -> v diff --git a/src/plugins/value/domains/cvalue/cvalue_transfer.mli b/src/plugins/value/domains/cvalue/cvalue_transfer.mli index d9f23bf0ff2..b74f2266beb 100644 --- a/src/plugins/value/domains/cvalue/cvalue_transfer.mli +++ b/src/plugins/value/domains/cvalue/cvalue_transfer.mli @@ -23,7 +23,7 @@ (** Transfer functions for the main domain of the Value analysis. *) type value = Main_values.CVal.t -type origin = value option +type origin = value type location = Main_locations.PLoc.location include Abstract_domain.Transfer diff --git a/src/plugins/value/domains/domain_builder.ml b/src/plugins/value/domains/domain_builder.ml index 83e734a69f5..4be9203e8c2 100644 --- a/src/plugins/value/domains/domain_builder.ml +++ b/src/plugins/value/domains/domain_builder.ml @@ -65,11 +65,11 @@ module Make_Minimal type value = Value.t type location = Location.location type state = Domain.t - type origin = unit + type origin let narrow x _y = `Value x - let top_answer = `Value (Value.top, ()), Alarmset.all + let top_answer = `Value (Value.top, None), Alarmset.all let extract_expr _oracle _state _expr = top_answer let extract_lval _oracle _state _lval _typ _location = top_answer let backward_location _state _lval _typ location value = `Value (location, value) @@ -184,16 +184,19 @@ module Complete_Simple_Cvalue (Domain: Simpler_domains.Simple_Cvalue) type value = Cvalue.V.t type location = Precise_locs.precise_location type state = Domain.t - type origin = unit + type origin let narrow x _y = `Value x let extract_expr _oracle state expr = - let v = Domain.extract_expr state expr >>-: fun v -> v, () in + let v = Domain.extract_expr state expr >>-: fun v -> v, None in v, Alarmset.all let extract_lval _oracle state lval typ location = - let v = Domain.extract_lval state lval typ location >>-: fun v -> v, () in + let v = + Domain.extract_lval state lval typ location >>-: fun v -> + v, None + in v, Alarmset.all let backward_location _state _lval _typ location value = diff --git a/src/plugins/value/domains/domain_product.ml b/src/plugins/value/domains/domain_product.ml index d73cc44bf4a..e9894fa2f06 100644 --- a/src/plugins/value/domains/domain_product.ml +++ b/src/plugins/value/domains/domain_product.ml @@ -37,8 +37,8 @@ module Make type location = Left.location type origin = { - left: reductness * Left.origin; - right: reductness * Right.origin; + left: reductness * Left.origin option; + right: reductness * Right.origin option; } let () = incr counter @@ -85,7 +85,7 @@ module Make else if Value.equal v2 Value.top then Created else Reduced in let origin = {left = left, o1; right = right, o2} in - value, origin + value, Some origin in value, alarms @@ -120,7 +120,7 @@ module Make | Reduced, Some (Created, _) -> Created | _ as x, _ -> x in - let origin = Extlib.opt_map snd origin in + let origin = Extlib.may_map snd ~dft:None origin in { record with origin; reductness } let lift_valuation side valuation = diff --git a/src/plugins/value/domains/equality/equality_domain.ml b/src/plugins/value/domains/equality/equality_domain.ml index b36c5560bf0..f78930c6d92 100644 --- a/src/plugins/value/domains/equality/equality_domain.ml +++ b/src/plugins/value/domains/equality/equality_domain.ml @@ -189,7 +189,7 @@ module Make type value = Value.t type location = Precise_locs.precise_location - type origin = unit + type origin let reduce_further (equalities, _, _) expr value = let atom = HCE.of_exp expr in @@ -232,12 +232,12 @@ module Make in let v = Equality.Equality.fold aux_eq equality (`Value Value.top) in (* Remove the 'origin' information of garbled mixes. *) - let v = v >>-: fun v -> imprecise_origin v, () in + let v = v >>-: fun v -> imprecise_origin v, None in (* All expressions used by the equality domain have already been evaluated before during the analysis; alarms about those expressions have already been emitted. *) v, Alarmset.none - | None -> `Value (Value.top, ()), Alarmset.all + | None -> `Value (Value.top, None), Alarmset.all let extract_expr (oracle: exp -> Value.t evaluated) (equalities, _, _) expr = let expr = Cil.constFold true expr in diff --git a/src/plugins/value/domains/gauges/gauges_domain.ml b/src/plugins/value/domains/gauges/gauges_domain.ml index 75acbedd0d9..3b60576b815 100644 --- a/src/plugins/value/domains/gauges/gauges_domain.ml +++ b/src/plugins/value/domains/gauges/gauges_domain.ml @@ -1130,7 +1130,7 @@ module D_Impl : Abstract_domain.S type value = Cvalue.V.t type state = G.t type location = Precise_locs.precise_location - type origin = unit + type origin include G @@ -1260,7 +1260,7 @@ module D_Impl : Abstract_domain.S (* TODO: it would be interesting to return something here, but we currently need a valuation to perform the translation. *) let extract_expr _oracle _state _exp = - `Value (Cvalue.V.top, ()), Alarmset.all + `Value (Cvalue.V.top, None), Alarmset.all let extract_lval _oracle state _lv typ loc = let v = @@ -1274,7 +1274,7 @@ module D_Impl : Abstract_domain.S (* We can probably return an empty set of alarms when the value is known, but the only possible alarms on lvalues are about indeterminateness, and it is not clear that we know more than the Cvalue domain. *) - `Value (v, ()), Alarmset.all + `Value (v, None), Alarmset.all let backward_location _state _lval _typ loc value = `Value (loc, value) diff --git a/src/plugins/value/domains/inout_domain.ml b/src/plugins/value/domains/inout_domain.ml index 6bdc2036383..da068efc2f9 100644 --- a/src/plugins/value/domains/inout_domain.ml +++ b/src/plugins/value/domains/inout_domain.ml @@ -213,7 +213,7 @@ module Internal type state = inout type value = Cvalue.V.t type location = Precise_locs.precise_location - type origin = unit + type origin include (LatticeInout: sig include Datatype.S_with_collections with type t = state @@ -269,7 +269,7 @@ module Internal let storage () = true - let top_query = `Value (Cvalue.V.top, ()), Alarmset.all + let top_query = `Value (Cvalue.V.top, None), Alarmset.all let extract_expr _oracle _state _expr = top_query let extract_lval _oracle _state _lv _typ _locs = top_query diff --git a/src/plugins/value/domains/octagons.ml b/src/plugins/value/domains/octagons.ml index 8ed828c84e0..853183f0d39 100644 --- a/src/plugins/value/domains/octagons.ml +++ b/src/plugins/value/domains/octagons.ml @@ -1037,9 +1037,9 @@ module Domain = struct type value = Cvalue.V.t type location = Precise_locs.precise_location - type origin = unit + type origin - let top_value = `Value (Cvalue.V.top, ()), Alarmset.all + let top_value = `Value (Cvalue.V.top, None), Alarmset.all let extract_expr oracle state expr = let evaluate_expr expr = @@ -1057,7 +1057,7 @@ module Domain = struct then top_value else if Ival.is_bottom ival then `Bottom, Alarmset.all - else `Value (Cvalue.V.inject_ival ival, ()), alarms + else `Value (Cvalue.V.inject_ival ival, None), alarms let extract_lval _oracle _t _lval _typ _loc = top_value diff --git a/src/plugins/value/domains/offsm_domain.ml b/src/plugins/value/domains/offsm_domain.ml index 87c59b27115..4d8a15d53eb 100644 --- a/src/plugins/value/domains/offsm_domain.ml +++ b/src/plugins/value/domains/offsm_domain.ml @@ -97,7 +97,7 @@ module Internal : Domain_builder.InputDomain type value = offsm_or_top type state = Memory.t type location = Precise_locs.precise_location - type origin = unit (* ???? *) + type origin include (Memory: sig include Datatype.S_with_collections with type t = state @@ -164,7 +164,7 @@ module Internal : Domain_builder.InputDomain let show_expr _valuation _state _fmt _expr = () let extract_expr _oracle _state _exp = - `Value (Offsm_value.Offsm.top, ()), Alarmset.all + `Value (Offsm_value.Offsm.top, None), Alarmset.all (* Basic 'find' on a location *) let find_loc state loc = @@ -181,7 +181,7 @@ module Internal : Domain_builder.InputDomain if Cil.typeHasQualifier "volatile" typ || not (Cil.isArithmeticOrPointerType typ) then - `Value (Top, ()) + `Value (Top, None) else try let aux_loc loc o = @@ -189,8 +189,8 @@ module Internal : Domain_builder.InputDomain Bottom.join Offsm_value.Offsm.join o o' in Precise_locs.fold aux_loc locs `Bottom >>-: fun v -> - v, () - with Abstract_interp.Error_Top -> `Value (Top, ()) + v, None + with Abstract_interp.Error_Top -> `Value (Top, None) in o, Alarmset.all diff --git a/src/plugins/value/domains/simple_memory.ml b/src/plugins/value/domains/simple_memory.ml index 56e9aecdb12..20f91dc4a99 100644 --- a/src/plugins/value/domains/simple_memory.ml +++ b/src/plugins/value/domains/simple_memory.ml @@ -187,7 +187,7 @@ module Make_Internal (Info: sig val name: string end) (Value: Value) = struct type state = t type value = Value.t type location = Precise_locs.precise_location - type origin = unit + type origin let log_category = Value_parameters.register_category ("d-" ^ Info.name) @@ -198,9 +198,9 @@ module Make_Internal (Info: sig val name: string end) (Value: Value) = struct evaluation. *) let extract_lval _oracle state _lv typ loc = let v = find loc typ state in - `Value (v, ()), Alarmset.all + `Value (v, None), Alarmset.all - let extract_expr _oracle _state _expr = `Value (Value.top, ()), Alarmset.all + let extract_expr _oracle _state _expr = `Value (Value.top, None), Alarmset.all let backward_location state _lval typ loc _value = let new_value = find loc typ state in diff --git a/src/plugins/value/domains/symbolic_locs.ml b/src/plugins/value/domains/symbolic_locs.ml index f7e994cc254..91b53803645 100644 --- a/src/plugins/value/domains/symbolic_locs.ml +++ b/src/plugins/value/domains/symbolic_locs.ml @@ -466,7 +466,7 @@ module Internal : Domain_builder.InputDomain type state = Memory.t type value = V.t type location = Precise_locs.precise_location - type origin = unit + type origin include (Memory: sig include Datatype.S_with_collections with type t = state @@ -569,7 +569,7 @@ module Internal : Domain_builder.InputDomain let show_expr _valuation _state _fmt _expr = () - let top_query = `Value (V.top, ()), Alarmset.all + let top_query = `Value (V.top, None), Alarmset.all (* For extraction functions, if we have an information about the value, this means that the key has been evaluated in all the paths that reach @@ -579,12 +579,12 @@ module Internal : Domain_builder.InputDomain let extract_expr _oracle state expr = match Memory.find_expr expr state with | None -> top_query - | Some v -> `Value (v, ()), Alarmset.none + | Some v -> `Value (v, None), Alarmset.none let extract_lval _oracle state lv _typ _locs = match Memory.find_lval lv state with | None -> top_query - | Some v -> `Value (v, ()), Alarmset.none + | Some v -> `Value (v, None), Alarmset.none let backward_location _state _lval _typ loc value = (* Nothing to do. We could check if [[lval]] intersects [value] and diff --git a/src/plugins/value/domains/traces_domain.ml b/src/plugins/value/domains/traces_domain.ml index 1761500f38f..4c533c30c2c 100644 --- a/src/plugins/value/domains/traces_domain.ml +++ b/src/plugins/value/domains/traces_domain.ml @@ -848,7 +848,7 @@ module Internal = struct type nonrec state = state type value = Cvalue.V.t type location = Precise_locs.precise_location - type origin = unit + type origin include (Traces: sig include Datatype.S_with_collections with type t = state @@ -940,7 +940,7 @@ module Internal = struct let storage () = true - let top_query = `Value (Cvalue.V.top, ()), Alarmset.all + let top_query = `Value (Cvalue.V.top, None), Alarmset.all let extract_expr _oracle _state _expr = top_query let extract_lval _oracle _state _lv _typ _locs = top_query diff --git a/src/plugins/value/domains/unit_domain.ml b/src/plugins/value/domains/unit_domain.ml index 00c59d6445c..5d1a5594218 100644 --- a/src/plugins/value/domains/unit_domain.ml +++ b/src/plugins/value/domains/unit_domain.ml @@ -52,9 +52,9 @@ module Make include Static type value = Value.t type location = Loc.location - type origin = unit + type origin - let eval_top = `Value (Value.top, ()), Alarmset.all + let eval_top = `Value (Value.top, None), Alarmset.all let extract_expr _ _ _ = eval_top let extract_lval _ _ _ _ _ = eval_top let backward_location _ _ _ loc value = `Value (loc, value) diff --git a/src/plugins/value/engine/evaluation.ml b/src/plugins/value/engine/evaluation.ml index 5e0445cf0ca..d4d08981adf 100644 --- a/src/plugins/value/engine/evaluation.ml +++ b/src/plugins/value/engine/evaluation.ml @@ -258,7 +258,7 @@ let indeterminate_copy lval result alarms = let reductness = Unreduced in let v, origin = match result with | `Bottom -> `Bottom, None - | `Value (v, origin) -> `Value v, Some origin + | `Value (v, origin) -> `Value v, origin in let value = { v; initialized; escaping } in let record = { value; origin; reductness; val_alarms = alarms} in @@ -853,7 +853,6 @@ module Make in let reduction = update_reduction reduction (Value.equal intern_value result) - and origin = Some origin and value = define_value result in (* The proper alarms will be set in the record by forward_eval. *) {value; origin; reductness; val_alarms = Alarmset.all}, @@ -1084,7 +1083,6 @@ module Make let v, alarms = assume_valid_value typ_lv lval (v, alarms) in (v, alarms) >>=: fun (value, origin) -> let value = define_value value - and origin = Some origin and reductness, reduction = if Alarmset.is_empty alarms then Unreduced, Neither else Reduced, Forward in -- GitLab From 1b7f90a6529fc5ad5c7a5b157da424b35b386b13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20B=C3=BChler?= <david.buhler@cea.fr> Date: Wed, 19 Feb 2020 10:12:41 +0100 Subject: [PATCH 150/218] [Eva] Abstract domains: changes the signature of [logic_assign]. The logical clause and the pre-state are now optional. The function can now be used to remove from a state all inferred properties that depend on a given memory location. This only impacts the cvalue domain, which is the only one to use the assign clause. --- src/plugins/value/domains/abstract_domain.mli | 13 +++++++------ src/plugins/value/domains/apron/apron_domain.ml | 2 +- src/plugins/value/domains/cvalue/cvalue_domain.ml | 10 +++++++--- src/plugins/value/domains/domain_builder.ml | 4 ++-- src/plugins/value/domains/domain_lift.ml | 4 ++-- src/plugins/value/domains/domain_product.ml | 11 ++++++++--- .../value/domains/equality/equality_domain.ml | 2 +- src/plugins/value/domains/gauges/gauges_domain.ml | 2 +- src/plugins/value/domains/inout_domain.ml | 2 +- src/plugins/value/domains/octagons.ml | 2 +- src/plugins/value/domains/offsm_domain.ml | 2 +- src/plugins/value/domains/simple_memory.ml | 2 +- src/plugins/value/domains/symbolic_locs.ml | 2 +- src/plugins/value/domains/traces_domain.ml | 2 +- src/plugins/value/domains/unit_domain.ml | 2 +- src/plugins/value/engine/transfer_specification.ml | 2 +- 16 files changed, 37 insertions(+), 27 deletions(-) diff --git a/src/plugins/value/domains/abstract_domain.mli b/src/plugins/value/domains/abstract_domain.mli index b1b06f70f1d..cc7d69a289e 100644 --- a/src/plugins/value/domains/abstract_domain.mli +++ b/src/plugins/value/domains/abstract_domain.mli @@ -358,12 +358,13 @@ module type S = sig (** Logical evaluation. This API is subject to changes. *) (* TODO: cooperative evaluation of predicates in the engine. *) - (** [logic_assign from loc_asgn pre state] applies the effect of the - [assigns ... \from ...] clause [from] to [state]. [pre] is the state - before the assign clauses, in which the terms of the clause are evaluated. - [loc_asgn] is the result of the evaluation of the [assigns] part of [from] - in [pre]. *) - val logic_assign: logic_assign -> location -> pre:state -> state -> state + (** [logic_assign None loc state] removes from [state] all inferred properties + that depend on the memory location [loc]. + If the first argument is not None, it contains the logical clause being + interpreted and the pre-state in which the terms of the clause are + evaluated. The clause can be an \assign, \allocated or \free clause. + [loc] is then the memory location concerned by the clause. *) + val logic_assign: (logic_assign * state) option -> location -> state -> state (** Evaluates a [predicate] to a logical status in the current [state]. The [logic_environment] contains the states at some labels and the diff --git a/src/plugins/value/domains/apron/apron_domain.ml b/src/plugins/value/domains/apron/apron_domain.ml index c9fd86075f1..c21820f2b2d 100644 --- a/src/plugins/value/domains/apron/apron_domain.ml +++ b/src/plugins/value/domains/apron/apron_domain.ml @@ -673,7 +673,7 @@ module Make (Man : Input) = struct let show_expr _valuation _state _fmt _expr = () - let logic_assign _assigns location ~pre:_ state = kill_bases location state + let logic_assign _assigns location state = kill_bases location state let evaluate_predicate _ _ _ = Alarmset.Unknown let reduce_by_predicate _ state _ _ = `Value state diff --git a/src/plugins/value/domains/cvalue/cvalue_domain.ml b/src/plugins/value/domains/cvalue/cvalue_domain.ml index b5a165f3189..5257e966b87 100644 --- a/src/plugins/value/domains/cvalue/cvalue_domain.ml +++ b/src/plugins/value/domains/cvalue/cvalue_domain.ml @@ -308,15 +308,19 @@ module State = struct Printer.pp_from assign pp_eval_error e; Cvalue.V.top - let logic_assign logic_assign location ~pre:(pre_state, _) (state, sclob) = + let logic_assign logic_assign location (state, sclob) = match logic_assign with - | Assigns assign -> + | None -> + let location = Precise_locs.imprecise_location location + and value = Cvalue.V.top in + Cvalue.Model.add_binding ~exact:false state location value, sclob + | Some (Assigns assign, (pre_state, _)) -> let location = Precise_locs.imprecise_location location in let env = Eval_terms.env_assigns pre_state in let value = evaluate_from_clause env assign in Locals_scoping.remember_if_locals_in_value sclob location value; Cvalue.Model.add_binding ~exact:false state location value, sclob - | Frees _ | Allocates _ -> state, sclob + | Some ((Frees _ | Allocates _), _) -> state, sclob (* ------------------------------------------------------------------------ *) (* Initialization *) diff --git a/src/plugins/value/domains/domain_builder.ml b/src/plugins/value/domains/domain_builder.ml index 4be9203e8c2..a574d3a3c4a 100644 --- a/src/plugins/value/domains/domain_builder.ml +++ b/src/plugins/value/domains/domain_builder.ml @@ -102,7 +102,7 @@ module Make_Minimal let lval = Cil.var varinfo in Domain.initialize_variable lval ~initialized:true Abstract_domain.Top state - let logic_assign _assigns _location ~pre:_ _state = top + let logic_assign _assigns _location _state = top let evaluate_predicate _ _ _ = Alarmset.Unknown let reduce_by_predicate _ t _ _ = `Value t @@ -239,7 +239,7 @@ module Complete_Simple_Cvalue (Domain: Simpler_domains.Simple_Cvalue) let lval = Cil.var varinfo in Domain.initialize_variable lval ~initialized:true Abstract_domain.Top state - let logic_assign _assigns _location ~pre:_ _state = top + let logic_assign _assigns _location _state = top let evaluate_predicate _ _ _ = Alarmset.Unknown let reduce_by_predicate _ t _ _ = `Value t diff --git a/src/plugins/value/domains/domain_lift.ml b/src/plugins/value/domains/domain_lift.ml index 0e8d958ef1d..46331911138 100644 --- a/src/plugins/value/domains/domain_lift.ml +++ b/src/plugins/value/domains/domain_lift.ml @@ -123,8 +123,8 @@ module Make let show_expr valuation = Domain.show_expr (lift_valuation valuation) - let logic_assign assigns location ~pre state = - Domain.logic_assign assigns (Convert.restrict_loc location) ~pre state + let logic_assign assigns location state = + Domain.logic_assign assigns (Convert.restrict_loc location) state let evaluate_predicate = Domain.evaluate_predicate let reduce_by_predicate = Domain.reduce_by_predicate diff --git a/src/plugins/value/domains/domain_product.ml b/src/plugins/value/domains/domain_product.ml index e9894fa2f06..06574e327e6 100644 --- a/src/plugins/value/domains/domain_product.ml +++ b/src/plugins/value/domains/domain_product.ml @@ -227,9 +227,14 @@ module Make print_one_side fmt right_log Right.name Right.pretty right) - let logic_assign assign location ~pre:(left_pre, right_pre) (left, right) = - Left.logic_assign assign location ~pre:left_pre left, - Right.logic_assign assign location ~pre:right_pre right + let logic_assign assign location (left, right) = + let left_assign, right_assign = + match assign with + | None -> None, None + | Some (assign, (left, right)) -> Some (assign, left), Some (assign, right) + in + Left.logic_assign left_assign location left, + Right.logic_assign right_assign location right let lift_logic_env f logic_env = Abstract_domain.{ states = (fun label -> f (logic_env.states label)); diff --git a/src/plugins/value/domains/equality/equality_domain.ml b/src/plugins/value/domains/equality/equality_domain.ml index f78930c6d92..b04cd0ffa19 100644 --- a/src/plugins/value/domains/equality/equality_domain.ml +++ b/src/plugins/value/domains/equality/equality_domain.ml @@ -503,7 +503,7 @@ module Make | Some equality -> Equality.Equality.pretty fmt equality | None -> () - let logic_assign _assigns location ~pre:_ state = + let logic_assign _assigns location state = let loc = Precise_locs.imprecise_location location in let zone = Locations.(enumerate_valid_bits Write loc) in kill Hcexprs.Modified zone state diff --git a/src/plugins/value/domains/gauges/gauges_domain.ml b/src/plugins/value/domains/gauges/gauges_domain.ml index 3b60576b815..4c8dec87e1e 100644 --- a/src/plugins/value/domains/gauges/gauges_domain.ml +++ b/src/plugins/value/domains/gauges/gauges_domain.ml @@ -1296,7 +1296,7 @@ module D_Impl : Abstract_domain.S let initialize_variable _ _ ~initialized:_ _ state = state (* Logic *) - let logic_assign _assigns location ~pre:_ state = kill location state + let logic_assign _assigns location state = kill location state let evaluate_predicate _ _ _ = Alarmset.Unknown let reduce_by_predicate _ state _ _ = `Value state diff --git a/src/plugins/value/domains/inout_domain.ml b/src/plugins/value/domains/inout_domain.ml index da068efc2f9..5bbf25ba1ff 100644 --- a/src/plugins/value/domains/inout_domain.ml +++ b/src/plugins/value/domains/inout_domain.ml @@ -261,7 +261,7 @@ module Internal let initialize_variable_using_type _ _ state = state (* TODO *) - let logic_assign _assign _location ~pre:_ _state = top + let logic_assign _assign _location _state = top (* Logic *) let evaluate_predicate _ _ _ = Alarmset.Unknown diff --git a/src/plugins/value/domains/octagons.ml b/src/plugins/value/domains/octagons.ml index 853183f0d39..b1faca4b4d6 100644 --- a/src/plugins/value/domains/octagons.ml +++ b/src/plugins/value/domains/octagons.ml @@ -1235,7 +1235,7 @@ module Domain = struct let show_expr _valuation _state _fmt _expr = () - let logic_assign _logic_assign location ~pre:_ state = + let logic_assign _logic_assign location state = let loc = Precise_locs.imprecise_location location in let zone = Locations.(enumerate_valid_bits Write loc) in let state = kill zone state in diff --git a/src/plugins/value/domains/offsm_domain.ml b/src/plugins/value/domains/offsm_domain.ml index 4d8a15d53eb..cb7c583d9e8 100644 --- a/src/plugins/value/domains/offsm_domain.ml +++ b/src/plugins/value/domains/offsm_domain.ml @@ -216,7 +216,7 @@ module Internal : Domain_builder.InputDomain let initialize_variable _ _ ~initialized:_ _ state = state (* Logic *) - let logic_assign _assign location ~pre:_ state = + let logic_assign _assign location state = let loc = Precise_locs.imprecise_location location in kill loc state diff --git a/src/plugins/value/domains/simple_memory.ml b/src/plugins/value/domains/simple_memory.ml index 20f91dc4a99..f2e84f2c345 100644 --- a/src/plugins/value/domains/simple_memory.ml +++ b/src/plugins/value/domains/simple_memory.ml @@ -300,7 +300,7 @@ module Make_Internal (Info: sig val name: string end) (Value: Value) = struct let incr_loop_counter _ state = state let leave_loop _ state = state - let logic_assign _assign location ~pre:_ state = remove location state + let logic_assign _assign location state = remove location state let evaluate_predicate _ _ _ = Alarmset.Unknown let reduce_by_predicate _ state _ _ = `Value state diff --git a/src/plugins/value/domains/symbolic_locs.ml b/src/plugins/value/domains/symbolic_locs.ml index 91b53803645..9464308a6e2 100644 --- a/src/plugins/value/domains/symbolic_locs.ml +++ b/src/plugins/value/domains/symbolic_locs.ml @@ -631,7 +631,7 @@ module Internal : Domain_builder.InputDomain let initialize_variable _ _ ~initialized:_ _ state = state (* Logic *) - let logic_assign _assigns location ~pre:_ state = + let logic_assign _assigns location state = let loc = Precise_locs.imprecise_location location in Memory.kill loc state diff --git a/src/plugins/value/domains/traces_domain.ml b/src/plugins/value/domains/traces_domain.ml index 4c533c30c2c..de5887617b6 100644 --- a/src/plugins/value/domains/traces_domain.ml +++ b/src/plugins/value/domains/traces_domain.ml @@ -931,7 +931,7 @@ module Internal = struct Traces.add_trans state (Msg msg) (* TODO *) - let logic_assign _assign _location ~pre:_ state = + let logic_assign _assign _location state = Traces.add_trans state (Msg "logic assign") (* Logic *) diff --git a/src/plugins/value/domains/unit_domain.ml b/src/plugins/value/domains/unit_domain.ml index 5d1a5594218..c12cdfc9f3c 100644 --- a/src/plugins/value/domains/unit_domain.ml +++ b/src/plugins/value/domains/unit_domain.ml @@ -67,7 +67,7 @@ module Make let finalize_call _ _ ~pre:_ ~post:_ = `Value () let show_expr _ _ _ _ = () - let logic_assign _ _ ~pre:_ _ = () + let logic_assign _ _ _ = () let evaluate_predicate _ _ _ = Alarmset.Unknown let reduce_by_predicate _ _ _ _ = `Value () diff --git a/src/plugins/value/engine/transfer_specification.ml b/src/plugins/value/engine/transfer_specification.ml index d84a01a562d..4521648ffbb 100644 --- a/src/plugins/value/engine/transfer_specification.ml +++ b/src/plugins/value/engine/transfer_specification.ml @@ -267,7 +267,7 @@ module Make let env = make_env state in let assigns_with_locations = evaluate_locations env retres_loc assigns in let transfer state (logic_assign, location) = - Domain.logic_assign logic_assign location ~pre state + Domain.logic_assign (Some (logic_assign, pre)) location state in List.fold_left transfer state assigns_with_locations -- GitLab From 11c319909094afb80d920fa90509d5863a447845 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20B=C3=BChler?= <david.buhler@cea.fr> Date: Mon, 17 Feb 2020 14:52:34 +0100 Subject: [PATCH 151/218] [Eva] Structure: adds an Option constructor for optional values. --- src/plugins/value/engine/abstractions.ml | 3 +++ src/plugins/value/utils/structure.ml | 15 +++++++++++++++ src/plugins/value/utils/structure.mli | 1 + 3 files changed, 19 insertions(+) diff --git a/src/plugins/value/engine/abstractions.ml b/src/plugins/value/engine/abstractions.ml index d393a206140..1b68607c5f3 100644 --- a/src/plugins/value/engine/abstractions.ml +++ b/src/plugins/value/engine/abstractions.ml @@ -224,6 +224,7 @@ module Internal_Value = struct let add_value_structure value internal = let rec aux: type v. (module Internal) -> v structure -> (module Internal) = fun value -> function + | Option (s, _) -> aux value s | Leaf (key, v) -> add_value_leaf value (V (key, v)) | Node (s1, s2) -> aux (aux value s1) s2 | Unit -> value @@ -258,6 +259,7 @@ module Internal_Value = struct | Node (s1, s2) -> let set1 = set s1 and set2 = set s2 in fun (v1, v2) value -> set1 v1 (set2 v2 value) + | Option (s, default) -> fun v -> set s (Extlib.opt_conv default v) | Unit -> fun () value -> value in set structure @@ -270,6 +272,7 @@ module Internal_Value = struct | Node (s1, s2) -> let get1 = get s1 and get2 = get s2 in fun v -> get1 v, get2 v + | Option (s, _) -> fun v -> Some (get s v) | Unit -> fun _ -> () in get structure diff --git a/src/plugins/value/utils/structure.ml b/src/plugins/value/utils/structure.ml index 1d221ef7590..b4594d86858 100644 --- a/src/plugins/value/utils/structure.ml +++ b/src/plugins/value/utils/structure.ml @@ -71,6 +71,7 @@ module type Shape = sig | Unit : unit structure | Leaf : 'a key * 'a data -> 'a structure | Node : 'a structure * 'b structure -> ('a * 'b) structure + | Option : 'a structure * 'a -> 'a option structure val eq_structure: 'a structure -> 'b structure -> ('a, 'b) eq option end @@ -83,6 +84,7 @@ module Shape (Key: Key) (Data: sig type 'a t end) = struct | Unit : unit structure | Leaf : 'a key * 'a data -> 'a structure | Node : 'a structure * 'b structure -> ('a * 'b) structure + | Option : 'a structure * 'a -> 'a option structure let rec eq_structure : type a b. a structure -> b structure -> (a, b) eq option = fun a b -> @@ -94,6 +96,12 @@ module Shape (Key: Key) (Data: sig type 'a t end) = struct | Some Eq, Some Eq -> Some Eq | _, _ -> None end + | Option (s1, _), Option (s2, _) -> + begin + match eq_structure s1 s2 with + | Some Eq -> Some Eq + | None -> None + end | Unit, Unit -> Some Eq | _, _ -> None end @@ -132,6 +140,7 @@ module Open | Unit -> false | Leaf (k, _) -> Shape.equal key k | Node (left, right) -> mem key left || mem key right + | Option (s, _) -> mem key s let mem key = mem key M.structure @@ -149,6 +158,9 @@ module Open let l = compute_getters left and r = compute_getters right in let l = KMap.map (lift_get fst) l and r = KMap.map (lift_get snd) r in KMap.union (fun _k a _b -> Some a) l r + | Option (s, default) -> + let l = compute_getters s in + KMap.map (lift_get (Extlib.opt_conv default)) l let getters = compute_getters M.structure let get (type a) (key: a Shape.key) : (M.t -> a) option = @@ -173,6 +185,9 @@ module Open let l = KMap.map (lift_set (fun set (l, r) -> set l, r)) l and r = KMap.map (lift_set (fun set (l, r) -> l, set r)) r in KMap.union (fun _k a _b -> Some a) l r + | Option (s, _) -> + let l = compute_setters s in + KMap.map (lift_set Extlib.opt_map) l let setters = compute_setters M.structure let set (type a) (key: a Shape.key) : (a -> M.t -> M.t) = diff --git a/src/plugins/value/utils/structure.mli b/src/plugins/value/utils/structure.mli index 51a5d26d183..4e99e2232c4 100644 --- a/src/plugins/value/utils/structure.mli +++ b/src/plugins/value/utils/structure.mli @@ -64,6 +64,7 @@ module type Shape = sig | Unit : unit structure | Leaf : 'a key * 'a data -> 'a structure | Node : 'a structure * 'b structure -> ('a * 'b) structure + | Option : 'a structure * 'a -> 'a option structure val eq_structure: 'a structure -> 'b structure -> ('a, 'b) eq option end -- GitLab From 2df5337b9ae31a606924d9621604e70cc9f76b43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20B=C3=BChler?= <david.buhler@cea.fr> Date: Tue, 18 Feb 2020 13:46:33 +0100 Subject: [PATCH 152/218] [Eva] Structure: adds a Void constructor for undescribed values of any type. --- src/plugins/value/engine/abstractions.ml | 7 +++++++ src/plugins/value/engine/abstractions.mli | 3 ++- src/plugins/value/utils/structure.ml | 8 +++++--- src/plugins/value/utils/structure.mli | 1 + 4 files changed, 15 insertions(+), 4 deletions(-) diff --git a/src/plugins/value/engine/abstractions.ml b/src/plugins/value/engine/abstractions.ml index 1b68607c5f3..7c7e4524ac8 100644 --- a/src/plugins/value/engine/abstractions.ml +++ b/src/plugins/value/engine/abstractions.ml @@ -221,6 +221,10 @@ module Internal_Value = struct let structure = Node (Value.structure, Leaf (key, v)) end) + let void_value () = + Value_parameters.fatal + "Cannot register a value module from a Void structure." + let add_value_structure value internal = let rec aux: type v. (module Internal) -> v structure -> (module Internal) = fun value -> function @@ -228,6 +232,7 @@ module Internal_Value = struct | Leaf (key, v) -> add_value_leaf value (V (key, v)) | Node (s1, s2) -> aux (aux value s1) s2 | Unit -> value + | Void -> void_value () in aux value internal @@ -261,6 +266,7 @@ module Internal_Value = struct fun (v1, v2) value -> set1 v1 (set2 v2 value) | Option (s, default) -> fun v -> set s (Extlib.opt_conv default v) | Unit -> fun () value -> value + | Void -> void_value () in set structure @@ -274,6 +280,7 @@ module Internal_Value = struct fun v -> get1 v, get2 v | Option (s, _) -> fun v -> Some (get s v) | Unit -> fun _ -> () + | Void -> void_value () in get structure diff --git a/src/plugins/value/engine/abstractions.mli b/src/plugins/value/engine/abstractions.mli index 0156b516d8a..8d646a00775 100644 --- a/src/plugins/value/engine/abstractions.mli +++ b/src/plugins/value/engine/abstractions.mli @@ -31,7 +31,8 @@ *) (** Module types of value abstractions: either a single leaf module, or - a compound of several modules described by a structure. *) + a compound of several modules described by a structure. In this last case, + the structure must not contain the Void constructor. *) type 'v value = | Single of (module Abstract_value.Leaf with type t = 'v) | Struct of 'v Abstract.Value.structure diff --git a/src/plugins/value/utils/structure.ml b/src/plugins/value/utils/structure.ml index b4594d86858..e1e1d9b84d2 100644 --- a/src/plugins/value/utils/structure.ml +++ b/src/plugins/value/utils/structure.ml @@ -69,6 +69,7 @@ module type Shape = sig type 'a structure = | Unit : unit structure + | Void : 'a structure | Leaf : 'a key * 'a data -> 'a structure | Node : 'a structure * 'b structure -> ('a * 'b) structure | Option : 'a structure * 'a -> 'a option structure @@ -82,6 +83,7 @@ module Shape (Key: Key) (Data: sig type 'a t end) = struct type 'a structure = | Unit : unit structure + | Void : 'a structure | Leaf : 'a key * 'a data -> 'a structure | Node : 'a structure * 'b structure -> ('a * 'b) structure | Option : 'a structure * 'a -> 'a option structure @@ -137,7 +139,7 @@ module Open open Shape let rec mem : type a. 'v Shape.key -> a structure -> bool = fun key -> function - | Unit -> false + | Unit | Void -> false | Leaf (k, _) -> Shape.equal key k | Node (left, right) -> mem key left || mem key right | Option (s, _) -> mem key s @@ -152,7 +154,7 @@ module Open let lift_get f (Get (key, get)) = Get (key, fun t -> get (f t)) let rec compute_getters : type a. a structure -> (a getter) KMap.t = function - | Unit -> KMap.empty + | Unit | Void -> KMap.empty | Leaf (key, _) -> KMap.singleton key (Get (key, fun (t : a) -> t)) | Node (left, right) -> let l = compute_getters left and r = compute_getters right in @@ -178,7 +180,7 @@ module Open let lift_set f (Set (key, set)) = Set (key, fun v b -> f (fun a -> set v a) b) let rec compute_setters : type a. a structure -> (a setter) KMap.t = function - | Unit -> KMap.empty + | Unit | Void -> KMap.empty | Leaf (key, _) -> KMap.singleton key (Set (key, fun v _t -> v)) | Node (left, right) -> let l = compute_setters left and r = compute_setters right in diff --git a/src/plugins/value/utils/structure.mli b/src/plugins/value/utils/structure.mli index 4e99e2232c4..96555303c0f 100644 --- a/src/plugins/value/utils/structure.mli +++ b/src/plugins/value/utils/structure.mli @@ -62,6 +62,7 @@ module type Shape = sig Used internally to automatically generate efficient accessors of its nodes. *) type 'a structure = | Unit : unit structure + | Void : 'a structure | Leaf : 'a key * 'a data -> 'a structure | Node : 'a structure * 'b structure -> ('a * 'b) structure | Option : 'a structure * 'a -> 'a option structure -- GitLab From aeac20ca00d8c681e74381d9119159aba72b6a98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20B=C3=BChler?= <david.buhler@cea.fr> Date: Tue, 18 Feb 2020 16:12:56 +0100 Subject: [PATCH 153/218] [Eva] Fixes structure for ocaml 4.05. --- src/plugins/value/utils/structure.ml | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/plugins/value/utils/structure.ml b/src/plugins/value/utils/structure.ml index e1e1d9b84d2..9722347d7d8 100644 --- a/src/plugins/value/utils/structure.ml +++ b/src/plugins/value/utils/structure.ml @@ -139,7 +139,8 @@ module Open open Shape let rec mem : type a. 'v Shape.key -> a structure -> bool = fun key -> function - | Unit | Void -> false + | Unit -> false + | Void -> false | Leaf (k, _) -> Shape.equal key k | Node (left, right) -> mem key left || mem key right | Option (s, _) -> mem key s @@ -154,7 +155,8 @@ module Open let lift_get f (Get (key, get)) = Get (key, fun t -> get (f t)) let rec compute_getters : type a. a structure -> (a getter) KMap.t = function - | Unit | Void -> KMap.empty + | Unit -> KMap.empty + | Void -> KMap.empty | Leaf (key, _) -> KMap.singleton key (Get (key, fun (t : a) -> t)) | Node (left, right) -> let l = compute_getters left and r = compute_getters right in @@ -180,7 +182,8 @@ module Open let lift_set f (Set (key, set)) = Set (key, fun v b -> f (fun a -> set v a) b) let rec compute_setters : type a. a structure -> (a setter) KMap.t = function - | Unit | Void -> KMap.empty + | Unit -> KMap.empty + | Void -> KMap.empty | Leaf (key, _) -> KMap.singleton key (Set (key, fun v _t -> v)) | Node (left, right) -> let l = compute_setters left and r = compute_setters right in -- GitLab From bf4350cc3055e9e923c1cbceaf4dc45b23f824d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20B=C3=BChler?= <david.buhler@cea.fr> Date: Mon, 27 Jan 2020 16:16:28 +0100 Subject: [PATCH 154/218] [Eva] Domain_builder: new Restrict functor to enable a domain on given functions. --- src/plugins/value/domains/domain_builder.ml | 326 ++++++++++++++++++- src/plugins/value/domains/domain_builder.mli | 15 + 2 files changed, 340 insertions(+), 1 deletion(-) diff --git a/src/plugins/value/domains/domain_builder.ml b/src/plugins/value/domains/domain_builder.ml index a574d3a3c4a..b8b6ee7d87a 100644 --- a/src/plugins/value/domains/domain_builder.ml +++ b/src/plugins/value/domains/domain_builder.ml @@ -20,7 +20,6 @@ (* *) (**************************************************************************) - module type InputDomain = sig include Abstract_domain.S val storage: unit -> bool @@ -252,3 +251,328 @@ module Complete_Simple_Cvalue (Domain: Simpler_domains.Simple_Cvalue) include Complete (D) end + +(* -------------------------------------------------------------------------- *) + +type permission = { read: bool; write: bool; } +type mode = { current: permission; calls: permission; } + +module Mode = struct + + let all = + let p = { read = true; write = true } in + { current = p; calls = p; } + + + include Datatype.Make_with_collections + (struct + include Datatype.Serializable_undefined + type t = mode + let name = "Domain_builder.Restrict_State" + let reprs = [ all ] + let compare _ _ = 0 + let equal _ _ = true + let hash _ = 0 + end) + + let merge f m1 m2 = + let merge_perm p1 p2 = + { read = f p1.read p2.read; + write = f p1.write p2.write; } + in + { current = merge_perm m1.current m2.current; + calls = merge_perm m1.calls m2.calls; } + + let join = merge (&&) + let narrow = merge (||) +end + +module Restrict + (Value: Abstract_value.S) + (Domain: Abstract.Domain.Internal with type value = Value.t) + (Scope: sig val functions: (Kernel_function.t * mode) list end) += struct + + let functions_map = + List.fold_left + (fun map (kf, mode) -> Kernel_function.Map.add kf mode map) + Kernel_function.Map.empty Scope.functions + + module Info = struct let module_name = Domain.name ^ " restricted" end + module D = Datatype.Pair_with_collections (Domain) (Mode) (Info) + + module I = struct let module_name = Domain.name ^ " option" end + include Datatype.Option_with_collections (D) (I) + + let default = Domain.top, Mode.all + let structure: t Abstract.Domain.structure = + Abstract.Domain.(Option ((Node (Domain.structure, Void)), default)) + + type state = t + type value = Domain.value + type location = Domain.location + type origin = Domain.origin + + let get_state = function + | None -> Domain.top + | Some (state, _mode) -> state + + let compute_starting_state () = + let empty = Domain.empty () in + let var_kind = Abstract_domain.Global in + let init varinfo _init state = + let state = Domain.enter_scope var_kind [varinfo] state in + Domain.initialize_variable_using_type var_kind varinfo state + in + Globals.Vars.fold init empty + + let get_starting_state = + let starting_state = ref None in + fun () -> + match !starting_state with + | None -> + let s = compute_starting_state () in + starting_state := Some s; + s + | Some state -> state + + (* ----- Lattice ---------------------------------------------------------- *) + + let top = None + + let is_included x y = + match x, y with + | _, None -> true + | None, _ -> false + | Some (d1, _), Some (d2, _) -> Domain.is_included d1 d2 + + let make_join join = fun x y -> + match x, y with + | None, _ | _, None -> None + | Some (d1, m1), Some (d2, m2) -> Some (join d1 d2, Mode.join m1 m2) + + let join = make_join Domain.join + let widen kf stmt = make_join (Domain.widen kf stmt) + + let narrow x y = + match x, y with + | None, s | s, None -> `Value s + | Some (d1, s1), Some (d2, s2) -> + Domain.narrow d1 d2 >>-: fun s -> + Some (s, Mode.narrow s1 s2) + + (* ----- Queries ---------------------------------------------------------- *) + + let default_query = `Value (Value.top, None), Alarmset.all + + let make_query default query = function + | None -> default + | Some (state, mode) -> + if mode.current.read + then query state + else default + + let extract_expr oracle state expr = + make_query default_query (fun s -> Domain.extract_expr oracle s expr) state + + let extract_lval oracle state lval typ location = + make_query + default_query + (fun s -> Domain.extract_lval oracle s lval typ location) + state + + let backward_location state lval typ location value = + make_query + (`Value (location, value)) + (fun s -> Domain.backward_location s lval typ location value) + state + + let reduce_further state expr value = + make_query [] (fun s -> Domain.reduce_further s expr value) state + + (* ----- Transfer functions ----------------------------------------------- *) + + let make_transfer f = function + | None -> `Value None + | Some (state, mode) -> + if mode.current.write + then f state >>-: fun state -> Some (state, mode) + else `Value (Some (state, mode)) + + let update valuation = make_transfer (Domain.update valuation) + let assume stmt expr positive valuation = + make_transfer (Domain.assume stmt expr positive valuation) + + let assign kinstr lvalue expr assigned valuation = function + | None -> `Value None + | Some (state, mode) -> + if mode.current.write + then + Domain.assign kinstr lvalue expr assigned valuation state >>-: fun s -> + Some (s, mode) + else + let state = Domain.logic_assign None lvalue.lloc state in + `Value (Some (state, mode)) + + let start_analysis call state = + let formals = List.map (fun argument -> argument.formal) call.arguments in + let kind = Abstract_domain.Formal call.kf in + let state = Domain.enter_scope kind formals state in + let initialize acc v = Domain.initialize_variable_using_type kind v acc in + let state = List.fold_left initialize state formals in + state + + let start_call stmt call valuation state = + let start_call_with_mode ?previous_mode ~new_mode state = + if new_mode.current.write + then + match previous_mode with + | Some mode when mode.current.write -> + Domain.start_call stmt call valuation state >>-: fun state -> + Some (state, new_mode) + | _ -> + `Value (Some (start_analysis call state, new_mode)) + else `Value (Some (state, new_mode)) + in + let called_mode = Kernel_function.Map.find_opt call.kf functions_map in + match state, called_mode with + | Some (state, previous_mode), Some new_mode -> + start_call_with_mode ~previous_mode ~new_mode state + | Some (state, previous_mode), None -> + let new_mode = { previous_mode with current = previous_mode.calls } in + start_call_with_mode ~previous_mode ~new_mode state + | None, Some new_mode -> + start_call_with_mode ~new_mode (get_starting_state ()) + | None, None -> + `Value None + + let finalize_call stmt call ~pre ~post = + match pre, post with + | None, _ | _, None -> `Value None + | Some (pre, pre_mode), Some (post, post_mode) -> + if post_mode.current.write + then + Domain.finalize_call stmt call ~pre ~post >>-: fun state -> + Some (state, pre_mode) + else + `Value (Some (post, pre_mode)) + + let show_expr valuation state fmt expr = + match state with + | None -> () + | Some (state, _mode) -> Domain.show_expr valuation state fmt expr + + (* ----- Logic evalutation ------------------------------------------------ *) + + let logic_assign assign location = function + | None -> None + | Some (state, mode) -> + let assign = + Extlib.opt_map (fun (assign, state) -> assign, get_state state) assign + in + Some (Domain.logic_assign assign location state, mode) + + let lift_env env = + let states label = get_state (env.Abstract_domain.states label) in + Abstract_domain.{ env with states = states } + + let evaluate_predicate env state predicate = + make_query + Alarmset.Unknown + (fun s -> Domain.evaluate_predicate (lift_env env) s predicate) + state + + let reduce_by_predicate env state predicate positive = + make_transfer + (fun s -> Domain.reduce_by_predicate (lift_env env) s predicate positive) + state + + (* ----- Scoping, initialization & loops ---------------------------------- *) + + let lift f = function + | None -> None + | Some (state, mode) as x -> + if mode.current.write + then Some (f state, mode) + else x + + let enter_scope kind varinfos = lift (Domain.enter_scope kind varinfos) + let leave_scope kf varinfos = lift (Domain.leave_scope kf varinfos) + + let empty () = + let main_kf = fst (Globals.entry_point ()) in + match Kernel_function.Map.find_opt main_kf functions_map with + | None -> None + | Some mode -> Some (Domain.empty (), mode) + + let initialize_variable lval location ~initialized init_value = + lift (Domain.initialize_variable lval location ~initialized init_value) + let initialize_variable_using_type init_kind varinfo = + lift (Domain.initialize_variable_using_type init_kind varinfo) + + let enter_loop stmt = lift (Domain.enter_loop stmt) + let incr_loop_counter stmt = lift (Domain.incr_loop_counter stmt) + let leave_loop stmt = lift (Domain.leave_loop stmt) + + (* ----- MemExec ---------------------------------------------------------- *) + + let relate kf bases = function + | None -> Base.SetLattice.empty + | Some (state, _mode) -> Domain.relate kf bases state + + let filter kf kind bases = function + | None -> None + | Some (state, mode) -> Some (Domain.filter kf kind bases state, mode) + + let reuse kf bases ~current_input ~previous_output = + match current_input, previous_output with + | None, _ | _, None -> None + | Some (current_input, mode), Some (previous_output, _) -> + Some (Domain.reuse kf bases ~current_input ~previous_output, mode) + + let log_category = Domain.log_category + + let post_analysis state = + let state = state >>-: get_state in + Domain.post_analysis state + + (* ----- Storage ---------------------------------------------------------- *) + + module Store = struct + + let register_global_state state = + let state = state >>-: get_state in + Domain.Store.register_global_state state + + let lift_register f state = f (get_state state) + + let register_initial_state callstack = + lift_register (Domain.Store.register_initial_state callstack) + let register_state_before_stmt callstack stmt = + lift_register (Domain.Store.register_state_before_stmt callstack stmt) + let register_state_after_stmt callstack stmt = + lift_register (Domain.Store.register_state_after_stmt callstack stmt) + + let inject state = Some (state, Mode.all) + + let get_global_state () = Domain.Store.get_global_state () >>-: inject + let get_initial_state kf = Domain.Store.get_initial_state kf >>-: inject + let get_stmt_state ~after stmt = + Domain.Store.get_stmt_state ~after stmt >>-: inject + + let inject_table = function + | `Top -> `Top + | `Bottom -> `Bottom + | `Value t -> + let module Hashtbl = Value_types.Callstack.Hashtbl in + let table = Hashtbl.create (Hashtbl.length t) in + Hashtbl.iter (fun key s -> Hashtbl.add table key (inject s)) t; + `Value table + + let get_initial_state_by_callstack kf = + inject_table (Domain.Store.get_initial_state_by_callstack kf) + let get_stmt_state_by_callstack ~after stmt = + inject_table (Domain.Store.get_stmt_state_by_callstack ~after stmt) + + end +end diff --git a/src/plugins/value/domains/domain_builder.mli b/src/plugins/value/domains/domain_builder.mli index b604579e939..f63aa2e6ded 100644 --- a/src/plugins/value/domains/domain_builder.mli +++ b/src/plugins/value/domains/domain_builder.mli @@ -55,3 +55,18 @@ module Complete_Simple_Cvalue : Abstract_domain.Leaf with type value = Cvalue.V.t and type location = Precise_locs.precise_location and type state = Domain.t + + +type permission = { read: bool; write: bool; } +type mode = { current: permission; calls: permission; } + +module Mode : sig + val all: mode +end + +module Restrict + (Value: Abstract_value.S) + (Domain: Abstract.Domain.Internal with type value = Value.t) + (Scope: sig val functions: (Kernel_function.t * mode) list end) + : Abstract.Domain.Internal with type value = Value.t + and type location = Domain.location -- GitLab From 248be1c3e0dbff2a4b7ab2636dcb9abdb8392292 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20B=C3=BChler?= <david.buhler@cea.fr> Date: Mon, 17 Feb 2020 15:02:10 +0100 Subject: [PATCH 155/218] [Eva] New option -eva-domains-function to enable domains on specific functions. --- Makefile | 2 +- headers/header_spec.txt | 2 + src/plugins/value/domains/domain_builder.ml | 52 ++++------- src/plugins/value/domains/domain_builder.mli | 10 +- src/plugins/value/domains/domain_mode.ml | 96 ++++++++++++++++++++ src/plugins/value/domains/domain_mode.mli | 35 +++++++ src/plugins/value/engine/abstractions.ml | 19 +++- src/plugins/value/value_parameters.ml | 24 ++++- src/plugins/value/value_parameters.mli | 3 + 9 files changed, 196 insertions(+), 47 deletions(-) create mode 100644 src/plugins/value/domains/domain_mode.ml create mode 100644 src/plugins/value/domains/domain_mode.mli diff --git a/Makefile b/Makefile index 977133d5e91..9e3ac8f0caf 100644 --- a/Makefile +++ b/Makefile @@ -861,7 +861,7 @@ endif # General rules for ordering files within PLUGIN_CMO: # - try to keep the legacy Value before Eva -PLUGIN_CMO:= partitioning/split_strategy value_parameters \ +PLUGIN_CMO:= partitioning/split_strategy domains/domain_mode value_parameters \ utils/value_perf utils/eva_annotations \ utils/value_util utils/red_statuses \ utils/mark_noresults \ diff --git a/headers/header_spec.txt b/headers/header_spec.txt index 2ada5971dd2..9c669cda939 100644 --- a/headers/header_spec.txt +++ b/headers/header_spec.txt @@ -1224,6 +1224,8 @@ src/plugins/value/domains/cvalue/locals_scoping.ml: CEA_LGPL_OR_PROPRIETARY src/plugins/value/domains/cvalue/locals_scoping.mli: CEA_LGPL_OR_PROPRIETARY src/plugins/value/domains/cvalue/warn.ml: CEA_LGPL_OR_PROPRIETARY src/plugins/value/domains/cvalue/warn.mli: CEA_LGPL_OR_PROPRIETARY +src/plugins/value/domains/domain_mode.ml: CEA_LGPL_OR_PROPRIETARY +src/plugins/value/domains/domain_mode.mli: CEA_LGPL_OR_PROPRIETARY src/plugins/value/domains/domain_builder.ml: CEA_LGPL_OR_PROPRIETARY src/plugins/value/domains/domain_builder.mli: CEA_LGPL_OR_PROPRIETARY src/plugins/value/domains/domain_lift.ml: CEA_LGPL_OR_PROPRIETARY diff --git a/src/plugins/value/domains/domain_builder.ml b/src/plugins/value/domains/domain_builder.ml index b8b6ee7d87a..876e52a7428 100644 --- a/src/plugins/value/domains/domain_builder.ml +++ b/src/plugins/value/domains/domain_builder.ml @@ -254,45 +254,29 @@ end (* -------------------------------------------------------------------------- *) -type permission = { read: bool; write: bool; } -type mode = { current: permission; calls: permission; } - -module Mode = struct - - let all = - let p = { read = true; write = true } in - { current = p; calls = p; } - - - include Datatype.Make_with_collections - (struct - include Datatype.Serializable_undefined - type t = mode - let name = "Domain_builder.Restrict_State" - let reprs = [ all ] - let compare _ _ = 0 - let equal _ _ = true - let hash _ = 0 - end) - - let merge f m1 m2 = - let merge_perm p1 p2 = - { read = f p1.read p2.read; - write = f p1.write p2.write; } - in - { current = merge_perm m1.current m2.current; - calls = merge_perm m1.calls m2.calls; } - - let join = merge (&&) - let narrow = merge (||) -end - module Restrict (Value: Abstract_value.S) (Domain: Abstract.Domain.Internal with type value = Value.t) - (Scope: sig val functions: (Kernel_function.t * mode) list end) + (Scope: sig val functions: Domain_mode.function_mode list end) = struct + open Domain_mode + + module Mode = struct + include Mode + + let merge f m1 m2 = + let merge_perm p1 p2 = + { read = f p1.read p2.read; + write = f p1.write p2.write; } + in + { current = merge_perm m1.current m2.current; + calls = merge_perm m1.calls m2.calls; } + + let join = merge (&&) + let narrow = merge (||) + end + let functions_map = List.fold_left (fun map (kf, mode) -> Kernel_function.Map.add kf mode map) diff --git a/src/plugins/value/domains/domain_builder.mli b/src/plugins/value/domains/domain_builder.mli index f63aa2e6ded..718c0c5febd 100644 --- a/src/plugins/value/domains/domain_builder.mli +++ b/src/plugins/value/domains/domain_builder.mli @@ -56,17 +56,9 @@ module Complete_Simple_Cvalue and type location = Precise_locs.precise_location and type state = Domain.t - -type permission = { read: bool; write: bool; } -type mode = { current: permission; calls: permission; } - -module Mode : sig - val all: mode -end - module Restrict (Value: Abstract_value.S) (Domain: Abstract.Domain.Internal with type value = Value.t) - (Scope: sig val functions: (Kernel_function.t * mode) list end) + (Scope: sig val functions: Domain_mode.function_mode list end) : Abstract.Domain.Internal with type value = Value.t and type location = Domain.location diff --git a/src/plugins/value/domains/domain_mode.ml b/src/plugins/value/domains/domain_mode.ml new file mode 100644 index 00000000000..4363dba6025 --- /dev/null +++ b/src/plugins/value/domains/domain_mode.ml @@ -0,0 +1,96 @@ +(**************************************************************************) +(* *) +(* This file is part of Frama-C. *) +(* *) +(* Copyright (C) 2007-2020 *) +(* CEA (Commissariat à l'énergie atomique et aux énergies *) +(* alternatives) *) +(* *) +(* you can redistribute it and/or modify it under the terms of the GNU *) +(* Lesser General Public License as published by the Free Software *) +(* Foundation, version 2.1. *) +(* *) +(* It is distributed in the hope that it will be useful, *) +(* but WITHOUT ANY WARRANTY; without even the implied warranty of *) +(* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *) +(* GNU Lesser General Public License for more details. *) +(* *) +(* See the GNU Lesser General Public License version 2.1 *) +(* for more details (enclosed in the file licenses/LGPLv2.1). *) +(* *) +(**************************************************************************) + +type permission = { read: bool; write: bool; } +type mode = { current: permission; calls: permission; } + +type function_mode = Kernel_function.t * mode + +module Mode = struct + let all_permission = { read = true; write = true; } + let no_permission = { read = false; write = false; } + + let default = { current = all_permission; calls = no_permission; } + let all = { current = all_permission; calls = all_permission; } + let none = { current = no_permission; calls = no_permission; } + + include Datatype.Make_with_collections + (struct + include Datatype.Serializable_undefined + type t = mode + let name = "Domain_mode.Mode" + let reprs = [ default ] + let compare = Transitioning.Stdlib.compare + let equal = Datatype.from_compare + let hash = Hashtbl.hash + end) + + let check str = + String.iter + (fun c -> + if Char.lowercase_ascii c <> 'r' && Char.lowercase_ascii c <> 'w' + then raise (Invalid_argument ("invalid mode " ^ str))) + str + + let of_string str = + check str; + let calls = + { read = String.contains str 'R'; + write = String.contains str 'W'; } + and current = + { read = String.contains str 'r'; + write = String.contains str 'w'; } + in + { current; calls; } + + let to_string t = + let string_if c b = if b then c else "" in + string_if "r" t.current.read ^ string_if "w" t.current.write ^ + string_if "R" t.calls.read ^ string_if "W" t.calls.write +end + +module Function_Mode = struct + include Datatype.Pair (Kernel_function) (Mode) + type key = string + + let of_string ~key ~prev:_ str = + match str with + | None -> raise (Invalid_argument ("no value bound to " ^ key)) + | Some str -> + let get_function str = + try Globals.Functions.find_by_name str + with Not_found -> raise (Invalid_argument ("no function " ^ str)) + in + match String.split_on_char '-' str with + | [ kf; "" ] -> Some (get_function kf, Mode.none) + | _ -> + match String.split_on_char '+' str with + | [ kf ] -> Some (get_function kf, Mode.default) + | [ kf; "" ] -> Some (get_function kf, Mode.all) + | [ kf; mode ] -> Some (get_function kf, Mode.of_string mode) + | _ -> raise (Invalid_argument ("invalid argument " ^ str)) + + let to_string ~key:_ = function + | None -> None + | Some (kf, mode) -> + Some (Kernel_function.get_name kf ^ "+" ^ Mode.to_string mode) +end diff --git a/src/plugins/value/domains/domain_mode.mli b/src/plugins/value/domains/domain_mode.mli new file mode 100644 index 00000000000..b56b75e7389 --- /dev/null +++ b/src/plugins/value/domains/domain_mode.mli @@ -0,0 +1,35 @@ +(**************************************************************************) +(* *) +(* This file is part of Frama-C. *) +(* *) +(* Copyright (C) 2007-2020 *) +(* CEA (Commissariat à l'énergie atomique et aux énergies *) +(* alternatives) *) +(* *) +(* you can redistribute it and/or modify it under the terms of the GNU *) +(* Lesser General Public License as published by the Free Software *) +(* Foundation, version 2.1. *) +(* *) +(* It is distributed in the hope that it will be useful, *) +(* but WITHOUT ANY WARRANTY; without even the implied warranty of *) +(* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *) +(* GNU Lesser General Public License for more details. *) +(* *) +(* See the GNU Lesser General Public License version 2.1 *) +(* for more details (enclosed in the file licenses/LGPLv2.1). *) +(* *) +(**************************************************************************) + +type permission = { read: bool; write: bool; } +type mode = { current: permission; calls: permission; } + +module Mode : sig + include Datatype.S_with_collections with type t = mode + val all: t +end + +type function_mode = Kernel_function.t * mode + +module Function_Mode: + Parameter_sig.Multiple_value_datatype with type key = string + and type t = function_mode diff --git a/src/plugins/value/engine/abstractions.ml b/src/plugins/value/engine/abstractions.ml index 7c7e4524ac8..c231134e548 100644 --- a/src/plugins/value/engine/abstractions.ml +++ b/src/plugins/value/engine/abstractions.ml @@ -85,12 +85,14 @@ module Config = struct let configure () = let aux config (Flag domain as flag) = if Value_parameters.Domains.mem domain.name + || Value_parameters.DomainsFunction.mem domain.name then add flag config else config in let config = List.fold_left aux empty !abstractions in let aux config (Dynamic { name; experimental; priority; abstraction; }) = if Value_parameters.Domains.mem name + || Value_parameters.DomainsFunction.mem name then let abstraction = abstraction () in let flag = Flag { name; experimental; priority; abstraction; } in @@ -307,7 +309,7 @@ let eq_value: | Abstract.Value.Leaf (key, _) -> Abstract.Value.eq_type key V.key | _ -> None -let add_domain (type v) (abstraction: v abstraction) (module Acc: Acc) = +let add_domain (type v) name (abstraction: v abstraction) (module Acc: Acc) = let domain : (module internal_domain with type value = Acc.Val.t) = match abstraction.domain with | Functor make -> @@ -327,6 +329,19 @@ let add_domain (type v) (abstraction: v abstraction) (module Acc: Acc) = let module Convert = Internal_Value.Convert (Acc.Val) (Struct) in (module Domain_lift.Make (Domain) (Convert)) in + let domain : (module internal_domain with type value = Acc.Val.t) = + try + let kf_modes = Value_parameters.DomainsFunction.find name in + let module Scope = struct let functions = kf_modes end in + let module Domain = + Domain_builder.Restrict + (Acc.Val) + ((val domain)) + (Scope) + in + (module Domain) + with Not_found -> domain + in let domain : (module internal_domain with type value = Acc.Val.t) = match Abstract.Domain.(eq_structure Acc.Dom.structure Unit) with | Some _ -> domain @@ -349,7 +364,7 @@ let warn_experimental flag = let build_domain config abstract = let build (Flag flag) acc = warn_experimental flag; - add_domain flag.abstraction acc + add_domain flag.name flag.abstraction acc in (* Domains in the [config] are sorted by increasing priority: domains with higher priority are added last: they will be at the top of the domains diff --git a/src/plugins/value/value_parameters.ml b/src/plugins/value/value_parameters.ml index 70311f618f1..bbe2cb24f8b 100644 --- a/src/plugins/value/value_parameters.ml +++ b/src/plugins/value/value_parameters.ml @@ -213,9 +213,31 @@ let () = Domains.add_set_hook (fun _old domains -> Datatype.String.Set.iter check_domain domains) +let () = Parameter_customize.set_group domains +module DomainsFunction = + String_multiple_map + (struct + include Domain_mode.Function_Mode + let of_string ~key ~prev str = + check_domain key; + try of_string ~key ~prev str + with Invalid_argument msg -> raise (Cannot_build msg) + end) + (struct + let option_name = "-eva-domains-function" + let help = "Enables a domain only for the given functions. \ + <d:f+> enables the domain [d] from function [f] \ + (the domain is enabled in all functions called from [f]). \ + <d:f-> disables the domain [d] from function [f]." + let arg_name = "d:f" + let default = Datatype.String.Map.empty + end) +let () = add_precision_dep DomainsFunction.parameter + (* Set of parameters defining the abstractions used in an Eva analysis. *) let parameters_abstractions = - ref (Typed_parameter.Set.singleton Domains.parameter) + ref (Typed_parameter.Set.of_list + [Domains.parameter; DomainsFunction.parameter]) let () = Parameter_customize.set_group domains diff --git a/src/plugins/value/value_parameters.mli b/src/plugins/value/value_parameters.mli index 8c338bbc48c..828113a3c87 100644 --- a/src/plugins/value/value_parameters.mli +++ b/src/plugins/value/value_parameters.mli @@ -29,6 +29,9 @@ module OracleDepth: Parameter_sig.Int module ReductionDepth: Parameter_sig.Int module Domains: Parameter_sig.String_set +module DomainsFunction: Parameter_sig.Multiple_map + with type key = string + and type value = Domain_mode.function_mode module EqualityCall: Parameter_sig.String module EqualityCallFunction: -- GitLab From be084e5b069af163fd5d6716daf40e9ac83f9347 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20B=C3=BChler?= <david.buhler@cea.fr> Date: Wed, 18 Mar 2020 10:19:08 +0100 Subject: [PATCH 156/218] [Eva] Engine: do not reset the analyzer when a domain parameter is changed. --- src/plugins/value/engine/analysis.ml | 11 +---------- src/plugins/value/value_parameters.ml | 7 ------- src/plugins/value/value_parameters.mli | 1 - 3 files changed, 1 insertion(+), 18 deletions(-) diff --git a/src/plugins/value/engine/analysis.ml b/src/plugins/value/engine/analysis.ml index 757510704f6..06c72bf5099 100644 --- a/src/plugins/value/engine/analysis.ml +++ b/src/plugins/value/engine/analysis.ml @@ -165,17 +165,8 @@ let force_compute () = let module Analyzer = (val snd !ref_analyzer) in Analyzer.compute_from_entry_point ~lib_entry kf -let set_hook_on_parameter parameter = - let open Typed_parameter in - match parameter.accessor with - | Bool (accessor, _) -> accessor.add_set_hook (fun _ _ -> reset_analyzer ()) - | Int (accessor, _) -> accessor.add_set_hook (fun _ _ -> reset_analyzer ()) - | String (accessor, _) -> accessor.add_set_hook (fun _ _ -> reset_analyzer ()) - -(* Resets the Analyzer whenever an abstraction parameter or the current project - is changed. This maintains the analyzer consistent with the Eva parameters. *) +(* Resets the Analyzer when the current project is changed. *) let () = - List.iter set_hook_on_parameter Value_parameters.parameters_abstractions; Project.register_after_set_current_hook ~user_only:true (fun _ -> reset_analyzer ()); Project.register_after_global_load_hook reset_analyzer diff --git a/src/plugins/value/value_parameters.ml b/src/plugins/value/value_parameters.ml index bbe2cb24f8b..597997dccc6 100644 --- a/src/plugins/value/value_parameters.ml +++ b/src/plugins/value/value_parameters.ml @@ -234,11 +234,6 @@ module DomainsFunction = end) let () = add_precision_dep DomainsFunction.parameter -(* Set of parameters defining the abstractions used in an Eva analysis. *) -let parameters_abstractions = - ref (Typed_parameter.Set.of_list - [Domains.parameter; DomainsFunction.parameter]) - let () = Parameter_customize.set_group domains module EqualityCall = @@ -1547,8 +1542,6 @@ let parameters_correctness = Typed_parameter.Set.elements !parameters_correctness let parameters_tuning = Typed_parameter.Set.elements !parameters_tuning -let parameters_abstractions = - Typed_parameter.Set.elements !parameters_abstractions diff --git a/src/plugins/value/value_parameters.mli b/src/plugins/value/value_parameters.mli index 828113a3c87..b31c526f864 100644 --- a/src/plugins/value/value_parameters.mli +++ b/src/plugins/value/value_parameters.mli @@ -163,7 +163,6 @@ val configure_precision: unit -> unit val parameters_correctness: Typed_parameter.t list val parameters_tuning: Typed_parameter.t list -val parameters_abstractions: Typed_parameter.t list (** Debug categories responsible for printing initial and final states of Value. Enabled by default, but can be disabled via the command-line: -- GitLab From 99a9289078a1ff5c8dac2fcd05ddd0f91975e184 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20B=C3=BChler?= <david.buhler@cea.fr> Date: Tue, 17 Mar 2020 17:35:15 +0100 Subject: [PATCH 157/218] [Eva] Abstractions: the configuration includes the domain modes. --- src/plugins/value/domains/domain_mode.ml | 2 + src/plugins/value/domains/domain_mode.mli | 3 ++ src/plugins/value/engine/abstractions.ml | 58 ++++++++++++++--------- src/plugins/value/engine/abstractions.mli | 9 +++- 4 files changed, 47 insertions(+), 25 deletions(-) diff --git a/src/plugins/value/domains/domain_mode.ml b/src/plugins/value/domains/domain_mode.ml index 4363dba6025..298f27fc57d 100644 --- a/src/plugins/value/domains/domain_mode.ml +++ b/src/plugins/value/domains/domain_mode.ml @@ -94,3 +94,5 @@ module Function_Mode = struct | Some (kf, mode) -> Some (Kernel_function.get_name kf ^ "+" ^ Mode.to_string mode) end + +include Datatype.List (Function_Mode) diff --git a/src/plugins/value/domains/domain_mode.mli b/src/plugins/value/domains/domain_mode.mli index b56b75e7389..96a2c64b69a 100644 --- a/src/plugins/value/domains/domain_mode.mli +++ b/src/plugins/value/domains/domain_mode.mli @@ -33,3 +33,6 @@ type function_mode = Kernel_function.t * mode module Function_Mode: Parameter_sig.Multiple_value_datatype with type key = string and type t = function_mode + +(** Analysis mode for a domain. *) +include Datatype.S with type t = function_mode list diff --git a/src/plugins/value/engine/abstractions.ml b/src/plugins/value/engine/abstractions.ml index c231134e548..d53585ed479 100644 --- a/src/plugins/value/engine/abstractions.ml +++ b/src/plugins/value/engine/abstractions.ml @@ -53,16 +53,23 @@ type flag = Flag: 'v abstraction with_info -> flag (* --- Config and registration ---------------------------------------------- *) module Config = struct - module Flag = struct - type t = flag + module OptMode = Datatype.Option (Domain_mode) + module Element = struct + type t = flag * Domain_mode.t option (* Flags are sorted by increasing priority order, and then by name. *) - let compare (Flag f1) (Flag f2) = + let compare (Flag f1, mode1) (Flag f2, mode2) = let c = Datatype.Int.compare f1.priority f2.priority in - if c <> 0 then c else Datatype.String.compare f1.name f2.name + if c <> 0 then c else + let c = Datatype.String.compare f1.name f2.name in + if c <> 0 then c else + OptMode.compare mode1 mode2 end - include Set.Make (Flag) + include Set.Make (Element) + + let mem (Flag domain) = + exists (fun (Flag flag, _mode) -> flag.name = domain.name) type dynamic = Dynamic: (unit -> 'v abstraction) with_info -> dynamic @@ -83,21 +90,26 @@ module Config = struct dynamic_abstractions := dynamic :: !dynamic_abstractions let configure () = - let aux config (Flag domain as flag) = - if Value_parameters.Domains.mem domain.name - || Value_parameters.DomainsFunction.mem domain.name - then add flag config + let add config name make = + let enabled = Value_parameters.Domains.mem name + and mode = + try Some (Value_parameters.DomainsFunction.find name) + with Not_found -> None + in + if enabled || mode <> None + then add (make (), mode) config else config in + let aux config (Flag domain as flag) = + add config domain.name (fun () -> flag) + in let config = List.fold_left aux empty !abstractions in let aux config (Dynamic { name; experimental; priority; abstraction; }) = - if Value_parameters.Domains.mem name - || Value_parameters.DomainsFunction.mem name - then + let make () = let abstraction = abstraction () in - let flag = Flag { name; experimental; priority; abstraction; } in - add flag config - else config + Flag { name; experimental; priority; abstraction; } + in + add config name make in List.fold_left aux config !dynamic_abstractions @@ -173,7 +185,7 @@ module Config = struct (* --- Default and legacy configurations ---------------------------------- *) let default = configure () - let legacy = singleton cvalue + let legacy = singleton (cvalue, None) end let register = Config.register @@ -239,7 +251,7 @@ module Internal_Value = struct aux value internal let build_values config initial_value = - let build (Flag flag) acc = + let build (Flag flag, _) acc = match flag.abstraction.values with | Struct structure -> add_value_structure acc structure | Single (module V) -> add_value_leaf acc (V (V.key, (module V))) @@ -309,7 +321,7 @@ let eq_value: | Abstract.Value.Leaf (key, _) -> Abstract.Value.eq_type key V.key | _ -> None -let add_domain (type v) name (abstraction: v abstraction) (module Acc: Acc) = +let add_domain (type v) mode (abstraction: v abstraction) (module Acc: Acc) = let domain : (module internal_domain with type value = Acc.Val.t) = match abstraction.domain with | Functor make -> @@ -330,8 +342,9 @@ let add_domain (type v) name (abstraction: v abstraction) (module Acc: Acc) = (module Domain_lift.Make (Domain) (Convert)) in let domain : (module internal_domain with type value = Acc.Val.t) = - try - let kf_modes = Value_parameters.DomainsFunction.find name in + match mode with + | None -> domain + | Some kf_modes -> let module Scope = struct let functions = kf_modes end in let module Domain = Domain_builder.Restrict @@ -340,7 +353,6 @@ let add_domain (type v) name (abstraction: v abstraction) (module Acc: Acc) = (Scope) in (module Domain) - with Not_found -> domain in let domain : (module internal_domain with type value = Acc.Val.t) = match Abstract.Domain.(eq_structure Acc.Dom.structure Unit) with @@ -362,9 +374,9 @@ let warn_experimental flag = "The %s domain is experimental." flag.name) let build_domain config abstract = - let build (Flag flag) acc = + let build (Flag flag, mode) acc = warn_experimental flag; - add_domain flag.name flag.abstraction acc + add_domain mode flag.abstraction acc in (* Domains in the [config] are sorted by increasing priority: domains with higher priority are added last: they will be at the top of the domains diff --git a/src/plugins/value/engine/abstractions.mli b/src/plugins/value/engine/abstractions.mli index 8d646a00775..a79fb578b89 100644 --- a/src/plugins/value/engine/abstractions.mli +++ b/src/plugins/value/engine/abstractions.mli @@ -138,9 +138,14 @@ val register_hook: ((module S) -> (module S)) -> unit (** {2 Configuration of an analysis.} *) (** Configuration defining the abstractions to be used in an analysis. - A configuration is a set of flags, i.e. a set of enabled abstractions. *) + A configuration is a set of flags, i.e. a set of abstract domain. Each flag + comes with an optional mode. None is the default mode: the given domain is + enabled for the whole analysis. See {!Domain_mode} for more details. *) module Config : sig - include Set.S with type elt = flag + include Set.S with type elt = flag * Domain_mode.t option + + (** Returns true if the given flag is in the configuration. *) + val mem: flag -> t -> bool (** Flags for the standard domains currently provided in Eva. *) -- GitLab From 7421ddf7b1a1e2debc799eebf35d68b7195ef99d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20B=C3=BChler?= <david.buhler@cea.fr> Date: Wed, 18 Mar 2020 18:20:48 +0100 Subject: [PATCH 158/218] [Eva] "-eva-domains name" is a shortcut for "-eva-domains-function name:main+". --- src/plugins/value/engine/abstractions.ml | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/plugins/value/engine/abstractions.ml b/src/plugins/value/engine/abstractions.ml index d53585ed479..5f568596c56 100644 --- a/src/plugins/value/engine/abstractions.ml +++ b/src/plugins/value/engine/abstractions.ml @@ -90,15 +90,18 @@ module Config = struct dynamic_abstractions := dynamic :: !dynamic_abstractions let configure () = + let add_main_mode mode = + let main, _ = Globals.entry_point () in + (main, Domain_mode.Mode.all) :: mode + in let add config name make = - let enabled = Value_parameters.Domains.mem name - and mode = - try Some (Value_parameters.DomainsFunction.find name) - with Not_found -> None - in - if enabled || mode <> None - then add (make (), mode) config - else config + let enabled = Value_parameters.Domains.mem name in + try + let mode = Value_parameters.DomainsFunction.find name in + let mode = if enabled then add_main_mode mode else mode in + add (make (), Some mode) config + with Not_found -> + if enabled then add (make (), None) config else config in let aux config (Flag domain as flag) = add config domain.name (fun () -> flag) -- GitLab From 2930745be3212a16a19b708c9d3e0ae33d9af224 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20B=C3=BChler?= <david.buhler@cea.fr> Date: Wed, 18 Mar 2020 18:35:30 +0100 Subject: [PATCH 159/218] [Eva] Value_parameters: fixes the list of enabled domains. To also include domains enabled by option -eva-domains-function. --- src/plugins/value/value_parameters.ml | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/plugins/value/value_parameters.ml b/src/plugins/value/value_parameters.ml index 597997dccc6..0258e4d77f6 100644 --- a/src/plugins/value/value_parameters.ml +++ b/src/plugins/value/value_parameters.ml @@ -193,12 +193,6 @@ let register_domain ~name ~descr = Cmdline.replace_option_help Domains.option_name "eva" domains (domains_help ()) -let enabled_domains () = - let domains = Domains.get () in - List.filter - (fun (name, _) -> Datatype.String.Set.mem name domains) - !domains_ref - (* Checks that a domain has been registered. *) let check_domain domain = if domain = "help" || domain = "list" @@ -234,6 +228,13 @@ module DomainsFunction = end) let () = add_precision_dep DomainsFunction.parameter +let enabled_domains () = + let domains = Domains.get () in + let domains_by_fct = DomainsFunction.get () in + List.filter + (fun (name, _) -> Datatype.String.Set.mem name domains + || Datatype.String.Map.mem name domains_by_fct) + !domains_ref let () = Parameter_customize.set_group domains module EqualityCall = -- GitLab From 014fffbd7a4cd4ff27c1239f98116fb9f1b26f2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20B=C3=BChler?= <david.buhler@cea.fr> Date: Mon, 24 Feb 2020 10:42:16 +0100 Subject: [PATCH 160/218] [Eva] Comments the Domain_builder.Restrict functor and Domain_mode signature. --- src/plugins/value/domains/domain_builder.ml | 42 +++++++++++++++++++- src/plugins/value/domains/domain_builder.mli | 5 +++ src/plugins/value/domains/domain_mode.mli | 18 ++++++++- 3 files changed, 62 insertions(+), 3 deletions(-) diff --git a/src/plugins/value/domains/domain_builder.ml b/src/plugins/value/domains/domain_builder.ml index 876e52a7428..36683d88b7a 100644 --- a/src/plugins/value/domains/domain_builder.ml +++ b/src/plugins/value/domains/domain_builder.ml @@ -262,6 +262,7 @@ module Restrict open Domain_mode + (* Defines the join and the narrow of different modes. *) module Mode = struct include Mode @@ -277,11 +278,19 @@ module Restrict let narrow = merge (||) end + (* Map that binds functions to their analysis mode. *) let functions_map = List.fold_left (fun map (kf, mode) -> Kernel_function.Map.add kf mode map) Kernel_function.Map.empty Scope.functions + (* This module propagates states of type [(state * mode) option]: + - None is propagated as long as no functions from [Scope.functions] + is analyzed. + - then the current [mode] is propagated alongside the state. Queries and + transfer functions are applied accordingly. The current mode is replaced + at function calls by [mode.calls]. *) + module Info = struct let module_name = Domain.name ^ " restricted" end module D = Datatype.Pair_with_collections (Domain) (Mode) (Info) @@ -301,6 +310,9 @@ module Restrict | None -> Domain.top | Some (state, _mode) -> state + (* When the first function from [Scope.functions] is encountered, starts the + analysis with the state computed by this function. It is an empty state in + which the global variables exist and may have any values. *) let compute_starting_state () = let empty = Domain.empty () in let var_kind = Abstract_domain.Global in @@ -310,6 +322,8 @@ module Restrict in Globals.Vars.fold init empty + (* Do not recompute each time the starting state. Do not compute the starting + state too early either, in case it depends on analysis options. *) let get_starting_state = let starting_state = ref None in fun () -> @@ -347,8 +361,8 @@ module Restrict (* ----- Queries ---------------------------------------------------------- *) - let default_query = `Value (Value.top, None), Alarmset.all - + (* Applies the [query] only if the current mode allows the domain to read. + Otherwise, returns [default]. *) let make_query default query = function | None -> default | Some (state, mode) -> @@ -356,6 +370,8 @@ module Restrict then query state else default + let default_query = `Value (Value.top, None), Alarmset.all + let extract_expr oracle state expr = make_query default_query (fun s -> Domain.extract_expr oracle s expr) state @@ -376,6 +392,8 @@ module Restrict (* ----- Transfer functions ----------------------------------------------- *) + (* Applies the transfer function [f] only if the current mode allows the + domain to write. Otherwise, returns the state unchanged. *) let make_transfer f = function | None -> `Value None | Some (state, mode) -> @@ -387,6 +405,9 @@ module Restrict let assume stmt expr positive valuation = make_transfer (Domain.assume stmt expr positive valuation) + (* Applies the [assign] transfer function according to the current mode. + In any case, removes from the state the properties depending on the memory + location modified by the assignment. *) let assign kinstr lvalue expr assigned valuation = function | None -> `Value None | Some (state, mode) -> @@ -398,6 +419,10 @@ module Restrict let state = Domain.logic_assign None lvalue.lloc state in `Value (Some (state, mode)) + (* Starts an analysis at call [call] with state [state]. The domain was not + enabled before this call: the concrete arguments may contain variables that + have never been introduced into the state, so we should not use them. This + function only introduce the formal parameters in the state. *) let start_analysis call state = let formals = List.map (fun argument -> argument.formal) call.arguments in let kind = Abstract_domain.Formal call.kf in @@ -406,7 +431,16 @@ module Restrict let state = List.fold_left initialize state formals in state + (* When interpreting a function call: + - if the mode of the function called allows the domain to infer properties, + use [start_call] and [finalize_call] as normal. If the current mode did + not allow the domain to infer properties, use [start_analysis] instead. + - otherwise, only propagate the state from the call site to kill the + properties that depend on locations written in the called functions. *) + let start_call stmt call valuation state = + (* Starts the call with mode [new_mode]. [previous_mode] is the current mode + of the caller. *) let start_call_with_mode ?previous_mode ~new_mode state = if new_mode.current.write then @@ -418,6 +452,9 @@ module Restrict `Value (Some (start_analysis call state, new_mode)) else `Value (Some (state, new_mode)) in + (* If an analysis mode is defined for the called function in [Scope], + then this mode becomes the new current mode. Otherwise, use the [calls] + field of the previous mode. *) let called_mode = Kernel_function.Map.find_opt call.kf functions_map in match state, called_mode with | Some (state, previous_mode), Some new_mode -> @@ -483,6 +520,7 @@ module Restrict let enter_scope kind varinfos = lift (Domain.enter_scope kind varinfos) let leave_scope kf varinfos = lift (Domain.leave_scope kf varinfos) + (* Uses the mode of the 'main' function to start the analysis. *) let empty () = let main_kf = fst (Globals.entry_point ()) in match Kernel_function.Map.find_opt main_kf functions_map with diff --git a/src/plugins/value/domains/domain_builder.mli b/src/plugins/value/domains/domain_builder.mli index 718c0c5febd..66613b44d54 100644 --- a/src/plugins/value/domains/domain_builder.mli +++ b/src/plugins/value/domains/domain_builder.mli @@ -56,6 +56,11 @@ module Complete_Simple_Cvalue and type location = Precise_locs.precise_location and type state = Domain.t +(* Restricts an abstract domain on specific functions. The domain will only be + enabled on the given functions. Moreover, a mode is associated to each of + these functions, allowing (or not) the domain to infer or use properties + in the current function and in all functions called from it. + See {!Domain_mode} for more details. *) module Restrict (Value: Abstract_value.S) (Domain: Abstract.Domain.Internal with type value = Value.t) diff --git a/src/plugins/value/domains/domain_mode.mli b/src/plugins/value/domains/domain_mode.mli index 96a2c64b69a..050aa6e4147 100644 --- a/src/plugins/value/domains/domain_mode.mli +++ b/src/plugins/value/domains/domain_mode.mli @@ -20,14 +20,30 @@ (* *) (**************************************************************************) +(** This module defines the mode to restrict an abstract domains on specific + functions. *) + +(** Permission for an abstract domain to read/write its state. + If [write] is true, the domain infers new properties when interpreting + assignments, assumptions, and logical assertions. Otherwise, it only + propagates already known properties as long as they hold. + If [read] is true, the domain uses its inferred properties to improve + the evaluation of expressions by extracting information from its state. + It can also evaluate logical assertions. *) type permission = { read: bool; write: bool; } + +(** Mode for the analysis of a function [f]: + - [current] is the read/write permission for [f]. + - [calls] is the read/write permission for all functions called from [f]. *) type mode = { current: permission; calls: permission; } +(** Datatype for modes. *) module Mode : sig include Datatype.S_with_collections with type t = mode - val all: t + val all: t (** Default mode: all permissions are granted. *) end +(** A function associated with an analysis mode. *) type function_mode = Kernel_function.t * mode module Function_Mode: -- GitLab From 35b4442ffc32b30eecfc55ad575e3bf7211039db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20B=C3=BChler?= <david.buhler@cea.fr> Date: Fri, 13 Mar 2020 18:21:47 +0100 Subject: [PATCH 161/218] [Eva] Updates test oracles. --- tests/value/numerors/oracle/numerors.res.oracle | 4 ++-- tests/value/traces/oracle/test1.res.oracle | 2 +- tests/value/traces/oracle/test2.res.oracle | 2 +- tests/value/traces/oracle/test3.res.oracle | 2 +- tests/value/traces/oracle/test4.res.oracle | 2 +- tests/value/traces/oracle/test5.res.oracle | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/tests/value/numerors/oracle/numerors.res.oracle b/tests/value/numerors/oracle/numerors.res.oracle index 96be7457bfd..6dc3b08df0f 100644 --- a/tests/value/numerors/oracle/numerors.res.oracle +++ b/tests/value/numerors/oracle/numerors.res.oracle @@ -1,10 +1,10 @@ -[eva:experimental] Warning: The numerors domain is experimental. [kernel] Parsing tests/value/numerors/numerors.c (with preprocessing) [kernel:parser:decimal-float] tests/value/numerors/numerors.c:24: Warning: Floating-point constant 0.69314718056 is not represented exactly. Will use 0x1.62e42fefa3bdcp-1. (warn-once: no further messages from category 'parser:decimal-float' will be emitted) [kernel:typing:implicit-function-declaration] tests/value/numerors/numerors.c:246: Warning: Calling undeclared function DPRINTFrama_C_domain_show_each_ex10. Old style K&R code? +[eva:experimental] Warning: The numerors domain is experimental. [eva] Analyzing a complete application starting at main [eva] Computing initial state [eva] Initial state computed @@ -298,7 +298,7 @@ In these functions, 257 statements reached (out of 257): 100% coverage. ---------------------------------------------------------------------------- Some errors and warnings have been raised during the analysis: - by the Eva analyzer: 0 errors 0 warnings + by the Eva analyzer: 0 errors 1 warning by the Frama-C kernel: 0 errors 3 warnings ---------------------------------------------------------------------------- 0 alarms generated by the analysis. diff --git a/tests/value/traces/oracle/test1.res.oracle b/tests/value/traces/oracle/test1.res.oracle index 3d86f189430..c89a9da2b49 100644 --- a/tests/value/traces/oracle/test1.res.oracle +++ b/tests/value/traces/oracle/test1.res.oracle @@ -1,5 +1,5 @@ -[eva:experimental] Warning: The traces domain is experimental. [kernel] Parsing tests/value/traces/test1.c (with preprocessing) +[eva:experimental] Warning: The traces domain is experimental. [eva] Analyzing a complete application starting at main [eva] Computing initial state [eva] Initial state computed diff --git a/tests/value/traces/oracle/test2.res.oracle b/tests/value/traces/oracle/test2.res.oracle index 200e815eb5c..3e1b821db9e 100644 --- a/tests/value/traces/oracle/test2.res.oracle +++ b/tests/value/traces/oracle/test2.res.oracle @@ -1,5 +1,5 @@ -[eva:experimental] Warning: The traces domain is experimental. [kernel] Parsing tests/value/traces/test2.i (no preprocessing) +[eva:experimental] Warning: The traces domain is experimental. [eva] Analyzing a complete application starting at main [eva] Computing initial state [eva] Initial state computed diff --git a/tests/value/traces/oracle/test3.res.oracle b/tests/value/traces/oracle/test3.res.oracle index 1557613f545..bff1a57599b 100644 --- a/tests/value/traces/oracle/test3.res.oracle +++ b/tests/value/traces/oracle/test3.res.oracle @@ -1,5 +1,5 @@ -[eva:experimental] Warning: The traces domain is experimental. [kernel] Parsing tests/value/traces/test3.i (no preprocessing) +[eva:experimental] Warning: The traces domain is experimental. [eva] Analyzing a complete application starting at main [eva] Computing initial state [eva] Initial state computed diff --git a/tests/value/traces/oracle/test4.res.oracle b/tests/value/traces/oracle/test4.res.oracle index ffd3f1dd1ce..45691fa981c 100644 --- a/tests/value/traces/oracle/test4.res.oracle +++ b/tests/value/traces/oracle/test4.res.oracle @@ -1,5 +1,5 @@ -[eva:experimental] Warning: The traces domain is experimental. [kernel] Parsing tests/value/traces/test4.i (no preprocessing) +[eva:experimental] Warning: The traces domain is experimental. [eva] Analyzing a complete application starting at main [eva] Computing initial state [eva] Initial state computed diff --git a/tests/value/traces/oracle/test5.res.oracle b/tests/value/traces/oracle/test5.res.oracle index 0715058c74b..739104c81f0 100644 --- a/tests/value/traces/oracle/test5.res.oracle +++ b/tests/value/traces/oracle/test5.res.oracle @@ -1,7 +1,7 @@ -[eva:experimental] Warning: The traces domain is experimental. [kernel] Parsing tests/value/traces/test5.i (no preprocessing) [kernel:typing:implicit-function-declaration] tests/value/traces/test5.i:21: Warning: Calling undeclared function my_switch. Old style K&R code? +[eva:experimental] Warning: The traces domain is experimental. [eva] Analyzing a complete application starting at main [eva] Computing initial state [eva] Initial state computed -- GitLab From 9cdeab4a0674c331b903ca9d8b2dca966c267c9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20B=C3=BChler?= <david.buhler@cea.fr> Date: Wed, 18 Mar 2020 13:25:10 +0100 Subject: [PATCH 162/218] [Eva] Adds a test of the -eva-domains-function option. --- tests/value/domains_function.c | 123 ++++++++ .../value/oracle/domains_function.res.oracle | 272 ++++++++++++++++++ 2 files changed, 395 insertions(+) create mode 100644 tests/value/domains_function.c create mode 100644 tests/value/oracle/domains_function.res.oracle diff --git a/tests/value/domains_function.c b/tests/value/domains_function.c new file mode 100644 index 00000000000..e81f3e8c8dc --- /dev/null +++ b/tests/value/domains_function.c @@ -0,0 +1,123 @@ +/* run.config* + STDOPT: #"-eva-domains-function symbolic-locations:infer+w,symbolic-locations:use+r,symbolic-locations:test_propagation-,symbolic-locations:enabled,symbolic-locations:disabled-,symbolic-locations:recursively_enabled+" +*/ + +#include <__fc_builtin.h> + +/* Tests the -eva-domains-function option that enables a domain for the given + functions. This test uses the symbolic locations domain to store the value + of the location t[i] where [i] is imprecise, from an assignment of t[i] + to a read of t[i]. + If the domain is not enabled, the value of t[i] remains imprecise because + [i] is imprecise. If the domain is enabled, the value of the first assignemnt + is stored until the read. If the assignment and the read are in different + functions, the domain should also be enabled in all functions in between. */ + +volatile int undet; +int i, result, t[10]; + +/* No interaction with the known properties about t[i]. */ +void nothing () { + int tmp = t[i] - t[0]; +} + +/* Modify the value of t[i]. */ +void kill () { + t[0] = undet; +} + +/* The domain has write access on this function: it infers the value of t[i]. */ +void infer () { + t[i] = 42; +} + +/* The domain has no write access on this function. */ +void no_infer () { + t[i] = 42; +} + +/* The domain has read access on this function: it can use the value of t[i]. */ +void use () { + result = t[i]; +} + +/* The domain has no read access on this function. */ +void no_use () { + result = t[i]; +} + +/* Test the propagation of information about t[i] from function [infer] + to function [use]. All other combinations of functions should not be + precise. */ +void test_propagation () { + infer (); + no_use (); + Frama_C_show_each_top(result); + nothing (); + use (); + Frama_C_show_each_singleton(result); + kill (); + use (); + Frama_C_show_each_top(result); + no_infer (); + use (); + Frama_C_show_each_top(result); +} + +/* The domain is enabled on this function. */ +void enabled () { + t[i] = 0; + result = t[i]; +} + +/* The domain is not enabled on this function. */ +void not_enabled () { + t[i] = 1; + result = t[i]; + Frama_C_show_each_top(result); +} + +/* The domain is disabled on this function. */ +void disabled () { + t[i] = 2; + result = t[i]; + Frama_C_show_each_top(result); +} + +/* Precise result only after [enabled], since it is the only function + where the domain is enabled. */ +void test () { + t[i] = 3; + result = t[i]; + Frama_C_show_each_top(result); + enabled (); + Frama_C_show_each_singleton(result); + not_enabled (); + Frama_C_show_each_top(result); + disabled (); + Frama_C_show_each_top(result); +} + +/* The domain is recursively enabled in this function and all functions called + from it: the results should be precise, except after [disabled] where the + domain is specifically disabled.*/ +void recursively_enabled () { + t[i] = 4; + result = t[i]; + Frama_C_show_each_singleton(result); + enabled (); + Frama_C_show_each_singleton(result); + not_enabled (); + Frama_C_show_each_singleton(result); + disabled (); + Frama_C_show_each_top(result); +} + +void main () { + for (int j = 0; j < 10; j++) + t[j] = undet; + i = Frama_C_interval(0,9); + test (); + recursively_enabled (); + test_propagation (); +} diff --git a/tests/value/oracle/domains_function.res.oracle b/tests/value/oracle/domains_function.res.oracle new file mode 100644 index 00000000000..51ded1eb5fd --- /dev/null +++ b/tests/value/oracle/domains_function.res.oracle @@ -0,0 +1,272 @@ +[kernel] Parsing tests/value/domains_function.c (with preprocessing) +[eva] Analyzing a complete application starting at main +[eva] Computing initial state +[eva] Initial state computed +[eva:initial-state] Values of globals at initialization + undet ∈ [--..--] + i ∈ {0} + result ∈ {0} + t[0..9] ∈ {0} +[eva] tests/value/domains_function.c:117: starting to merge loop iterations +[eva] computing for function Frama_C_interval <- main. + Called from tests/value/domains_function.c:119. +[eva] using specification for function Frama_C_interval +[eva] tests/value/domains_function.c:119: + function Frama_C_interval: precondition 'order' got status valid. +[eva] Done for function Frama_C_interval +[eva] computing for function test <- main. + Called from tests/value/domains_function.c:120. +[eva] tests/value/domains_function.c:92: + Frama_C_show_each_top: [-2147483648..2147483647] +[eva] computing for function enabled <- test <- main. + Called from tests/value/domains_function.c:93. +[eva] Recording results for enabled +[eva] Done for function enabled +[eva] tests/value/domains_function.c:94: Frama_C_show_each_singleton: {0} +[eva] computing for function not_enabled <- test <- main. + Called from tests/value/domains_function.c:95. +[eva] tests/value/domains_function.c:77: + Frama_C_show_each_top: [-2147483648..2147483647] +[eva] Recording results for not_enabled +[eva] Done for function not_enabled +[eva] tests/value/domains_function.c:96: + Frama_C_show_each_top: [-2147483648..2147483647] +[eva] computing for function disabled <- test <- main. + Called from tests/value/domains_function.c:97. +[eva] tests/value/domains_function.c:84: + Frama_C_show_each_top: [-2147483648..2147483647] +[eva] Recording results for disabled +[eva] Done for function disabled +[eva] tests/value/domains_function.c:98: + Frama_C_show_each_top: [-2147483648..2147483647] +[eva] Recording results for test +[eva] Done for function test +[eva] computing for function recursively_enabled <- main. + Called from tests/value/domains_function.c:121. +[eva] tests/value/domains_function.c:107: Frama_C_show_each_singleton: {4} +[eva] computing for function enabled <- recursively_enabled <- main. + Called from tests/value/domains_function.c:108. +[eva] Recording results for enabled +[eva] Done for function enabled +[eva] tests/value/domains_function.c:109: Frama_C_show_each_singleton: {0} +[eva] computing for function not_enabled <- recursively_enabled <- main. + Called from tests/value/domains_function.c:110. +[eva] tests/value/domains_function.c:77: Frama_C_show_each_top: {1} +[eva] Recording results for not_enabled +[eva] Done for function not_enabled +[eva] tests/value/domains_function.c:111: Frama_C_show_each_singleton: {1} +[eva] computing for function disabled <- recursively_enabled <- main. + Called from tests/value/domains_function.c:112. +[eva] tests/value/domains_function.c:84: + Frama_C_show_each_top: [-2147483648..2147483647] +[eva] Recording results for disabled +[eva] Done for function disabled +[eva] tests/value/domains_function.c:113: + Frama_C_show_each_top: [-2147483648..2147483647] +[eva] Recording results for recursively_enabled +[eva] Done for function recursively_enabled +[eva] computing for function test_propagation <- main. + Called from tests/value/domains_function.c:122. +[eva] computing for function infer <- test_propagation <- main. + Called from tests/value/domains_function.c:53. +[eva] Recording results for infer +[eva] Done for function infer +[eva] computing for function no_use <- test_propagation <- main. + Called from tests/value/domains_function.c:54. +[eva] Recording results for no_use +[eva] Done for function no_use +[eva] tests/value/domains_function.c:55: + Frama_C_show_each_top: [-2147483648..2147483647] +[eva] computing for function nothing <- test_propagation <- main. + Called from tests/value/domains_function.c:56. +[eva:alarm] tests/value/domains_function.c:21: Warning: + signed overflow. assert -2147483648 ≤ t[i] - t[0]; +[eva:alarm] tests/value/domains_function.c:21: Warning: + signed overflow. assert t[i] - t[0] ≤ 2147483647; +[eva] Recording results for nothing +[eva] Done for function nothing +[eva] computing for function use <- test_propagation <- main. + Called from tests/value/domains_function.c:57. +[eva] Recording results for use +[eva] Done for function use +[eva] tests/value/domains_function.c:58: Frama_C_show_each_singleton: {42} +[eva] computing for function kill <- test_propagation <- main. + Called from tests/value/domains_function.c:59. +[eva] Recording results for kill +[eva] Done for function kill +[eva] computing for function use <- test_propagation <- main. + Called from tests/value/domains_function.c:60. +[eva] Recording results for use +[eva] Done for function use +[eva] tests/value/domains_function.c:61: + Frama_C_show_each_top: [-2147483648..2147483647] +[eva] computing for function no_infer <- test_propagation <- main. + Called from tests/value/domains_function.c:62. +[eva] Recording results for no_infer +[eva] Done for function no_infer +[eva] tests/value/domains_function.c:63: Reusing old results for call to use +[eva] tests/value/domains_function.c:64: + Frama_C_show_each_top: [-2147483648..2147483647] +[eva] Recording results for test_propagation +[eva] Done for function test_propagation +[eva] Recording results for main +[eva] done for function main +[eva] ====== VALUES COMPUTED ====== +[eva:final-states] Values at end of function disabled: + result ∈ [--..--] + t[0..9] ∈ [--..--] +[eva:final-states] Values at end of function enabled: + result ∈ {0} + t[0..9] ∈ [--..--] +[eva:final-states] Values at end of function infer: + t[0..9] ∈ [--..--] +[eva:final-states] Values at end of function kill: + t[0..9] ∈ [--..--] +[eva:final-states] Values at end of function no_infer: + t[0..9] ∈ [--..--] +[eva:final-states] Values at end of function no_use: + result ∈ [--..--] +[eva:final-states] Values at end of function not_enabled: + result ∈ [--..--] + t[0..9] ∈ [--..--] +[eva:final-states] Values at end of function nothing: + tmp ∈ [--..--] +[eva:final-states] Values at end of function recursively_enabled: + result ∈ [--..--] + t[0..9] ∈ [--..--] +[eva:final-states] Values at end of function test: + result ∈ [--..--] + t[0..9] ∈ [--..--] +[eva:final-states] Values at end of function use: + result ∈ [--..--] +[eva:final-states] Values at end of function test_propagation: + result ∈ [--..--] + t[0..9] ∈ [--..--] +[eva:final-states] Values at end of function main: + Frama_C_entropy_source ∈ [--..--] + i ∈ [0..9] + result ∈ [--..--] + t[0..9] ∈ [--..--] +[from] Computing for function disabled +[from] Done for function disabled +[from] Computing for function enabled +[from] Done for function enabled +[from] Computing for function infer +[from] Done for function infer +[from] Computing for function kill +[from] Done for function kill +[from] Computing for function no_infer +[from] Done for function no_infer +[from] Computing for function no_use +[from] Done for function no_use +[from] Computing for function not_enabled +[from] Done for function not_enabled +[from] Computing for function nothing +[from] Done for function nothing +[from] Computing for function recursively_enabled +[from] Done for function recursively_enabled +[from] Computing for function test +[from] Done for function test +[from] Computing for function use +[from] Done for function use +[from] Computing for function test_propagation +[from] Done for function test_propagation +[from] Computing for function main +[from] Computing for function Frama_C_interval <-main +[from] Done for function Frama_C_interval +[from] Done for function main +[from] ====== DEPENDENCIES COMPUTED ====== + These dependencies hold at termination for the executions that terminate: +[from] Function Frama_C_interval: + Frama_C_entropy_source FROM Frama_C_entropy_source (and SELF) + \result FROM Frama_C_entropy_source; min; max +[from] Function disabled: + result FROM i; t[0..9] + t[0..9] FROM i (and SELF) +[from] Function enabled: + result FROM i; t[0..9] + t[0..9] FROM i (and SELF) +[from] Function infer: + t[0..9] FROM i (and SELF) +[from] Function kill: + t[0] FROM undet +[from] Function no_infer: + t[0..9] FROM i (and SELF) +[from] Function no_use: + result FROM i; t[0..9] +[from] Function not_enabled: + result FROM i; t[0..9] + t[0..9] FROM i (and SELF) +[from] Function nothing: + NO EFFECTS +[from] Function recursively_enabled: + result FROM i; t[0..9] + t[0..9] FROM i (and SELF) +[from] Function test: + result FROM i; t[0..9] + t[0..9] FROM i (and SELF) +[from] Function use: + result FROM i; t[0..9] +[from] Function test_propagation: + result FROM undet; i; t[1..9] + t[0] FROM undet; i + [1..9] FROM i (and SELF) +[from] Function main: + Frama_C_entropy_source FROM Frama_C_entropy_source (and SELF) + i FROM Frama_C_entropy_source + result FROM Frama_C_entropy_source; undet; t[1..9] + t[0] FROM Frama_C_entropy_source; undet + [1..9] FROM Frama_C_entropy_source; undet (and SELF) +[from] ====== END OF DEPENDENCIES ====== +[inout] Out (internal) for function disabled: + result; t[0..9] +[inout] Inputs for function disabled: + i; result; t[0..9] +[inout] Out (internal) for function enabled: + result; t[0..9] +[inout] Inputs for function enabled: + i; t[0..9] +[inout] Out (internal) for function infer: + t[0..9] +[inout] Inputs for function infer: + i +[inout] Out (internal) for function kill: + t[0] +[inout] Inputs for function kill: + undet +[inout] Out (internal) for function no_infer: + t[0..9] +[inout] Inputs for function no_infer: + i +[inout] Out (internal) for function no_use: + result +[inout] Inputs for function no_use: + i; t[0..9] +[inout] Out (internal) for function not_enabled: + result; t[0..9] +[inout] Inputs for function not_enabled: + i; result; t[0..9] +[inout] Out (internal) for function nothing: + tmp +[inout] Inputs for function nothing: + i; t[0..9] +[inout] Out (internal) for function recursively_enabled: + result; t[0..9] +[inout] Inputs for function recursively_enabled: + i; result; t[0..9] +[inout] Out (internal) for function test: + result; t[0..9] +[inout] Inputs for function test: + i; result; t[0..9] +[inout] Out (internal) for function use: + result +[inout] Inputs for function use: + i; t[0..9] +[inout] Out (internal) for function test_propagation: + result; t[0..9] +[inout] Inputs for function test_propagation: + undet; i; result; t[0..9] +[inout] Out (internal) for function main: + Frama_C_entropy_source; i; result; t[0..9]; j +[inout] Inputs for function main: + Frama_C_entropy_source; undet; i; result; t[0..9] -- GitLab From 9752800f759746738204b2ddddcb81bea2540c86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20B=C3=BChler?= <david.buhler@cea.fr> Date: Wed, 18 Mar 2020 17:44:56 +0100 Subject: [PATCH 163/218] [Eva] User manual: documents the -eva-domains-function option. --- doc/value/main.tex | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/doc/value/main.tex b/doc/value/main.tex index dd2d364f61e..96d66840582 100644 --- a/doc/value/main.tex +++ b/doc/value/main.tex @@ -3904,7 +3904,7 @@ with large arrays and matrices, it is worth considering its usage. \label{sec:eva} -Starting from \FramaC Silicon, new analysis \emph{domains} are +This section presents the analysis \emph{domains} available to improve the precision on specific code constructs. They can (and probably should) be enabled at the beginning of the analysis. Their only downside is that they increase the analysis time. @@ -3913,7 +3913,21 @@ These analysis domains are enabled by the option \texttt{-eva-domains}, followed by a list of domain names. A list of the available domains, and a short description of each one, can be displayed with \texttt{-eva-domains help}. -\emph{Restrictions:} +Domains can also be enabled for specific functions through option +\texttt{-eva-domains-function}: +\begin{itemize} +\item \texttt{-eva-domains-function d1:f,d1:g,d2:h} enables the domain + \texttt{d1} on functions \lstinline+f+ and \lstinline+g+, and the domain + \texttt{d2} on function \lstinline+h+. +\item \texttt{-eva-domains-function d:f+} enables the domain + \texttt{d} on function \lstinline+f+ and on any function called + from \lstinline+f+. +\item \texttt{-eva-domains-function d:f-} disables the domain + \texttt{d} on function \lstinline+f+ and on any function called + from \lstinline+f+. +\end{itemize} + +These analysis domains currently have some restrictions: \begin{itemize} \item adding a new domain may interact with the \lstinline+slevel+ partitioning in unpredictable ways, and new alarms may sometimes appear; -- GitLab From 1fb898cc69252148be5ad9af9ce8f60a7fcd76b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20B=C3=BChler?= <david.buhler@cea.fr> Date: Fri, 20 Mar 2020 10:02:30 +0100 Subject: [PATCH 164/218] [Eva] Option -eva-domains-function always checks the domains name. Even when no function is bound to the domain name (which should raise an error anyway). --- src/plugins/value/value_parameters.ml | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/plugins/value/value_parameters.ml b/src/plugins/value/value_parameters.ml index 0258e4d77f6..ef524a0d179 100644 --- a/src/plugins/value/value_parameters.ml +++ b/src/plugins/value/value_parameters.ml @@ -209,11 +209,16 @@ let () = let () = Parameter_customize.set_group domains module DomainsFunction = - String_multiple_map + Make_multiple_map + (struct + include Datatype.String + let of_string str = check_domain str; str + let of_singleton_string = no_element_of_string + let to_string str = str + end) (struct include Domain_mode.Function_Mode let of_string ~key ~prev str = - check_domain key; try of_string ~key ~prev str with Invalid_argument msg -> raise (Cannot_build msg) end) @@ -225,6 +230,7 @@ module DomainsFunction = <d:f-> disables the domain [d] from function [f]." let arg_name = "d:f" let default = Datatype.String.Map.empty + let dependencies = [] end) let () = add_precision_dep DomainsFunction.parameter -- GitLab From 272e20edd6090d2851c3bc3837db1c4edf07dac7 Mon Sep 17 00:00:00 2001 From: Andre Maroneze <andre.oliveiramaroneze@cea.fr> Date: Mon, 6 Apr 2020 18:39:44 +0200 Subject: [PATCH 165/218] [Eva] Fix a few typos --- src/plugins/value/domains/abstract_domain.mli | 2 +- src/plugins/value/domains/domain_builder.ml | 4 ++-- src/plugins/value/domains/domain_mode.mli | 2 +- src/plugins/value/engine/abstractions.mli | 8 ++++---- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/plugins/value/domains/abstract_domain.mli b/src/plugins/value/domains/abstract_domain.mli index cc7d69a289e..c6093135e2a 100644 --- a/src/plugins/value/domains/abstract_domain.mli +++ b/src/plugins/value/domains/abstract_domain.mli @@ -362,7 +362,7 @@ module type S = sig that depend on the memory location [loc]. If the first argument is not None, it contains the logical clause being interpreted and the pre-state in which the terms of the clause are - evaluated. The clause can be an \assign, \allocated or \free clause. + evaluated. The clause can be an assigns, allocates or frees clause. [loc] is then the memory location concerned by the clause. *) val logic_assign: (logic_assign * state) option -> location -> state -> state diff --git a/src/plugins/value/domains/domain_builder.ml b/src/plugins/value/domains/domain_builder.ml index 36683d88b7a..af877385426 100644 --- a/src/plugins/value/domains/domain_builder.ml +++ b/src/plugins/value/domains/domain_builder.ml @@ -286,7 +286,7 @@ module Restrict (* This module propagates states of type [(state * mode) option]: - None is propagated as long as no functions from [Scope.functions] - is analyzed. + are analyzed. - then the current [mode] is propagated alongside the state. Queries and transfer functions are applied accordingly. The current mode is replaced at function calls by [mode.calls]. *) @@ -422,7 +422,7 @@ module Restrict (* Starts an analysis at call [call] with state [state]. The domain was not enabled before this call: the concrete arguments may contain variables that have never been introduced into the state, so we should not use them. This - function only introduce the formal parameters in the state. *) + function only introduces the formal parameters in the state. *) let start_analysis call state = let formals = List.map (fun argument -> argument.formal) call.arguments in let kind = Abstract_domain.Formal call.kf in diff --git a/src/plugins/value/domains/domain_mode.mli b/src/plugins/value/domains/domain_mode.mli index 050aa6e4147..cbb9a07e2c7 100644 --- a/src/plugins/value/domains/domain_mode.mli +++ b/src/plugins/value/domains/domain_mode.mli @@ -20,7 +20,7 @@ (* *) (**************************************************************************) -(** This module defines the mode to restrict an abstract domains on specific +(** This module defines the mode to restrict an abstract domain on specific functions. *) (** Permission for an abstract domain to read/write its state. diff --git a/src/plugins/value/engine/abstractions.mli b/src/plugins/value/engine/abstractions.mli index a79fb578b89..3f3ff8d674e 100644 --- a/src/plugins/value/engine/abstractions.mli +++ b/src/plugins/value/engine/abstractions.mli @@ -25,9 +25,9 @@ (** {2 Registration of abstractions.} *) (** Dynamic registration of the abstractions to be used in an Eva analysis: - - value abstractions, detailled in the {Abstract_value} signature; - - location abstractions, detailled in the {Abstract_location} signature; - - state abstractions, or abstract domains, detailled in {Abstract_domain}. + - value abstractions, detailed in the {Abstract_value} signature; + - location abstractions, detailed in the {Abstract_location} signature; + - state abstractions, or abstract domains, detailed in {Abstract_domain}. *) (** Module types of value abstractions: either a single leaf module, or @@ -138,7 +138,7 @@ val register_hook: ((module S) -> (module S)) -> unit (** {2 Configuration of an analysis.} *) (** Configuration defining the abstractions to be used in an analysis. - A configuration is a set of flags, i.e. a set of abstract domain. Each flag + A configuration is a set of flags, i.e. a set of abstract domains. Each flag comes with an optional mode. None is the default mode: the given domain is enabled for the whole analysis. See {!Domain_mode} for more details. *) module Config : sig -- GitLab From 328bae76652ea919ede3b8bdba6cbe55cde1cce6 Mon Sep 17 00:00:00 2001 From: Virgile Prevosto <virgile.prevosto@m4x.org> Date: Tue, 7 Apr 2020 08:12:27 +0200 Subject: [PATCH 166/218] [doc] rephrase Floating_point.has_suffix doc --- src/libraries/utils/floating_point.mli | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/utils/floating_point.mli b/src/libraries/utils/floating_point.mli index d698d950308..11190c51425 100644 --- a/src/libraries/utils/floating_point.mli +++ b/src/libraries/utils/floating_point.mli @@ -70,7 +70,7 @@ type parsed_float = { val parse: string -> Cil_types.fkind * parsed_float (** Checks if the (uppercased) string ends with an explicit [F|D|L] - suffix for the given float kind. *) + suffix corresponding to the given float kind. *) val has_suffix: Cil_types.fkind -> string -> bool val pretty_normal : use_hex : bool -> Format.formatter -> float -> unit -- GitLab From 4ed7d795fc031597265e8efe5335bfa7d39d9dd0 Mon Sep 17 00:00:00 2001 From: Andre Maroneze <andre.oliveiramaroneze@cea.fr> Date: Mon, 6 Apr 2020 21:37:51 +0200 Subject: [PATCH 167/218] [Lib] fix crash when truncating rich text buffer --- src/libraries/utils/rich_text.ml | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/libraries/utils/rich_text.ml b/src/libraries/utils/rich_text.ml index 4d114a414e4..fe8a162367f 100644 --- a/src/libraries/utils/rich_text.ml +++ b/src/libraries/utils/rich_text.ml @@ -152,12 +152,10 @@ let truncate_text buffer size = let n_right = size - n_left - 5 in if p > 0 then Buffer.blit buffer.content p (Buffer.to_bytes buffer.content) 0 n_left; - Buffer.add_substring buffer.content "[...]" n_left 5 ; - Buffer.blit - buffer.content (q-n_right+1) - (Buffer.to_bytes buffer.content) (n_left + 5) - n_right ; - Buffer.truncate buffer.content size ; + let buf_right = Buffer.sub buffer.content (q-n_right+1) n_right in + Buffer.truncate buffer.content n_left; + Buffer.add_string buffer.content "[...]"; + Buffer.add_string buffer.content buf_right; end end -- GitLab From c0c60b77aab9dde5470d5f6c9ca572338505da83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20B=C3=BChler?= <david.buhler@cea.fr> Date: Tue, 7 Apr 2020 11:41:16 +0200 Subject: [PATCH 168/218] Updates the Changelog for MR !2581. --- Changelog | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Changelog b/Changelog index 1d2fb8f1988..5f91ac2bd11 100644 --- a/Changelog +++ b/Changelog @@ -17,6 +17,10 @@ Open Source Release <next-release> ################################## +- Eva [2020/04/06] New option -eva-domains-function to enable domains + only on given functions. Argument <d:f> enables the domain [d] + on function [f], while <d:f+> also enables it on all functions + called from [f]. <d:f-> disables [d] from function [f]. - Eva [2020/04/03] New experimental builtins for dynamic allocation Frama_C_*alloc_imprecise: faster convergence, but very imprecise. - Kernel [2020/04/01] Report user errors when keys are not bound to a -- GitLab From acee44d3e1958f685966d7ea181d71ce37b00db8 Mon Sep 17 00:00:00 2001 From: Virgile Robles <virgile.robles@protonmail.ch> Date: Tue, 7 Apr 2020 13:06:36 +0200 Subject: [PATCH 169/218] [rte] Remove call site preconds from help msg --- src/plugins/rte/options.ml | 3 +-- src/plugins/rte/register.ml | 6 ++---- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/plugins/rte/options.ml b/src/plugins/rte/options.ml index d46193ae8e0..e5ad90472cf 100644 --- a/src/plugins/rte/options.ml +++ b/src/plugins/rte/options.ml @@ -20,8 +20,7 @@ (* *) (**************************************************************************) -let help_msg = "generates annotations for runtime error checking and \ - preconditions at call sites" +let help_msg = "generates annotations for runtime error checking" include Plugin.Register (struct diff --git a/src/plugins/rte/register.ml b/src/plugins/rte/register.ml index a3f3df56f04..cb4f763b97e 100644 --- a/src/plugins/rte/register.ml +++ b/src/plugins/rte/register.ml @@ -112,8 +112,7 @@ let _ = ~journalize:false Generator.emitter -(* retrieve list of generated rte annotations (not precond) for - a given stmt *) +(* retrieve list of generated rte annotations for a given stmt *) let _ignore = Dynamic.register ~comment:"Get the list of annotations previously emitted by RTE for the \ @@ -149,8 +148,7 @@ let _ignore = Visit.get_annotations_exp let main () = - (* reset "rte generated"/"called precond generated" properties for all - functions *) + (* reset "rte generated" properties for all functions *) if Options.Enabled.get () then begin Options.feedback ~level:2 "generating annotations"; !Db.RteGen.compute (); -- GitLab From 618f21ce4fabed0a990e2661c4a6e9470da4a544 Mon Sep 17 00:00:00 2001 From: Andre Maroneze <andre.oliveiramaroneze@cea.fr> Date: Fri, 30 Aug 2019 16:12:39 +0200 Subject: [PATCH 170/218] [Libc] add spec for GNU function strchrnul; improve spec for strchr --- share/libc/string.h | 8 +- tests/builtins/oracle/memcpy.res.oracle | 181 ++++++++++-------- tests/libc/oracle/coverage.res.oracle | 2 +- tests/libc/oracle/fc_libc.0.res.oracle | 38 ++-- tests/libc/oracle/fc_libc.1.res.oracle | 12 +- tests/libc/oracle/netdb_c.res.oracle | 3 +- tests/libc/oracle/stdlib_c_env.res.oracle | 2 +- tests/libc/oracle/string_c.res.oracle | 42 ++-- tests/libc/oracle/string_c_generic.res.oracle | 32 ++-- tests/libc/oracle/string_c_strstr.res.oracle | 6 +- tests/libc/oracle/string_h.res.oracle | 25 ++- tests/libc/string_h.c | 7 + 12 files changed, 209 insertions(+), 149 deletions(-) diff --git a/share/libc/string.h b/share/libc/string.h index 097225f94e8..a2b62c15e8d 100644 --- a/share/libc/string.h +++ b/share/libc/string.h @@ -155,7 +155,7 @@ extern int strncmp (const char *s1, const char *s2, size_t n); extern int strcoll (const char *s1, const char *s2); /*@ requires valid_string_s: valid_read_string(s); - @ assigns \result \from s, s[0..],c; + @ assigns \result \from s, indirect:s[0..strlen(s)], indirect:c; @ behavior found: @ assumes char_found: strchr(s,c); @ ensures result_char: *\result == (char)c; @@ -172,6 +172,12 @@ extern int strcoll (const char *s1, const char *s2); @*/ extern char *strchr(const char *s, int c); +/*@ requires valid_string_s: valid_read_string(s); + @ assigns \result \from s, indirect:s[0..strlen(s)], indirect:c; + @ ensures result_same_base: \subset(\result, s+(0..strlen(s))); + @*/ +extern char *strchrnul(const char *s, int c); + /*@ requires valid_string_s: valid_read_string(s); @ assigns \result \from s, s[0..],c; @ behavior found: diff --git a/tests/builtins/oracle/memcpy.res.oracle b/tests/builtins/oracle/memcpy.res.oracle index 68da1692272..dd7e4c0161b 100644 --- a/tests/builtins/oracle/memcpy.res.oracle +++ b/tests/builtins/oracle/memcpy.res.oracle @@ -1318,6 +1318,19 @@ [ Valid ] Behavior 'not_found' by Frama-C kernel. +-------------------------------------------------------------------------------- +--- Properties of Function 'strchrnul' +-------------------------------------------------------------------------------- + +[ Extern ] Post-condition 'result_same_base' + Unverifiable but considered Valid. +[ Extern ] Assigns nothing + Unverifiable but considered Valid. +[ Extern ] Froms (file share/libc/string.h, line 176) + Unverifiable but considered Valid. +[ Valid ] Default behavior + by Frama-C kernel. + -------------------------------------------------------------------------------- --- Properties of Function 'strrchr' -------------------------------------------------------------------------------- @@ -1334,7 +1347,7 @@ Unverifiable but considered Valid. [ Extern ] Assigns nothing Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/string.h, line 176) +[ Extern ] Froms (file share/libc/string.h, line 182) Unverifiable but considered Valid. [ Valid ] Behavior 'default' by Frama-C kernel. @@ -1353,7 +1366,7 @@ Unverifiable but considered Valid. [ Extern ] Assigns nothing Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/string.h, line 193) +[ Extern ] Froms (file share/libc/string.h, line 199) Unverifiable but considered Valid. [ Valid ] Default behavior by Frama-C kernel. @@ -1364,11 +1377,11 @@ [ Extern ] Post-condition 'result_bounded' Unverifiable but considered Valid. -[ Extern ] Assigns (file share/libc/string.h, line 200) +[ Extern ] Assigns (file share/libc/string.h, line 206) Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/string.h, line 200) +[ Extern ] Froms (file share/libc/string.h, line 206) Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/string.h, line 201) +[ Extern ] Froms (file share/libc/string.h, line 207) Unverifiable but considered Valid. [ Valid ] Default behavior by Frama-C kernel. @@ -1381,7 +1394,7 @@ Unverifiable but considered Valid. [ Extern ] Assigns nothing Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/string.h, line 208) +[ Extern ] Froms (file share/libc/string.h, line 214) Unverifiable but considered Valid. [ Valid ] Default behavior by Frama-C kernel. @@ -1394,7 +1407,7 @@ Unverifiable but considered Valid. [ Extern ] Assigns nothing Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/string.h, line 216) +[ Extern ] Froms (file share/libc/string.h, line 222) Unverifiable but considered Valid. [ Valid ] Default behavior by Frama-C kernel. @@ -1407,7 +1420,7 @@ Unverifiable but considered Valid. [ Extern ] Assigns nothing Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/string.h, line 227) +[ Extern ] Froms (file share/libc/string.h, line 233) Unverifiable but considered Valid. [ Valid ] Default behavior by Frama-C kernel. @@ -1424,31 +1437,31 @@ Unverifiable but considered Valid. [ Extern ] Post-condition for 'resume_str' 'ptr_subset' Unverifiable but considered Valid. -[ Extern ] Assigns (file share/libc/string.h, line 240) +[ Extern ] Assigns (file share/libc/string.h, line 246) Unverifiable but considered Valid. -[ Extern ] Assigns for 'new_str' (file share/libc/string.h, line 255) +[ Extern ] Assigns for 'new_str' (file share/libc/string.h, line 261) Unverifiable but considered Valid. -[ Extern ] Assigns for 'resume_str' (file share/libc/string.h, line 263) +[ Extern ] Assigns for 'resume_str' (file share/libc/string.h, line 269) Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/string.h, line 240) +[ Extern ] Froms (file share/libc/string.h, line 246) Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/string.h, line 242) +[ Extern ] Froms (file share/libc/string.h, line 248) Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/string.h, line 244) +[ Extern ] Froms (file share/libc/string.h, line 250) Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/string.h, line 246) +[ Extern ] Froms (file share/libc/string.h, line 252) Unverifiable but considered Valid. -[ Extern ] Froms for 'new_str' (file share/libc/string.h, line 255) +[ Extern ] Froms for 'new_str' (file share/libc/string.h, line 261) Unverifiable but considered Valid. -[ Extern ] Froms for 'new_str' (file share/libc/string.h, line 256) +[ Extern ] Froms for 'new_str' (file share/libc/string.h, line 262) Unverifiable but considered Valid. -[ Extern ] Froms for 'new_str' (file share/libc/string.h, line 257) +[ Extern ] Froms for 'new_str' (file share/libc/string.h, line 263) Unverifiable but considered Valid. -[ Extern ] Froms for 'resume_str' (file share/libc/string.h, line 263) +[ Extern ] Froms for 'resume_str' (file share/libc/string.h, line 269) Unverifiable but considered Valid. -[ Extern ] Froms for 'resume_str' (file share/libc/string.h, line 266) +[ Extern ] Froms for 'resume_str' (file share/libc/string.h, line 272) Unverifiable but considered Valid. -[ Extern ] Froms for 'resume_str' (file share/libc/string.h, line 269) +[ Extern ] Froms for 'resume_str' (file share/libc/string.h, line 275) Unverifiable but considered Valid. [ Valid ] Default behavior by Frama-C kernel. @@ -1471,31 +1484,31 @@ Unverifiable but considered Valid. [ Extern ] Post-condition for 'resume_str' 'saveptr_subset' Unverifiable but considered Valid. -[ Extern ] Assigns (file share/libc/string.h, line 282) +[ Extern ] Assigns (file share/libc/string.h, line 288) Unverifiable but considered Valid. -[ Extern ] Assigns for 'new_str' (file share/libc/string.h, line 297) +[ Extern ] Assigns for 'new_str' (file share/libc/string.h, line 303) Unverifiable but considered Valid. -[ Extern ] Assigns for 'resume_str' (file share/libc/string.h, line 307) +[ Extern ] Assigns for 'resume_str' (file share/libc/string.h, line 313) Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/string.h, line 282) +[ Extern ] Froms (file share/libc/string.h, line 288) Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/string.h, line 284) +[ Extern ] Froms (file share/libc/string.h, line 290) Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/string.h, line 286) +[ Extern ] Froms (file share/libc/string.h, line 292) Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/string.h, line 288) +[ Extern ] Froms (file share/libc/string.h, line 294) Unverifiable but considered Valid. -[ Extern ] Froms for 'new_str' (file share/libc/string.h, line 297) +[ Extern ] Froms for 'new_str' (file share/libc/string.h, line 303) Unverifiable but considered Valid. -[ Extern ] Froms for 'new_str' (file share/libc/string.h, line 298) +[ Extern ] Froms for 'new_str' (file share/libc/string.h, line 304) Unverifiable but considered Valid. -[ Extern ] Froms for 'new_str' (file share/libc/string.h, line 299) +[ Extern ] Froms for 'new_str' (file share/libc/string.h, line 305) Unverifiable but considered Valid. -[ Extern ] Froms for 'resume_str' (file share/libc/string.h, line 307) +[ Extern ] Froms for 'resume_str' (file share/libc/string.h, line 313) Unverifiable but considered Valid. -[ Extern ] Froms for 'resume_str' (file share/libc/string.h, line 310) +[ Extern ] Froms for 'resume_str' (file share/libc/string.h, line 316) Unverifiable but considered Valid. -[ Extern ] Froms for 'resume_str' (file share/libc/string.h, line 313) +[ Extern ] Froms for 'resume_str' (file share/libc/string.h, line 319) Unverifiable but considered Valid. [ Valid ] Default behavior by Frama-C kernel. @@ -1508,11 +1521,11 @@ --- Properties of Function 'strsep' -------------------------------------------------------------------------------- -[ Extern ] Assigns (file share/libc/string.h, line 325) +[ Extern ] Assigns (file share/libc/string.h, line 331) Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/string.h, line 325) +[ Extern ] Froms (file share/libc/string.h, line 331) Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/string.h, line 326) +[ Extern ] Froms (file share/libc/string.h, line 332) Unverifiable but considered Valid. [ Valid ] Default behavior by Frama-C kernel. @@ -1529,7 +1542,7 @@ Unverifiable but considered Valid. [ Extern ] Assigns nothing Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/string.h, line 336) +[ Extern ] Froms (file share/libc/string.h, line 342) Unverifiable but considered Valid. [ Valid ] Default behavior by Frama-C kernel. @@ -1542,11 +1555,11 @@ Unverifiable but considered Valid. [ Extern ] Post-condition 'result_ptr' Unverifiable but considered Valid. -[ Extern ] Assigns (file share/libc/string.h, line 349) +[ Extern ] Assigns (file share/libc/string.h, line 355) Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/string.h, line 349) +[ Extern ] Froms (file share/libc/string.h, line 355) Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/string.h, line 350) +[ Extern ] Froms (file share/libc/string.h, line 356) Unverifiable but considered Valid. [ Valid ] Default behavior by Frama-C kernel. @@ -1563,11 +1576,11 @@ Unverifiable but considered Valid. [ Extern ] Post-condition for 'partial' 'equal_prefix' Unverifiable but considered Valid. -[ Extern ] Assigns (file share/libc/string.h, line 361) +[ Extern ] Assigns (file share/libc/string.h, line 367) Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/string.h, line 361) +[ Extern ] Froms (file share/libc/string.h, line 367) Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/string.h, line 362) +[ Extern ] Froms (file share/libc/string.h, line 368) Unverifiable but considered Valid. [ Valid ] Behavior 'complete' by Frama-C kernel. @@ -1584,11 +1597,11 @@ Unverifiable but considered Valid. [ Extern ] Post-condition 'bounded_result' Unverifiable but considered Valid. -[ Extern ] Assigns (file share/libc/string.h, line 382) +[ Extern ] Assigns (file share/libc/string.h, line 388) Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/string.h, line 382) +[ Extern ] Froms (file share/libc/string.h, line 388) Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/string.h, line 383) +[ Extern ] Froms (file share/libc/string.h, line 389) Unverifiable but considered Valid. [ Valid ] Default behavior by Frama-C kernel. @@ -1601,11 +1614,11 @@ Unverifiable but considered Valid. [ Extern ] Post-condition 'points_to_end' Unverifiable but considered Valid. -[ Extern ] Assigns (file share/libc/string.h, line 394) +[ Extern ] Assigns (file share/libc/string.h, line 400) Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/string.h, line 394) +[ Extern ] Froms (file share/libc/string.h, line 400) Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/string.h, line 395) +[ Extern ] Froms (file share/libc/string.h, line 401) Unverifiable but considered Valid. [ Valid ] Default behavior by Frama-C kernel. @@ -1622,11 +1635,11 @@ Unverifiable but considered Valid. [ Extern ] Post-condition 'result_ptr' Unverifiable but considered Valid. -[ Extern ] Assigns (file share/libc/string.h, line 405) +[ Extern ] Assigns (file share/libc/string.h, line 411) Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/string.h, line 405) +[ Extern ] Froms (file share/libc/string.h, line 411) Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/string.h, line 408) +[ Extern ] Froms (file share/libc/string.h, line 414) Unverifiable but considered Valid. [ Valid ] Default behavior by Frama-C kernel. @@ -1641,23 +1654,23 @@ Unverifiable but considered Valid. [ Extern ] Post-condition for 'partial' 'sum_of_bounded_lengths' Unverifiable but considered Valid. -[ Extern ] Assigns for 'complete' (file share/libc/string.h, line 425) +[ Extern ] Assigns for 'complete' (file share/libc/string.h, line 431) Unverifiable but considered Valid. -[ Extern ] Assigns (file share/libc/string.h, line 419) +[ Extern ] Assigns (file share/libc/string.h, line 425) Unverifiable but considered Valid. -[ Extern ] Assigns for 'partial' (file share/libc/string.h, line 433) +[ Extern ] Assigns for 'partial' (file share/libc/string.h, line 439) Unverifiable but considered Valid. -[ Extern ] Froms for 'complete' (file share/libc/string.h, line 425) +[ Extern ] Froms for 'complete' (file share/libc/string.h, line 431) Unverifiable but considered Valid. -[ Extern ] Froms for 'complete' (file share/libc/string.h, line 427) +[ Extern ] Froms for 'complete' (file share/libc/string.h, line 433) Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/string.h, line 419) +[ Extern ] Froms (file share/libc/string.h, line 425) Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/string.h, line 420) +[ Extern ] Froms (file share/libc/string.h, line 426) Unverifiable but considered Valid. -[ Extern ] Froms for 'partial' (file share/libc/string.h, line 433) +[ Extern ] Froms for 'partial' (file share/libc/string.h, line 439) Unverifiable but considered Valid. -[ Extern ] Froms for 'partial' (file share/libc/string.h, line 435) +[ Extern ] Froms for 'partial' (file share/libc/string.h, line 441) Unverifiable but considered Valid. [ Valid ] Behavior 'complete' by Frama-C kernel. @@ -1672,11 +1685,11 @@ [ Extern ] Post-condition 'bounded_result' Unverifiable but considered Valid. -[ Extern ] Assigns (file share/libc/string.h, line 445) +[ Extern ] Assigns (file share/libc/string.h, line 451) Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/string.h, line 445) +[ Extern ] Froms (file share/libc/string.h, line 451) Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/string.h, line 446) +[ Extern ] Froms (file share/libc/string.h, line 452) Unverifiable but considered Valid. [ Valid ] Default behavior by Frama-C kernel. @@ -1685,11 +1698,11 @@ --- Properties of Function 'strxfrm' -------------------------------------------------------------------------------- -[ Extern ] Assigns (file share/libc/string.h, line 454) +[ Extern ] Assigns (file share/libc/string.h, line 460) Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/string.h, line 454) +[ Extern ] Froms (file share/libc/string.h, line 460) Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/string.h, line 455) +[ Extern ] Froms (file share/libc/string.h, line 461) Unverifiable but considered Valid. [ Valid ] Default behavior by Frama-C kernel. @@ -1704,19 +1717,19 @@ Unverifiable but considered Valid. [ Extern ] Post-condition for 'no_allocation' 'result_null' Unverifiable but considered Valid. -[ Extern ] Assigns for 'allocation' (file share/libc/string.h, line 467) +[ Extern ] Assigns for 'allocation' (file share/libc/string.h, line 473) Unverifiable but considered Valid. [ Extern ] Assigns nothing Unverifiable but considered Valid. [ Extern ] Assigns for 'no_allocation' nothing Unverifiable but considered Valid. -[ Extern ] Froms for 'allocation' (file share/libc/string.h, line 467) +[ Extern ] Froms for 'allocation' (file share/libc/string.h, line 473) Unverifiable but considered Valid. -[ Extern ] Froms for 'allocation' (file share/libc/string.h, line 468) +[ Extern ] Froms for 'allocation' (file share/libc/string.h, line 474) Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/string.h, line 464) +[ Extern ] Froms (file share/libc/string.h, line 470) Unverifiable but considered Valid. -[ Extern ] Froms for 'no_allocation' (file share/libc/string.h, line 474) +[ Extern ] Froms for 'no_allocation' (file share/libc/string.h, line 480) Unverifiable but considered Valid. [ Valid ] Behavior 'allocation' by Frama-C kernel. @@ -1724,7 +1737,7 @@ by Frama-C kernel. [ Valid ] Behavior 'no_allocation' by Frama-C kernel. -[ Extern ] Frees/Allocates nothing/(file share/libc/string.h, line 463) +[ Extern ] Frees/Allocates nothing/(file share/libc/string.h, line 469) Unverifiable but considered Valid. [ Extern ] Frees/Allocates for 'no_allocation' nothing/nothing Unverifiable but considered Valid. @@ -1739,19 +1752,19 @@ Unverifiable but considered Valid. [ Extern ] Post-condition for 'no_allocation' 'result_null' Unverifiable but considered Valid. -[ Extern ] Assigns for 'allocation' (file share/libc/string.h, line 486) +[ Extern ] Assigns for 'allocation' (file share/libc/string.h, line 492) Unverifiable but considered Valid. [ Extern ] Assigns nothing Unverifiable but considered Valid. [ Extern ] Assigns for 'no_allocation' nothing Unverifiable but considered Valid. -[ Extern ] Froms for 'allocation' (file share/libc/string.h, line 486) +[ Extern ] Froms for 'allocation' (file share/libc/string.h, line 492) Unverifiable but considered Valid. -[ Extern ] Froms for 'allocation' (file share/libc/string.h, line 487) +[ Extern ] Froms for 'allocation' (file share/libc/string.h, line 493) Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/string.h, line 482) +[ Extern ] Froms (file share/libc/string.h, line 488) Unverifiable but considered Valid. -[ Extern ] Froms for 'no_allocation' (file share/libc/string.h, line 496) +[ Extern ] Froms for 'no_allocation' (file share/libc/string.h, line 502) Unverifiable but considered Valid. [ Valid ] Behavior 'allocation' by Frama-C kernel. @@ -1759,7 +1772,7 @@ by Frama-C kernel. [ Valid ] Behavior 'no_allocation' by Frama-C kernel. -[ Extern ] Frees/Allocates nothing/(file share/libc/string.h, line 481) +[ Extern ] Frees/Allocates nothing/(file share/libc/string.h, line 487) Unverifiable but considered Valid. [ Extern ] Frees/Allocates for 'no_allocation' nothing/nothing Unverifiable but considered Valid. @@ -1776,7 +1789,7 @@ Unverifiable but considered Valid. [ Extern ] Assigns nothing Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/string.h, line 512) +[ Extern ] Froms (file share/libc/string.h, line 518) Unverifiable but considered Valid. [ Valid ] Default behavior by Frama-C kernel. @@ -2238,10 +2251,10 @@ -------------------------------------------------------------------------------- --- Status Report Summary -------------------------------------------------------------------------------- - 162 Completely validated + 163 Completely validated 1 Locally validated - 239 Considered valid + 242 Considered valid 32 To be validated 4 Alarms emitted - 438 Total + 442 Total -------------------------------------------------------------------------------- diff --git a/tests/libc/oracle/coverage.res.oracle b/tests/libc/oracle/coverage.res.oracle index 420792611b3..f0696a6f2d1 100644 --- a/tests/libc/oracle/coverage.res.oracle +++ b/tests/libc/oracle/coverage.res.oracle @@ -28,7 +28,7 @@ main: 4 stmts out of 4 (100.0%) [metrics] Eva coverage statistics ======================= - Syntactically reachable functions = 2 (out of 112) + Syntactically reachable functions = 2 (out of 113) Semantically reached functions = 2 Coverage estimation = 100.0% [metrics] Statements analyzed by Eva diff --git a/tests/libc/oracle/fc_libc.0.res.oracle b/tests/libc/oracle/fc_libc.0.res.oracle index 02529fbe95f..413b1aee0f0 100644 --- a/tests/libc/oracle/fc_libc.0.res.oracle +++ b/tests/libc/oracle/fc_libc.0.res.oracle @@ -40,7 +40,7 @@ unsetenv (0 call); wcscat (0 call); wcscpy (0 call); wcslen (2 calls); wcsncat (0 call); wcsncpy (0 call); wmemcpy (0 call); wmemset (0 call); - Undefined functions (394) + Undefined functions (395) ========================= FD_CLR (0 call); FD_ISSET (0 call); FD_SET (0 call); FD_ZERO (0 call); Frama_C_int_interval (0 call); Frama_C_long_interval (0 call); @@ -142,23 +142,23 @@ sinf (0 call); sinl (0 call); socket (0 call); socketpair (0 call); sqrt (0 call); sqrtf (0 call); sqrtl (0 call); srand (0 call); srand48 (0 call); srandom (0 call); stat (0 call); stpcpy (0 call); - strcasestr (0 call); strcoll (0 call); strcspn (0 call); strftime (0 call); - strlcat (0 call); strlcpy (0 call); strncasecmp (0 call); strpbrk (0 call); - strsep (0 call); strspn (0 call); strtod (0 call); strtof (0 call); - strtoimax (0 call); strtok (0 call); strtok_r (0 call); strtol (0 call); - strtold (0 call); strtoll (0 call); strtoul (0 call); strtoull (0 call); - strxfrm (0 call); sync (0 call); sysconf (0 call); syslog (0 call); - system (0 call); tcflush (0 call); tcgetattr (0 call); tcsetattr (0 call); - time (0 call); times (0 call); tmpfile (0 call); tmpnam (0 call); - trunc (0 call); truncf (0 call); truncl (0 call); ttyname (0 call); - tzset (0 call); umask (0 call); ungetc (0 call); unlink (0 call); - usleep (0 call); utimes (0 call); vfprintf (0 call); vfscanf (0 call); - vprintf (0 call); vscanf (0 call); vsnprintf (0 call); vsprintf (0 call); - vsyslog (0 call); wait (0 call); waitpid (0 call); wcschr (0 call); - wcscmp (0 call); wcscspn (0 call); wcslcat (0 call); wcslcpy (0 call); - wcsncmp (0 call); wcspbrk (0 call); wcsrchr (0 call); wcsspn (0 call); - wcsstr (0 call); wcstombs (0 call); wctomb (0 call); wmemchr (0 call); - wmemcmp (0 call); wmemmove (0 call); write (0 call); + strcasestr (0 call); strchrnul (0 call); strcoll (0 call); strcspn (0 call); + strftime (0 call); strlcat (0 call); strlcpy (0 call); strncasecmp (0 call); + strpbrk (0 call); strsep (0 call); strspn (0 call); strtod (0 call); + strtof (0 call); strtoimax (0 call); strtok (0 call); strtok_r (0 call); + strtol (0 call); strtold (0 call); strtoll (0 call); strtoul (0 call); + strtoull (0 call); strxfrm (0 call); sync (0 call); sysconf (0 call); + syslog (0 call); system (0 call); tcflush (0 call); tcgetattr (0 call); + tcsetattr (0 call); time (0 call); times (0 call); tmpfile (0 call); + tmpnam (0 call); trunc (0 call); truncf (0 call); truncl (0 call); + ttyname (0 call); tzset (0 call); umask (0 call); ungetc (0 call); + unlink (0 call); usleep (0 call); utimes (0 call); vfprintf (0 call); + vfscanf (0 call); vprintf (0 call); vscanf (0 call); vsnprintf (0 call); + vsprintf (0 call); vsyslog (0 call); wait (0 call); waitpid (0 call); + wcschr (0 call); wcscmp (0 call); wcscspn (0 call); wcslcat (0 call); + wcslcpy (0 call); wcsncmp (0 call); wcspbrk (0 call); wcsrchr (0 call); + wcsspn (0 call); wcsstr (0 call); wcstombs (0 call); wctomb (0 call); + wmemchr (0 call); wmemcmp (0 call); wmemmove (0 call); write (0 call); 'Extern' global variables (16) ============================== @@ -181,7 +181,7 @@ Goto = 89 Assignment = 438 Exit point = 82 - Function = 476 + Function = 477 Function call = 89 Pointer dereferencing = 158 Cyclomatic complexity = 286 diff --git a/tests/libc/oracle/fc_libc.1.res.oracle b/tests/libc/oracle/fc_libc.1.res.oracle index 3ac0899086f..34abdcbb6ed 100644 --- a/tests/libc/oracle/fc_libc.1.res.oracle +++ b/tests/libc/oracle/fc_libc.1.res.oracle @@ -3999,6 +3999,15 @@ extern int strcoll(char const *s1, char const *s2); char *strchr(char const *s, int c); +/*@ requires valid_string_s: valid_read_string(s); + ensures + result_same_base: \subset(\result, \old(s) + (0 .. strlen(\old(s)))); + assigns \result; + assigns \result + \from s, (indirect: *(s + (0 .. strlen{Old}(s)))), (indirect: c); + */ +extern char *strchrnul(char const *s, int c); + char *strrchr(char const *s, int c); /*@ requires valid_string_s: valid_read_string(s); @@ -5919,7 +5928,8 @@ char *strncpy(char *dest, char const *src, size_t n) /*@ requires valid_string_s: valid_read_string(s); assigns \result; - assigns \result \from s, *(s + (0 ..)), c; + assigns \result + \from s, (indirect: *(s + (0 .. strlen{Old}(s)))), (indirect: c); behavior found: assumes char_found: strchr(s, c) ≡ \true; diff --git a/tests/libc/oracle/netdb_c.res.oracle b/tests/libc/oracle/netdb_c.res.oracle index 7245bc0aa8f..d3a9ddf8739 100644 --- a/tests/libc/oracle/netdb_c.res.oracle +++ b/tests/libc/oracle/netdb_c.res.oracle @@ -21,6 +21,7 @@ \return(memmove) == 0 (auto) \return(memset) == 0 (auto) \return(strchr) == 0 (auto) + \return(strchrnul) == 0 (auto) \return(strrchr) == 0 (auto) \return(strpbrk) == 0 (auto) \return(strstr) == 0 (auto) @@ -248,7 +249,7 @@ function strncpy: precondition 'room_nstring' got status valid. [eva] share/libc/netdb.c:147: function strncpy: precondition 'separation' got status valid. -[eva] share/libc/string.h:367: +[eva] share/libc/string.h:373: cannot evaluate ACSL term, unsupported ACSL construct: logic function strcmp [eva] Done for function strncpy [eva] Recording results for gethostbyname diff --git a/tests/libc/oracle/stdlib_c_env.res.oracle b/tests/libc/oracle/stdlib_c_env.res.oracle index 5322b2985d4..fc9107a8102 100644 --- a/tests/libc/oracle/stdlib_c_env.res.oracle +++ b/tests/libc/oracle/stdlib_c_env.res.oracle @@ -105,7 +105,7 @@ function strcpy: precondition 'room_string' got status valid. [eva] tests/libc/stdlib_c_env.c:15: function strcpy: precondition 'separation' got status valid. -[eva] share/libc/string.h:351: +[eva] share/libc/string.h:357: cannot evaluate ACSL term, unsupported ACSL construct: logic function strcmp [eva] Done for function strcpy [eva] computing for function getenv <- main. diff --git a/tests/libc/oracle/string_c.res.oracle b/tests/libc/oracle/string_c.res.oracle index 65a4843c64b..033c83c6b47 100644 --- a/tests/libc/oracle/string_c.res.oracle +++ b/tests/libc/oracle/string_c.res.oracle @@ -494,13 +494,13 @@ function strlen: precondition 'valid_string_s' got status valid. [eva] Recording results for strlen [eva] Done for function strlen -[eva] share/libc/string.h:407: +[eva] share/libc/string.h:413: function strcat: postcondition 'sum_of_lengths' got status valid. -[eva] share/libc/string.h:410: +[eva] share/libc/string.h:416: function strcat: postcondition 'initialization,dest' got status valid. -[eva] share/libc/string.h:411: +[eva] share/libc/string.h:417: function strcat: postcondition 'dest_null_terminated' got status valid. -[eva] share/libc/string.h:412: +[eva] share/libc/string.h:418: function strcat: postcondition 'result_ptr' got status valid. [eva] Recording results for strcat [eva] Done for function strcat @@ -559,11 +559,11 @@ function strcpy: precondition 'room_string' got status valid. [eva] tests/libc/string_c.c:142: function strcpy: precondition 'separation' got status valid. -[eva] share/libc/string.h:351: +[eva] share/libc/string.h:357: cannot evaluate ACSL term, unsupported ACSL construct: logic function strcmp -[eva:alarm] share/libc/string.h:351: Warning: +[eva:alarm] share/libc/string.h:357: Warning: function strcpy: postcondition 'equal_contents' got status unknown. -[eva] share/libc/string.h:352: +[eva] share/libc/string.h:358: function strcpy: postcondition 'result_ptr' got status valid. [eva] Recording results for strcpy [eva] Done for function strcpy @@ -603,13 +603,13 @@ function strncpy: precondition 'room_nstring' got status valid. [eva] tests/libc/string_c.c:154: function strncpy: precondition 'separation' got status valid. -[eva] share/libc/string.h:363: +[eva] share/libc/string.h:369: function strncpy: postcondition 'result_ptr' got status valid. -[eva] share/libc/string.h:364: +[eva] share/libc/string.h:370: function strncpy: postcondition 'initialization' got status valid. -[eva] share/libc/string.h:367: +[eva] share/libc/string.h:373: cannot evaluate ACSL term, unsupported ACSL construct: logic function strcmp -[eva:alarm] share/libc/string.h:367: Warning: +[eva:alarm] share/libc/string.h:373: Warning: function strncpy, behavior complete: postcondition 'equal_after_copy' got status unknown. [eva] Recording results for strncpy [eva] Done for function strncpy @@ -623,9 +623,9 @@ function strncpy: precondition 'room_nstring' got status valid. [eva] tests/libc/string_c.c:157: function strncpy: precondition 'separation' got status valid. -[eva] share/libc/string.h:370: +[eva] share/libc/string.h:376: cannot evaluate ACSL term, unsupported ACSL construct: logic function memcmp -[eva:alarm] share/libc/string.h:370: Warning: +[eva:alarm] share/libc/string.h:376: Warning: function strncpy, behavior partial: postcondition 'equal_prefix' got status unknown. [eva] Recording results for strncpy [eva] Done for function strncpy @@ -712,13 +712,13 @@ function strlen: precondition 'valid_string_s' got status valid. [eva] Recording results for strlen [eva] Done for function strlen -[eva] share/libc/string.h:179: +[eva] share/libc/string.h:185: function strrchr, behavior found: postcondition 'result_char' got status valid. -[eva] share/libc/string.h:180: +[eva] share/libc/string.h:186: function strrchr, behavior found: postcondition 'result_same_base' got status valid. -[eva] share/libc/string.h:181: - function strrchr, behavior found: postcondition 'result_valid_string' got status valid. [eva] share/libc/string.h:187: + function strrchr, behavior found: postcondition 'result_valid_string' got status valid. +[eva] share/libc/string.h:193: function strrchr, behavior default: postcondition 'result_null_or_same_base' got status valid. [eva] Recording results for strrchr [eva] Done for function strrchr @@ -728,7 +728,7 @@ [eva] tests/libc/string_c.c:216: function strrchr: precondition 'valid_string_s' got status valid. [eva] share/libc/string.c:237: Reusing old results for call to strlen -[eva] share/libc/string.h:184: +[eva] share/libc/string.h:190: function strrchr, behavior not_found: postcondition 'result_null' got status valid. [eva] Recording results for strrchr [eva] Done for function strrchr @@ -883,9 +883,9 @@ function strstr: precondition 'valid_string_haystack' got status valid. [eva] tests/libc/string_c.c:261: function strstr: precondition 'valid_string_needle' got status valid. -[eva] share/libc/string.h:221: +[eva] share/libc/string.h:227: cannot evaluate ACSL term, unsupported ACSL construct: logic function memcmp -[eva:alarm] share/libc/string.h:219: Warning: +[eva:alarm] share/libc/string.h:225: Warning: function strstr: postcondition 'result_null_or_in_haystack' got status unknown. [eva] Recording results for strstr [eva] Done for function strstr @@ -905,7 +905,7 @@ function strstr: precondition 'valid_string_haystack' got status valid. [eva] tests/libc/string_c.c:265: function strstr: precondition 'valid_string_needle' got status valid. -[eva] share/libc/string.h:219: +[eva] share/libc/string.h:225: function strstr: postcondition 'result_null_or_in_haystack' got status valid. [eva] Recording results for strstr [eva] Done for function strstr diff --git a/tests/libc/oracle/string_c_generic.res.oracle b/tests/libc/oracle/string_c_generic.res.oracle index 41ee7f4cbff..d2f546a60ac 100644 --- a/tests/libc/oracle/string_c_generic.res.oracle +++ b/tests/libc/oracle/string_c_generic.res.oracle @@ -12,11 +12,11 @@ function strcpy: precondition 'room_string' got status valid. [eva] tests/libc/string_c_generic.c:56: function strcpy: precondition 'separation' got status valid. -[eva] share/libc/string.h:351: +[eva] share/libc/string.h:357: cannot evaluate ACSL term, unsupported ACSL construct: logic function strcmp -[eva:alarm] share/libc/string.h:351: Warning: +[eva:alarm] share/libc/string.h:357: Warning: function strcpy: postcondition 'equal_contents' got status unknown. -[eva] share/libc/string.h:352: +[eva] share/libc/string.h:358: function strcpy: postcondition 'result_ptr' got status valid. [eva] Recording results for strcpy [eva] Done for function strcpy @@ -161,13 +161,13 @@ [eva] tests/libc/string_c_generic.c:73: function strncpy: precondition 'separation' got status valid. [eva] share/libc/string.c:220: starting to merge loop iterations -[eva] share/libc/string.h:363: +[eva] share/libc/string.h:369: function strncpy: postcondition 'result_ptr' got status valid. -[eva] share/libc/string.h:364: +[eva] share/libc/string.h:370: function strncpy: postcondition 'initialization' got status valid. -[eva] share/libc/string.h:367: +[eva] share/libc/string.h:373: cannot evaluate ACSL term, unsupported ACSL construct: logic function strcmp -[eva:alarm] share/libc/string.h:367: Warning: +[eva:alarm] share/libc/string.h:373: Warning: function strncpy, behavior complete: postcondition 'equal_after_copy' got status unknown. [eva] Recording results for strncpy [eva] Done for function strncpy @@ -199,9 +199,9 @@ function strncpy: precondition 'room_nstring' got status valid. [eva] tests/libc/string_c_generic.c:78: function strncpy: precondition 'separation' got status valid. -[eva] share/libc/string.h:370: +[eva] share/libc/string.h:376: cannot evaluate ACSL term, unsupported ACSL construct: logic function memcmp -[eva:alarm] share/libc/string.h:370: Warning: +[eva:alarm] share/libc/string.h:376: Warning: function strncpy, behavior partial: postcondition 'equal_prefix' got status unknown. [eva] Recording results for strncpy [eva] Done for function strncpy @@ -252,9 +252,9 @@ function strlen: postcondition 'acsl_c_equiv' got status valid. [eva] Recording results for strlen [eva] Done for function strlen -[eva] share/libc/string.h:421: +[eva] share/libc/string.h:427: function strncat: postcondition 'result_ptr' got status valid. -[eva] share/libc/string.h:436: +[eva] share/libc/string.h:442: function strncat, behavior partial: postcondition 'sum_of_bounded_lengths' got status valid. [eva] Recording results for strncat [eva] Done for function strncat @@ -312,13 +312,13 @@ function strlen: precondition 'valid_string_s' got status valid. [eva] Recording results for strlen [eva] Done for function strlen -[eva] share/libc/string.h:179: +[eva] share/libc/string.h:185: function strrchr, behavior found: postcondition 'result_char' got status valid. -[eva] share/libc/string.h:180: +[eva] share/libc/string.h:186: function strrchr, behavior found: postcondition 'result_same_base' got status valid. -[eva] share/libc/string.h:181: - function strrchr, behavior found: postcondition 'result_valid_string' got status valid. [eva] share/libc/string.h:187: + function strrchr, behavior found: postcondition 'result_valid_string' got status valid. +[eva] share/libc/string.h:193: function strrchr, behavior default: postcondition 'result_null_or_same_base' got status valid. [eva] Recording results for strrchr [eva] Done for function strrchr @@ -328,7 +328,7 @@ function strrchr: precondition 'valid_string_s' got status valid. [eva] share/libc/string.c:237: Reusing old results for call to strlen [eva] share/libc/string.c:237: starting to merge loop iterations -[eva] share/libc/string.h:184: +[eva] share/libc/string.h:190: function strrchr, behavior not_found: postcondition 'result_null' got status valid. [eva] Recording results for strrchr [eva] Done for function strrchr diff --git a/tests/libc/oracle/string_c_strstr.res.oracle b/tests/libc/oracle/string_c_strstr.res.oracle index 6009523b883..ab662fa0802 100644 --- a/tests/libc/oracle/string_c_strstr.res.oracle +++ b/tests/libc/oracle/string_c_strstr.res.oracle @@ -10,7 +10,7 @@ function strstr: precondition 'valid_string_haystack' got status valid. [eva] tests/libc/string_c_strstr.c:52: function strstr: precondition 'valid_string_needle' got status valid. -[eva] share/libc/string.h:219: +[eva] share/libc/string.h:225: function strstr: postcondition 'result_null_or_in_haystack' got status valid. [eva] Recording results for strstr [eva] Done for function strstr @@ -101,9 +101,9 @@ function strstr: precondition 'valid_string_haystack' got status valid. [eva] tests/libc/string_c_strstr.c:64: function strstr: precondition 'valid_string_needle' got status valid. -[eva] share/libc/string.h:221: +[eva] share/libc/string.h:227: cannot evaluate ACSL term, unsupported ACSL construct: logic function memcmp -[eva:alarm] share/libc/string.h:219: Warning: +[eva:alarm] share/libc/string.h:225: Warning: function strstr: postcondition 'result_null_or_in_haystack' got status unknown. [eva] Recording results for strstr [eva] Done for function strstr diff --git a/tests/libc/oracle/string_h.res.oracle b/tests/libc/oracle/string_h.res.oracle index 89300398e63..5e1e94a0719 100644 --- a/tests/libc/oracle/string_h.res.oracle +++ b/tests/libc/oracle/string_h.res.oracle @@ -51,7 +51,7 @@ function strstr: precondition 'valid_string_haystack' got status valid. [eva] tests/libc/string_h.c:24: function strstr: precondition 'valid_string_needle' got status valid. -[eva] share/libc/string.h:221: +[eva] share/libc/string.h:227: cannot evaluate ACSL term, unsupported ACSL construct: logic function memcmp [eva] Done for function strstr [eva:alarm] tests/libc/string_h.c:25: Warning: assertion got status unknown. @@ -330,6 +330,23 @@ [eva] Done for function strlcpy [eva] Recording results for test_strlcpy [eva] Done for function test_strlcpy +[eva] tests/libc/string_h.c:154: Call to builtin strchr +[eva] tests/libc/string_h.c:154: + function strchr: precondition 'valid_string_s' got status valid. +[eva] computing for function strchrnul <- main. + Called from tests/libc/string_h.c:155. +[eva] using specification for function strchrnul +[eva] tests/libc/string_h.c:155: + function strchrnul: precondition 'valid_string_s' got status valid. +[eva] Done for function strchrnul +[eva] tests/libc/string_h.c:157: Call to builtin strchr +[eva] tests/libc/string_h.c:157: + function strchr: precondition 'valid_string_s' got status valid. +[eva] computing for function strchrnul <- main. + Called from tests/libc/string_h.c:158. +[eva] tests/libc/string_h.c:158: + function strchrnul: precondition 'valid_string_s' got status valid. +[eva] Done for function strchrnul [eva] Recording results for main [eva] done for function main [eva] ====== VALUES COMPUTED ====== @@ -395,4 +412,10 @@ a ∈ [--..--] b ∈ [--..--] strsig ∈ {{ &__fc_strsignal[0] }} + c ∈ {{ "haystack" }} + d ∈ {97; 110} + chr1 ∈ {{ "haystack" + {2; 7} }} + nul1 ∈ {{ "haystack" + [0..8] }} + chr2 ∈ {{ NULL ; "haystack" + {1} }} + nul2 ∈ {{ "haystack" + [0..8] }} __retres ∈ {0} diff --git a/tests/libc/string_h.c b/tests/libc/string_h.c index 0b264a61566..cf18b8e5463 100644 --- a/tests/libc/string_h.c +++ b/tests/libc/string_h.c @@ -149,5 +149,12 @@ int main(int argc, char **argv) //@ assert valid_read_string(strsig); test_strncpy(); test_strlcpy(); + char *c = "haystack"; + char d = nondet ? 'y' : 'k'; + char *chr1 = strchr(c, d); + char *nul1 = strchrnul(c, d); + d = nondet ? 'a' : 'n'; + char *chr2 = strchr(c, d); + char *nul2 = strchrnul(c, d); return 0; } -- GitLab From 9f3d8206a18fbce9ffefb7ec707d0352386983dc Mon Sep 17 00:00:00 2001 From: Michele Alberti <michele.alberti@cea.fr> Date: Wed, 8 Apr 2020 10:29:35 +0200 Subject: [PATCH 171/218] [journal] Port to Filepath for session filename. No internal representation change. --- src/kernel_services/plugin_entry_points/journal.ml | 13 ++++++++----- src/kernel_services/plugin_entry_points/journal.mli | 4 ++-- src/kernel_services/plugin_entry_points/plugin.ml | 6 +----- 3 files changed, 11 insertions(+), 12 deletions(-) diff --git a/src/kernel_services/plugin_entry_points/journal.ml b/src/kernel_services/plugin_entry_points/journal.ml index 52a50fb59f9..9294d088ba4 100644 --- a/src/kernel_services/plugin_entry_points/journal.ml +++ b/src/kernel_services/plugin_entry_points/journal.ml @@ -113,9 +113,11 @@ let now () = Unix.localtime (Unix.time ()) let default_filename = "frama_c_journal.ml" let filename = ref default_filename let get_session_file = ref (fun _ -> assert false) -let get_name () = +let get_name () = let f = !filename in - if f == default_filename then !get_session_file f else f + if f == default_filename + then !get_session_file f + else Datatype.Filepath.of_string f let set_name s = filename := s @@ -136,11 +138,12 @@ let print_header fmt = "(* Run the user commands *)@;@[<hv 2>let run () =@;@[<hv 0>" let print_trailer fmt = + let name = Format.asprintf "%a" Datatype.Filepath.pretty (get_name ()) in Format.fprintf fmt "@[(* Main *)@]@\n"; Format.fprintf fmt "@[<hv 2>let main () =@;"; Format.fprintf fmt "@[<hv 0>@[<hv 2>Journal.keep_file@;\"%s\";@]@;" - (get_name ()); + name; Format.fprintf fmt "try run ()@;"; Format.fprintf fmt "@[<v>with@;@[<hv 2>| Unreachable ->@ "; Format.fprintf fmt @@ -155,7 +158,7 @@ let print_trailer fmt = Format.fprintf fmt "@[(* Registering *)@]@\n"; Format.fprintf fmt "@[<hv 2>let main : unit -> unit =@;@[<hv 2>Dynamic.register@;~plugin:%S@;\"main\"@;" - (String.capitalize_ascii (Filename.basename (get_name ()))); + (String.capitalize_ascii (Filename.basename name)); Format.fprintf fmt "@[<hv 2>(Datatype.func@;Datatype.unit@;Datatype.unit)@]@;"; Format.fprintf fmt "~journalize:false@;main@]@]@\n@\n"; @@ -173,7 +176,7 @@ let keep_file s = preserved_files := s :: !preserved_files let get_filename = let cpt = ref 0 in let rec get_filename first = - let name = get_name () in + let name = Format.asprintf "%a" Datatype.Filepath.pretty (get_name ()) in if (not first && Sys.file_exists name) || List.mem name !preserved_files then begin incr cpt; diff --git a/src/kernel_services/plugin_entry_points/journal.mli b/src/kernel_services/plugin_entry_points/journal.mli index 33573824a5c..82d2b8d6529 100644 --- a/src/kernel_services/plugin_entry_points/journal.mli +++ b/src/kernel_services/plugin_entry_points/journal.mli @@ -83,7 +83,7 @@ end (** {2 Journal management} *) (* ****************************************************************************) -val get_name: unit -> string +val get_name: unit -> Datatype.Filepath.t (** @return the filename which the journal will be written into. *) val set_name: string -> unit @@ -110,7 +110,7 @@ val keep_file: string -> unit (** This function has not to be used explicitly. Only offers functions retrieving when running a journal file. *) -val get_session_file: (string -> string) ref +val get_session_file: (string -> Datatype.Filepath.t) ref (* Local Variables: diff --git a/src/kernel_services/plugin_entry_points/plugin.ml b/src/kernel_services/plugin_entry_points/plugin.ml index 667d8aeef6e..4b7b4a2de3b 100644 --- a/src/kernel_services/plugin_entry_points/plugin.ml +++ b/src/kernel_services/plugin_entry_points/plugin.ml @@ -417,11 +417,7 @@ struct end) let () = if is_kernel () - then - Journal.get_session_file := - (fun s -> - let f = Session.file ~error:false s in - Format.asprintf "%a" Datatype.Filepath.pretty f) + then Journal.get_session_file := (fun s -> Session.file ~error:false s) module Config = Make_specific_dir -- GitLab From f93dc3a8d82e8c1c5e12d6525d7a20c2bbfde127 Mon Sep 17 00:00:00 2001 From: Andre Maroneze <andre.oliveiramaroneze@cea.fr> Date: Fri, 30 Aug 2019 17:58:44 +0200 Subject: [PATCH 172/218] [Libc] add specs for ftello/fseeko --- share/libc/stdio.h | 19 ++- .../tests/arith/oracle_ci/gen_functions.c | 10 +- .../tests/gmp-only/oracle_ci/gen_functions.c | 10 +- .../tests/erroneous/oracle/printf.res.oracle | 2 +- .../tests/known/oracle/printf.res.oracle | 2 +- .../oracle/printf_garbled_mix.res.oracle | 2 +- .../oracle/printf_wrong_arity.res.oracle | 2 +- .../oracle/printf_wrong_pointers.res.oracle | 2 +- .../oracle/printf_wrong_types.res.oracle | 4 +- .../tests/known/oracle/scanf.res.oracle | 2 +- .../tests/known/oracle/scanf_loop.res.oracle | 2 +- .../tests/known/oracle/scanf_wrong.res.oracle | 2 +- .../tests/known/oracle/snprintf.res.oracle | 2 +- .../tests/known/oracle/stdio_print.res.oracle | 2 +- .../tests/known/oracle/stdio_scan.res.oracle | 2 +- .../tests/known/oracle/swprintf.res.oracle | 2 +- .../tests/known/oracle/wchar.res.oracle | 2 +- tests/idct/oracle/ieee_1180_1990.res.oracle | 134 ++++++++++++------ tests/libc/oracle/fc_libc.0.res.oracle | 10 +- tests/libc/oracle/fc_libc.1.res.oracle | 22 +++ tests/libc/oracle/stdio_h.res.oracle | 56 +++++--- tests/libc/stdio_h.c | 3 + tests/metrics/oracle/libc.1.res.oracle | 34 ++--- tests/rte/oracle/value_rte.res.oracle | 116 +++++++++------ 24 files changed, 293 insertions(+), 151 deletions(-) diff --git a/share/libc/stdio.h b/share/libc/stdio.h index c0dd5448ba9..c3fa3488a76 100644 --- a/share/libc/stdio.h +++ b/share/libc/stdio.h @@ -389,6 +389,15 @@ extern int fgetpos(FILE * restrict stream, */ extern int fseek(FILE *stream, long int offset, int whence); +/*@ + requires valid_stream: \valid(stream); + requires whence_enum: whence == SEEK_SET || whence == SEEK_CUR || whence == SEEK_END; + assigns *stream \from *stream, indirect:offset, indirect:whence; + assigns \result, __fc_errno \from indirect:*stream, indirect:offset, + indirect:whence; +*/ +extern int fseeko(FILE *stream, off_t offset, int whence); + /*@ requires valid_stream: \valid(stream); requires valid_pos: \valid_read(pos); @@ -397,7 +406,7 @@ extern int fseek(FILE *stream, long int offset, int whence); */ extern int fsetpos(FILE *stream, const fpos_t *pos); -/*@ +/*@ // missing: assigns errno: EBADF, EOVERFLOW, ESPIPE requires valid_stream: \valid(stream); assigns \result, __fc_errno \from indirect:*stream ; ensures success_or_error: @@ -405,6 +414,14 @@ extern int fsetpos(FILE *stream, const fpos_t *pos); */ extern long int ftell(FILE *stream); +/*@ // missing: assigns errno: EBADF, EOVERFLOW, ESPIPE + requires valid_stream: \valid(stream); + assigns \result, __fc_errno \from indirect:*stream ; + ensures success_or_error: + \result == -1 || (\result >= 0 && __fc_errno == \old(__fc_errno)); +*/ +extern off_t ftello(FILE *stream); + /*@ requires valid_stream: \valid(stream); assigns *stream \from \nothing; diff --git a/src/plugins/e-acsl/tests/arith/oracle_ci/gen_functions.c b/src/plugins/e-acsl/tests/arith/oracle_ci/gen_functions.c index 457ff5d2aa2..42381d641e8 100644 --- a/src/plugins/e-acsl/tests/arith/oracle_ci/gen_functions.c +++ b/src/plugins/e-acsl/tests/arith/oracle_ci/gen_functions.c @@ -232,6 +232,11 @@ void __gen_e_acsl_k(int x) return; } +int __gen_e_acsl_h_short(int s) +{ + return s; +} + int __gen_e_acsl_g_hidden(int x) { return x; @@ -379,9 +384,4 @@ int __gen_e_acsl_h_char(int c) return c; } -int __gen_e_acsl_h_short(int s) -{ - return s; -} - diff --git a/src/plugins/e-acsl/tests/gmp-only/oracle_ci/gen_functions.c b/src/plugins/e-acsl/tests/gmp-only/oracle_ci/gen_functions.c index f7f9708c3cc..2bdf4cd9f28 100644 --- a/src/plugins/e-acsl/tests/gmp-only/oracle_ci/gen_functions.c +++ b/src/plugins/e-acsl/tests/gmp-only/oracle_ci/gen_functions.c @@ -277,6 +277,11 @@ void __gen_e_acsl_k(int x) return; } +int __gen_e_acsl_h_short(int s) +{ + return s; +} + int __gen_e_acsl_g_hidden(int x) { return x; @@ -472,9 +477,4 @@ int __gen_e_acsl_h_char(int c) return c; } -int __gen_e_acsl_h_short(int s) -{ - return s; -} - diff --git a/src/plugins/variadic/tests/erroneous/oracle/printf.res.oracle b/src/plugins/variadic/tests/erroneous/oracle/printf.res.oracle index ebb217fac02..bf32832912e 100644 --- a/src/plugins/variadic/tests/erroneous/oracle/printf.res.oracle +++ b/src/plugins/variadic/tests/erroneous/oracle/printf.res.oracle @@ -12,7 +12,7 @@ Declaration of variadic function sprintf. [variadic] FRAMAC_SHARE/libc/stdio.h:217: Declaration of variadic function sscanf. -[variadic] FRAMAC_SHARE/libc/stdio.h:521: +[variadic] FRAMAC_SHARE/libc/stdio.h:538: Declaration of variadic function dprintf. [variadic] tests/erroneous/printf.c:8: Warning: Multiple usage of flag '-'. [variadic] tests/erroneous/printf.c:8: Warning: diff --git a/src/plugins/variadic/tests/known/oracle/printf.res.oracle b/src/plugins/variadic/tests/known/oracle/printf.res.oracle index f04b44a2b44..d7102dda0aa 100644 --- a/src/plugins/variadic/tests/known/oracle/printf.res.oracle +++ b/src/plugins/variadic/tests/known/oracle/printf.res.oracle @@ -24,7 +24,7 @@ Declaration of variadic function sprintf. [variadic] FRAMAC_SHARE/libc/stdio.h:217: Declaration of variadic function sscanf. -[variadic] FRAMAC_SHARE/libc/stdio.h:521: +[variadic] FRAMAC_SHARE/libc/stdio.h:538: Declaration of variadic function dprintf. [variadic] tests/known/printf.c:37: Translating call to printf to a call to the specialized version printf_va_1. diff --git a/src/plugins/variadic/tests/known/oracle/printf_garbled_mix.res.oracle b/src/plugins/variadic/tests/known/oracle/printf_garbled_mix.res.oracle index 545c7824113..e7591173023 100644 --- a/src/plugins/variadic/tests/known/oracle/printf_garbled_mix.res.oracle +++ b/src/plugins/variadic/tests/known/oracle/printf_garbled_mix.res.oracle @@ -12,7 +12,7 @@ Declaration of variadic function sprintf. [variadic] FRAMAC_SHARE/libc/stdio.h:217: Declaration of variadic function sscanf. -[variadic] FRAMAC_SHARE/libc/stdio.h:521: +[variadic] FRAMAC_SHARE/libc/stdio.h:538: Declaration of variadic function dprintf. [variadic] tests/known/printf_garbled_mix.c:8: Variadic builtin Frama_C_show_each_nb_printed left untransformed. diff --git a/src/plugins/variadic/tests/known/oracle/printf_wrong_arity.res.oracle b/src/plugins/variadic/tests/known/oracle/printf_wrong_arity.res.oracle index d7f8115fec3..4ee27be4661 100644 --- a/src/plugins/variadic/tests/known/oracle/printf_wrong_arity.res.oracle +++ b/src/plugins/variadic/tests/known/oracle/printf_wrong_arity.res.oracle @@ -12,7 +12,7 @@ Declaration of variadic function sprintf. [variadic] FRAMAC_SHARE/libc/stdio.h:217: Declaration of variadic function sscanf. -[variadic] FRAMAC_SHARE/libc/stdio.h:521: +[variadic] FRAMAC_SHARE/libc/stdio.h:538: Declaration of variadic function dprintf. [variadic] tests/known/printf_wrong_arity.c:8: Translating call to printf to a call to the specialized version printf_va_1. diff --git a/src/plugins/variadic/tests/known/oracle/printf_wrong_pointers.res.oracle b/src/plugins/variadic/tests/known/oracle/printf_wrong_pointers.res.oracle index 48af02448ee..2c72bbbab04 100644 --- a/src/plugins/variadic/tests/known/oracle/printf_wrong_pointers.res.oracle +++ b/src/plugins/variadic/tests/known/oracle/printf_wrong_pointers.res.oracle @@ -12,7 +12,7 @@ Declaration of variadic function sprintf. [variadic] FRAMAC_SHARE/libc/stdio.h:217: Declaration of variadic function sscanf. -[variadic] FRAMAC_SHARE/libc/stdio.h:521: +[variadic] FRAMAC_SHARE/libc/stdio.h:538: Declaration of variadic function dprintf. [variadic] tests/known/printf_wrong_pointers.c:14: Translating call to printf to a call to the specialized version printf_va_1. diff --git a/src/plugins/variadic/tests/known/oracle/printf_wrong_types.res.oracle b/src/plugins/variadic/tests/known/oracle/printf_wrong_types.res.oracle index b720645e934..5d41306e7d7 100644 --- a/src/plugins/variadic/tests/known/oracle/printf_wrong_types.res.oracle +++ b/src/plugins/variadic/tests/known/oracle/printf_wrong_types.res.oracle @@ -12,7 +12,7 @@ Declaration of variadic function sprintf. [variadic] FRAMAC_SHARE/libc/stdio.h:217: Declaration of variadic function sscanf. -[variadic] FRAMAC_SHARE/libc/stdio.h:521: +[variadic] FRAMAC_SHARE/libc/stdio.h:538: Declaration of variadic function dprintf. [variadic] tests/known/printf_wrong_types.c:18: Translating call to printf to a call to the specialized version printf_va_1. @@ -424,7 +424,7 @@ int main(void) Declaration of variadic function sprintf. [variadic] FRAMAC_SHARE/libc/stdio.h:217: Declaration of variadic function sscanf. -[variadic] FRAMAC_SHARE/libc/stdio.h:521: +[variadic] FRAMAC_SHARE/libc/stdio.h:538: Declaration of variadic function dprintf. [variadic] tests/known/printf_wrong_types.c:18: Translating call to printf to a call to the specialized version printf_va_1. diff --git a/src/plugins/variadic/tests/known/oracle/scanf.res.oracle b/src/plugins/variadic/tests/known/oracle/scanf.res.oracle index cd8ae9652f3..bf4a9d81548 100644 --- a/src/plugins/variadic/tests/known/oracle/scanf.res.oracle +++ b/src/plugins/variadic/tests/known/oracle/scanf.res.oracle @@ -12,7 +12,7 @@ Declaration of variadic function sprintf. [variadic] FRAMAC_SHARE/libc/stdio.h:217: Declaration of variadic function sscanf. -[variadic] FRAMAC_SHARE/libc/stdio.h:521: +[variadic] FRAMAC_SHARE/libc/stdio.h:538: Declaration of variadic function dprintf. [variadic] tests/known/scanf.c:7: Translating call to scanf to a call to the specialized version scanf_va_1. diff --git a/src/plugins/variadic/tests/known/oracle/scanf_loop.res.oracle b/src/plugins/variadic/tests/known/oracle/scanf_loop.res.oracle index db959e60948..e563ba2f274 100644 --- a/src/plugins/variadic/tests/known/oracle/scanf_loop.res.oracle +++ b/src/plugins/variadic/tests/known/oracle/scanf_loop.res.oracle @@ -12,7 +12,7 @@ Declaration of variadic function sprintf. [variadic] FRAMAC_SHARE/libc/stdio.h:217: Declaration of variadic function sscanf. -[variadic] FRAMAC_SHARE/libc/stdio.h:521: +[variadic] FRAMAC_SHARE/libc/stdio.h:538: Declaration of variadic function dprintf. [variadic] tests/known/scanf_loop.c:6: Translating call to scanf to a call to the specialized version scanf_va_1. diff --git a/src/plugins/variadic/tests/known/oracle/scanf_wrong.res.oracle b/src/plugins/variadic/tests/known/oracle/scanf_wrong.res.oracle index b468aea8aca..704b3de7532 100644 --- a/src/plugins/variadic/tests/known/oracle/scanf_wrong.res.oracle +++ b/src/plugins/variadic/tests/known/oracle/scanf_wrong.res.oracle @@ -12,7 +12,7 @@ Declaration of variadic function sprintf. [variadic] FRAMAC_SHARE/libc/stdio.h:217: Declaration of variadic function sscanf. -[variadic] FRAMAC_SHARE/libc/stdio.h:521: +[variadic] FRAMAC_SHARE/libc/stdio.h:538: Declaration of variadic function dprintf. [variadic] tests/known/scanf_wrong.c:8: Translating call to scanf to a call to the specialized version scanf_va_1. diff --git a/src/plugins/variadic/tests/known/oracle/snprintf.res.oracle b/src/plugins/variadic/tests/known/oracle/snprintf.res.oracle index 2b2dd3e7684..cecc5cc5431 100644 --- a/src/plugins/variadic/tests/known/oracle/snprintf.res.oracle +++ b/src/plugins/variadic/tests/known/oracle/snprintf.res.oracle @@ -12,7 +12,7 @@ Declaration of variadic function sprintf. [variadic] FRAMAC_SHARE/libc/stdio.h:217: Declaration of variadic function sscanf. -[variadic] FRAMAC_SHARE/libc/stdio.h:521: +[variadic] FRAMAC_SHARE/libc/stdio.h:538: Declaration of variadic function dprintf. [variadic] tests/known/snprintf.c:12: Translating call to snprintf to a call to the specialized version snprintf_va_1. diff --git a/src/plugins/variadic/tests/known/oracle/stdio_print.res.oracle b/src/plugins/variadic/tests/known/oracle/stdio_print.res.oracle index 0cacefc0330..cc3c40be6d6 100644 --- a/src/plugins/variadic/tests/known/oracle/stdio_print.res.oracle +++ b/src/plugins/variadic/tests/known/oracle/stdio_print.res.oracle @@ -12,7 +12,7 @@ Declaration of variadic function sprintf. [variadic] FRAMAC_SHARE/libc/stdio.h:217: Declaration of variadic function sscanf. -[variadic] FRAMAC_SHARE/libc/stdio.h:521: +[variadic] FRAMAC_SHARE/libc/stdio.h:538: Declaration of variadic function dprintf. [variadic] tests/known/stdio_print.c:9: Warning: Call to function fprintf with non-static format argument: diff --git a/src/plugins/variadic/tests/known/oracle/stdio_scan.res.oracle b/src/plugins/variadic/tests/known/oracle/stdio_scan.res.oracle index 671f5bf3f35..f157c9d36bf 100644 --- a/src/plugins/variadic/tests/known/oracle/stdio_scan.res.oracle +++ b/src/plugins/variadic/tests/known/oracle/stdio_scan.res.oracle @@ -12,7 +12,7 @@ Declaration of variadic function sprintf. [variadic] FRAMAC_SHARE/libc/stdio.h:217: Declaration of variadic function sscanf. -[variadic] FRAMAC_SHARE/libc/stdio.h:521: +[variadic] FRAMAC_SHARE/libc/stdio.h:538: Declaration of variadic function dprintf. [variadic] tests/known/stdio_scan.c:10: Warning: Call to function fscanf with non-static format argument: diff --git a/src/plugins/variadic/tests/known/oracle/swprintf.res.oracle b/src/plugins/variadic/tests/known/oracle/swprintf.res.oracle index 79025ff0d26..585983473b2 100644 --- a/src/plugins/variadic/tests/known/oracle/swprintf.res.oracle +++ b/src/plugins/variadic/tests/known/oracle/swprintf.res.oracle @@ -24,7 +24,7 @@ Declaration of variadic function sprintf. [variadic] FRAMAC_SHARE/libc/stdio.h:217: Declaration of variadic function sscanf. -[variadic] FRAMAC_SHARE/libc/stdio.h:521: +[variadic] FRAMAC_SHARE/libc/stdio.h:538: Declaration of variadic function dprintf. [variadic] tests/known/swprintf.c:12: Translating call to swprintf to a call to the specialized version swprintf_va_1. diff --git a/src/plugins/variadic/tests/known/oracle/wchar.res.oracle b/src/plugins/variadic/tests/known/oracle/wchar.res.oracle index 0e93065e23f..b85bb1c1d06 100644 --- a/src/plugins/variadic/tests/known/oracle/wchar.res.oracle +++ b/src/plugins/variadic/tests/known/oracle/wchar.res.oracle @@ -24,7 +24,7 @@ Declaration of variadic function sprintf. [variadic] FRAMAC_SHARE/libc/stdio.h:217: Declaration of variadic function sscanf. -[variadic] FRAMAC_SHARE/libc/stdio.h:521: +[variadic] FRAMAC_SHARE/libc/stdio.h:538: Declaration of variadic function dprintf. [variadic] tests/known/wchar.c:11: Translating call to wprintf to a call to the specialized version wprintf_va_1. diff --git a/tests/idct/oracle/ieee_1180_1990.res.oracle b/tests/idct/oracle/ieee_1180_1990.res.oracle index 73d8292ef2d..6019d52b697 100644 --- a/tests/idct/oracle/ieee_1180_1990.res.oracle +++ b/tests/idct/oracle/ieee_1180_1990.res.oracle @@ -1938,14 +1938,39 @@ default behavior by Frama-C kernel. +-------------------------------------------------------------------------------- +--- Properties of Function 'fseeko' +-------------------------------------------------------------------------------- + +[ Extern ] Assigns (file share/libc/stdio.h, line 395) + assigns *stream, \result, __fc_errno; + Unverifiable but considered Valid. +[ Extern ] Froms (file share/libc/stdio.h, line 395) + assigns *stream + \from *stream, (indirect: offset), (indirect: whence); + Unverifiable but considered Valid. +[ Extern ] Froms (file share/libc/stdio.h, line 396) + assigns \result + \from (indirect: *stream), (indirect: offset), + (indirect: whence); + Unverifiable but considered Valid. +[ Extern ] Froms (file share/libc/stdio.h, line 396) + assigns __fc_errno + \from (indirect: *stream), (indirect: offset), + (indirect: whence); + Unverifiable but considered Valid. +[ Valid ] Default behavior + default behavior + by Frama-C kernel. + -------------------------------------------------------------------------------- --- Properties of Function 'fsetpos' -------------------------------------------------------------------------------- -[ Extern ] Assigns (file share/libc/stdio.h, line 396) +[ Extern ] Assigns (file share/libc/stdio.h, line 405) assigns *stream; Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/stdio.h, line 396) +[ Extern ] Froms (file share/libc/stdio.h, line 405) assigns *stream \from *pos; Unverifiable but considered Valid. [ Valid ] Default behavior @@ -1962,13 +1987,36 @@ \result ≡ -1 ∨ (\result ≥ 0 ∧ __fc_errno ≡ \old(__fc_errno)) Unverifiable but considered Valid. -[ Extern ] Assigns (file share/libc/stdio.h, line 402) +[ Extern ] Assigns (file share/libc/stdio.h, line 411) assigns \result, __fc_errno; Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/stdio.h, line 402) +[ Extern ] Froms (file share/libc/stdio.h, line 411) assigns \result \from (indirect: *stream); Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/stdio.h, line 402) +[ Extern ] Froms (file share/libc/stdio.h, line 411) + assigns __fc_errno \from (indirect: *stream); + Unverifiable but considered Valid. +[ Valid ] Default behavior + default behavior + by Frama-C kernel. + +-------------------------------------------------------------------------------- +--- Properties of Function 'ftello' +-------------------------------------------------------------------------------- + +[ Extern ] Post-condition 'success_or_error' + ensures + success_or_error: + \result ≡ -1 ∨ + (\result ≥ 0 ∧ __fc_errno ≡ \old(__fc_errno)) + Unverifiable but considered Valid. +[ Extern ] Assigns (file share/libc/stdio.h, line 419) + assigns \result, __fc_errno; + Unverifiable but considered Valid. +[ Extern ] Froms (file share/libc/stdio.h, line 419) + assigns \result \from (indirect: *stream); + Unverifiable but considered Valid. +[ Extern ] Froms (file share/libc/stdio.h, line 419) assigns __fc_errno \from (indirect: *stream); Unverifiable but considered Valid. [ Valid ] Default behavior @@ -1979,10 +2027,10 @@ --- Properties of Function 'rewind' -------------------------------------------------------------------------------- -[ Extern ] Assigns (file share/libc/stdio.h, line 410) +[ Extern ] Assigns (file share/libc/stdio.h, line 427) assigns *stream; Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/stdio.h, line 410) +[ Extern ] Froms (file share/libc/stdio.h, line 427) assigns *stream \from \nothing; Unverifiable but considered Valid. [ Valid ] Default behavior @@ -1993,10 +2041,10 @@ --- Properties of Function 'clearerr' -------------------------------------------------------------------------------- -[ Extern ] Assigns (file share/libc/stdio.h, line 416) +[ Extern ] Assigns (file share/libc/stdio.h, line 433) assigns *stream; Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/stdio.h, line 416) +[ Extern ] Froms (file share/libc/stdio.h, line 433) assigns *stream \from \nothing; Unverifiable but considered Valid. [ Valid ] Default behavior @@ -2010,7 +2058,7 @@ [ Extern ] Assigns nothing assigns \nothing; Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/stdio.h, line 422) +[ Extern ] Froms (file share/libc/stdio.h, line 439) assigns \result \from (indirect: *stream); Unverifiable but considered Valid. [ Valid ] Default behavior @@ -2024,7 +2072,7 @@ [ Extern ] Assigns nothing assigns \nothing; Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/stdio.h, line 428) +[ Extern ] Froms (file share/libc/stdio.h, line 445) assigns \result \from (indirect: *stream); Unverifiable but considered Valid. [ Valid ] Default behavior @@ -2035,10 +2083,10 @@ --- Properties of Function 'flockfile' -------------------------------------------------------------------------------- -[ Extern ] Assigns (file share/libc/stdio.h, line 434) +[ Extern ] Assigns (file share/libc/stdio.h, line 451) assigns *stream; Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/stdio.h, line 434) +[ Extern ] Froms (file share/libc/stdio.h, line 451) assigns *stream \from \nothing; Unverifiable but considered Valid. [ Valid ] Default behavior @@ -2049,10 +2097,10 @@ --- Properties of Function 'funlockfile' -------------------------------------------------------------------------------- -[ Extern ] Assigns (file share/libc/stdio.h, line 440) +[ Extern ] Assigns (file share/libc/stdio.h, line 457) assigns *stream; Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/stdio.h, line 440) +[ Extern ] Froms (file share/libc/stdio.h, line 457) assigns *stream \from \nothing; Unverifiable but considered Valid. [ Valid ] Default behavior @@ -2063,13 +2111,13 @@ --- Properties of Function 'ftrylockfile' -------------------------------------------------------------------------------- -[ Extern ] Assigns (file share/libc/stdio.h, line 446) +[ Extern ] Assigns (file share/libc/stdio.h, line 463) assigns \result, *stream; Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/stdio.h, line 446) +[ Extern ] Froms (file share/libc/stdio.h, line 463) assigns \result \from \nothing; Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/stdio.h, line 446) +[ Extern ] Froms (file share/libc/stdio.h, line 463) assigns *stream \from \nothing; Unverifiable but considered Valid. [ Valid ] Default behavior @@ -2083,7 +2131,7 @@ [ Extern ] Assigns nothing assigns \nothing; Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/stdio.h, line 452) +[ Extern ] Froms (file share/libc/stdio.h, line 469) assigns \result \from (indirect: *stream); Unverifiable but considered Valid. [ Valid ] Default behavior @@ -2094,10 +2142,10 @@ --- Properties of Function 'perror' -------------------------------------------------------------------------------- -[ Extern ] Assigns (file share/libc/stdio.h, line 458) +[ Extern ] Assigns (file share/libc/stdio.h, line 475) assigns __fc_stdout; Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/stdio.h, line 458) +[ Extern ] Froms (file share/libc/stdio.h, line 475) assigns __fc_stdout \from __fc_errno, *(s + (0 .. strlen{Old}(s))); Unverifiable but considered Valid. @@ -2109,13 +2157,13 @@ --- Properties of Function 'getc_unlocked' -------------------------------------------------------------------------------- -[ Extern ] Assigns (file share/libc/stdio.h, line 464) +[ Extern ] Assigns (file share/libc/stdio.h, line 481) assigns \result, *stream; Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/stdio.h, line 464) +[ Extern ] Froms (file share/libc/stdio.h, line 481) assigns \result \from *stream; Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/stdio.h, line 464) +[ Extern ] Froms (file share/libc/stdio.h, line 481) assigns *stream \from *stream; Unverifiable but considered Valid. [ Valid ] Default behavior @@ -2129,7 +2177,7 @@ [ Extern ] Assigns nothing assigns \nothing; Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/stdio.h, line 469) +[ Extern ] Froms (file share/libc/stdio.h, line 486) assigns \result \from *__fc_stdin; Unverifiable but considered Valid. [ Valid ] Default behavior @@ -2140,13 +2188,13 @@ --- Properties of Function 'putc_unlocked' -------------------------------------------------------------------------------- -[ Extern ] Assigns (file share/libc/stdio.h, line 475) +[ Extern ] Assigns (file share/libc/stdio.h, line 492) assigns *stream, \result; Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/stdio.h, line 475) +[ Extern ] Froms (file share/libc/stdio.h, line 492) assigns *stream \from c; Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/stdio.h, line 476) +[ Extern ] Froms (file share/libc/stdio.h, line 493) assigns \result \from (indirect: *stream); Unverifiable but considered Valid. [ Valid ] Default behavior @@ -2157,13 +2205,13 @@ --- Properties of Function 'putchar_unlocked' -------------------------------------------------------------------------------- -[ Extern ] Assigns (file share/libc/stdio.h, line 481) +[ Extern ] Assigns (file share/libc/stdio.h, line 498) assigns *__fc_stdout, \result; Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/stdio.h, line 481) +[ Extern ] Froms (file share/libc/stdio.h, line 498) assigns *__fc_stdout \from c; Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/stdio.h, line 482) +[ Extern ] Froms (file share/libc/stdio.h, line 499) assigns \result \from (indirect: *__fc_stdout); Unverifiable but considered Valid. [ Valid ] Default behavior @@ -2174,10 +2222,10 @@ --- Properties of Function 'clearerr_unlocked' -------------------------------------------------------------------------------- -[ Extern ] Assigns (file share/libc/stdio.h, line 488) +[ Extern ] Assigns (file share/libc/stdio.h, line 505) assigns *stream; Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/stdio.h, line 488) +[ Extern ] Froms (file share/libc/stdio.h, line 505) assigns *stream \from \nothing; Unverifiable but considered Valid. [ Valid ] Default behavior @@ -2191,7 +2239,7 @@ [ Extern ] Assigns nothing assigns \nothing; Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/stdio.h, line 494) +[ Extern ] Froms (file share/libc/stdio.h, line 511) assigns \result \from (indirect: *stream); Unverifiable but considered Valid. [ Valid ] Default behavior @@ -2205,7 +2253,7 @@ [ Extern ] Assigns nothing assigns \nothing; Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/stdio.h, line 500) +[ Extern ] Froms (file share/libc/stdio.h, line 517) assigns \result \from (indirect: *stream); Unverifiable but considered Valid. [ Valid ] Default behavior @@ -2219,7 +2267,7 @@ [ Extern ] Assigns nothing assigns \nothing; Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/stdio.h, line 506) +[ Extern ] Froms (file share/libc/stdio.h, line 523) assigns \result \from (indirect: *stream); Unverifiable but considered Valid. [ Valid ] Default behavior @@ -2237,14 +2285,14 @@ (\subset(\result, &__fc_fopen[0 .. 16 - 1]) ∧ is_open_pipe(\result)) Unverifiable but considered Valid. -[ Extern ] Assigns (file share/libc/stdio.h, line 533) +[ Extern ] Assigns (file share/libc/stdio.h, line 550) assigns \result, __fc_fopen[0 ..]; Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/stdio.h, line 533) +[ Extern ] Froms (file share/libc/stdio.h, line 550) assigns \result \from (indirect: *command), (indirect: *type), __fc_p_fopen; Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/stdio.h, line 535) +[ Extern ] Froms (file share/libc/stdio.h, line 552) assigns __fc_fopen[0 ..] \from (indirect: *command), (indirect: *type), __fc_fopen[0 ..]; Unverifiable but considered Valid. @@ -2262,7 +2310,7 @@ [ Extern ] Assigns nothing assigns \nothing; Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/stdio.h, line 547) +[ Extern ] Froms (file share/libc/stdio.h, line 564) assigns \result \from (indirect: *stream); Unverifiable but considered Valid. [ Valid ] Default behavior @@ -4058,9 +4106,9 @@ -------------------------------------------------------------------------------- --- Status Report Summary -------------------------------------------------------------------------------- - 179 Completely validated + 181 Completely validated 16 Locally validated - 486 Considered valid + 494 Considered valid 56 To be validated - 737 Total + 747 Total -------------------------------------------------------------------------------- diff --git a/tests/libc/oracle/fc_libc.0.res.oracle b/tests/libc/oracle/fc_libc.0.res.oracle index 413b1aee0f0..f0d8a56d9da 100644 --- a/tests/libc/oracle/fc_libc.0.res.oracle +++ b/tests/libc/oracle/fc_libc.0.res.oracle @@ -40,7 +40,7 @@ unsetenv (0 call); wcscat (0 call); wcscpy (0 call); wcslen (2 calls); wcsncat (0 call); wcsncpy (0 call); wmemcpy (0 call); wmemset (0 call); - Undefined functions (395) + Undefined functions (397) ========================= FD_CLR (0 call); FD_ISSET (0 call); FD_SET (0 call); FD_ZERO (0 call); Frama_C_int_interval (0 call); Frama_C_long_interval (0 call); @@ -91,9 +91,9 @@ flockfile (0 call); floor (0 call); floorf (0 call); floorl (0 call); fmod (0 call); fmodf (0 call); fopen (0 call); fork (0 call); fputc (0 call); fputs (0 call); fread (0 call); free (1 call); - freeaddrinfo (0 call); freopen (0 call); fseek (0 call); fsetpos (0 call); - ftell (0 call); ftrylockfile (0 call); funlockfile (0 call); - fwrite (0 call); gai_strerror (0 call); getc (0 call); + freeaddrinfo (0 call); freopen (0 call); fseek (0 call); fseeko (0 call); + fsetpos (0 call); ftell (0 call); ftello (0 call); ftrylockfile (0 call); + funlockfile (0 call); fwrite (0 call); gai_strerror (0 call); getc (0 call); getc_unlocked (0 call); getchar (0 call); getchar_unlocked (0 call); getcwd (0 call); getegid (0 call); geteuid (0 call); getgid (0 call); gethostname (0 call); getitimer (0 call); getopt (0 call); @@ -181,7 +181,7 @@ Goto = 89 Assignment = 438 Exit point = 82 - Function = 477 + Function = 479 Function call = 89 Pointer dereferencing = 158 Cyclomatic complexity = 286 diff --git a/tests/libc/oracle/fc_libc.1.res.oracle b/tests/libc/oracle/fc_libc.1.res.oracle index 34abdcbb6ed..c4e0a539a60 100644 --- a/tests/libc/oracle/fc_libc.1.res.oracle +++ b/tests/libc/oracle/fc_libc.1.res.oracle @@ -4811,6 +4811,17 @@ extern int fgetpos(FILE * __restrict stream, fpos_t * __restrict pos); */ extern int fseek(FILE *stream, long offset, int whence); +/*@ requires valid_stream: \valid(stream); + requires whence_enum: whence ≡ 0 ∨ whence ≡ 1 ∨ whence ≡ 2; + assigns *stream, \result, __fc_errno; + assigns *stream \from *stream, (indirect: offset), (indirect: whence); + assigns \result + \from (indirect: *stream), (indirect: offset), (indirect: whence); + assigns __fc_errno + \from (indirect: *stream), (indirect: offset), (indirect: whence); + */ +extern int fseeko(FILE *stream, off_t offset, int whence); + /*@ requires valid_stream: \valid(stream); requires valid_pos: \valid_read(pos); requires initialization: pos: \initialized(pos); @@ -4830,6 +4841,17 @@ extern int fsetpos(FILE *stream, fpos_t const *pos); */ extern long ftell(FILE *stream); +/*@ requires valid_stream: \valid(stream); + ensures + success_or_error: + \result ≡ -1 ∨ + (\result ≥ 0 ∧ __fc_errno ≡ \old(__fc_errno)); + assigns \result, __fc_errno; + assigns \result \from (indirect: *stream); + assigns __fc_errno \from (indirect: *stream); + */ +extern off_t ftello(FILE *stream); + /*@ requires valid_stream: \valid(stream); assigns *stream; assigns *stream \from \nothing; diff --git a/tests/libc/oracle/stdio_h.res.oracle b/tests/libc/oracle/stdio_h.res.oracle index 8262aa6c408..e839ecd549f 100644 --- a/tests/libc/oracle/stdio_h.res.oracle +++ b/tests/libc/oracle/stdio_h.res.oracle @@ -51,47 +51,67 @@ [eva] tests/libc/stdio_h.c:25: function fseek: precondition 'whence_enum' got status valid. [eva] Done for function fseek -[eva] computing for function fclose <- main. +[eva] computing for function fseeko <- main. Called from tests/libc/stdio_h.c:26. -[eva] using specification for function fclose +[eva] using specification for function fseeko +[eva] tests/libc/stdio_h.c:26: + function fseeko: precondition 'valid_stream' got status valid. [eva] tests/libc/stdio_h.c:26: + function fseeko: precondition 'whence_enum' got status valid. +[eva] Done for function fseeko +[eva] computing for function ftell <- main. + Called from tests/libc/stdio_h.c:27. +[eva] using specification for function ftell +[eva] tests/libc/stdio_h.c:27: + function ftell: precondition 'valid_stream' got status valid. +[eva] Done for function ftell +[eva] computing for function ftello <- main. + Called from tests/libc/stdio_h.c:28. +[eva] using specification for function ftello +[eva] tests/libc/stdio_h.c:28: + function ftello: precondition 'valid_stream' got status valid. +[eva] Done for function ftello +[eva] computing for function fclose <- main. + Called from tests/libc/stdio_h.c:29. +[eva] using specification for function fclose +[eva] tests/libc/stdio_h.c:29: function fclose: precondition 'valid_stream' got status valid. [eva] Done for function fclose [eva] computing for function freopen <- main. - Called from tests/libc/stdio_h.c:28. + Called from tests/libc/stdio_h.c:31. [eva] using specification for function freopen -[eva] tests/libc/stdio_h.c:28: +[eva] tests/libc/stdio_h.c:31: function freopen: precondition 'valid_filename' got status valid. -[eva] tests/libc/stdio_h.c:28: +[eva] tests/libc/stdio_h.c:31: function freopen: precondition 'valid_mode' got status valid. -[eva:alarm] tests/libc/stdio_h.c:28: Warning: +[eva:alarm] tests/libc/stdio_h.c:31: Warning: function freopen: precondition 'valid_stream' got status unknown. [eva] Done for function freopen [eva] computing for function printf_va_1 <- main. - Called from tests/libc/stdio_h.c:30. + Called from tests/libc/stdio_h.c:33. [eva] using specification for function printf_va_1 -[eva] tests/libc/stdio_h.c:30: +[eva] tests/libc/stdio_h.c:33: function printf_va_1: precondition got status valid. [eva] Done for function printf_va_1 [eva] computing for function fclose <- main. - Called from tests/libc/stdio_h.c:31. -[eva] tests/libc/stdio_h.c:31: + Called from tests/libc/stdio_h.c:34. +[eva] tests/libc/stdio_h.c:34: function fclose: precondition 'valid_stream' got status valid. [eva] Done for function fclose [eva] computing for function fgets <- main. - Called from tests/libc/stdio_h.c:34. + Called from tests/libc/stdio_h.c:37. [eva] using specification for function fgets -[eva] tests/libc/stdio_h.c:34: +[eva] tests/libc/stdio_h.c:37: function fgets: precondition 'valid_stream' got status valid. -[eva] tests/libc/stdio_h.c:34: +[eva] tests/libc/stdio_h.c:37: function fgets: precondition 'room_s' got status valid. [eva] Done for function fgets -[eva:alarm] tests/libc/stdio_h.c:36: Warning: check got status unknown. +[eva:alarm] tests/libc/stdio_h.c:39: Warning: check got status unknown. [eva] computing for function fgets <- main. - Called from tests/libc/stdio_h.c:38. -[eva] tests/libc/stdio_h.c:38: + Called from tests/libc/stdio_h.c:41. +[eva] tests/libc/stdio_h.c:41: function fgets: precondition 'valid_stream' got status valid. -[eva:alarm] tests/libc/stdio_h.c:38: Warning: +[eva:alarm] tests/libc/stdio_h.c:41: Warning: function fgets: precondition 'room_s' got status invalid. [eva] Done for function fgets [eva] Recording results for main @@ -104,6 +124,8 @@ f ∈ {{ NULL ; &__fc_fopen + [0..120],0%8 }} r ∈ [--..--] tmp_2 ∈ {{ NULL ; &__fc_fopen + [0..120],0%8 }} + told ∈ [-1..2147483647] + toldo ∈ [-1..2147483647] redirected ∈ {{ NULL ; &__fc_fopen + [0..120],0%8 }} fgets_buf0[0] ∈ [--..--] or UNINITIALIZED fgets_res ∈ {{ NULL ; &fgets_buf0[0] }} diff --git a/tests/libc/stdio_h.c b/tests/libc/stdio_h.c index a1d6f3fa161..1150500b6cb 100644 --- a/tests/libc/stdio_h.c +++ b/tests/libc/stdio_h.c @@ -23,6 +23,9 @@ int main() { FILE *tmp = tmpfile(); if (!tmp) return 2; fseek(tmp, 0L, SEEK_SET); + fseeko(tmp, 0, SEEK_SET); + long told = ftell(tmp); + off_t toldo = ftello(tmp); fclose(tmp); FILE *redirected = freopen("/tmp/mytmp.txt", "w+", stdout); diff --git a/tests/metrics/oracle/libc.1.res.oracle b/tests/metrics/oracle/libc.1.res.oracle index 24cfd8d35b1..b00598fd71a 100644 --- a/tests/metrics/oracle/libc.1.res.oracle +++ b/tests/metrics/oracle/libc.1.res.oracle @@ -4,7 +4,7 @@ bar (1 call); f (0 call); foo (1 call); g (address taken) (0 call); getopt (1 call); main (0 call); - Undefined functions (120) + Undefined functions (122) ========================= _exit (0 call); access (0 call); chdir (0 call); chown (0 call); chroot (0 call); clearerr (0 call); clearerr_unlocked (0 call); @@ -15,20 +15,20 @@ fflush (0 call); fgetc (0 call); fgetpos (0 call); fgets (0 call); fileno (0 call); fileno_unlocked (0 call); flockfile (0 call); fopen (0 call); fork (0 call); fputc (0 call); fputs (0 call); - fread (0 call); freopen (0 call); fseek (0 call); fsetpos (0 call); - ftell (0 call); ftrylockfile (0 call); funlockfile (0 call); - fwrite (0 call); getc (0 call); getc_unlocked (0 call); getchar (1 call); - getchar_unlocked (0 call); getcwd (0 call); getegid (0 call); - geteuid (0 call); getgid (0 call); gethostname (0 call); - getopt_long (0 call); getopt_long_only (0 call); getpgid (0 call); - getpgrp (0 call); getpid (0 call); getppid (0 call); getresgid (0 call); - getresuid (0 call); gets (0 call); getsid (0 call); getuid (0 call); - isalnum (0 call); isalpha (1 call); isascii (0 call); isatty (0 call); - isblank (1 call); iscntrl (0 call); isdigit (0 call); isgraph (0 call); - islower (0 call); isprint (0 call); ispunct (0 call); isspace (0 call); - isupper (0 call); isxdigit (0 call); lseek (0 call); pathconf (0 call); - pclose (0 call); perror (0 call); pipe (0 call); popen (0 call); - putc (0 call); putc_unlocked (0 call); putchar (0 call); + fread (0 call); freopen (0 call); fseek (0 call); fseeko (0 call); + fsetpos (0 call); ftell (0 call); ftello (0 call); ftrylockfile (0 call); + funlockfile (0 call); fwrite (0 call); getc (0 call); + getc_unlocked (0 call); getchar (1 call); getchar_unlocked (0 call); + getcwd (0 call); getegid (0 call); geteuid (0 call); getgid (0 call); + gethostname (0 call); getopt_long (0 call); getopt_long_only (0 call); + getpgid (0 call); getpgrp (0 call); getpid (0 call); getppid (0 call); + getresgid (0 call); getresuid (0 call); gets (0 call); getsid (0 call); + getuid (0 call); isalnum (0 call); isalpha (1 call); isascii (0 call); + isatty (0 call); isblank (1 call); iscntrl (0 call); isdigit (0 call); + isgraph (0 call); islower (0 call); isprint (0 call); ispunct (0 call); + isspace (0 call); isupper (0 call); isxdigit (0 call); lseek (0 call); + pathconf (0 call); pclose (0 call); perror (0 call); pipe (0 call); + popen (0 call); putc (0 call); putc_unlocked (0 call); putchar (0 call); putchar_unlocked (0 call); puts (0 call); read (0 call); remove (0 call); rename (0 call); rewind (0 call); setbuf (0 call); setegid (0 call); seteuid (0 call); setgid (0 call); sethostname (0 call); setpgid (0 call); @@ -59,7 +59,7 @@ Goto = 0 Assignment = 8 Exit point = 6 - Function = 126 + Function = 128 Function call = 7 Pointer dereferencing = 1 Cyclomatic complexity = 6 @@ -87,7 +87,7 @@ ---------------------------------------------------------------------------- [metrics] Eva coverage statistics ======================= - Syntactically reachable functions = 7 (out of 126) + Syntactically reachable functions = 7 (out of 128) Semantically reached functions = 7 Coverage estimation = 100.0% [metrics] References to non-analyzed functions diff --git a/tests/rte/oracle/value_rte.res.oracle b/tests/rte/oracle/value_rte.res.oracle index 2cf4947a7f1..1fa05cbf8c6 100644 --- a/tests/rte/oracle/value_rte.res.oracle +++ b/tests/rte/oracle/value_rte.res.oracle @@ -603,13 +603,28 @@ by Frama-C kernel. -------------------------------------------------------------------------------- ---- Properties of Function 'fsetpos' +--- Properties of Function 'fseeko' -------------------------------------------------------------------------------- -[ Extern ] Assigns (file share/libc/stdio.h, line 396) +[ Extern ] Assigns (file share/libc/stdio.h, line 395) + Unverifiable but considered Valid. +[ Extern ] Froms (file share/libc/stdio.h, line 395) Unverifiable but considered Valid. [ Extern ] Froms (file share/libc/stdio.h, line 396) Unverifiable but considered Valid. +[ Extern ] Froms (file share/libc/stdio.h, line 396) + Unverifiable but considered Valid. +[ Valid ] Default behavior + by Frama-C kernel. + +-------------------------------------------------------------------------------- +--- Properties of Function 'fsetpos' +-------------------------------------------------------------------------------- + +[ Extern ] Assigns (file share/libc/stdio.h, line 405) + Unverifiable but considered Valid. +[ Extern ] Froms (file share/libc/stdio.h, line 405) + Unverifiable but considered Valid. [ Valid ] Default behavior by Frama-C kernel. @@ -619,11 +634,26 @@ [ Extern ] Post-condition 'success_or_error' Unverifiable but considered Valid. -[ Extern ] Assigns (file share/libc/stdio.h, line 402) +[ Extern ] Assigns (file share/libc/stdio.h, line 411) Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/stdio.h, line 402) +[ Extern ] Froms (file share/libc/stdio.h, line 411) Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/stdio.h, line 402) +[ Extern ] Froms (file share/libc/stdio.h, line 411) + Unverifiable but considered Valid. +[ Valid ] Default behavior + by Frama-C kernel. + +-------------------------------------------------------------------------------- +--- Properties of Function 'ftello' +-------------------------------------------------------------------------------- + +[ Extern ] Post-condition 'success_or_error' + Unverifiable but considered Valid. +[ Extern ] Assigns (file share/libc/stdio.h, line 419) + Unverifiable but considered Valid. +[ Extern ] Froms (file share/libc/stdio.h, line 419) + Unverifiable but considered Valid. +[ Extern ] Froms (file share/libc/stdio.h, line 419) Unverifiable but considered Valid. [ Valid ] Default behavior by Frama-C kernel. @@ -632,9 +662,9 @@ --- Properties of Function 'rewind' -------------------------------------------------------------------------------- -[ Extern ] Assigns (file share/libc/stdio.h, line 410) +[ Extern ] Assigns (file share/libc/stdio.h, line 427) Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/stdio.h, line 410) +[ Extern ] Froms (file share/libc/stdio.h, line 427) Unverifiable but considered Valid. [ Valid ] Default behavior by Frama-C kernel. @@ -643,9 +673,9 @@ --- Properties of Function 'clearerr' -------------------------------------------------------------------------------- -[ Extern ] Assigns (file share/libc/stdio.h, line 416) +[ Extern ] Assigns (file share/libc/stdio.h, line 433) Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/stdio.h, line 416) +[ Extern ] Froms (file share/libc/stdio.h, line 433) Unverifiable but considered Valid. [ Valid ] Default behavior by Frama-C kernel. @@ -656,7 +686,7 @@ [ Extern ] Assigns nothing Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/stdio.h, line 422) +[ Extern ] Froms (file share/libc/stdio.h, line 439) Unverifiable but considered Valid. [ Valid ] Default behavior by Frama-C kernel. @@ -667,7 +697,7 @@ [ Extern ] Assigns nothing Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/stdio.h, line 428) +[ Extern ] Froms (file share/libc/stdio.h, line 445) Unverifiable but considered Valid. [ Valid ] Default behavior by Frama-C kernel. @@ -676,9 +706,9 @@ --- Properties of Function 'flockfile' -------------------------------------------------------------------------------- -[ Extern ] Assigns (file share/libc/stdio.h, line 434) +[ Extern ] Assigns (file share/libc/stdio.h, line 451) Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/stdio.h, line 434) +[ Extern ] Froms (file share/libc/stdio.h, line 451) Unverifiable but considered Valid. [ Valid ] Default behavior by Frama-C kernel. @@ -687,9 +717,9 @@ --- Properties of Function 'funlockfile' -------------------------------------------------------------------------------- -[ Extern ] Assigns (file share/libc/stdio.h, line 440) +[ Extern ] Assigns (file share/libc/stdio.h, line 457) Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/stdio.h, line 440) +[ Extern ] Froms (file share/libc/stdio.h, line 457) Unverifiable but considered Valid. [ Valid ] Default behavior by Frama-C kernel. @@ -698,11 +728,11 @@ --- Properties of Function 'ftrylockfile' -------------------------------------------------------------------------------- -[ Extern ] Assigns (file share/libc/stdio.h, line 446) +[ Extern ] Assigns (file share/libc/stdio.h, line 463) Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/stdio.h, line 446) +[ Extern ] Froms (file share/libc/stdio.h, line 463) Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/stdio.h, line 446) +[ Extern ] Froms (file share/libc/stdio.h, line 463) Unverifiable but considered Valid. [ Valid ] Default behavior by Frama-C kernel. @@ -713,7 +743,7 @@ [ Extern ] Assigns nothing Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/stdio.h, line 452) +[ Extern ] Froms (file share/libc/stdio.h, line 469) Unverifiable but considered Valid. [ Valid ] Default behavior by Frama-C kernel. @@ -722,9 +752,9 @@ --- Properties of Function 'perror' -------------------------------------------------------------------------------- -[ Extern ] Assigns (file share/libc/stdio.h, line 458) +[ Extern ] Assigns (file share/libc/stdio.h, line 475) Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/stdio.h, line 458) +[ Extern ] Froms (file share/libc/stdio.h, line 475) Unverifiable but considered Valid. [ Valid ] Default behavior by Frama-C kernel. @@ -733,11 +763,11 @@ --- Properties of Function 'getc_unlocked' -------------------------------------------------------------------------------- -[ Extern ] Assigns (file share/libc/stdio.h, line 464) +[ Extern ] Assigns (file share/libc/stdio.h, line 481) Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/stdio.h, line 464) +[ Extern ] Froms (file share/libc/stdio.h, line 481) Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/stdio.h, line 464) +[ Extern ] Froms (file share/libc/stdio.h, line 481) Unverifiable but considered Valid. [ Valid ] Default behavior by Frama-C kernel. @@ -748,7 +778,7 @@ [ Extern ] Assigns nothing Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/stdio.h, line 469) +[ Extern ] Froms (file share/libc/stdio.h, line 486) Unverifiable but considered Valid. [ Valid ] Default behavior by Frama-C kernel. @@ -757,11 +787,11 @@ --- Properties of Function 'putc_unlocked' -------------------------------------------------------------------------------- -[ Extern ] Assigns (file share/libc/stdio.h, line 475) +[ Extern ] Assigns (file share/libc/stdio.h, line 492) Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/stdio.h, line 475) +[ Extern ] Froms (file share/libc/stdio.h, line 492) Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/stdio.h, line 476) +[ Extern ] Froms (file share/libc/stdio.h, line 493) Unverifiable but considered Valid. [ Valid ] Default behavior by Frama-C kernel. @@ -770,11 +800,11 @@ --- Properties of Function 'putchar_unlocked' -------------------------------------------------------------------------------- -[ Extern ] Assigns (file share/libc/stdio.h, line 481) +[ Extern ] Assigns (file share/libc/stdio.h, line 498) Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/stdio.h, line 481) +[ Extern ] Froms (file share/libc/stdio.h, line 498) Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/stdio.h, line 482) +[ Extern ] Froms (file share/libc/stdio.h, line 499) Unverifiable but considered Valid. [ Valid ] Default behavior by Frama-C kernel. @@ -783,9 +813,9 @@ --- Properties of Function 'clearerr_unlocked' -------------------------------------------------------------------------------- -[ Extern ] Assigns (file share/libc/stdio.h, line 488) +[ Extern ] Assigns (file share/libc/stdio.h, line 505) Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/stdio.h, line 488) +[ Extern ] Froms (file share/libc/stdio.h, line 505) Unverifiable but considered Valid. [ Valid ] Default behavior by Frama-C kernel. @@ -796,7 +826,7 @@ [ Extern ] Assigns nothing Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/stdio.h, line 494) +[ Extern ] Froms (file share/libc/stdio.h, line 511) Unverifiable but considered Valid. [ Valid ] Default behavior by Frama-C kernel. @@ -807,7 +837,7 @@ [ Extern ] Assigns nothing Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/stdio.h, line 500) +[ Extern ] Froms (file share/libc/stdio.h, line 517) Unverifiable but considered Valid. [ Valid ] Default behavior by Frama-C kernel. @@ -818,7 +848,7 @@ [ Extern ] Assigns nothing Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/stdio.h, line 506) +[ Extern ] Froms (file share/libc/stdio.h, line 523) Unverifiable but considered Valid. [ Valid ] Default behavior by Frama-C kernel. @@ -829,11 +859,11 @@ [ Extern ] Post-condition 'result_error_or_valid_open_pipe' Unverifiable but considered Valid. -[ Extern ] Assigns (file share/libc/stdio.h, line 533) +[ Extern ] Assigns (file share/libc/stdio.h, line 550) Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/stdio.h, line 533) +[ Extern ] Froms (file share/libc/stdio.h, line 550) Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/stdio.h, line 535) +[ Extern ] Froms (file share/libc/stdio.h, line 552) Unverifiable but considered Valid. [ Valid ] Default behavior by Frama-C kernel. @@ -846,7 +876,7 @@ Unverifiable but considered Valid. [ Extern ] Assigns nothing Unverifiable but considered Valid. -[ Extern ] Froms (file share/libc/stdio.h, line 547) +[ Extern ] Froms (file share/libc/stdio.h, line 564) Unverifiable but considered Valid. [ Valid ] Default behavior by Frama-C kernel. @@ -865,8 +895,8 @@ -------------------------------------------------------------------------------- --- Status Report Summary -------------------------------------------------------------------------------- - 72 Completely validated - 198 Considered valid + 74 Completely validated + 206 Considered valid 1 To be validated - 271 Total + 281 Total -------------------------------------------------------------------------------- -- GitLab From 62c282b68cd59bd332cd2f5a10c394edad7e4d68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20B=C3=BChler?= <david.buhler@cea.fr> Date: Thu, 9 Apr 2020 08:53:57 +0200 Subject: [PATCH 173/218] [Eva] Allows registering a dynamic abstraction with several possible values. The function given to [dynamic_register] builds directly the flag instead of only the abstraction. --- src/plugins/value/engine/abstractions.ml | 23 ++++++----------------- src/plugins/value/engine/abstractions.mli | 3 +-- 2 files changed, 7 insertions(+), 19 deletions(-) diff --git a/src/plugins/value/engine/abstractions.ml b/src/plugins/value/engine/abstractions.ml index 5f568596c56..9e18ff813ba 100644 --- a/src/plugins/value/engine/abstractions.ml +++ b/src/plugins/value/engine/abstractions.ml @@ -71,10 +71,8 @@ module Config = struct let mem (Flag domain) = exists (fun (Flag flag, _mode) -> flag.name = domain.name) - type dynamic = Dynamic: (unit -> 'v abstraction) with_info -> dynamic - let abstractions = ref [] - let dynamic_abstractions : dynamic list ref = ref [] + let dynamic_abstractions = ref [] let register ~name ~descr ?(experimental=false) ?(priority=0) abstraction = let descr = if experimental then "Experimental. " ^ descr else descr in @@ -83,18 +81,16 @@ module Config = struct abstractions := flag :: !abstractions; flag - let dynamic_register ~name ~descr ?(experimental=false) ?(priority=0) make = - let descr = if experimental then "Experimental. " ^ descr else descr in + let dynamic_register ~name ~descr make = Value_parameters.register_domain ~name ~descr; - let dynamic = Dynamic { name; experimental; priority; abstraction=make; } in - dynamic_abstractions := dynamic :: !dynamic_abstractions + dynamic_abstractions := (name, make) :: !dynamic_abstractions let configure () = let add_main_mode mode = let main, _ = Globals.entry_point () in (main, Domain_mode.Mode.all) :: mode in - let add config name make = + let add config (name, make) = let enabled = Value_parameters.Domains.mem name in try let mode = Value_parameters.DomainsFunction.find name in @@ -104,17 +100,10 @@ module Config = struct if enabled then add (make (), None) config else config in let aux config (Flag domain as flag) = - add config domain.name (fun () -> flag) + add config (domain.name, (fun () -> flag)) in let config = List.fold_left aux empty !abstractions in - let aux config (Dynamic { name; experimental; priority; abstraction; }) = - let make () = - let abstraction = abstraction () in - Flag { name; experimental; priority; abstraction; } - in - add config name make - in - List.fold_left aux config !dynamic_abstractions + List.fold_left add config !dynamic_abstractions (* --- Register default abstractions -------------------------------------- *) diff --git a/src/plugins/value/engine/abstractions.mli b/src/plugins/value/engine/abstractions.mli index 3f3ff8d674e..8c98ee9b149 100644 --- a/src/plugins/value/engine/abstractions.mli +++ b/src/plugins/value/engine/abstractions.mli @@ -94,8 +94,7 @@ val register: the last argument when starting an analysis, if the -eva-domains option has been set to [name]. See function {!register} for more details. *) val dynamic_register: - name:string -> descr:string -> ?experimental:bool -> ?priority:int -> - (unit -> 'v abstraction) -> unit + name:string -> descr:string -> (unit -> flag) -> unit (** Reduced product between two value abstractions, identified by their keys. *) type ('a, 'b) value_reduced_product = -- GitLab From c762eadadf2e99bd762434b4c15e4333b62bdc0a Mon Sep 17 00:00:00 2001 From: Andre Maroneze <andre.oliveiramaroneze@cea.fr> Date: Mon, 30 Mar 2020 14:12:44 +0200 Subject: [PATCH 174/218] [Makefile] fix make src-distrib --- Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 9e3ac8f0caf..9cfab312094 100644 --- a/Makefile +++ b/Makefile @@ -319,7 +319,7 @@ DISTRIB_TESTS=$(shell git ls-files \ tests \ src/plugins/aorai/tests \ src/plugins/report/tests \ - src/plugins/wp/tests) + src/plugins/wp/tests | $(SED) 's/ /@/g') # files that are needed to compile API documentation of external plugins @@ -2437,7 +2437,7 @@ endif @#although it seems to segfault in 4.0 (but not in 4.1) $(RM) file_list_to_archive.tmp @$(foreach file,$(DISTRIB_FILES) $(DISTRIB_TESTS),\ - echo $(file) >> file_list_to_archive.tmp$(NEWLINE)) + echo $(file) | $(SED) 's/@/ /g' >> file_list_to_archive.tmp$(NEWLINE)) $(TAR) -cf - --files-from file_list_to_archive.tmp | $(TAR) -C $(CLIENT_DIR) -xf - $(RM) file_list_to_archive.tmp $(PRINT_MAKING) files -- GitLab From fda985af69ca792978ceeef396213fd94095e25a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20B=C3=BChler?= <david.buhler@cea.fr> Date: Thu, 9 Apr 2020 20:25:59 +0200 Subject: [PATCH 175/218] [Eva] Fixes the output of "-eva-domains help" for domains without description. --- src/plugins/value/value_parameters.ml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/plugins/value/value_parameters.ml b/src/plugins/value/value_parameters.ml index ef524a0d179..0677d81616e 100644 --- a/src/plugins/value/value_parameters.ml +++ b/src/plugins/value/value_parameters.ml @@ -182,8 +182,9 @@ let domains_list () = (fun fmt -> Format.pp_print_text fmt descr) in feedback ~level:0 - "List of available domains:@. %a@." - (Pretty_utils.pp_list ~sep:"@," pp_dom) (List.rev !domains_ref); + "List of available domains:@,%a" + (Pretty_utils.pp_list ~pre:"@[<v>" ~sep:"@," ~suf:"@]" pp_dom) + (List.rev !domains_ref); raise Cmdline.Exit (* Registers a new domain. Updates the help message of -eva-domains. *) -- GitLab From 1e009cb5024dbdb695bbe6e6d6123a3e5459b1d8 Mon Sep 17 00:00:00 2001 From: Virgile Prevosto <virgile.prevosto@m4x.org> Date: Fri, 10 Apr 2020 12:01:13 +0200 Subject: [PATCH 176/218] [ptests] ensure exec log comparison are done in the relevant directory --- ptests/ptests.ml | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/ptests/ptests.ml b/ptests/ptests.ml index 9318f4ebd96..1891dae0962 100644 --- a/ptests/ptests.ml +++ b/ptests/ptests.ml @@ -1568,6 +1568,13 @@ let default_config () = end else default_config () +(* if we have some references to directories in the default config, they + need to be adapted to the actual test directory. *) +let update_dir_ref dir config = + let update_execnow e = { e with ex_dir = dir } in + let dc_execnow = List.map update_execnow config.dc_execnow in + { config with dc_execnow } + let () = (* enqueue the test files *) let default_suites () = @@ -1612,13 +1619,15 @@ let () = suite) in let config = SubDir.make_file directory dir_config_file in + let default = default_config () in + let default = update_dir_ref directory default in let dir_config = if Sys.file_exists config then begin let scan_buffer = Scanf.Scanning.from_file config in - scan_options directory scan_buffer (default_config ()) + scan_options directory scan_buffer default end - else default_config () + else default in if interpret_as_file then begin -- GitLab From 705b7c9a8683a2c0314176cccf9afe626be1f13a Mon Sep 17 00:00:00 2001 From: Virgile Prevosto <virgile.prevosto@m4x.org> Date: Fri, 10 Apr 2020 13:06:11 +0200 Subject: [PATCH 177/218] [lint] fix ptests.ml indentation --- Makefile | 1 + ptests/ptests.ml | 986 +++++++++++++++++++++++------------------------ 2 files changed, 494 insertions(+), 493 deletions(-) diff --git a/Makefile b/Makefile index 9cfab312094..17e1df72b14 100644 --- a/Makefile +++ b/Makefile @@ -1705,6 +1705,7 @@ check-devguide: $(CHECK_CODE) $(DOC_DEPEND) $(DOC_DIR)/kernel-doc.ocamldoc # Note: the find command below is *very* ugly, but it should be POSIX-compliant. ALL_ML_FILES:=$(shell find src -name '*.ml' -print -o -name '*.mli' -print -o -path '*/tests' -prune '!' -name '*') +ALL_ML_FILES+=ptests/ptests.ml MANUAL_ML_FILES:=$(filter-out $(GENERATED) $(PLUGIN_GENERATED_LIST), $(ALL_ML_FILES)) # Allow control of files to be linted/fixed by external sources diff --git a/ptests/ptests.ml b/ptests/ptests.ml index 1891dae0962..8343b8cc01a 100644 --- a/ptests/ptests.ml +++ b/ptests/ptests.ml @@ -90,21 +90,21 @@ let default_env = ref [] let add_default_env x y = default_env:=(x,y)::!default_env let add_env var value = - add_default_env var value; - Unix.putenv var value + add_default_env var value; + Unix.putenv var value let print_default_env fmt = match !default_env with - [] -> () - | l -> - Format.fprintf fmt "@[Env:@\n"; - List.iter (fun (x,y) -> Format.fprintf fmt "%s = \"%s\"@\n" x y) l; - Format.fprintf fmt "@]" + [] -> () + | l -> + Format.fprintf fmt "@[Env:@\n"; + List.iter (fun (x,y) -> Format.fprintf fmt "%s = \"%s\"@\n" x y) l; + Format.fprintf fmt "@]" let default_env var value = try let v = Unix.getenv var in - add_default_env (var ^ " (set from outside)") v + add_default_env (var ^ " (set from outside)") v with Not_found -> add_env var value (** the name of the directory-wide configuration file*) @@ -147,7 +147,7 @@ let output_unix_error (exn : exn) = let message = Unix.error_message error in if arg = "" then Format.eprintf "%s@." message - else + else Format.eprintf "%s: %s@." arg message | _ -> assert false @@ -251,10 +251,10 @@ let () = let example_msg = Format.sprintf "@.@[<v 0>\ - A test suite can be the name of a directory in ./tests or \ - the path to a file.@ @ \ - @[<v 1>\ - Some variables can be used in test command:@ \ + A test suite can be the name of a directory in ./tests or \ + the path to a file.@ @ \ + @[<v 1>\ + Some variables can be used in test command:@ \ @@PTEST_CONFIG@@ \ # test configuration suffix@ \ @@PTEST_FILE@@ \ @@ -265,8 +265,8 @@ let example_msg = # basename of the test file@ \ @@PTEST_NUMBER@@ \ # test command number@] @ \ - @[<v 1>\ - Examples:@ \ + @[<v 1>\ + Examples:@ \ ptests@ \ ptests -diff \"echo diff\" -examine \ # see again the list of tests that failed@ \ @@ -285,70 +285,70 @@ let umsg = "Usage: ptests [options] [names of test suites]";; let rec argspec = [ - "-examine", Arg.Unit (fun () -> behavior := Examine) , - " Examine the logs that are different from oracles."; - "-gui", Arg.Unit (fun () -> - behavior := Gui; - n := 1; (* Disable parallelism to see which GUI is launched *) - ) , - " Start the tests in Frama-C's gui."; - "-update", Arg.Unit (fun () -> behavior := Update) , - " Take the current logs as oracles."; - "-show", Arg.Unit (fun () -> behavior := Show) , - " Show the results of the tests."; - "-run", Arg.Unit (fun () -> behavior := Run) , - " (default) Delete logs, run tests, then examine logs different from \ - oracles."; - "-v", Arg.Unit (fun () -> incr verbosity), - " Increase verbosity (up to twice)" ; - "-dry-run", Arg.Unit (fun () -> dry_run := true), - " Do not run commands (use with -v to print all commands which would be run)" ; - "-diff", Arg.String (fun s -> do_diffs := s; - if !use_diff_as_cmp then do_cmp := s), - "<command> Use command for diffs" ; - "-cmp", Arg.String (fun s -> do_cmp:=s), - "<command> Use command for comparison"; - "-make", Arg.String (fun s -> do_make := s;), - "<command> Use command instead of make"; - "-use-diff-as-cmp", - Arg.Unit (fun () -> use_diff_as_cmp:=true; do_cmp:=!do_diffs), - " Use the diff command for performing comparisons"; - "-j", Arg.Int - (fun i -> if i>=0 - then n := i - else ( lock_printf "Option -j requires nonnegative argument@."; - exit (-1))), - "<n> Use nonnegative integer n for level of parallelism" ; - "-byte", Arg.Set use_byte, - " Use bytecode toplevel"; - "-opt", Arg.Clear use_byte, - " Use native toplevel (default)"; - "-config", Arg.Set_string special_config, - " <name> Use special configuration and oracles"; - "-add-options", Arg.Set_string additional_options, - "<options> Add additional options to be passed to the toplevels \ - that will be launched. <options> are added after standard test options"; - "-add-options-pre", Arg.Set_string additional_options_pre, - "<options> Add additional options to be passed to the toplevels \ - that will be launched. <options> are added before standard test options."; - "-add-options-post", Arg.Set_string additional_options, - "Synonym of -add-options"; - "-exclude", Arg.String exclude, - "<name> Exclude a test or a suite from the run"; - "-xunit", Arg.Set xunit, - " Create a xUnit file named xunit.xml collecting results"; - "-error-code", Arg.Set do_error_code, - " Exit with error code 1 if tests failed (useful for scripts"; -] + "-examine", Arg.Unit (fun () -> behavior := Examine) , + " Examine the logs that are different from oracles."; + "-gui", Arg.Unit (fun () -> + behavior := Gui; + n := 1; (* Disable parallelism to see which GUI is launched *) + ) , + " Start the tests in Frama-C's gui."; + "-update", Arg.Unit (fun () -> behavior := Update) , + " Take the current logs as oracles."; + "-show", Arg.Unit (fun () -> behavior := Show) , + " Show the results of the tests."; + "-run", Arg.Unit (fun () -> behavior := Run) , + " (default) Delete logs, run tests, then examine logs different from \ + oracles."; + "-v", Arg.Unit (fun () -> incr verbosity), + " Increase verbosity (up to twice)" ; + "-dry-run", Arg.Unit (fun () -> dry_run := true), + " Do not run commands (use with -v to print all commands which would be run)" ; + "-diff", Arg.String (fun s -> do_diffs := s; + if !use_diff_as_cmp then do_cmp := s), + "<command> Use command for diffs" ; + "-cmp", Arg.String (fun s -> do_cmp:=s), + "<command> Use command for comparison"; + "-make", Arg.String (fun s -> do_make := s;), + "<command> Use command instead of make"; + "-use-diff-as-cmp", + Arg.Unit (fun () -> use_diff_as_cmp:=true; do_cmp:=!do_diffs), + " Use the diff command for performing comparisons"; + "-j", Arg.Int + (fun i -> if i>=0 + then n := i + else ( lock_printf "Option -j requires nonnegative argument@."; + exit (-1))), + "<n> Use nonnegative integer n for level of parallelism" ; + "-byte", Arg.Set use_byte, + " Use bytecode toplevel"; + "-opt", Arg.Clear use_byte, + " Use native toplevel (default)"; + "-config", Arg.Set_string special_config, + " <name> Use special configuration and oracles"; + "-add-options", Arg.Set_string additional_options, + "<options> Add additional options to be passed to the toplevels \ + that will be launched. <options> are added after standard test options"; + "-add-options-pre", Arg.Set_string additional_options_pre, + "<options> Add additional options to be passed to the toplevels \ + that will be launched. <options> are added before standard test options."; + "-add-options-post", Arg.Set_string additional_options, + "Synonym of -add-options"; + "-exclude", Arg.String exclude, + "<name> Exclude a test or a suite from the run"; + "-xunit", Arg.Set xunit, + " Create a xUnit file named xunit.xml collecting results"; + "-error-code", Arg.Set do_error_code, + " Exit with error code 1 if tests failed (useful for scripts"; + ] and help_msg () = Arg.usage (Arg.align argspec) umsg;; let () = Arg.parse ((Arg.align (List.sort - (fun (optname1, _, _) (optname2, _, _) -> - compare optname1 optname2 - ) argspec) + (fun (optname1, _, _) (optname2, _, _) -> + compare optname1 optname2 + ) argspec) ) @ ["", Arg.Unit (fun () -> ()), example_msg;]) make_test_suite umsg ;; @@ -360,19 +360,19 @@ let fail s = (** split the filename into before including "tests" dir and after including "tests" dir NOTA: both part contains "tests" (one as suffix the other as prefix). - *) +*) let rec get_upper_test_dir initial dir = let tests = Filename.dirname dir in if tests = dir then - (* root directory *) + (* root directory *) (fail (Printf.sprintf "Can't find a tests directory below %s" initial)) else let base = Filename.basename dir in - if base = "tests" then - dir, "tests" - else - let tests, suffix = get_upper_test_dir initial tests in - tests, Filename.concat suffix base + if base = "tests" then + dir, "tests" + else + let tests, suffix = get_upper_test_dir initial tests in + tests, Filename.concat suffix base let rec get_test_path = function | [] -> @@ -497,19 +497,19 @@ end = struct end type execnow = - { - ex_cmd: string; (** command to launch *) - ex_log: string list; (** log files *) - ex_bin: string list; (** bin files *) - ex_dir: SubDir.t; (** directory of test suite *) - ex_once: bool; (** true iff the command has to be executed only once - per config file (otherwise it is executed for - every file of the test suite) *) - ex_done: bool ref; (** has the command been already fully executed. - Shared between all copies of this EXECNOW. Do - NOT use a mutable field here, as execnows - are duplicated using OCaml 'with' syntax. *) - } + { + ex_cmd: string; (** command to launch *) + ex_log: string list; (** log files *) + ex_bin: string list; (** bin files *) + ex_dir: SubDir.t; (** directory of test suite *) + ex_once: bool; (** true iff the command has to be executed only once + per config file (otherwise it is executed for + every file of the test suite) *) + ex_done: bool ref; (** has the command been already fully executed. + Shared between all copies of this EXECNOW. Do + NOT use a mutable field here, as execnows + are duplicated using OCaml 'with' syntax. *) + } module Macros = @@ -585,22 +585,22 @@ end (** configuration of a directory/test. *) type config = - { - dc_test_regexp: string; (** regexp of test files. *) - dc_execnow : execnow list; (** command to be launched before - the toplevel(s) - *) - dc_macros: Macros.t; (** existing macros. *) - dc_default_toplevel : string; - (** full path of the default toplevel. *) - dc_filter : string option; (** optional filter to apply to - standard output *) - dc_toplevels : (string * string * string list * Macros.t) list; - (** toplevel full path, options to launch the toplevel on, and list - of output files to monitor beyond stdout and stderr. *) - dc_dont_run : bool; - dc_default_log: string list; - } + { + dc_test_regexp: string; (** regexp of test files. *) + dc_execnow : execnow list; (** command to be launched before + the toplevel(s) + *) + dc_macros: Macros.t; (** existing macros. *) + dc_default_toplevel : string; + (** full path of the default toplevel. *) + dc_filter : string option; (** optional filter to apply to + standard output *) + dc_toplevels : (string * string * string list * Macros.t) list; + (** toplevel full path, options to launch the toplevel on, and list + of output files to monitor beyond stdout and stderr. *) + dc_dont_run : bool; + dc_default_log: string list; + } let default_macros () = let l = [ @@ -651,20 +651,20 @@ let scan_execnow ~once dir (s:string) = try Scanf.sscanf s.ex_cmd "%_[ ]LOG%_[ ]%[-A-Za-z0-9_',+=:.\\@@]%_[ ]%s@\n" (fun name cmd -> - aux { s with ex_cmd = cmd; ex_log = name :: s.ex_log }) + aux { s with ex_cmd = cmd; ex_log = name :: s.ex_log }) with Scanf.Scan_failure _ -> - try - Scanf.sscanf s.ex_cmd "%_[ ]BIN%_[ ]%[A-Za-z0-9_.\\-@@]%_[ ]%s@\n" - (fun name cmd -> - aux { s with ex_cmd = cmd; ex_bin = name :: s.ex_bin }) - with Scanf.Scan_failure _ -> - try - Scanf.sscanf s.ex_cmd "%_[ ]make%_[ ]%s@\n" - (fun cmd -> - let s = aux ({ s with ex_cmd = cmd; }) in - { s with ex_cmd = !do_make^" "^cmd; } ) - with Scanf.Scan_failure _ -> - s + try + Scanf.sscanf s.ex_cmd "%_[ ]BIN%_[ ]%[A-Za-z0-9_.\\-@@]%_[ ]%s@\n" + (fun name cmd -> + aux { s with ex_cmd = cmd; ex_bin = name :: s.ex_bin }) + with Scanf.Scan_failure _ -> + try + Scanf.sscanf s.ex_cmd "%_[ ]make%_[ ]%s@\n" + (fun cmd -> + let s = aux ({ s with ex_cmd = cmd; }) in + { s with ex_cmd = !do_make^" "^cmd; } ) + with Scanf.Scan_failure _ -> + s in aux { ex_cmd = s; @@ -684,18 +684,18 @@ let make_custom_opts = fun stdopts s -> let rec aux opts s = try - Scanf.sscanf s "%_[ ]%1[+#\\-]%_[ ]%S%_[ ]%s@\n" + Scanf.sscanf s "%_[ ]%1[+#\\-]%_[ ]%S%_[ ]%s@\n" (fun c opt rem -> - match c with - | "+" -> aux (opt :: opts) rem - | "#" -> aux (opts @ [ opt ]) rem - | "-" -> aux (List.filter (fun x -> x <> opt) opts) rem - | _ -> assert false (* format of scanned string disallow it *)) + match c with + | "+" -> aux (opt :: opts) rem + | "#" -> aux (opts @ [ opt ]) rem + | "-" -> aux (List.filter (fun x -> x <> opt) opts) rem + | _ -> assert false (* format of scanned string disallow it *)) with | Scanf.Scan_failure _ -> - if s <> "" then - lock_eprintf "unknown STDOPT configuration string: %s\n%!" s; - opts + if s <> "" then + lock_eprintf "unknown STDOPT configuration string: %s\n%!" s; + opts | End_of_file -> opts in (* NB: current settings does not allow to remove a multiple-argument @@ -718,7 +718,7 @@ let config_macro _dir s current = Mutex.lock str_mutex; if Str.string_match regex s 0 then begin let name = Str.matched_group 1 s in - let def = + let def = try Str.matched_group 3 s with Not_found -> (* empty text *) "" in Mutex.unlock str_mutex; @@ -740,16 +740,16 @@ let config_module dir s current = let config_options = [ "CMD", - (fun _ s current -> + (fun _ s current -> { current with dc_default_toplevel = s}); "OPT", (fun _ s current -> let t = current.dc_default_toplevel, s, current.dc_default_log, current.dc_macros in { current with -(* dc_default_toplevel = !current_default_toplevel;*) - dc_default_log = !current_default_log; - dc_toplevels = t :: current.dc_toplevels }); + (* dc_default_toplevel = !current_default_toplevel;*) + dc_default_log = !current_default_log; + dc_toplevels = t :: current.dc_toplevels }); "STDOPT", (fun _ s current -> @@ -783,7 +783,7 @@ let config_options = "MODULE", config_module; "LOG", (fun _ s current -> - { current with dc_default_log = s :: current.dc_default_log }) + { current with dc_default_log = s :: current.dc_default_log }) ] @@ -798,10 +798,10 @@ let scan_options dir scan_buffer default = try Scanf.sscanf s "%[ *]%[A-Za-z0-9]: %s@\n" (fun _ name opt -> - try - r := (List.assoc name config_options) dir opt !r - with Not_found -> - lock_eprintf "@[unknown configuration option: %s@\n%!@]" name) + try + r := (List.assoc name config_options) dir opt !r + with Not_found -> + lock_eprintf "@[unknown configuration option: %s@\n%!@]" name) with Scanf.Scan_failure _ -> if str_string_match end_comment s 0 then raise End_of_file @@ -814,9 +814,9 @@ let scan_options dir scan_buffer default = assert false with End_of_file -> - (match !r.dc_toplevels with - | [] -> { !r with dc_toplevels = default.dc_toplevels } - | l -> { !r with dc_toplevels = List.rev l }) + (match !r.dc_toplevels with + | [] -> { !r with dc_toplevels = default.dc_toplevels } + | l -> { !r with dc_toplevels = List.rev l }) let split_config = Str.regexp ",[ ]*" @@ -827,52 +827,52 @@ let scan_test_file default dir f = (Unix.lstat f).Unix.st_kind = Unix.S_REG with Unix.Unix_error _ | Sys_error _ -> false in - if exists_as_file then begin - let scan_buffer = Scanf.Scanning.open_in f in - let rec scan_config () = - (* space in format string matches any number of whitespace *) - Scanf.bscanf scan_buffer " /* %s@\n" - (fun names -> - let is_current_config name = - name = "run.config*" || - name = "run.config" && !special_config = "" || - name = "run.config_" ^ !special_config - in - let configs = Str.split split_config (String.trim names) in - if List.exists is_current_config configs then - (* Found options for current config! *) - scan_options dir scan_buffer default - else (* config name does not match: eat config and continue. - But only if the comment is still opened by the end of - the line... - *) - (if not (str_string_match end_comment names 0) then - ignore (scan_options dir scan_buffer default); - scan_config ())) - in - try - let options = scan_config () in - Scanf.Scanning.close_in scan_buffer; - options - with End_of_file | Scanf.Scan_failure _ -> - Scanf.Scanning.close_in scan_buffer; - default - end else - (* if the file has disappeared, don't try to run it... *) - { default with dc_dont_run = true } + if exists_as_file then begin + let scan_buffer = Scanf.Scanning.open_in f in + let rec scan_config () = + (* space in format string matches any number of whitespace *) + Scanf.bscanf scan_buffer " /* %s@\n" + (fun names -> + let is_current_config name = + name = "run.config*" || + name = "run.config" && !special_config = "" || + name = "run.config_" ^ !special_config + in + let configs = Str.split split_config (String.trim names) in + if List.exists is_current_config configs then + (* Found options for current config! *) + scan_options dir scan_buffer default + else (* config name does not match: eat config and continue. + But only if the comment is still opened by the end of + the line... + *) + (if not (str_string_match end_comment names 0) then + ignore (scan_options dir scan_buffer default); + scan_config ())) + in + try + let options = scan_config () in + Scanf.Scanning.close_in scan_buffer; + options + with End_of_file | Scanf.Scan_failure _ -> + Scanf.Scanning.close_in scan_buffer; + default + end else + (* if the file has disappeared, don't try to run it... *) + { default with dc_dont_run = true } type toplevel_command = - { macros: Macros.t; - mutable log_files: string list; - file : string ; - nb_files : int ; - options : string ; - toplevel: string ; - filter : string option ; - directory : SubDir.t ; - n : int; - execnow:bool - } + { macros: Macros.t; + mutable log_files: string list; + file : string ; + nb_files : int ; + options : string ; + toplevel: string ; + filter : string option ; + directory : SubDir.t ; + n : int; + execnow:bool + } type command = | Toplevel of toplevel_command @@ -890,24 +890,24 @@ type cmps = | Cmp_Log of SubDir.t (** directory *) * string (** file *) type shared = - { lock : Mutex.t ; - mutable building_target : bool ; - target_queue : command Queue.t ; - commands_empty : Condition.t ; - work_available : Condition.t ; - diff_available : Condition.t ; - mutable commands : command Queue.t ; (* file, options, number *) - cmps : cmps Queue.t ; - (* command that has finished its execution *) - diffs : diff Queue.t ; - (* cmp that showed some difference *) - mutable commands_finished : bool ; - mutable cmp_finished : bool ; - mutable summary_time : float ; - mutable summary_run : int ; - mutable summary_ok : int ; - mutable summary_log : int; - } + { lock : Mutex.t ; + mutable building_target : bool ; + target_queue : command Queue.t ; + commands_empty : Condition.t ; + work_available : Condition.t ; + diff_available : Condition.t ; + mutable commands : command Queue.t ; (* file, options, number *) + cmps : cmps Queue.t ; + (* command that has finished its execution *) + diffs : diff Queue.t ; + (* cmp that showed some difference *) + mutable commands_finished : bool ; + mutable cmp_finished : bool ; + mutable summary_time : float ; + mutable summary_run : int ; + mutable summary_ok : int ; + mutable summary_log : int; + } let shared = { lock = Mutex.create () ; @@ -940,8 +940,8 @@ let name_without_extension command = (Filename.chop_extension command.file) with Invalid_argument _ -> - fail ("this test file does not have any extension: " ^ - command.file) + fail ("this test file does not have any extension: " ^ + command.file) let gen_prefix gen_file cmd = let prefix = gen_file cmd.directory (name_without_extension cmd) in @@ -1044,39 +1044,39 @@ let command_string command = let stderr = match command.filter with None -> errlog | Some _ -> - let stderr = - Filename.temp_file (Filename.basename log_prefix) ".err.log" - in - at_exit (fun () -> unlink stderr); - stderr + let stderr = + Filename.temp_file (Filename.basename log_prefix) ".err.log" + in + at_exit (fun () -> unlink stderr); + stderr in let filter = match command.filter with | None -> None | Some filter -> - let len = String.length filter in - let rec split_filter i = - if i < len && filter.[i] = ' ' then split_filter (i+1) - else - try - let idx = String.index_from filter i ' ' in - String.sub filter i idx, - String.sub filter idx (len - idx) - with Not_found -> - String.sub filter i (len - i), "" - in - let exec_name, params = split_filter 0 in - let exec_name = - if Sys.file_exists exec_name || not (Filename.is_relative exec_name) - then exec_name - else - match find_in_path exec_name with - | Some full_exec_name -> full_exec_name - | None -> - Filename.concat - (Filename.dirname (Filename.dirname log_prefix)) - (Filename.basename exec_name) - in - Some (exec_name ^ params) + let len = String.length filter in + let rec split_filter i = + if i < len && filter.[i] = ' ' then split_filter (i+1) + else + try + let idx = String.index_from filter i ' ' in + String.sub filter i idx, + String.sub filter idx (len - idx) + with Not_found -> + String.sub filter i (len - i), "" + in + let exec_name, params = split_filter 0 in + let exec_name = + if Sys.file_exists exec_name || not (Filename.is_relative exec_name) + then exec_name + else + match find_in_path exec_name with + | Some full_exec_name -> full_exec_name + | None -> + Filename.concat + (Filename.dirname (Filename.dirname log_prefix)) + (Filename.basename exec_name) + in + Some (exec_name ^ params) in let command_string = basic_command_string command in let command_string = @@ -1091,12 +1091,12 @@ let command_string command = let command_string = match filter with | None -> command_string | Some filter -> - Printf.sprintf "%s && %s < %s >%s && rm -f %s" - command_string - filter - (Filename.sanitize stderr) - (Filename.sanitize errlog) - (Filename.sanitize stderr) + Printf.sprintf "%s && %s < %s >%s && rm -f %s" + command_string + filter + (Filename.sanitize stderr) + (Filename.sanitize errlog) + (Filename.sanitize stderr) in command_string @@ -1111,17 +1111,17 @@ let update_toplevel_command command = mv (log_prefix ^ ".res.log") (oracle_prefix ^ ".res.oracle"); (* Is there an error log ? *) begin try - let log = log_prefix ^ ".err.log" - and oracle = oracle_prefix ^ ".err.oracle" - in - if is_file_empty_or_nonexisting log then - (* No, remove the error oracle *) - unlink ~silent:false oracle - else - (* Yes, update the error oracle*) - mv log oracle - with (* Possible error in [is_file_empty] *) - Unix.Unix_error _ -> () + let log = log_prefix ^ ".err.log" + and oracle = oracle_prefix ^ ".err.oracle" + in + if is_file_empty_or_nonexisting log then + (* No, remove the error oracle *) + unlink ~silent:false oracle + else + (* Yes, update the error oracle*) + mv log oracle + with (* Possible error in [is_file_empty] *) + Unix.Unix_error _ -> () end; let macros = get_macros command in let log_files = List.map (Macros.expand macros) command.log_files @@ -1131,8 +1131,8 @@ let update_toplevel_command command = let rec update_command = function Toplevel cmd -> update_toplevel_command cmd | Target (execnow,cmds) -> - List.iter (update_log_files execnow.ex_dir) execnow.ex_log; - Queue.iter update_command cmds + List.iter (update_log_files execnow.ex_dir) execnow.ex_log; + Queue.iter update_command cmds let remove_execnow_results execnow = List.iter @@ -1141,13 +1141,13 @@ let remove_execnow_results execnow = module Make_Report(M:sig type t end)=struct module H=Hashtbl.Make - (struct - type t = toplevel_command - let project cmd = (cmd.directory,cmd.file,cmd.n) - let compare c1 c2 = compare (project c1) (project c2) - let equal c1 c2 = (project c1)=(project c2) - let hash c = Hashtbl.hash (project c) - end) + (struct + type t = toplevel_command + let project cmd = (cmd.directory,cmd.file,cmd.n) + let compare c1 c2 = compare (project c1) (project c2) + let equal c1 c2 = (project c1)=(project c2) + let hash c = Hashtbl.hash (project c) + end) let tbl = H.create 774 let m = Mutex.create () let record cmd (v:M.t) = @@ -1166,7 +1166,7 @@ module Make_Report(M:sig type t end)=struct end module Report_run=Make_Report(struct type t=int*float (* At some point will contain the running time*) -end) + end) let report_run cmp r = Report_run.record cmp r module Report_cmp=Make_Report(struct type t=int*int end) @@ -1174,12 +1174,12 @@ let report_cmp = Report_cmp.record let pretty_report fmt = Report_run.iter (fun test (_run_result,time_result) -> - Format.fprintf fmt - "<testcase classname=%S name=%S time=\"%f\">%s</testcase>@." - (Filename.basename (SubDir.get test.directory)) test.file time_result - (let res,err = Report_cmp.find test in - Report_cmp.remove test; - (if res=0 && err=0 then "" else + Format.fprintf fmt + "<testcase classname=%S name=%S time=\"%f\">%s</testcase>@." + (Filename.basename (SubDir.get test.directory)) test.file time_result + (let res,err = Report_cmp.find test in + Report_cmp.remove test; + (if res=0 && err=0 then "" else Format.sprintf "<failure type=\"Regression\">%s</failure>" (if res=1 then "Stdout oracle difference" else if res=2 then "Stdout System Error (missing oracle?)" @@ -1189,10 +1189,10 @@ let pretty_report fmt = (* Test that were compared but not runned *) Report_cmp.iter (fun test (res,err) -> - Format.fprintf fmt - "<testcase classname=%S name=%S>%s</testcase>@." - (Filename.basename (SubDir.get test.directory)) test.file - (if res=0 && err=0 then "" else + Format.fprintf fmt + "<testcase classname=%S name=%S>%s</testcase>@." + (Filename.basename (SubDir.get test.directory)) test.file + (if res=0 && err=0 then "" else Format.sprintf "<failure type=\"Regression\">%s</failure>" (if res=1 then "Stdout oracle difference" else if res=2 then "Stdout System Error (missing oracle?)" @@ -1205,8 +1205,8 @@ let xunit_report () = let fmt = Format.formatter_of_out_channel out in Format.fprintf fmt "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\ - @\n<testsuite errors=\"0\" failures=\"%d\" name=\"%s\" tests=\"%d\" time=\"%f\" timestamp=\"%f\">\ - @\n%t</testsuite>@." + @\n<testsuite errors=\"0\" failures=\"%d\" name=\"%s\" tests=\"%d\" time=\"%f\" timestamp=\"%f\">\ + @\n%t</testsuite>@." (shared.summary_log-shared.summary_ok) "Frama-C" shared.summary_log @@ -1220,112 +1220,112 @@ let xunit_report () = let do_command command = match command with | Toplevel command -> - (* Update : copy the logs. Do not enqueue any cmp - Run | Show: launch the command, then enqueue the cmp - Gui: launch the command in the gui - Examine : just enqueue the cmp *) - if !behavior = Update - then update_toplevel_command command + (* Update : copy the logs. Do not enqueue any cmp + Run | Show: launch the command, then enqueue the cmp + Gui: launch the command in the gui + Examine : just enqueue the cmp *) + if !behavior = Update + then update_toplevel_command command + else begin + (* Run, Show, Gui or Examine *) + if !behavior = Gui then begin + (* basic_command_string does not redirect the outputs, and does + not overwrite the result files *) + let basic_command_string = basic_command_string command in + lock_printf "%% launch %s@." basic_command_string ; + ignore (launch basic_command_string) + end else begin - (* Run, Show, Gui or Examine *) - if !behavior = Gui then begin - (* basic_command_string does not redirect the outputs, and does - not overwrite the result files *) - let basic_command_string = basic_command_string command in - lock_printf "%% launch %s@." basic_command_string ; - ignore (launch basic_command_string) - end - else begin - (* command string also replaces macros in logfiles names, which - is useful for Examine as well. *) - let command_string = command_string command in - if !behavior <> Examine - then begin - if !verbosity >= 1 - then lock_printf "%% launch %s@." command_string ; - let launch_result = launch command_string in - let time = 0. (* Individual time is difficult to compute correctly - for now, and currently unused *) in - report_run command (launch_result, time) - end; - lock (); - shared.summary_run <- succ shared.summary_run ; - Queue.push (Cmp_Toplevel command) shared.cmps; + (* command string also replaces macros in logfiles names, which + is useful for Examine as well. *) + let command_string = command_string command in + if !behavior <> Examine + then begin + if !verbosity >= 1 + then lock_printf "%% launch %s@." command_string ; + let launch_result = launch command_string in + let time = 0. (* Individual time is difficult to compute correctly + for now, and currently unused *) in + report_run command (launch_result, time) + end; + lock (); + shared.summary_run <- succ shared.summary_run ; + Queue.push (Cmp_Toplevel command) shared.cmps; + List.iter + (fun f -> Queue.push (Cmp_Log (command.directory, f)) shared.cmps) + command.log_files; + unlock () + end + end + | Target (execnow, cmds) -> + let continue res = + lock(); + shared.summary_log <- succ shared.summary_log; + if res = 0 + then begin + shared.summary_ok <- succ shared.summary_ok; + Queue.transfer shared.commands cmds; + shared.commands <- cmds; + shared.building_target <- false; + Condition.broadcast shared.work_available; + if !behavior = Examine || !behavior = Run + then begin List.iter - (fun f -> Queue.push (Cmp_Log (command.directory, f)) shared.cmps) - command.log_files; - unlock () + (fun f -> Queue.push (Cmp_Log(execnow.ex_dir, f)) shared.cmps) + execnow.ex_log end end - | Target (execnow, cmds) -> - let continue res = - lock(); - shared.summary_log <- succ shared.summary_log; - if res = 0 - then begin - shared.summary_ok <- succ shared.summary_ok; - Queue.transfer shared.commands cmds; - shared.commands <- cmds; - shared.building_target <- false; - Condition.broadcast shared.work_available; - if !behavior = Examine || !behavior = Run - then begin - List.iter - (fun f -> Queue.push (Cmp_Log(execnow.ex_dir, f)) shared.cmps) - execnow.ex_log - end - end - else begin - let rec treat_cmd = function - Toplevel cmd -> - shared.summary_run <- shared.summary_run + 1; - let log_prefix = log_prefix cmd in - unlink (log_prefix ^ ".res.log ") - | Target (execnow,cmds) -> - shared.summary_run <- succ shared.summary_run; - remove_execnow_results execnow; - Queue.iter treat_cmd cmds - in - Queue.iter treat_cmd cmds; - Queue.push (Target_error execnow) shared.diffs; - shared.building_target <- false; - Condition.signal shared.diff_available - end; - unlock() - in + else begin + let rec treat_cmd = function + Toplevel cmd -> + shared.summary_run <- shared.summary_run + 1; + let log_prefix = log_prefix cmd in + unlink (log_prefix ^ ".res.log ") + | Target (execnow,cmds) -> + shared.summary_run <- succ shared.summary_run; + remove_execnow_results execnow; + Queue.iter treat_cmd cmds + in + Queue.iter treat_cmd cmds; + Queue.push (Target_error execnow) shared.diffs; + shared.building_target <- false; + Condition.signal shared.diff_available + end; + unlock() + in - if !behavior = Update then begin - update_command command; - lock (); - shared.building_target <- false; - Condition.signal shared.work_available; - unlock (); - end else - begin - if !behavior <> Examine && not (!(execnow.ex_done) && execnow.ex_once) - then begin - remove_execnow_results execnow; - let cmd = - if !use_byte then - execnow_opt_to_byte execnow.ex_cmd - else - execnow.ex_cmd - in - if !verbosity >= 1 then begin - lock_printf "%% launch %s@." cmd; - end; - let r = launch cmd in - (* mark as already executed. For EXECNOW in test_config files, - other instances (for example another test of the same - directory), won't relaunch the command. For EXECNOW in - stand-alone tests, there is only one copy of the EXECNOW - anyway *) - execnow.ex_done := true; - continue r - end + if !behavior = Update then begin + update_command command; + lock (); + shared.building_target <- false; + Condition.signal shared.work_available; + unlock (); + end else + begin + if !behavior <> Examine && not (!(execnow.ex_done) && execnow.ex_once) + then begin + remove_execnow_results execnow; + let cmd = + if !use_byte then + execnow_opt_to_byte execnow.ex_cmd else - continue 0 + execnow.ex_cmd + in + if !verbosity >= 1 then begin + lock_printf "%% launch %s@." cmd; + end; + let r = launch cmd in + (* mark as already executed. For EXECNOW in test_config files, + other instances (for example another test of the same + directory), won't relaunch the command. For EXECNOW in + stand-alone tests, there is only one copy of the EXECNOW + anyway *) + execnow.ex_done := true; + continue r end + else + continue 0 + end let log_ext = function Res -> ".res" | Err -> ".err" @@ -1414,13 +1414,13 @@ let compare_one_log_file dir file = let do_cmp = function | Cmp_Toplevel cmp -> - let log_prefix = log_prefix cmp in - let oracle_prefix = oracle_prefix cmp in - let res = compare_one_file cmp log_prefix oracle_prefix Res in - let err = compare_one_file cmp log_prefix oracle_prefix Err in - report_cmp cmp (res,err) + let log_prefix = log_prefix cmp in + let oracle_prefix = oracle_prefix cmp in + let res = compare_one_file cmp log_prefix oracle_prefix Res in + let err = compare_one_file cmp log_prefix oracle_prefix Err in + report_cmp cmp (res,err) | Cmp_Log(dir, f) -> - ignore (compare_one_log_file dir f) + ignore (compare_one_log_file dir f) let worker_thread () = while true do @@ -1432,47 +1432,47 @@ let worker_thread () = unlock () ; do_cmp cmp with Queue.Empty -> - try - let rec real_command () = - let command = - try - if shared.building_target then raise Queue.Empty; - Queue.pop shared.target_queue - with Queue.Empty -> - Queue.pop shared.commands - in - match command with - Target _ -> - if shared.building_target - then begin - Queue.push command shared.target_queue; - real_command() - end - else begin - shared.building_target <- true; - command - end - | _ -> command + try + let rec real_command () = + let command = + try + if shared.building_target then raise Queue.Empty; + Queue.pop shared.target_queue + with Queue.Empty -> + Queue.pop shared.commands in - let command = real_command() in - unlock () ; - do_command command - with Queue.Empty -> - if shared.commands_finished - && Queue.is_empty shared.target_queue - && not shared.building_target - (* a target being built would mean work can still appear *) + match command with + Target _ -> + if shared.building_target + then begin + Queue.push command shared.target_queue; + real_command() + end + else begin + shared.building_target <- true; + command + end + | _ -> command + in + let command = real_command() in + unlock () ; + do_command command + with Queue.Empty -> + if shared.commands_finished + && Queue.is_empty shared.target_queue + && not shared.building_target + (* a target being built would mean work can still appear *) - then (unlock () ; Thread.exit ()); + then (unlock () ; Thread.exit ()); - Condition.signal shared.commands_empty; - (* we still have the lock at this point *) + Condition.signal shared.commands_empty; + (* we still have the lock at this point *) - Condition.wait shared.work_available shared.lock; - (* this atomically releases the lock and suspends - the thread on the condition work_available *) + Condition.wait shared.work_available shared.lock; + (* this atomically releases the lock and suspends + the thread on the condition work_available *) - unlock (); + unlock (); done let diff_check_exist old_file new_file = @@ -1484,26 +1484,26 @@ let diff_check_exist old_file new_file = old_file ^ "\";" ^ " cat " ^ old_file end end else begin - "echo \"--- " ^ old_file ^ " does not exist. Showing " ^ - new_file ^ "\";" ^ " cat " ^ new_file + "echo \"--- " ^ old_file ^ " does not exist. Showing " ^ + new_file ^ "\";" ^ " cat " ^ new_file end let do_diff = function - | Command_error (diff, kind) -> - let log_prefix = log_prefix diff in - let log_ext = log_ext kind in - let log_file = Filename.sanitize (log_prefix ^ log_ext ^ ".log") in - let command_string = command_string diff in - lock_printf "%tCommand:@\n%s@." print_default_env command_string; - if !behavior = Show - then ignore (launch ("cat " ^ log_file)) - else - let oracle_prefix = oracle_prefix diff in - let oracle_file = - Filename.sanitize (oracle_prefix ^ log_ext ^ ".oracle") - in - let diff_string = diff_check_exist oracle_file log_file in - ignore (launch diff_string) + | Command_error (diff, kind) -> + let log_prefix = log_prefix diff in + let log_ext = log_ext kind in + let log_file = Filename.sanitize (log_prefix ^ log_ext ^ ".log") in + let command_string = command_string diff in + lock_printf "%tCommand:@\n%s@." print_default_env command_string; + if !behavior = Show + then ignore (launch ("cat " ^ log_file)) + else + let oracle_prefix = oracle_prefix diff in + let oracle_file = + Filename.sanitize (oracle_prefix ^ log_ext ^ ".oracle") + in + let diff_string = diff_check_exist oracle_file log_file in + ignore (launch diff_string) | Target_error execnow -> lock_printf "Custom command failed: %s@\n" execnow.ex_cmd; let print_redirected out redir_str = @@ -1520,18 +1520,18 @@ let do_diff = function print_redirected "stdout" "[^2]> ?\\([-a-zA-Z0-9_/.]+\\)"; print_redirected "stderr" "2> ?\\([-a-zA-Z0-9_/.]+\\)"; | Log_error(dir, file) -> - let result_file = - Filename.sanitize (SubDir.make_result_file dir file) + let result_file = + Filename.sanitize (SubDir.make_result_file dir file) + in + lock_printf "Log of %s:@." result_file; + if !behavior = Show + then ignore (launch ("cat " ^ result_file)) + else + let oracle_file = + Filename.sanitize (SubDir.make_oracle_file dir file) in - lock_printf "Log of %s:@." result_file; - if !behavior = Show - then ignore (launch ("cat " ^ result_file)) - else - let oracle_file = - Filename.sanitize (SubDir.make_oracle_file dir file) - in - let diff_string = diff_check_exist oracle_file result_file in - ignore (launch diff_string) + let diff_string = diff_check_exist oracle_file result_file in + ignore (launch diff_string) let diff_thread () = lock () ; @@ -1595,11 +1595,11 @@ let () = ) [] l in let interpret_as_file suite = - try - let ext = Filename.chop_extension suite in - ext <> "" - with Invalid_argument _ -> false - in + try + let ext = Filename.chop_extension suite in + ext <> "" + with Invalid_argument _ -> false + in let exclude_suite, exclude_file = List.fold_left (fun (suite,test) x -> @@ -1609,7 +1609,7 @@ let () = List.iter (fun suite -> if !verbosity >= 2 then lock_printf "%% producer now treating test %s\n%!" suite; - (* the "suite" may be a directory or a single file *) + (* the "suite" may be a directory or a single file *) let interpret_as_file = interpret_as_file suite in let directory = SubDir.create (if interpret_as_file @@ -1641,11 +1641,11 @@ let () = let file = dir_files.(i) in assert (Filename.is_relative file); if test_pattern dir_config file && - (not (List.mem (SubDir.make_file directory file) exclude_file)) + (not (List.mem (SubDir.make_file directory file) exclude_file)) then Queue.push (file, directory, dir_config) files; done end - end) + end) suites let dispatcher () = @@ -1672,18 +1672,18 @@ let dispatcher () = } in let mk_cmd s = - { - file = file; - nb_files = nb_files; - log_files = []; - options = ""; - toplevel = s; - n = !e; - directory = directory; - filter = config.dc_filter; - macros = config.dc_macros; - execnow = true; - } + { + file = file; + nb_files = nb_files; + log_files = []; + options = ""; + toplevel = s; + n = !e; + directory = directory; + filter = config.dc_filter; + macros = config.dc_macros; + execnow = true; + } in let process_macros_cmd s = basic_command_string (mk_cmd s) in let macros = get_macros (mk_cmd "/bin/true") in @@ -1711,21 +1711,21 @@ let dispatcher () = then begin (match config.dc_execnow with | hd :: tl -> - let subworkqueue = Queue.create () in - List.iter (treat_option subworkqueue) config.dc_toplevels; - let target = - List.fold_left - (fun current_target execnow -> - let subworkqueue = Queue.create () in - Queue.add current_target subworkqueue; - Target(make_execnow_cmd execnow,subworkqueue)) - (Target(make_execnow_cmd hd,subworkqueue)) tl - in - Queue.push target shared.commands + let subworkqueue = Queue.create () in + List.iter (treat_option subworkqueue) config.dc_toplevels; + let target = + List.fold_left + (fun current_target execnow -> + let subworkqueue = Queue.create () in + Queue.add current_target subworkqueue; + Target(make_execnow_cmd execnow,subworkqueue)) + (Target(make_execnow_cmd hd,subworkqueue)) tl + in + Queue.push target shared.commands | [] -> - List.iter - (treat_option shared.commands) - config.dc_toplevels); + List.iter + (treat_option shared.commands) + config.dc_toplevels); Condition.broadcast shared.work_available; end; unlock () ; @@ -1736,7 +1736,7 @@ let dispatcher () = let () = let worker_ids = Array.init !n - (fun _ -> Thread.create worker_thread ()) + (fun _ -> Thread.create worker_thread ()) in let diff_id = Thread.create diff_thread () in @@ -1745,12 +1745,12 @@ let () = then lock_printf "%% Dispatch finished, waiting for workers to complete@."; ignore (Thread.create - (fun () -> - while true do - Condition.broadcast shared.work_available; - Thread.delay 0.5; - done) - ()); + (fun () -> + while true do + Condition.broadcast shared.work_available; + Thread.delay 0.5; + done) + ()); Array.iter Thread.join worker_ids; if !behavior = Run @@ -1760,12 +1760,12 @@ let () = shared.cmp_finished <- true; unlock(); ignore (Thread.create - (fun () -> - while true do - Condition.broadcast shared.diff_available; - Thread.delay 0.5; - done) - ()); + (fun () -> + while true do + Condition.broadcast shared.diff_available; + Thread.delay 0.5; + done) + ()); Thread.join diff_id; if !behavior = Run then @@ -1773,7 +1773,7 @@ let () = shared.summary_run shared.summary_ok shared.summary_log ((Unix.times()).Unix.tms_cutime -. shared.summary_time); xunit_report (); - let error_code = + let error_code = if !do_error_code && shared.summary_log <> shared.summary_ok then 1 else 0 -- GitLab From 6099010a57c1e616d6c3dc3fa56a09055bb5c2a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Loi=CC=88c=20Correnson?= <loic.correnson@cea.fr> Date: Fri, 10 Apr 2020 13:14:43 +0200 Subject: [PATCH 178/218] [wp] removed -wp-check option --- src/plugins/wp/GuiList.ml | 2 +- src/plugins/wp/GuiProver.ml | 2 +- src/plugins/wp/ProofScript.ml | 2 +- src/plugins/wp/ProverCoq.ml | 30 ++------------- src/plugins/wp/ProverErgo.ml | 38 ++++++------------- src/plugins/wp/ProverTask.ml | 6 +-- src/plugins/wp/ProverTask.mli | 6 ++- src/plugins/wp/ProverWhy3.ml | 5 +-- src/plugins/wp/VCS.ml | 6 +-- src/plugins/wp/VCS.mli | 2 - src/plugins/wp/prover.ml | 35 ++++++++--------- src/plugins/wp/register.ml | 11 +----- src/plugins/wp/tests/wp_plugin/bit_test.c | 2 +- src/plugins/wp/tests/wp_plugin/model.i | 2 +- .../oracle_qualif/bit_test.res.oracle | 6 +-- .../wp_plugin/oracle_qualif/model.res.oracle | 6 +-- src/plugins/wp/tests/wp_plugin/rte.i | 2 +- src/plugins/wp/wp_parameters.ml | 10 ----- src/plugins/wp/wp_parameters.mli | 1 - 19 files changed, 54 insertions(+), 120 deletions(-) diff --git a/src/plugins/wp/GuiList.ml b/src/plugins/wp/GuiList.ml index 2187eebd8fb..17d2f761fce 100644 --- a/src/plugins/wp/GuiList.ml +++ b/src/plugins/wp/GuiList.ml @@ -52,7 +52,7 @@ let render_prover_result p = let icn_running = icn_stock "gtk-execute" in let open VCS in let icon_of_verdict = function - | Checked | NoResult -> icn_none + | NoResult -> icn_none | Valid -> icn_valid | Invalid -> icn_invalid | Unknown -> icn_unknown diff --git a/src/plugins/wp/GuiProver.ml b/src/plugins/wp/GuiProver.ml index c74179056de..eec80f95700 100644 --- a/src/plugins/wp/GuiProver.ml +++ b/src/plugins/wp/GuiProver.ml @@ -125,7 +125,7 @@ class prover ~(console:Wtext.text) ~prover = self#set_status `EXECUTE ; self#set_action ~tooltip:"Interrrupt Prover" ~icon:`STOP ~callback () ; Pretty_utils.ksfprintf self#set_label "%a (...)" VCS.pp_prover prover ; - | VCS.Valid | VCS.Checked -> + | VCS.Valid -> let callback () = self#run wpo in self#set_status ok_status ; self#set_action ~tooltip:"Run Prover" ~icon:`MEDIA_PLAY ~callback () ; diff --git a/src/plugins/wp/ProofScript.ml b/src/plugins/wp/ProofScript.ml index a7b3155076a..73c77b5b71d 100644 --- a/src/plugins/wp/ProofScript.ml +++ b/src/plugins/wp/ProofScript.ml @@ -316,7 +316,7 @@ let tactic_of_json js = (* -------------------------------------------------------------------------- *) let json_of_verdict = function - | VCS.NoResult | VCS.Checked | VCS.Computing _ -> `String "none" + | VCS.NoResult | VCS.Computing _ -> `String "none" | VCS.Valid -> `String "valid" | VCS.Unknown -> `String "unknown" | VCS.Timeout -> `String "timeout" diff --git a/src/plugins/wp/ProverCoq.ml b/src/plugins/wp/ProverCoq.ml index 2313a5ba111..446fceadc1b 100644 --- a/src/plugins/wp/ProverCoq.ml +++ b/src/plugins/wp/ProverCoq.ml @@ -435,10 +435,9 @@ class runcoq includes source = self#timeout (coq_timeout ()) ; Task.call (fun () -> - if not (Wp_parameters.Check.get ()) then - let name = Filename.basename source in - Wp_parameters.feedback ~ontty:`Transient - "[Coq] Compiling '%s'." name) () + let name = Filename.basename source in + Wp_parameters.feedback ~ontty:`Transient + "[Coq] Compiling '%s'." name) () >>= self#run ~logout ~logerr >>= fun r -> if r = 127 then Task.failed "Command '%s' not found" cmd @@ -523,13 +522,6 @@ type coq_wpo = { cw_includes : included list ; (* -R ... ... *) } -let make_check w = - Command.print_file w.cw_script - begin fun fmt -> - Command.pp_from_file fmt w.cw_goal ; - Format.fprintf fmt "Proof.@\nAdmitted.@\n@." ; - end - let make_script w script closing = Command.print_file w.cw_script begin fun fmt -> @@ -541,10 +533,6 @@ let try_script w script closing = make_script w script closing ; (new runcoq w.cw_includes w.cw_script)#check -let check_script w = - make_check w ; - (new runcoq w.cw_includes w.cw_script)#check - let rec try_hints w = function | [] -> Task.return false | (kind,script,closing) :: hints -> @@ -618,8 +606,6 @@ let prove_session ~mode w = end >>= Task.call (fun r -> if r then VCS.valid else VCS.unknown) -exception Admitted_not_proved - let gen_session w = begin make_script w " ...\n" "Qed." ; @@ -627,19 +613,9 @@ let gen_session w = Task.return VCS.no_result end -let check_session w = - compile_headers w.cw_includes false w.cw_headers >>= - (fun () -> check_script w) >>> function - | Task.Result true -> Task.return VCS.checked - | Task.Failed e -> Task.raised e - | Task.Canceled | Task.Timeout _ | Task.Result false -> - Task.raised Admitted_not_proved - let prove_session ~mode w = if Wp_parameters.Generate.get () then gen_session w - else if Wp_parameters.Check.get () then - check_session w else prove_session ~mode w diff --git a/src/plugins/wp/ProverErgo.ml b/src/plugins/wp/ProverErgo.ml index 8aa0d51c86a..9ad747a9afb 100644 --- a/src/plugins/wp/ProverErgo.ml +++ b/src/plugins/wp/ProverErgo.ml @@ -396,37 +396,21 @@ class altergo ~config ~pid ~gui ~file ~lines ~logout ~logerr = VCS.result ~time:(if gui then 0.0 else timer) ~steps verdict - with - | Not_found when Wp_parameters.Check.get () -> - if r = 0 then VCS.checked - else - begin - if Wp_parameters.verbose_atleast 1 then begin - ProverTask.pp_file ~message:"Alt-Ergo (stdout)" ~file:logout ; - ProverTask.pp_file ~message:"Alt-Ergo (stderr)" ~file:logerr ; - end; - VCS.failed "Alt-Ergo type-checking failed." - end - | Not_found -> - begin - if Wp_parameters.verbose_atleast 1 then begin - ProverTask.pp_file ~message:"Alt-Ergo (stdout)" ~file:logout ; - ProverTask.pp_file ~message:"Alt-Ergo (stderr)" ~file:logerr ; - end; - if r = 0 then VCS.failed "Unexpected Alt-Ergo output" - else VCS.kfailed "Alt-Ergo exits with status [%d]." r - end + with Not_found -> + begin + if Wp_parameters.verbose_atleast 1 then begin + ProverTask.pp_file ~message:"Alt-Ergo (stdout)" ~file:logout ; + ProverTask.pp_file ~message:"Alt-Ergo (stderr)" ~file:logerr ; + end; + if r = 0 then VCS.failed "Unexpected Alt-Ergo output" + else VCS.kfailed "Alt-Ergo exits with status [%d]." r + end method prove = files <- lines ; if gui then ergo#set_command (Wp_parameters.AltGrErgo.get ()) ; - if Wp_parameters.Check.get () then - ergo#add ["-type-only"] - else - begin - ergo#add_parameter ~name:"-proof" Wp_parameters.ProofTrace.get ; - ergo#add_parameter ~name:"-model" Wp_parameters.ProofTrace.get ; - end ; + ergo#add_parameter ~name:"-proof" Wp_parameters.ProofTrace.get ; + ergo#add_parameter ~name:"-model" Wp_parameters.ProofTrace.get ; let flags = List.filter (fun p -> p <> "qlet") (Wp_parameters.AltErgoFlags.get ()) in diff --git a/src/plugins/wp/ProverTask.ml b/src/plugins/wp/ProverTask.ml index ff94ff83913..c1c45be5d62 100644 --- a/src/plugins/wp/ProverTask.ml +++ b/src/plugins/wp/ProverTask.ml @@ -28,7 +28,6 @@ open Task let dkey_prover = Wp_parameters.register_category "prover" - (* -------------------------------------------------------------------------- *) (* --- Export Printer --- *) (* -------------------------------------------------------------------------- *) @@ -315,7 +314,8 @@ let schedule task = Task.spawn server (Task.thread task) let silent _ = () -let spawn ?(monitor=silent) ?pool (jobs : ('a * bool Task.task) list) = +let spawn ?(monitor=silent) ?pool ~all + (jobs : ('a * bool Task.task) list) = if jobs <> [] then begin let step = ref 0 in @@ -323,7 +323,7 @@ let spawn ?(monitor=silent) ?pool (jobs : ('a * bool Task.task) list) = let canceled = ref false in let callback a r = if r then - begin if not !canceled && not (Wp_parameters.RunAllProvers.get()) then + begin if not all && not !canceled then begin canceled := true ; monitor (Some a) ; diff --git a/src/plugins/wp/ProverTask.mli b/src/plugins/wp/ProverTask.mli index a585b37e0d5..4f0bc09934e 100644 --- a/src/plugins/wp/ProverTask.mli +++ b/src/plugins/wp/ProverTask.mli @@ -85,8 +85,10 @@ val schedule : 'a Task.task -> unit val spawn : ?monitor:('a option -> unit) -> ?pool:Task.pool -> + all:bool -> ('a * bool Task.task) list -> unit + (** Spawn all the tasks over the server and retain the first 'validated' one. The callback [monitor] is called with [Some] at first success, and [None] - if none succeed. - An option [pool] task can be passed to register the associated threads. *) + if none succeed. An option [pool] task can be passed to register + the associated threads. *) diff --git a/src/plugins/wp/ProverWhy3.ml b/src/plugins/wp/ProverWhy3.ml index 7f1b7515561..b4074ed1bb1 100644 --- a/src/plugins/wp/ProverWhy3.ml +++ b/src/plugins/wp/ProverWhy3.ml @@ -1338,7 +1338,7 @@ let steps_seized steps steplimit = let promote ~timeout ~steplimit (res : VCS.result) = match res.verdict with - | VCS.NoResult | VCS.Computing _ | VCS.Checked -> VCS.no_result + | VCS.NoResult | VCS.Computing _ -> VCS.no_result | VCS.Failed -> res | VCS.Invalid | VCS.Valid | VCS.Unknown -> if not (steps_fits res.prover_steps steplimit) then @@ -1404,9 +1404,6 @@ let build_proof_task ?timeout ?steplimit ~prover wpo () = (* Always generate common task *) let context = Wpo.get_context wpo in let task = WpContext.on_context context task_of_wpo wpo in - if Wp_parameters.Check.get () - then Task.return VCS.checked (* Why3 tasks are type-checked *) - else if Wp_parameters.Generate.get () then Task.return VCS.no_result (* Only generate *) else diff --git a/src/plugins/wp/VCS.ml b/src/plugins/wp/VCS.ml index db0cb3b6584..57a3b380532 100644 --- a/src/plugins/wp/VCS.ml +++ b/src/plugins/wp/VCS.ml @@ -194,7 +194,6 @@ type verdict = | Timeout | Stepout | Computing of (unit -> unit) (* kill function *) - | Checked | Valid | Failed @@ -209,7 +208,7 @@ type result = { } let is_verdict r = match r.verdict with - | Valid | Checked | Unknown | Invalid | Timeout | Stepout | Failed -> true + | Valid | Unknown | Invalid | Timeout | Stepout | Failed -> true | NoResult | Computing _ -> false let is_valid = function { verdict = Valid } -> true | _ -> false @@ -276,7 +275,6 @@ let result ?(cached=false) ?(solver=0.0) ?(time=0.0) ?(steps=0) verdict = let no_result = result NoResult let valid = result Valid -let checked = result Checked let invalid = result Invalid let unknown = result Unknown let timeout t = result ~time:(float t) Timeout @@ -317,7 +315,6 @@ let pp_res ~extended fmt r = match r.verdict with | NoResult -> Format.pp_print_string fmt (if extended then "No Result" else "-") | Computing _ -> Format.pp_print_string fmt "Computing" - | Checked -> Format.fprintf fmt "Typechecked" | Invalid -> Format.pp_print_string fmt "Invalid" | Valid when Wp_parameters.has_dkey dkey_success_only -> Format.pp_print_string fmt "Valid" @@ -340,7 +337,6 @@ let compare p q = | Timeout | Stepout -> 3 | Valid -> 4 | Invalid -> 5 - | Checked -> 6 in let r = rank q.verdict - rank p.verdict in if r <> 0 then r else diff --git a/src/plugins/wp/VCS.mli b/src/plugins/wp/VCS.mli index dae1064fb01..6f37aab30d3 100644 --- a/src/plugins/wp/VCS.mli +++ b/src/plugins/wp/VCS.mli @@ -80,7 +80,6 @@ type verdict = | Timeout | Stepout | Computing of (unit -> unit) (* kill function *) - | Checked | Valid | Failed @@ -96,7 +95,6 @@ type result = { val no_result : result val valid : result -val checked : result val invalid : result val unknown : result val stepout : int -> result diff --git a/src/plugins/wp/prover.ml b/src/plugins/wp/prover.ml index 59e5e5497e9..78092c65d91 100644 --- a/src/plugins/wp/prover.ml +++ b/src/plugins/wp/prover.ml @@ -97,27 +97,28 @@ let prove wpo ?config ?mode ?start ?progress ?result prover = let spawn wpo ~delayed ?config ?start ?progress ?result ?success ?pool provers = if provers<>[] then - let do_monitor on_success wpo = function - | None -> on_success wpo None - | Some prover -> - let r = Wpo.get_result wpo VCS.Qed in - let prover = - if VCS.( r.verdict == Valid ) then VCS.Qed else prover in - on_success wpo (Some prover) - in let monitor = match success with | None -> None - | Some on_success -> Some (do_monitor on_success wpo) - in + | Some on_success -> + Some + begin function + | None -> on_success wpo None + | Some prover -> + let r = Wpo.get_result wpo VCS.Qed in + let prover = + if VCS.( r.verdict == Valid ) then VCS.Qed else prover in + on_success wpo (Some prover) + end in let process (mode,prover) = prove wpo ?config ~mode ?start ?progress ?result prover in - let canceled = - match success with None -> None | Some f -> Some (fun _ -> f wpo None) in - ProverTask.spawn ?monitor ?pool - (List.map (fun mp -> snd mp , - if delayed then Task.later ?canceled process mp - else process mp) - provers) + let all = Wp_parameters.RunAllProvers.get() in + ProverTask.spawn ?monitor ?pool ~all + (List.map + (fun mp -> + let prover = snd mp in + let task = if delayed then Task.later process mp else process mp in + prover , task + ) provers) else let process = simplify ?start ?result wpo in let thread = Task.thread process in diff --git a/src/plugins/wp/register.ml b/src/plugins/wp/register.ml index 509dbcb3e7b..bb74fcb202c 100644 --- a/src/plugins/wp/register.ml +++ b/src/plugins/wp/register.ml @@ -351,7 +351,7 @@ let do_wpo_stat goal prover res = let smoke = Wpo.is_smoke_test goal in let verdict = VCS.verdict ~smoke res in match verdict with - | Checked | NoResult | Computing _ | Unknown -> + | NoResult | Computing _ | Unknown -> s.unknown <- succ s.unknown | Stepout | Timeout -> s.interrupted <- succ s.interrupted @@ -369,15 +369,6 @@ let do_wpo_stat goal prover res = let do_wpo_result goal prover res = if VCS.is_verdict res then begin - if Wp_parameters.Check.get () then - begin - let open VCS in - let ontty = if res.verdict = Checked then `Feedback else `Message in - Wp_parameters.feedback ~ontty - "[%a] Goal %s : %a" - VCS.pp_prover prover (Wpo.get_gid goal) - VCS.pp_result res ; - end ; if prover = VCS.Qed then do_progress goal "Qed" ; do_wpo_stat goal prover res ; end diff --git a/src/plugins/wp/tests/wp_plugin/bit_test.c b/src/plugins/wp/tests/wp_plugin/bit_test.c index b0b19bf9b8c..96f24adfa14 100644 --- a/src/plugins/wp/tests/wp_plugin/bit_test.c +++ b/src/plugins/wp/tests/wp_plugin/bit_test.c @@ -3,7 +3,7 @@ */ /* run.config_qualif - OPT: -wp-driver tests/wp_plugin/bit_test.driver -wp-prover why3:alt-ergo -wp-check + OPT: -wp-driver tests/wp_plugin/bit_test.driver -wp-prover why3:alt-ergo */ /*@ diff --git a/src/plugins/wp/tests/wp_plugin/model.i b/src/plugins/wp/tests/wp_plugin/model.i index 4b57d2f03e0..81b49ed20d4 100644 --- a/src/plugins/wp/tests/wp_plugin/model.i +++ b/src/plugins/wp/tests/wp_plugin/model.i @@ -4,7 +4,7 @@ */ /* run.config_qualif - OPT: -wp-msg-key print-generated -wp-model Typed -wp-check -then -wp -wp-model Typed+ref -wp-check + OPT: -wp-msg-key print-generated -wp-model Typed -then -wp -wp-model Typed+ref */ //@ predicate P(integer a); diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/bit_test.res.oracle b/src/plugins/wp/tests/wp_plugin/oracle_qualif/bit_test.res.oracle index 6ee9e856658..f6a082b42cc 100644 --- a/src/plugins/wp/tests/wp_plugin/oracle_qualif/bit_test.res.oracle +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/bit_test.res.oracle @@ -4,9 +4,9 @@ [wp] Loading driver 'share/wp.driver' [wp] Warning: Missing RTE guards [wp] 3 goals scheduled -[wp] [Alt-Ergo] Goal typed_bit_test_check1_ensures_ko : Typechecked -[wp] [Alt-Ergo] Goal typed_bit_test_check2_ensures_ko : Typechecked -[wp] [Alt-Ergo] Goal typed_bit_test_check3_ensures_ko : Typechecked +[wp] [Alt-Ergo] Goal typed_bit_test_check1_ensures_ko : Unsuccess +[wp] [Alt-Ergo] Goal typed_bit_test_check2_ensures_ko : Unsuccess +[wp] [Alt-Ergo] Goal typed_bit_test_check3_ensures_ko : Unsuccess [wp] Proved goals: 0 / 3 Alt-Ergo: 0 (unsuccess: 3) ------------------------------------------------------------ diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/model.res.oracle b/src/plugins/wp/tests/wp_plugin/oracle_qualif/model.res.oracle index 43185ba1c36..45defe11c25 100644 --- a/src/plugins/wp/tests/wp_plugin/oracle_qualif/model.res.oracle +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/model.res.oracle @@ -77,7 +77,7 @@ end let x = get t (shift_sint32 a i) in region (base a) <= 0 -> is_sint32 i -> is_sint32 x -> P_P x end -[wp] [Alt-Ergo] Goal typed_f_ensures : Typechecked +[wp] [Alt-Ergo] Goal typed_f_ensures : Unsuccess [wp] Proved goals: 0 / 1 Alt-Ergo: 0 (unsuccess: 1) ------------------------------------------------------------ @@ -115,7 +115,7 @@ end let x = get t (shift_sint32 a i) in region (base a) <= 0 -> is_sint32 i -> is_sint32 x -> P_P x end -[wp] [Alt-Ergo] Goal typed_f_ensures : Typechecked +[wp] [Alt-Ergo] Goal typed_f_ensures : Unsuccess --------------------------------------------- --- Context 'typed_ref_f' Cluster 'Compound' --------------------------------------------- @@ -187,7 +187,7 @@ end let x = get1 t (shift_sint321 a i) in region1 (base1 a) <=' 0 -> is_sint321 i -> is_sint321 x -> P_P1 x end -[wp] [Alt-Ergo] Goal typed_ref_f_ensures : Typechecked +[wp] [Alt-Ergo] Goal typed_ref_f_ensures : Unsuccess [wp] Proved goals: 0 / 2 Alt-Ergo: 0 (unsuccess: 2) ------------------------------------------------------------ diff --git a/src/plugins/wp/tests/wp_plugin/rte.i b/src/plugins/wp/tests/wp_plugin/rte.i index 1b63b3768c8..65e8988e572 100644 --- a/src/plugins/wp/tests/wp_plugin/rte.i +++ b/src/plugins/wp/tests/wp_plugin/rte.i @@ -1,5 +1,5 @@ /* run.config - CMD: @frama-c@ -wp -wp-prover none -wp-check -wp-share ./share -wp-msg-key shell -wp-msg-key rte + CMD: @frama-c@ -wp -wp-prover none -wp-share ./share -wp-msg-key shell -wp-msg-key rte OPT: -wp-rte -no-warn-invalid-bool -then -print -no-unicode OPT: -wp-rte -no-warn-signed-overflow -then -print -no-unicode OPT: -wp-rte -warn-unsigned-overflow -then -print -no-unicode diff --git a/src/plugins/wp/wp_parameters.ml b/src/plugins/wp/wp_parameters.ml index 219694d2e8f..630ee22a7c0 100644 --- a/src/plugins/wp/wp_parameters.ml +++ b/src/plugins/wp/wp_parameters.ml @@ -992,16 +992,6 @@ module OutputDir = Defaults to some temporary directory." end) -let () = Parameter_customize.set_group wp_po -let () = Parameter_customize.do_not_save () -module Check = - Action(struct - let option_name = "-wp-check" - let help = - "Check the syntax and type of the produced file, instead of proving." - end) -let () = on_reset Print.clear - (* -------------------------------------------------------------------------- *) (* --- Overflows --- *) (* -------------------------------------------------------------------------- *) diff --git a/src/plugins/wp/wp_parameters.mli b/src/plugins/wp/wp_parameters.mli index af829e5f8a2..2d763525c65 100644 --- a/src/plugins/wp/wp_parameters.mli +++ b/src/plugins/wp/wp_parameters.mli @@ -146,7 +146,6 @@ module Report: Parameter_sig.String_list module ReportJson: Parameter_sig.String module ReportName: Parameter_sig.String module MemoryContext: Parameter_sig.Bool -module Check: Parameter_sig.Bool module SmokeTests: Parameter_sig.Bool (** {2 Getters} *) -- GitLab From 8185a987d355bf088d52730f4cf7d60cf249afc5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Loi=CC=88c=20Correnson?= <loic.correnson@cea.fr> Date: Fri, 10 Apr 2020 13:15:24 +0200 Subject: [PATCH 179/218] [lib] improved dotgraph API --- src/libraries/utils/dotgraph.ml | 8 +++---- src/libraries/utils/dotgraph.mli | 36 +++++++++++--------------------- src/plugins/wp/RegionDump.ml | 6 +++--- 3 files changed, 19 insertions(+), 31 deletions(-) diff --git a/src/libraries/utils/dotgraph.ml b/src/libraries/utils/dotgraph.ml index a3520a869df..f162ef75c89 100644 --- a/src/libraries/utils/dotgraph.ml +++ b/src/libraries/utils/dotgraph.ml @@ -154,7 +154,7 @@ let println dot msg = Format.kfprintf (fun fmt -> Format.pp_print_newline fmt ()) dot.fmt msg let push dot f = Queue.push f dot.queue -let pop_all dot = +let run dot = while not (Queue.is_empty dot.queue) do (Queue.pop dot.queue) () done @@ -342,6 +342,7 @@ struct let node = Printf.sprintf "%s%03d" prefix k in index := M.add a node !index ; !once a node ; node + let add a = ignore (get a) let node dot a attr = node dot (get a) attr let inode dot a attr = inode dot ~id:(get a) attr @@ -353,9 +354,8 @@ struct let prefix p = prefix := Some p - let once f = once := f - let push dot f = once (fun a n -> push dot (fun () -> f a n)) - let clear () = index := M.empty ; kid := 0 ; once skip + let define dot f = once := fun a n -> push dot (fun () -> f a n) + let clear () = index := M.empty ; kid := 0 ; once := skip end (* -------------------------------------------------------------------------- *) diff --git a/src/libraries/utils/dotgraph.mli b/src/libraries/utils/dotgraph.mli index 6cd0fb8bd64..12d7faeb84e 100644 --- a/src/libraries/utils/dotgraph.mli +++ b/src/libraries/utils/dotgraph.mli @@ -40,18 +40,15 @@ begin let dot = G.open_dot ~name:"mygraph" () in (* For each generated node, declare it and link to its children. *) - N.push dot - (fun a -> - let na = N.inode dot a in + N.define dot + (fun a na -> try List.iter - (fun b -> G.link dot na (N.get b)) + (fun b -> G.edge dot na (N.get b) []) (M.find a graph) with Not_found -> ()) ; - (* Starts by emitting roots *) - List.iter - (fun r -> ignore (N.get r)) - roots ; + (* Starts by emitting some roots, or all nodes *) + List.iter N.add roots ; (* Proceeds to the traversal *) G.pop_all dot ; (* You may then complete your graph @@ -214,6 +211,7 @@ end module Node(M : Map) : sig type t = M.key + val add : t -> unit val get : t -> node val node : dot -> t -> attr list -> unit val inode : dot -> t -> attr list -> node @@ -221,22 +219,12 @@ sig val irecord : dot -> t -> ?rounded:bool -> ?attr:attr list -> record -> node val clear : unit -> unit - (** Executes the callback {i once} for all created nodes. - Any previously registered callback by [once] or [push] is replaced - by the new one. - - {b Warning:} the callback is executed as soon as [get] is called - for the first time, possibly interfering with your current output - on a [dot] buffer. To insert additional Dot material with a callback, - use [push] instead. - *) - val once : (t -> node -> unit) -> unit - - (** Pushes the callback {i once} for all created nodes. - You must call [pop_call] at some point to flush them. - Any previsously registred callback by [once] or [push] is replaced + (** Pushes the callback which will be executed {i once} + for all created nodes. + You must call [run dot] at some point to flush them. + Any previsously registred callback is replaced by the new one. *) - val push : dot -> (t -> node -> unit) -> unit + val define : dot -> (t -> node -> unit) -> unit (** Set node prefix. Otherwize, some default one is created for each functor application. *) @@ -247,7 +235,7 @@ end val push : dot -> (unit -> unit) -> unit (** Flushes all pending continuations. *) -val pop_all : dot -> unit +val run : dot -> unit (** {1 Decorator} *) diff --git a/src/plugins/wp/RegionDump.ml b/src/plugins/wp/RegionDump.ml index da852ab007a..a52e783d163 100644 --- a/src/plugins/wp/RegionDump.ml +++ b/src/plugins/wp/RegionDump.ml @@ -261,10 +261,10 @@ let dotgraph dot map = G.node_default dot node_default ; G.edge_default dot edge_default ; R.clear () ; - R.push dot (dotregion dot map) ; + R.define dot (dotregion dot map) ; Region.iter_vars map (dotvar dot) ; Region.iter_strings map (dotstr dot) ; - G.pop_all dot ; + G.run dot ; if Wp.has_dkey rid_key then Region.iter map (dotrid dot) ; Region.iter_names map (dotlabel dot) ; if Region.has_return map then @@ -276,7 +276,7 @@ let dotgraph dot map = else dotlabel dot "Fusion (Self)" r ) ; - G.pop_all dot ; + G.run dot ; end let dump ~dir kf map = -- GitLab From d37b98370caa8b6622937d9816cc0912567fc124 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Loi=CC=88c=20Correnson?= <loic.correnson@cea.fr> Date: Fri, 10 Apr 2020 13:15:48 +0200 Subject: [PATCH 180/218] [wp] extended smoke tests --- headers/header_spec.txt | 2 + src/plugins/wp/Makefile.in | 2 +- src/plugins/wp/Splitter.ml | 9 +- src/plugins/wp/Splitter.mli | 3 +- src/plugins/wp/VCS.ml | 13 +- src/plugins/wp/VCS.mli | 1 + src/plugins/wp/calculus.ml | 5 + src/plugins/wp/cfgWP.ml | 30 +- src/plugins/wp/doc/manual/wp_plugin.tex | 21 +- src/plugins/wp/register.ml | 80 ++--- src/plugins/wp/tests/wp_plugin/doomed_call.i | 122 +++++++ src/plugins/wp/tests/wp_plugin/doomed_dead.i | 96 ++++++ .../wp_plugin/oracle/doomed.1.res.oracle | 10 +- .../wp_plugin/oracle/doomed_axioms.res.oracle | 34 +- .../wp_plugin/oracle/doomed_loop.res.oracle | 12 +- .../wp_plugin/oracle/doomed_unroll.res.oracle | 15 + .../wp_plugin/oracle_qualif/doomed.res.oracle | 16 +- .../oracle_qualif/doomed_axioms.res.oracle | 19 +- .../oracle_qualif/doomed_call.0.res.oracle | 29 ++ .../oracle_qualif/doomed_call.1.res.oracle | 63 ++++ .../oracle_qualif/doomed_call.2.res.oracle | 66 ++++ .../oracle_qualif/doomed_dead.0.res.oracle | 69 ++++ .../oracle_qualif/doomed_dead.1.res.oracle | 71 +++++ .../oracle_qualif/doomed_loop.res.oracle | 19 +- .../oracle_qualif/doomed_report_ko.res.oracle | 29 +- .../oracle_qualif/doomed_report_ok.res.oracle | 20 +- .../oracle_qualif/doomed_unroll.res.oracle | 12 +- .../d8be6e9b6d537a313b4ec0e4a4a74e3a.json | 1 + .../438d25bfabd351c105105d10af4c170a.json | 1 + .../scripts/unrolled_loop_ensures_zero.json | 54 ++++ src/plugins/wp/wpAnnot.ml | 124 ++++---- src/plugins/wp/wpAnnot.mli | 12 +- src/plugins/wp/wpPropId.ml | 17 +- src/plugins/wp/wpPropId.mli | 3 + src/plugins/wp/wpReached.ml | 299 ++++++++++++++++++ src/plugins/wp/wpReached.mli | 52 +++ src/plugins/wp/wpReport.ml | 32 +- src/plugins/wp/wpStrategy.ml | 31 +- src/plugins/wp/wpStrategy.mli | 17 +- src/plugins/wp/wp_parameters.ml | 21 ++ src/plugins/wp/wp_parameters.mli | 3 + src/plugins/wp/wpo.ml | 118 +++---- src/plugins/wp/wpo.mli | 2 +- 43 files changed, 1395 insertions(+), 260 deletions(-) create mode 100644 src/plugins/wp/tests/wp_plugin/doomed_call.i create mode 100644 src/plugins/wp/tests/wp_plugin/doomed_dead.i create mode 100644 src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_call.0.res.oracle create mode 100644 src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_call.1.res.oracle create mode 100644 src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_call.2.res.oracle create mode 100644 src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_dead.0.res.oracle create mode 100644 src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_dead.1.res.oracle create mode 100644 src/plugins/wp/tests/wp_plugin/oracle_qualif/float_real.1.session/cache/d8be6e9b6d537a313b4ec0e4a4a74e3a.json create mode 100644 src/plugins/wp/tests/wp_plugin/oracle_qualif/model.0.session/cache/438d25bfabd351c105105d10af4c170a.json create mode 100644 src/plugins/wp/tests/wp_plugin/unroll/wp/scripts/unrolled_loop_ensures_zero.json create mode 100644 src/plugins/wp/wpReached.ml create mode 100644 src/plugins/wp/wpReached.mli diff --git a/headers/header_spec.txt b/headers/header_spec.txt index c93566dd8f2..593ff2ec4ba 100644 --- a/headers/header_spec.txt +++ b/headers/header_spec.txt @@ -1775,6 +1775,8 @@ src/plugins/wp/wpContext.ml: CEA_WP src/plugins/wp/wpContext.mli: CEA_WP src/plugins/wp/wpPropId.ml: CEA_WP src/plugins/wp/wpPropId.mli: CEA_WP +src/plugins/wp/wpReached.ml: CEA_WP +src/plugins/wp/wpReached.mli: CEA_WP src/plugins/wp/wpReport.ml: CEA_WP src/plugins/wp/wpReport.mli: CEA_WP src/plugins/wp/wpRTE.ml: CEA_WP diff --git a/src/plugins/wp/Makefile.in b/src/plugins/wp/Makefile.in index 9b3384e53f8..25abfcc1650 100644 --- a/src/plugins/wp/Makefile.in +++ b/src/plugins/wp/Makefile.in @@ -81,7 +81,7 @@ PLUGIN_CMO:= \ Sigma MemLoader \ MemEmpty MemZeroAlias MemVar \ MemMemory MemTyped MemRegion \ - wpStrategy wpRTE wpAnnot \ + wpReached wpStrategy wpRTE wpAnnot \ CfgCompiler StmtSemantics \ VCS script proof wpo wpReport \ Footprint Tactical Strategy \ diff --git a/src/plugins/wp/Splitter.ml b/src/plugins/wp/Splitter.ml index fff59f0cda6..b5930b40748 100644 --- a/src/plugins/wp/Splitter.ml +++ b/src/plugins/wp/Splitter.ml @@ -28,7 +28,6 @@ open Cil_types open Cil_datatype type tag = - | MARK of stmt | THEN of stmt | ELSE of stmt | CALL of stmt * kernel_function @@ -37,7 +36,6 @@ type tag = | ASSERT of identified_predicate * int * int (* part *) let pretty fmt = function - | MARK _ -> Format.fprintf fmt "Stmt" | THEN _ -> Format.fprintf fmt "Then" | ELSE _ -> Format.fprintf fmt "Else" | CASE(_,[]) -> Format.fprintf fmt "Case(s)" @@ -51,15 +49,12 @@ let pretty fmt = function | ASSERT(_,k,n) -> Format.fprintf fmt "Disjunction (%d/%d)" k n let loc = function - | THEN s | ELSE s | MARK s | CASE(s,_) | CALL(s,_) | DEFAULT s -> Stmt.loc s + | THEN s | ELSE s | CASE(s,_) | CALL(s,_) | DEFAULT s -> Stmt.loc s | ASSERT(p,_,_) -> p.ip_content.pred_loc let compare p q = if p == q then 0 else match p,q with - | MARK s , MARK t -> Stmt.compare s t - | MARK _ , _ -> (-1) - | _ , MARK _ -> 1 | THEN s , THEN t -> Stmt.compare s t | THEN _ , _ -> (-1) | _ , THEN _ -> 1 @@ -129,7 +124,6 @@ let switch_cases stmt ks = CASE(stmt,ks) let switch_default stmt = DEFAULT stmt let if_then stmt = THEN stmt let if_else stmt = ELSE stmt -let mark stmt = MARK stmt let call stmt kf = CALL(stmt,kf) (* -------------------------------------------------------------------------- *) @@ -178,6 +172,7 @@ let group tag merge m = let length = List.length let empty = [] let singleton e = [[],e] +let unmark merge m = [[] , merge (List.map snd m)] let union merge m1 m2 = M.union (fun _ -> merge) m1 m2 let rec merge ~left ~both ~right m1 m2 = diff --git a/src/plugins/wp/Splitter.mli b/src/plugins/wp/Splitter.mli index 655230e3f58..6604b2fcd7d 100644 --- a/src/plugins/wp/Splitter.mli +++ b/src/plugins/wp/Splitter.mli @@ -23,7 +23,6 @@ open Cil_types type tag = - | MARK of stmt | THEN of stmt | ELSE of stmt | CALL of stmt * kernel_function @@ -34,7 +33,6 @@ type tag = val loc : tag -> location val pretty : Format.formatter -> tag -> unit -val mark : stmt -> tag val if_then : stmt -> tag val if_else : stmt -> tag val switch_cases : stmt -> int64 list -> tag @@ -56,6 +54,7 @@ val merge : 'a t -> 'b t -> 'c t val merge_all : ('a list -> 'a) -> 'a t list -> 'a t +val unmark : ('a list -> 'a) -> 'a t -> 'a t (** erase all tags *) val length : 'a t -> int diff --git a/src/plugins/wp/VCS.ml b/src/plugins/wp/VCS.ml index 57a3b380532..8d76eddc45b 100644 --- a/src/plugins/wp/VCS.ml +++ b/src/plugins/wp/VCS.ml @@ -214,13 +214,12 @@ let is_verdict r = match r.verdict with let is_valid = function { verdict = Valid } -> true | _ -> false let is_computing = function { verdict=Computing _ } -> true | _ -> false -let verdict ~smoke r = - if smoke then - match r.verdict with - | (Failed | NoResult | Checked | Computing _) as r -> r - | Valid -> Invalid - | Invalid | Unknown | Timeout | Stepout -> Valid - else r.verdict +let smoked = function + | (Failed | NoResult | Computing _) as r -> r + | Valid -> Invalid + | Invalid | Unknown | Timeout | Stepout -> Valid + +let verdict ~smoke r = if smoke then smoked r.verdict else r.verdict let is_proved ~smoke r = (verdict ~smoke r = Valid) diff --git a/src/plugins/wp/VCS.mli b/src/plugins/wp/VCS.mli index 6f37aab30d3..370fb5be0d5 100644 --- a/src/plugins/wp/VCS.mli +++ b/src/plugins/wp/VCS.mli @@ -112,6 +112,7 @@ val is_valid: result -> bool val is_computing: result -> bool val is_proved: smoke:bool -> result -> bool +val smoked : verdict -> verdict val verdict: smoke:bool -> result -> verdict val configure : result -> config diff --git a/src/plugins/wp/calculus.ml b/src/plugins/wp/calculus.ml index 2f3c5e7e07f..b380551db5c 100644 --- a/src/plugins/wp/calculus.ml +++ b/src/plugins/wp/calculus.ml @@ -420,6 +420,9 @@ module Cfg (W : Mcfg.S) = struct | Some _ -> obj | None -> assert false + let add_call_post wenv annots kf obj = + List.fold_left (add_goal wenv) obj (WpStrategy.get_call_post annots kf) + let wp_call_kf wenv cenv stmt lval kf args precond ~p_post ~p_exit = let call_asgn = WpStrategy.get_call_asgn cenv.post_annots (Some kf) in let assigns = match call_asgn with @@ -428,6 +431,8 @@ module Cfg (W : Mcfg.S) = struct | WpPropId.AssignsAny _ -> WritesAny | WpPropId.NoAssignsInfo -> assert false (* see above *) in + let p_post = add_call_post wenv cenv.post_annots kf p_post in + let p_exit = add_call_post wenv cenv.exit_annots kf p_exit in let pre_hyp, pre_goals = WpStrategy.get_call_pre cenv.pre_annots kf in let obj = W.call wenv stmt lval kf args ~pre:(pre_hyp) diff --git a/src/plugins/wp/cfgWP.ml b/src/plugins/wp/cfgWP.ml index 6085b6bff43..6108632979a 100644 --- a/src/plugins/wp/cfgWP.ml +++ b/src/plugins/wp/cfgWP.ml @@ -76,6 +76,9 @@ struct let equal g1 g2 = (compare g1 g2 = 0) let prop_id = function Gprop p | Gposteffect p | Geffect(p,_,_) -> p let source = function Gprop _ | Gposteffect _ -> None | Geffect(_,s,e) -> Some(s,e) + let is_smoke_test = function + | Gprop p -> WpPropId.is_smoke_test p + | Gposteffect _ | Geffect _ -> false let pretty fmt = function | Gprop p -> WpPropId.pretty fmt p | Geffect(p,s,FromCode) -> Format.fprintf fmt "%a at sid:%d" WpPropId.pretty p s.sid @@ -344,7 +347,13 @@ struct let targets = List.fold_left (fun goals vcs -> Gset.union goals (Gmap.domain vcs)) Gset.empty cases in - let goal g vcs = try Gmap.find g vcs with Not_found -> Splitter.empty in + let goal g vcs = + try + let vcs = Gmap.find g vcs in + if TARGET.is_smoke_test g + then Splitter.unmark merge_vcs vcs + else vcs + with Not_found -> Splitter.empty in Gset.mapping (fun g -> Splitter.merge_all merge_vcs (List.map (goal g) cases)) targets @@ -749,9 +758,9 @@ struct let condition ~descr ?stmt ?warn pa h vc = passify_vc pa (assume_vc ?stmt ?warn ~descr h vc) - let mark m = function + let mark ?(smoke=false) m = function | None -> Splitter.empty - | Some s -> Splitter.group m merge_vcs s + | Some s -> if smoke then s else Splitter.group m merge_vcs s let random () = let v = Lang.freshvar ~basename:"cond" Logic.Bool in @@ -781,12 +790,15 @@ struct let vcs = if dosplit then let cneg = p_not cond in - let vcs1 = gmap (condition pa1 ~stmt ~warn ~descr:"Then" [cond]) wp1.vcs in - let vcs2 = gmap (condition pa2 ~stmt ~warn ~descr:"Else" [cneg]) wp2.vcs in + let vcs1 = + gmap (condition pa1 ~stmt ~warn ~descr:"Then" [cond]) wp1.vcs in + let vcs2 = + gmap (condition pa2 ~stmt ~warn ~descr:"Else" [cneg]) wp2.vcs in Gmap.merge - (fun _g w1 w2 -> - let s1 = mark (Splitter.if_then stmt) w1 in - let s2 = mark (Splitter.if_else stmt) w2 in + (fun g w1 w2 -> + let smoke = TARGET.is_smoke_test g in + let s1 = mark ~smoke (Splitter.if_then stmt) w1 in + let s2 = mark ~smoke (Splitter.if_else stmt) w2 in Some (Splitter.union (merge_vc) s1 s2) ) vcs1 vcs2 else @@ -1342,7 +1354,7 @@ struct else Bag.concat trivial_wpo provers_wpo in - WpAnnot.split + WpPropId.split_bag begin fun po_pid wpo -> let po_sid = WpPropId.get_propid po_pid in let po_leg = WpPropId.get_legacy po_pid in diff --git a/src/plugins/wp/doc/manual/wp_plugin.tex b/src/plugins/wp/doc/manual/wp_plugin.tex index 1b78a494694..403ea107b96 100644 --- a/src/plugins/wp/doc/manual/wp_plugin.tex +++ b/src/plugins/wp/doc/manual/wp_plugin.tex @@ -916,27 +916,30 @@ weakest precondition calculus. \subsection{Smoke Tests} During modular deductive verification, inconsistencies in function requirements -can be difficult to detect untill you actually call it. +can be difficult to detect until you actually call it. Although, such inconsistencies make its post-conditions provable, while its pre-conditions would never be provable. The \textsf{WP} plug-in can generate smoke-tests to detect such inconsistencies. Basically, it consists in checking if \verb+\false+ is provable under the requirements -or assumptions of a behavior, or under the invariants of a loop. +or assumptions of a behaviour, or under the invariants of a loop. Also, a simple reachability +analysis is performed to track dead-code statements and calls that neither terminates nor exits. This is best-effort verification : if at least one prover succeed in proving \verb+\false+, -an inconsistency is detected. Otherwized, the test is not conclusive, and you can never be sure -that your annotations are free of inconsistencies. +an inconsistency is detected. Otherwise, the test is not conclusive, and you can never be sure +that the ACSL annotations are free of inconsistencies. In case any smoke-test fails, a ``\textit{False if reachable}'' status is put on the -inconsistent requirements, or on the loop with inconsistent invariants, and finally, -\textsf{WP} generates a user error. +inconsistent requirements, or on the loop with inconsistent invariants, and +\textsf{WP} generates a user warning. \begin{description} -\item[\tt -wp-(no)-smoke-tests] generates checks to detect inconsistent - annotations. +\item[\tt -wp-(no)-smoke-tests] generates checks to detect inconsistencies. \item[\tt -wp-(no)-smoke-timeout] timeout to be used for trying to prove \verb+\false+ on smoke-tests (default is \verb+2+ seconds). +\item[\tt -wp-no-smoke-dead-code] exclude smoke tests for dead code. +\item[\tt -wp-no-smoke-dead-loop] exclude smoke tests for inconsistent loop invariants. +\item[\tt -wp-no-smoke-dead-call] exclude smoke tests for non-terminating calls. \end{description} When reporting prover results for smoke-tests, the \textsf{WP} displays @@ -1078,7 +1081,7 @@ Suppose you have the following configuration: \end{logs} Then, to use (for instance) \textsf{CVC4 1.6}, -you can use \verb+-wp-prover cvc4+ or \verb+-wp-prover CVC4:1.6+ +you can use \verb+-wp-prover cvc4+ or \verb+-wp-prover CVC4:1.6+. Similarly, if you want to use \textsf{Z3 4.6.0} without bitvectors, you can use \verb+-wp-prover z3-nobv+. Finally, since \textsf{Why-3} also provides the alias \verb+altergo+ for this prover, \verb+-wp-prover altergo+ will also run it \emph{via} \textsf{Why-3}. diff --git a/src/plugins/wp/register.ml b/src/plugins/wp/register.ml index bb74fcb202c..bc0cf0c9d05 100644 --- a/src/plugins/wp/register.ml +++ b/src/plugins/wp/register.ml @@ -373,8 +373,13 @@ let do_wpo_result goal prover res = do_wpo_stat goal prover res ; end +let results g = + List.filter + (fun (_,r) -> VCS.is_verdict r) + (Wpo.get_results g) + let do_wpo_failed goal = - match Wpo.get_results goal with + match results goal with | [p,r] -> Wp_parameters.result "[%a] Goal %s : %a%a" VCS.pp_prover p (Wpo.get_gid goal) @@ -390,45 +395,45 @@ let do_wpo_failed goal = ) pres ; end -let do_wpo_smoke goal = - let results = Wpo.get_results goal in - let verdicts = List.filter (fun (_,r) -> VCS.is_verdict r) results in - let proved,unproved = List.partition (fun (_,r) -> VCS.is_valid r) verdicts in - let pp_provers fmt = function - | [] -> () - | (p,_)::prs -> - VCS.pp_prover fmt p ; - List.iter (fun (p,_) -> Format.fprintf fmt ", %a" VCS.pp_prover p) prs - in - if proved <> [] then - let loc = Property.location (Wpo.get_target goal) in - Wp_parameters.warning ~wkey:wkey_smoke ~source:(fst loc) - "Smoke-test %s : Failed (%a)" - (Wpo.get_gid goal) pp_provers proved - else - if unproved <> [] then - Wp_parameters.feedback ~ontty:`Silent - "Smoke-test %s : Passed (%a)" - (Wpo.get_gid goal) pp_provers unproved - else - let loc = Property.location (Wpo.get_target goal) in - Wp_parameters.warning ~source:(fst loc) - "Smoke-test %s : Non-conclusive (no-result)" - (Wpo.get_gid goal) +let do_wpo_smoke status goal = + Wp_parameters.result "[%s] Smoke-test %s%t" + (match status with + | `Failed -> "Failed" + | `Passed -> "Passed" + | `Unknown -> "Partial") + (Wpo.get_gid goal) + begin fun fmt -> + pp_warnings fmt goal ; + List.iter + (fun (p,r) -> + Format.fprintf fmt "@\n%8s: @[<hv>%a@]" + (VCS.title_of_prover p) + VCS.pp_result r + ) (results goal) ; + end let do_wpo_success goal s = - if not (Wp_parameters.Check.get ()) then - if Wp_parameters.Generate.get () then - match s with - | None -> () - | Some prover -> + if Wp_parameters.Generate.get () then + match s with + | None -> () + | Some prover -> + Wp_parameters.feedback ~ontty:`Silent + "[%a] Goal %s : Valid" VCS.pp_prover prover (Wpo.get_gid goal) + else + if Wpo.is_smoke_test goal then + begin match s with + | None -> Wp_parameters.feedback ~ontty:`Silent - "[%a] Goal %s : Valid" VCS.pp_prover prover (Wpo.get_gid goal) - else - if Wpo.is_smoke_test goal then - do_wpo_smoke goal - else - match s with + "[Passed] Smoke-test %s" (Wpo.get_gid goal) + | Some _ -> + let status,target = Wpo.get_proof goal in + do_wpo_smoke status goal ; + if status = `Failed then + let source = fst (Property.location target) in + Wp_parameters.warning ~source "Failed smoke-test" + end + else + begin match s with | None -> do_wpo_failed goal | Some (VCS.Tactical as script) -> Wp_parameters.feedback ~ontty:`Silent @@ -440,6 +445,7 @@ let do_wpo_success goal s = "[%a] Goal %s : %a" VCS.pp_prover prover (Wpo.get_gid goal) VCS.pp_result result + end let do_report_time fmt s = begin diff --git a/src/plugins/wp/tests/wp_plugin/doomed_call.i b/src/plugins/wp/tests/wp_plugin/doomed_call.i new file mode 100644 index 00000000000..a084798044a --- /dev/null +++ b/src/plugins/wp/tests/wp_plugin/doomed_call.i @@ -0,0 +1,122 @@ +/* run.config + DONTRUN: + */ + +/* run.config_qualif + OPT: + OPT: -wp-smoke-tests + OPT: -wp-smoke-tests -wp-split +*/ + +/* -------------------------------------------------------------------------- */ +// --- All functions shall be proved without smoke tests +// --- All functions « ok » shall pass the smoke tests +// --- All functions « ko » shall reveal dead code +/* -------------------------------------------------------------------------- */ + +/*@ + ensures \false ; + exits \false ; + assigns \nothing ; + */ +void call_ko(void); + +/*@ + ensures \true ; + exits \false ; + assigns \nothing ; + */ +void call_post_ok(void); + +/*@ + ensures \false ; + exits \true ; + assigns \nothing ; + */ +void call_exit_ok(void); + +int E ; + +/*@ + ensures E ; + exits E ; + assigns \nothing ; + */ +void call_ko_global(void); + +/*@ ensures p ; exits !p ; */ +void f1_ok(int p) +{ + if (!p) + call_exit_ok(); + E++; +} + +/*@ ensures p ; exits !p ; */ +void f2_ok(int p) +{ + if (p) + call_post_ok(); + else + call_exit_ok(); + E++; +} + +/*@ ensures E == \old(E)+1 ; */ +void f3_ko(void) +{ + call_ko(); + E++; +} + +/*@ ensures \false ; */ +void f3_ok(void) +{ + call_exit_ok(); +} + +/*@ ensures E ; */ +void f4_ok(void) +{ + E=1; + call_ko_global(); +} + +/*@ ensures !E ; */ +void f4_ko(void) +{ + E=0; + call_ko_global(); +} + +/*@ + ensures E == \old(E)+1 ; + assigns \nothing ; + */ +void call_wrong(void); + +/*@ + ensures E == \old(E)+1 ; + assigns E ; + */ +void call_effect(void); + +/*@ + ensures E == \old(E)+3 ; +*/ +void f5_ok(void) +{ + call_effect(); + call_effect(); + call_effect(); +} + +/*@ + ensures E == \old(E)+3 ; +*/ +void f5_ko(void) +{ + call_effect(); + call_wrong(); + call_effect(); +} diff --git a/src/plugins/wp/tests/wp_plugin/doomed_dead.i b/src/plugins/wp/tests/wp_plugin/doomed_dead.i new file mode 100644 index 00000000000..5cba4b4ae13 --- /dev/null +++ b/src/plugins/wp/tests/wp_plugin/doomed_dead.i @@ -0,0 +1,96 @@ +/* run.config + DONTRUN: + */ + +/* run.config_qualif + OPT: -wp-smoke-tests + OPT: -wp-smoke-tests -wp-split +*/ + +//@ assigns \nothing ; +int f1_ok(int x) +{ + int r ; + if (x) r++; + if (x) r++; + return r; +} + +/*@ + ensures \false ; + exits \true ; + assigns \nothing ; +*/ +void exit(void); + +/*@ + assigns \nothing ; +*/ +void call(void); + +//@ assigns \nothing ; +int f2_ok(int x) +{ + int r ; + if (x) { exit(); } + r++; + return r; +} + +//@ assigns \nothing ; +int f2_ko(int x) +{ + int r ; + if (x) { exit(); r++; } + return r; +} + +//@ assigns \nothing ; +int f3_ok(int x) +{ + int r ; + if (x) { call(); r++; } + return r; +} + +//@ assigns \nothing ; +int f4_ok(int x) +{ + int r ; + if (x) { + exit(); + //@ assert \false ; + r++; + } else { + r++; + } + return r; +} + +//@ assigns \nothing ; +int f5_ok(int op,int a) +{ + switch(op) { + case 1: + case 2: + return a+1; + case 3: + return a-1; + default: + return a; + } +} + +//@ assigns \nothing ; +int f5_ko(int op,int a) +{ + if (op == 1) return 0; + switch(op) { + case 1: + return a+1; + case 2: + return a-1; + default: + return a; + } +} diff --git a/src/plugins/wp/tests/wp_plugin/oracle/doomed.1.res.oracle b/src/plugins/wp/tests/wp_plugin/oracle/doomed.1.res.oracle index c8ab85eccdb..96ea7f28a84 100644 --- a/src/plugins/wp/tests/wp_plugin/oracle/doomed.1.res.oracle +++ b/src/plugins/wp/tests/wp_plugin/oracle/doomed.1.res.oracle @@ -7,7 +7,7 @@ Function bar ------------------------------------------------------------ -Goal Smoke_default_requires in 'bar': +Goal Wp_smoke_default_requires in 'bar': Assume { Type: is_sint32(x). (* Pre-condition *) Have: 0 < x. } Prove: false. @@ -21,7 +21,7 @@ Prove: true. Function buzz ------------------------------------------------------------ -Goal Smoke_default_requires in 'buzz': +Goal Wp_smoke_default_requires in 'buzz': Prove: true. ------------------------------------------------------------ @@ -34,7 +34,7 @@ Prove: true. Function foo ------------------------------------------------------------ -Goal Smoke_default_requires in 'foo': +Goal Wp_smoke_default_requires in 'foo': Assume { Type: is_sint32(x). (* Pre-condition *) @@ -51,7 +51,7 @@ Prove: false. Function foo with behavior A ------------------------------------------------------------ -Goal Smoke_A_requires in 'foo': +Goal Wp_smoke_A_requires in 'foo': Prove: true. ------------------------------------------------------------ @@ -59,7 +59,7 @@ Prove: true. Function foo with behavior B ------------------------------------------------------------ -Goal Smoke_B_requires in 'foo': +Goal Wp_smoke_B_requires in 'foo': Assume { Type: is_sint32(x). (* Pre-condition *) diff --git a/src/plugins/wp/tests/wp_plugin/oracle/doomed_axioms.res.oracle b/src/plugins/wp/tests/wp_plugin/oracle/doomed_axioms.res.oracle index 01bfc26467c..66b4587a6b7 100644 --- a/src/plugins/wp/tests/wp_plugin/oracle/doomed_axioms.res.oracle +++ b/src/plugins/wp/tests/wp_plugin/oracle/doomed_axioms.res.oracle @@ -7,7 +7,7 @@ Function foo ------------------------------------------------------------ -Goal Smoke_loop_invariant in 'foo' at loop (file tests/wp_plugin/doomed_axioms.i, line 29): +Goal Wp_smoke_dead_loop in 'foo' at loop (file tests/wp_plugin/doomed_axioms.i, line 29): Assume { Type: is_sint32(n). (* Invariant 'C' *) @@ -21,6 +21,38 @@ Prove: false. ------------------------------------------------------------ +Goal Wp_smoke_dead_code in 'foo' at instruction (file tests/wp_plugin/doomed_axioms.i, line 30): +Assume { + Type: is_sint32(n) /\ is_sint32(x). + (* Invariant 'C' *) + Have: P_R(n). + (* Invariant 'B' *) + Have: P_Q(n). + (* Invariant 'A' *) + Have: P_P(n). + (* Then *) + Have: 0 < x. +} +Prove: false. + +------------------------------------------------------------ + +Goal Wp_smoke_dead_code in 'foo' at return (file tests/wp_plugin/doomed_axioms.i, line 32): +Assume { + Type: is_sint32(n) /\ is_sint32(x). + (* Invariant 'C' *) + Have: P_R(n). + (* Invariant 'B' *) + Have: P_Q(n). + (* Invariant 'A' *) + Have: P_P(n). + (* Else *) + Have: x <= 0. +} +Prove: false. + +------------------------------------------------------------ + Goal Preservation of Invariant 'A' (file tests/wp_plugin/doomed_axioms.i, line 24): Let x_1 = 1 + n. Assume { diff --git a/src/plugins/wp/tests/wp_plugin/oracle/doomed_loop.res.oracle b/src/plugins/wp/tests/wp_plugin/oracle/doomed_loop.res.oracle index 1eb7464b45e..665deb24842 100644 --- a/src/plugins/wp/tests/wp_plugin/oracle/doomed_loop.res.oracle +++ b/src/plugins/wp/tests/wp_plugin/oracle/doomed_loop.res.oracle @@ -7,7 +7,17 @@ Function foo ------------------------------------------------------------ -Goal Smoke_loop_invariant in 'foo' at loop (file tests/wp_plugin/doomed_loop.i, line 22): +Goal Wp_smoke_dead_loop in 'foo' at loop (file tests/wp_plugin/doomed_loop.i, line 22): +Prove: true. + +------------------------------------------------------------ + +Goal Wp_smoke_dead_code in 'foo' at instruction (file tests/wp_plugin/doomed_loop.i, line 23): +Prove: true. + +------------------------------------------------------------ + +Goal Wp_smoke_dead_code in 'foo' at return (file tests/wp_plugin/doomed_loop.i, line 25): Prove: true. ------------------------------------------------------------ diff --git a/src/plugins/wp/tests/wp_plugin/oracle/doomed_unroll.res.oracle b/src/plugins/wp/tests/wp_plugin/oracle/doomed_unroll.res.oracle index 3f7c7566dcf..16932140287 100644 --- a/src/plugins/wp/tests/wp_plugin/oracle/doomed_unroll.res.oracle +++ b/src/plugins/wp/tests/wp_plugin/oracle/doomed_unroll.res.oracle @@ -9,6 +9,21 @@ Function foo ------------------------------------------------------------ +Goal Wp_smoke_dead_code in 'foo' at instruction (file tests/wp_plugin/doomed_unroll.i, line 15): +Prove: false. + +------------------------------------------------------------ + +Goal Wp_smoke_dead_code in 'foo' at instruction (file tests/wp_plugin/doomed_unroll.i, line 15): +Prove: false. + +------------------------------------------------------------ + +Goal Wp_smoke_dead_code in 'foo' at instruction (file tests/wp_plugin/doomed_unroll.i, line 15): +Prove: false. + +------------------------------------------------------------ + Goal Preservation of Invariant (generated): Prove: true. diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed.res.oracle b/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed.res.oracle index fd6fc26aa12..a3d176c2b04 100644 --- a/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed.res.oracle +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed.res.oracle @@ -4,15 +4,17 @@ [wp] Loading driver 'share/wp.driver' [wp] Warning: Missing RTE guards [wp] 7 goals scheduled -[wp] Smoke-test typed_bar_smoke_default_requires : Passed (Alt-Ergo) +[wp] [Passed] Smoke-test typed_bar_wp_smoke_default_requires [wp] [Qed] Goal typed_bar_ensures : Valid -[wp:smoke] tests/wp_plugin/doomed.i:41: Warning: - Smoke-test typed_buzz_smoke_default_requires : Failed (Qed) +[wp] [Failed] Smoke-test typed_buzz_wp_smoke_default_requires + Qed: Valid +[wp] tests/wp_plugin/doomed.i:41: Warning: Failed smoke-test [wp] [Qed] Goal typed_buzz_ensures : Valid -[wp] Smoke-test typed_foo_smoke_default_requires : Passed (Alt-Ergo) -[wp:smoke] tests/wp_plugin/doomed.i:27: Warning: - Smoke-test typed_foo_smoke_A_requires : Failed (Qed) -[wp] Smoke-test typed_foo_smoke_B_requires : Passed (Alt-Ergo) +[wp] [Passed] Smoke-test typed_foo_wp_smoke_default_requires +[wp] [Failed] Smoke-test typed_foo_wp_smoke_A_requires + Qed: Valid +[wp] tests/wp_plugin/doomed.i:27: Warning: Failed smoke-test +[wp] [Passed] Smoke-test typed_foo_wp_smoke_B_requires [wp] Proved goals: 5 / 7 Qed: 2 (failed: 2) Alt-Ergo: 3 diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_axioms.res.oracle b/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_axioms.res.oracle index d6996bf2fea..f11a3888e1d 100644 --- a/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_axioms.res.oracle +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_axioms.res.oracle @@ -3,9 +3,16 @@ [wp] Running WP plugin... [wp] Loading driver 'share/wp.driver' [wp] Warning: Missing RTE guards -[wp] 8 goals scheduled -[wp:smoke] tests/wp_plugin/doomed_axioms.i:29: Warning: - Smoke-test typed_foo_smoke_loop_invariant_s2 : Failed (Alt-Ergo) +[wp] 10 goals scheduled +[wp] [Failed] Smoke-test typed_foo_wp_smoke_dead_loop_s2 + Alt-Ergo: Valid +[wp] tests/wp_plugin/doomed_axioms.i:29: Warning: Failed smoke-test +[wp] [Failed] Smoke-test typed_foo_wp_smoke_dead_code_s7 + Alt-Ergo: Valid +[wp] tests/wp_plugin/doomed_axioms.i:30: Warning: Failed smoke-test +[wp] [Failed] Smoke-test typed_foo_wp_smoke_dead_code_s9 + Alt-Ergo: Valid +[wp] tests/wp_plugin/doomed_axioms.i:32: Warning: Failed smoke-test [wp] [Alt-Ergo] Goal typed_foo_loop_invariant_A_preserved : Valid [wp] [Alt-Ergo] Goal typed_foo_loop_invariant_A_established : Valid [wp] [Alt-Ergo] Goal typed_foo_loop_invariant_B_preserved : Valid @@ -13,10 +20,10 @@ [wp] [Alt-Ergo] Goal typed_foo_loop_invariant_C_preserved : Valid [wp] [Alt-Ergo] Goal typed_foo_loop_invariant_C_established : Valid [wp] [Qed] Goal typed_foo_loop_assigns : Valid -[wp] Proved goals: 7 / 8 +[wp] Proved goals: 7 / 10 Qed: 1 - Alt-Ergo: 6 (failed: 1) + Alt-Ergo: 6 (failed: 3) ------------------------------------------------------------ Functions WP Alt-Ergo Total Success - foo 1 6 8 87.5% + foo 1 6 10 70.0% ------------------------------------------------------------ diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_call.0.res.oracle b/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_call.0.res.oracle new file mode 100644 index 00000000000..31663282840 --- /dev/null +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_call.0.res.oracle @@ -0,0 +1,29 @@ +# frama-c -wp [...] +[kernel] Parsing tests/wp_plugin/doomed_call.i (no preprocessing) +[wp] Running WP plugin... +[wp] Loading driver 'share/wp.driver' +[wp] Warning: Missing RTE guards +[wp] 10 goals scheduled +[wp] [Qed] Goal typed_f1_ok_ensures : Valid +[wp] [Qed] Goal typed_f1_ok_exits : Valid +[wp] [Qed] Goal typed_f2_ok_ensures : Valid +[wp] [Qed] Goal typed_f2_ok_exits : Valid +[wp] [Qed] Goal typed_f3_ko_ensures : Valid +[wp] [Qed] Goal typed_f3_ok_ensures : Valid +[wp] [Qed] Goal typed_f4_ko_ensures : Valid +[wp] [Qed] Goal typed_f4_ok_ensures : Valid +[wp] [Qed] Goal typed_f5_ko_ensures : Valid +[wp] [Qed] Goal typed_f5_ok_ensures : Valid +[wp] Proved goals: 10 / 10 + Qed: 10 +------------------------------------------------------------ + Functions WP Alt-Ergo Total Success + f1_ok 2 - 2 100% + f2_ok 2 - 2 100% + f3_ko 1 - 1 100% + f3_ok 1 - 1 100% + f4_ok 1 - 1 100% + f4_ko 1 - 1 100% + f5_ok 1 - 1 100% + f5_ko 1 - 1 100% +------------------------------------------------------------ diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_call.1.res.oracle b/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_call.1.res.oracle new file mode 100644 index 00000000000..3d349ae8897 --- /dev/null +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_call.1.res.oracle @@ -0,0 +1,63 @@ +# frama-c -wp [...] +[kernel] Parsing tests/wp_plugin/doomed_call.i (no preprocessing) +[wp] Running WP plugin... +[wp] Loading driver 'share/wp.driver' +[wp] Warning: Missing RTE guards +[wp] 33 goals scheduled +[wp] [Passed] Smoke-test typed_call_exit_ok_wp_smoke_dead_call_s2 +[wp] [Passed] Smoke-test typed_f1_ok_wp_smoke_dead_code_s2 +[wp] [Passed] Smoke-test typed_f1_ok_wp_smoke_dead_code_s4 +[wp] [Qed] Goal typed_f1_ok_ensures : Valid +[wp] [Qed] Goal typed_f1_ok_exits : Valid +[wp] [Passed] Smoke-test typed_call_post_ok_wp_smoke_dead_call_s9 +[wp] [Passed] Smoke-test typed_call_exit_ok_wp_smoke_dead_call_s10 +[wp] [Passed] Smoke-test typed_f2_ok_wp_smoke_dead_code_s9 +[wp] [Passed] Smoke-test typed_f2_ok_wp_smoke_dead_code_s10 +[wp] [Passed] Smoke-test typed_f2_ok_wp_smoke_dead_code_s11 +[wp] [Qed] Goal typed_f2_ok_ensures : Valid +[wp] [Qed] Goal typed_f2_ok_exits : Valid +[wp] [Failed] Smoke-test typed_call_ko_wp_smoke_dead_call_s14 + Qed: Valid +[wp] tests/wp_plugin/doomed_call.i:68: Warning: Failed smoke-test +[wp] [Failed] Smoke-test typed_f3_ko_wp_smoke_dead_code_s15 + Qed: Valid +[wp] tests/wp_plugin/doomed_call.i:69: Warning: Failed smoke-test +[wp] [Qed] Goal typed_f3_ko_ensures : Valid +[wp] [Passed] Smoke-test typed_call_exit_ok_wp_smoke_dead_call_s18 +[wp] [Qed] Goal typed_f3_ok_ensures : Valid +[wp] [Failed] Smoke-test typed_call_ko_global_wp_smoke_dead_call_s26 + Qed: Valid +[wp] tests/wp_plugin/doomed_call.i:89: Warning: Failed smoke-test +[wp] [Qed] Goal typed_f4_ko_ensures : Valid +[wp] [Passed] Smoke-test typed_call_ko_global_wp_smoke_dead_call_s22 +[wp] [Qed] Goal typed_f4_ok_ensures : Valid +[wp] [Passed] Smoke-test typed_call_wrong_wp_smoke_dead_call_s35 +[wp] [Passed] Smoke-test typed_call_effect_wp_smoke_dead_call_s34 +[wp] [Failed] Smoke-test typed_call_effect_wp_smoke_dead_call_s36 + Qed: Valid +[wp] tests/wp_plugin/doomed_call.i:121: Warning: Failed smoke-test +[wp] [Passed] Smoke-test typed_f5_ko_wp_smoke_dead_code_s35 +[wp] [Failed] Smoke-test typed_f5_ko_wp_smoke_dead_code_s36 + Qed: Valid +[wp] tests/wp_plugin/doomed_call.i:121: Warning: Failed smoke-test +[wp] [Qed] Goal typed_f5_ko_ensures : Valid +[wp] [Passed] Smoke-test typed_call_effect_wp_smoke_dead_call_s29 +[wp] [Passed] Smoke-test typed_call_effect_wp_smoke_dead_call_s30 +[wp] [Passed] Smoke-test typed_call_effect_wp_smoke_dead_call_s31 +[wp] [Passed] Smoke-test typed_f5_ok_wp_smoke_dead_code_s30 +[wp] [Passed] Smoke-test typed_f5_ok_wp_smoke_dead_code_s31 +[wp] [Qed] Goal typed_f5_ok_ensures : Valid +[wp] Proved goals: 28 / 33 + Qed: 10 (failed: 5) + Alt-Ergo: 18 +------------------------------------------------------------ + Functions WP Alt-Ergo Total Success + f1_ok 2 3 5 100% + f2_ok 2 5 7 100% + f3_ko 1 - 3 33.3% + f3_ok 1 1 2 100% + f4_ok 1 1 2 100% + f4_ko 1 - 2 50.0% + f5_ok 1 5 6 100% + f5_ko 1 3 6 66.7% +------------------------------------------------------------ diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_call.2.res.oracle b/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_call.2.res.oracle new file mode 100644 index 00000000000..51c6311db51 --- /dev/null +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_call.2.res.oracle @@ -0,0 +1,66 @@ +# frama-c -wp -wp-split [...] +[kernel] Parsing tests/wp_plugin/doomed_call.i (no preprocessing) +[wp] Running WP plugin... +[wp] Loading driver 'share/wp.driver' +[wp] Warning: Missing RTE guards +[wp] 36 goals scheduled +[wp] [Passed] Smoke-test typed_call_exit_ok_wp_smoke_dead_call_s2 +[wp] [Passed] Smoke-test typed_f1_ok_wp_smoke_dead_code_s2 +[wp] [Passed] Smoke-test typed_f1_ok_wp_smoke_dead_code_s4 +[wp] [Qed] Goal typed_f1_ok_ensures_part1 : Valid +[wp] [Qed] Goal typed_f1_ok_ensures_part2 : Valid +[wp] [Qed] Goal typed_f1_ok_exits : Valid +[wp] [Passed] Smoke-test typed_call_post_ok_wp_smoke_dead_call_s9 +[wp] [Passed] Smoke-test typed_call_exit_ok_wp_smoke_dead_call_s10 +[wp] [Passed] Smoke-test typed_f2_ok_wp_smoke_dead_code_s9 +[wp] [Passed] Smoke-test typed_f2_ok_wp_smoke_dead_code_s10 +[wp] [Passed] Smoke-test typed_f2_ok_wp_smoke_dead_code_s11 +[wp] [Qed] Goal typed_f2_ok_ensures_part1 : Valid +[wp] [Qed] Goal typed_f2_ok_ensures_part2 : Valid +[wp] [Qed] Goal typed_f2_ok_exits_part1 : Valid +[wp] [Qed] Goal typed_f2_ok_exits_part2 : Valid +[wp] [Failed] Smoke-test typed_call_ko_wp_smoke_dead_call_s14 + Qed: Valid +[wp] tests/wp_plugin/doomed_call.i:68: Warning: Failed smoke-test +[wp] [Failed] Smoke-test typed_f3_ko_wp_smoke_dead_code_s15 + Qed: Valid +[wp] tests/wp_plugin/doomed_call.i:69: Warning: Failed smoke-test +[wp] [Qed] Goal typed_f3_ko_ensures : Valid +[wp] [Passed] Smoke-test typed_call_exit_ok_wp_smoke_dead_call_s18 +[wp] [Qed] Goal typed_f3_ok_ensures : Valid +[wp] [Failed] Smoke-test typed_call_ko_global_wp_smoke_dead_call_s26 + Qed: Valid +[wp] tests/wp_plugin/doomed_call.i:89: Warning: Failed smoke-test +[wp] [Qed] Goal typed_f4_ko_ensures : Valid +[wp] [Passed] Smoke-test typed_call_ko_global_wp_smoke_dead_call_s22 +[wp] [Qed] Goal typed_f4_ok_ensures : Valid +[wp] [Passed] Smoke-test typed_call_wrong_wp_smoke_dead_call_s35 +[wp] [Passed] Smoke-test typed_call_effect_wp_smoke_dead_call_s34 +[wp] [Failed] Smoke-test typed_call_effect_wp_smoke_dead_call_s36 + Qed: Valid +[wp] tests/wp_plugin/doomed_call.i:121: Warning: Failed smoke-test +[wp] [Passed] Smoke-test typed_f5_ko_wp_smoke_dead_code_s35 +[wp] [Failed] Smoke-test typed_f5_ko_wp_smoke_dead_code_s36 + Qed: Valid +[wp] tests/wp_plugin/doomed_call.i:121: Warning: Failed smoke-test +[wp] [Qed] Goal typed_f5_ko_ensures : Valid +[wp] [Passed] Smoke-test typed_call_effect_wp_smoke_dead_call_s29 +[wp] [Passed] Smoke-test typed_call_effect_wp_smoke_dead_call_s30 +[wp] [Passed] Smoke-test typed_call_effect_wp_smoke_dead_call_s31 +[wp] [Passed] Smoke-test typed_f5_ok_wp_smoke_dead_code_s30 +[wp] [Passed] Smoke-test typed_f5_ok_wp_smoke_dead_code_s31 +[wp] [Qed] Goal typed_f5_ok_ensures : Valid +[wp] Proved goals: 31 / 36 + Qed: 13 (failed: 5) + Alt-Ergo: 18 +------------------------------------------------------------ + Functions WP Alt-Ergo Total Success + f1_ok 3 3 6 100% + f2_ok 4 5 9 100% + f3_ko 1 - 3 33.3% + f3_ok 1 1 2 100% + f4_ok 1 1 2 100% + f4_ko 1 - 2 50.0% + f5_ok 1 5 6 100% + f5_ko 1 3 6 66.7% +------------------------------------------------------------ diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_dead.0.res.oracle b/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_dead.0.res.oracle new file mode 100644 index 00000000000..0b7ac571bbb --- /dev/null +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_dead.0.res.oracle @@ -0,0 +1,69 @@ +# frama-c -wp [...] +[kernel] Parsing tests/wp_plugin/doomed_dead.i (no preprocessing) +[wp] Running WP plugin... +[wp] Loading driver 'share/wp.driver' +[wp] Warning: Missing RTE guards +[wp] 46 goals scheduled +[wp] [Passed] Smoke-test typed_f1_ok_wp_smoke_dead_code_s3 +[wp] [Passed] Smoke-test typed_f1_ok_wp_smoke_dead_code_s7 +[wp] [Passed] Smoke-test typed_f1_ok_wp_smoke_dead_code_s10 +[wp] [Qed] Goal typed_f1_ok_assigns_part1 : Valid +[wp] [Qed] Goal typed_f1_ok_assigns_part2 : Valid +[wp] [Passed] Smoke-test typed_exit_wp_smoke_dead_call_s22 +[wp] [Passed] Smoke-test typed_f2_ko_wp_smoke_dead_code_s22 +[wp] [Failed] Smoke-test typed_f2_ko_wp_smoke_dead_code_s23 + Qed: Valid +[wp] tests/wp_plugin/doomed_dead.i:44: Warning: Failed smoke-test +[wp] [Passed] Smoke-test typed_f2_ko_wp_smoke_dead_code_s26 +[wp] [Qed] Goal typed_f2_ko_assigns_exit : Valid +[wp] [Qed] Goal typed_f2_ko_assigns_normal_part1 : Valid +[wp] [Qed] Goal typed_f2_ko_assigns_normal_part2 : Valid +[wp] [Passed] Smoke-test typed_exit_wp_smoke_dead_call_s14 +[wp] [Passed] Smoke-test typed_f2_ok_wp_smoke_dead_code_s14 +[wp] [Passed] Smoke-test typed_f2_ok_wp_smoke_dead_code_s16 +[wp] [Qed] Goal typed_f2_ok_assigns_exit : Valid +[wp] [Qed] Goal typed_f2_ok_assigns_normal_part1 : Valid +[wp] [Qed] Goal typed_f2_ok_assigns_normal_part2 : Valid +[wp] [Passed] Smoke-test typed_call_wp_smoke_dead_call_s30 +[wp] [Passed] Smoke-test typed_f3_ok_wp_smoke_dead_code_s30 +[wp] [Passed] Smoke-test typed_f3_ok_wp_smoke_dead_code_s31 +[wp] [Passed] Smoke-test typed_f3_ok_wp_smoke_dead_code_s34 +[wp] [Qed] Goal typed_f3_ok_assigns_exit : Valid +[wp] [Qed] Goal typed_f3_ok_assigns_normal_part1 : Valid +[wp] [Qed] Goal typed_f3_ok_assigns_normal_part2 : Valid +[wp] [Passed] Smoke-test typed_exit_wp_smoke_dead_call_s38 +[wp] [Passed] Smoke-test typed_f4_ok_wp_smoke_dead_code_s41 +[wp] [Qed] Goal typed_f4_ok_assert : Valid +[wp] [Qed] Goal typed_f4_ok_assigns_exit : Valid +[wp] [Qed] Goal typed_f4_ok_assigns_normal_part1 : Valid +[wp] [Qed] Goal typed_f4_ok_assigns_normal_part2 : Valid +[wp] [Qed] Goal typed_f4_ok_assigns_normal_part3 : Valid +[wp] [Passed] Smoke-test typed_f5_ko_wp_smoke_dead_code_s56 +[wp] [Failed] Smoke-test typed_f5_ko_wp_smoke_dead_code_s61 + Qed: Valid +[wp] tests/wp_plugin/doomed_dead.i:90: Warning: Failed smoke-test +[wp] [Passed] Smoke-test typed_f5_ko_wp_smoke_dead_code_s63 +[wp] [Passed] Smoke-test typed_f5_ko_wp_smoke_dead_code_s65 +[wp] [Qed] Goal typed_f5_ko_assigns_part1 : Valid +[wp] [Qed] Goal typed_f5_ko_assigns_part2 : Valid +[wp] [Qed] Goal typed_f5_ko_assigns_part3 : Valid +[wp] [Qed] Goal typed_f5_ko_assigns_part4 : Valid +[wp] [Passed] Smoke-test typed_f5_ok_wp_smoke_dead_code_s48 +[wp] [Passed] Smoke-test typed_f5_ok_wp_smoke_dead_code_s50 +[wp] [Passed] Smoke-test typed_f5_ok_wp_smoke_dead_code_s52 +[wp] [Qed] Goal typed_f5_ok_assigns_part1 : Valid +[wp] [Qed] Goal typed_f5_ok_assigns_part2 : Valid +[wp] [Qed] Goal typed_f5_ok_assigns_part3 : Valid +[wp] Proved goals: 44 / 46 + Qed: 23 (failed: 2) + Alt-Ergo: 21 +------------------------------------------------------------ + Functions WP Alt-Ergo Total Success + f1_ok 2 3 5 100% + f2_ok 3 3 6 100% + f2_ko 3 3 7 85.7% + f3_ok 3 4 7 100% + f4_ok 5 2 7 100% + f5_ok 3 3 6 100% + f5_ko 4 3 8 87.5% +------------------------------------------------------------ diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_dead.1.res.oracle b/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_dead.1.res.oracle new file mode 100644 index 00000000000..b5c0258a177 --- /dev/null +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_dead.1.res.oracle @@ -0,0 +1,71 @@ +# frama-c -wp -wp-split [...] +[kernel] Parsing tests/wp_plugin/doomed_dead.i (no preprocessing) +[wp] Running WP plugin... +[wp] Loading driver 'share/wp.driver' +[wp] Warning: Missing RTE guards +[wp] 48 goals scheduled +[wp] [Passed] Smoke-test typed_f1_ok_wp_smoke_dead_code_s3 +[wp] [Passed] Smoke-test typed_f1_ok_wp_smoke_dead_code_s7 +[wp] [Passed] Smoke-test typed_f1_ok_wp_smoke_dead_code_s10 +[wp] [Qed] Goal typed_f1_ok_assigns_part1 : Valid +[wp] [Qed] Goal typed_f1_ok_assigns_part2 : Valid +[wp] [Qed] Goal typed_f1_ok_assigns_part3 : Valid +[wp] [Passed] Smoke-test typed_exit_wp_smoke_dead_call_s22 +[wp] [Passed] Smoke-test typed_f2_ko_wp_smoke_dead_code_s22 +[wp] [Failed] Smoke-test typed_f2_ko_wp_smoke_dead_code_s23 + Qed: Valid +[wp] tests/wp_plugin/doomed_dead.i:44: Warning: Failed smoke-test +[wp] [Passed] Smoke-test typed_f2_ko_wp_smoke_dead_code_s26 +[wp] [Qed] Goal typed_f2_ko_assigns_exit : Valid +[wp] [Qed] Goal typed_f2_ko_assigns_normal_part1 : Valid +[wp] [Qed] Goal typed_f2_ko_assigns_normal_part2 : Valid +[wp] [Passed] Smoke-test typed_exit_wp_smoke_dead_call_s14 +[wp] [Passed] Smoke-test typed_f2_ok_wp_smoke_dead_code_s14 +[wp] [Passed] Smoke-test typed_f2_ok_wp_smoke_dead_code_s16 +[wp] [Qed] Goal typed_f2_ok_assigns_exit : Valid +[wp] [Qed] Goal typed_f2_ok_assigns_normal_part1 : Valid +[wp] [Qed] Goal typed_f2_ok_assigns_normal_part2 : Valid +[wp] [Qed] Goal typed_f2_ok_assigns_normal_part3 : Valid +[wp] [Passed] Smoke-test typed_call_wp_smoke_dead_call_s30 +[wp] [Passed] Smoke-test typed_f3_ok_wp_smoke_dead_code_s30 +[wp] [Passed] Smoke-test typed_f3_ok_wp_smoke_dead_code_s31 +[wp] [Passed] Smoke-test typed_f3_ok_wp_smoke_dead_code_s34 +[wp] [Qed] Goal typed_f3_ok_assigns_exit : Valid +[wp] [Qed] Goal typed_f3_ok_assigns_normal_part1 : Valid +[wp] [Qed] Goal typed_f3_ok_assigns_normal_part2 : Valid +[wp] [Passed] Smoke-test typed_exit_wp_smoke_dead_call_s38 +[wp] [Passed] Smoke-test typed_f4_ok_wp_smoke_dead_code_s41 +[wp] [Qed] Goal typed_f4_ok_assert : Valid +[wp] [Qed] Goal typed_f4_ok_assigns_exit : Valid +[wp] [Qed] Goal typed_f4_ok_assigns_normal_part1 : Valid +[wp] [Qed] Goal typed_f4_ok_assigns_normal_part2 : Valid +[wp] [Qed] Goal typed_f4_ok_assigns_normal_part3 : Valid +[wp] [Passed] Smoke-test typed_f5_ko_wp_smoke_dead_code_s56 +[wp] [Failed] Smoke-test typed_f5_ko_wp_smoke_dead_code_s61 + Qed: Valid +[wp] tests/wp_plugin/doomed_dead.i:90: Warning: Failed smoke-test +[wp] [Passed] Smoke-test typed_f5_ko_wp_smoke_dead_code_s63 +[wp] [Passed] Smoke-test typed_f5_ko_wp_smoke_dead_code_s65 +[wp] [Qed] Goal typed_f5_ko_assigns_part1 : Valid +[wp] [Qed] Goal typed_f5_ko_assigns_part2 : Valid +[wp] [Qed] Goal typed_f5_ko_assigns_part3 : Valid +[wp] [Qed] Goal typed_f5_ko_assigns_part4 : Valid +[wp] [Passed] Smoke-test typed_f5_ok_wp_smoke_dead_code_s48 +[wp] [Passed] Smoke-test typed_f5_ok_wp_smoke_dead_code_s50 +[wp] [Passed] Smoke-test typed_f5_ok_wp_smoke_dead_code_s52 +[wp] [Qed] Goal typed_f5_ok_assigns_part1 : Valid +[wp] [Qed] Goal typed_f5_ok_assigns_part2 : Valid +[wp] [Qed] Goal typed_f5_ok_assigns_part3 : Valid +[wp] Proved goals: 46 / 48 + Qed: 25 (failed: 2) + Alt-Ergo: 21 +------------------------------------------------------------ + Functions WP Alt-Ergo Total Success + f1_ok 3 3 6 100% + f2_ok 4 3 7 100% + f2_ko 3 3 7 85.7% + f3_ok 3 4 7 100% + f4_ok 5 2 7 100% + f5_ok 3 3 6 100% + f5_ko 4 3 8 87.5% +------------------------------------------------------------ diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_loop.res.oracle b/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_loop.res.oracle index 50df612e79a..c1ea877c9ba 100644 --- a/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_loop.res.oracle +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_loop.res.oracle @@ -3,18 +3,25 @@ [wp] Running WP plugin... [wp] Loading driver 'share/wp.driver' [wp] Warning: Missing RTE guards -[wp] 6 goals scheduled -[wp:smoke] tests/wp_plugin/doomed_loop.i:22: Warning: - Smoke-test typed_foo_smoke_loop_invariant_s2 : Failed (Qed) +[wp] 8 goals scheduled +[wp] [Failed] Smoke-test typed_foo_wp_smoke_dead_loop_s2 + Qed: Valid +[wp] tests/wp_plugin/doomed_loop.i:22: Warning: Failed smoke-test +[wp] [Failed] Smoke-test typed_foo_wp_smoke_dead_code_s7 + Qed: Valid +[wp] tests/wp_plugin/doomed_loop.i:23: Warning: Failed smoke-test +[wp] [Failed] Smoke-test typed_foo_wp_smoke_dead_code_s9 + Qed: Valid +[wp] tests/wp_plugin/doomed_loop.i:25: Warning: Failed smoke-test [wp] [Qed] Goal typed_foo_loop_invariant_A_preserved : Valid [wp] [Alt-Ergo] Goal typed_foo_loop_invariant_A_established : Unsuccess [wp] [Qed] Goal typed_foo_loop_invariant_B_preserved : Valid [wp] [Alt-Ergo] Goal typed_foo_loop_invariant_B_established : Unsuccess [wp] [Qed] Goal typed_foo_loop_assigns : Valid -[wp] Proved goals: 3 / 6 - Qed: 3 (failed: 1) +[wp] Proved goals: 3 / 8 + Qed: 3 (failed: 3) Alt-Ergo: 0 (unsuccess: 2) ------------------------------------------------------------ Functions WP Alt-Ergo Total Success - foo 3 - 6 50.0% + foo 3 - 8 37.5% ------------------------------------------------------------ diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_report_ko.res.oracle b/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_report_ko.res.oracle index 912b133c975..9daa85dfb61 100644 --- a/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_report_ko.res.oracle +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_report_ko.res.oracle @@ -3,9 +3,16 @@ [wp] Running WP plugin... [wp] Loading driver 'share/wp.driver' [wp] Warning: Missing RTE guards -[wp] 8 goals scheduled -[wp:smoke] tests/wp_plugin/doomed_report_ko.i:29: Warning: - Smoke-test typed_foo_smoke_loop_invariant_s2 : Failed (Alt-Ergo) +[wp] 10 goals scheduled +[wp] [Failed] Smoke-test typed_foo_wp_smoke_dead_loop_s2 + Alt-Ergo: Valid +[wp] tests/wp_plugin/doomed_report_ko.i:29: Warning: Failed smoke-test +[wp] [Failed] Smoke-test typed_foo_wp_smoke_dead_code_s7 + Alt-Ergo: Valid +[wp] tests/wp_plugin/doomed_report_ko.i:29: Warning: Failed smoke-test +[wp] [Failed] Smoke-test typed_foo_wp_smoke_dead_code_s9 + Alt-Ergo: Valid +[wp] tests/wp_plugin/doomed_report_ko.i:30: Warning: Failed smoke-test [wp] [Alt-Ergo] Goal typed_foo_loop_invariant_A_preserved : Valid [wp] [Alt-Ergo] Goal typed_foo_loop_invariant_A_established : Valid [wp] [Alt-Ergo] Goal typed_foo_loop_invariant_B_preserved : Valid @@ -13,22 +20,24 @@ [wp] [Alt-Ergo] Goal typed_foo_loop_invariant_C_preserved : Valid [wp] [Alt-Ergo] Goal typed_foo_loop_invariant_C_established : Valid [wp] [Qed] Goal typed_foo_loop_assigns : Valid -[wp] Proved goals: 7 / 8 +[wp] Proved goals: 7 / 10 Qed: 1 - Alt-Ergo: 6 (failed: 1) + Alt-Ergo: 6 (failed: 3) ------------------------------------------------------------ Functions WP Alt-Ergo Total Success - foo 1 6 8 87.5% + foo 1 6 10 70.0% ------------------------------------------------------------ Qed Ergo Failed foo_loop_assigns 1 - - foo_loop_invariant_A - 2 - foo_loop_invariant_B - 2 - foo_loop_invariant_C - 2 - - foo_smoke_loop_invariant_s2 - - 1 + foo_wp_smoke_dead_code_s7 - - 1 + foo_wp_smoke_dead_code_s9 - - 1 + foo_wp_smoke_dead_loop_s2 - - 1 ------------------------------------------------------------- -Success: 80.0% - Total : 5 properties +Success: 57.1% + Total : 7 properties Valid : 4 - Failed : 1 + Failed : 3 ------------------------------------------------------------- diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_report_ok.res.oracle b/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_report_ok.res.oracle index adbb20e71ea..2b80ca79ba3 100644 --- a/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_report_ok.res.oracle +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_report_ok.res.oracle @@ -3,8 +3,10 @@ [wp] Running WP plugin... [wp] Loading driver 'share/wp.driver' [wp] Warning: Missing RTE guards -[wp] 8 goals scheduled -[wp] Smoke-test typed_foo_smoke_loop_invariant_s2 : Passed (Alt-Ergo) +[wp] 10 goals scheduled +[wp] [Passed] Smoke-test typed_foo_wp_smoke_dead_loop_s2 +[wp] [Passed] Smoke-test typed_foo_wp_smoke_dead_code_s7 +[wp] [Passed] Smoke-test typed_foo_wp_smoke_dead_code_s9 [wp] [Alt-Ergo] Goal typed_foo_loop_invariant_A_preserved : Valid [wp] [Alt-Ergo] Goal typed_foo_loop_invariant_A_established : Valid [wp] [Alt-Ergo] Goal typed_foo_loop_invariant_B_preserved : Valid @@ -12,22 +14,24 @@ [wp] [Alt-Ergo] Goal typed_foo_loop_invariant_C_preserved : Valid [wp] [Alt-Ergo] Goal typed_foo_loop_invariant_C_established : Valid [wp] [Qed] Goal typed_foo_loop_assigns : Valid -[wp] Proved goals: 8 / 8 +[wp] Proved goals: 10 / 10 Qed: 1 - Alt-Ergo: 7 + Alt-Ergo: 9 ------------------------------------------------------------ Functions WP Alt-Ergo Total Success - foo 1 7 8 100% + foo 1 9 10 100% ------------------------------------------------------------ Qed Ergo Failed foo_loop_assigns 1 - - foo_loop_invariant_A - 2 - foo_loop_invariant_B - 2 - foo_loop_invariant_C - 2 - - foo_smoke_loop_invariant_s2 - 1 - + foo_wp_smoke_dead_code_s7 - 1 - + foo_wp_smoke_dead_code_s9 - 1 - + foo_wp_smoke_dead_loop_s2 - 1 - ------------------------------------------------------------- Success: 100% - Total : 5 properties - Valid : 5 + Total : 7 properties + Valid : 7 Failed : - ------------------------------------------------------------- diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_unroll.res.oracle b/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_unroll.res.oracle index 236bb768af8..bcd42d15cb2 100644 --- a/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_unroll.res.oracle +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_unroll.res.oracle @@ -5,12 +5,16 @@ [wp] Warning: Missing RTE guards [wp] tests/wp_plugin/doomed_unroll.i:15: Warning: Missing assigns clause (assigns 'everything' instead) -[wp] 2 goals scheduled +[wp] 5 goals scheduled +[wp] [Passed] Smoke-test typed_foo_wp_smoke_dead_code_s27 +[wp] [Passed] Smoke-test typed_foo_wp_smoke_dead_code_s31 +[wp] [Passed] Smoke-test typed_foo_wp_smoke_dead_code_s35 [wp] [Qed] Goal typed_foo_loop_invariant_preserved : Valid [wp] [Qed] Goal typed_foo_loop_invariant_established : Valid -[wp] Proved goals: 2 / 2 - Qed: 2 +[wp] Proved goals: 5 / 5 + Qed: 2 + Alt-Ergo: 3 ------------------------------------------------------------ Functions WP Alt-Ergo Total Success - foo 2 - 2 100% + foo 2 3 5 100% ------------------------------------------------------------ diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/float_real.1.session/cache/d8be6e9b6d537a313b4ec0e4a4a74e3a.json b/src/plugins/wp/tests/wp_plugin/oracle_qualif/float_real.1.session/cache/d8be6e9b6d537a313b4ec0e4a4a74e3a.json new file mode 100644 index 00000000000..b8e36e2803f --- /dev/null +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/float_real.1.session/cache/d8be6e9b6d537a313b4ec0e4a4a74e3a.json @@ -0,0 +1 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "timeout", "time": 10. } diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/model.0.session/cache/438d25bfabd351c105105d10af4c170a.json b/src/plugins/wp/tests/wp_plugin/oracle_qualif/model.0.session/cache/438d25bfabd351c105105d10af4c170a.json new file mode 100644 index 00000000000..b8e36e2803f --- /dev/null +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/model.0.session/cache/438d25bfabd351c105105d10af4c170a.json @@ -0,0 +1 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "timeout", "time": 10. } diff --git a/src/plugins/wp/tests/wp_plugin/unroll/wp/scripts/unrolled_loop_ensures_zero.json b/src/plugins/wp/tests/wp_plugin/unroll/wp/scripts/unrolled_loop_ensures_zero.json new file mode 100644 index 00000000000..1c97c0efd6f --- /dev/null +++ b/src/plugins/wp/tests/wp_plugin/unroll/wp/scripts/unrolled_loop_ensures_zero.json @@ -0,0 +1,54 @@ +[ { "header": "Definition", "tactic": "Wp.unfold", "params": {}, + "select": { "select": "clause-goal", + "target": "(P_zeroed\n Mint_37[(shift_uint32 t_2 0)->0][(shift_uint32 t_2 1)->0]\n [(shift_uint32 t_2 2)->0][(shift_uint32 t_2 3)->0][(shift_uint32 t_2 4)\n ->0][(shift_uint32 t_2 5)->0][(shift_uint32 t_2 6)->0]\n [(shift_uint32 t_2 7)->0][(shift_uint32 t_2 8)->0][(shift_uint32 t_2 9)\n ->0][(shift_uint32 t_2 10)->0][(shift_uint32 t_2 11)->0]\n [(shift_uint32 t_2 12)->0][(shift_uint32 t_2 13)->0]\n [(shift_uint32 t_2 14)->0][(shift_uint32 t_2 15)->0] t_2 0 15)", + "pattern": "P_zeroed[=]$t015[=]shift_uint320" }, + "children": { "Unfold 'P_zeroed'": [ { "header": "Range", + "tactic": "Wp.range", + "params": { "inf": 0, "sup": 15 }, + "select": { "select": "inside-goal", + "occur": 0, + "target": "i_0", + "pattern": "$i" }, + "children": { "Lower 0": [ { "prover": "qed", + "verdict": "valid" } ], + "Value 0": [ { "prover": "qed", + "verdict": "valid" } ], + "Value 1": [ { "prover": "qed", + "verdict": "valid" } ], + "Value 2": [ { "prover": "qed", + "verdict": "valid" } ], + "Value 3": [ { "prover": "qed", + "verdict": "valid" } ], + "Value 4": [ { "prover": "qed", + "verdict": "valid" } ], + "Value 5": [ { "prover": "qed", + "verdict": "valid" } ], + "Value 6": [ { "prover": "qed", + "verdict": "valid" } ], + "Value 7": [ { "prover": "qed", + "verdict": "valid" } ], + "Value 8": [ { "prover": "qed", + "verdict": "valid" } ], + "Value 9": [ { "prover": "qed", + "verdict": "valid" } ], + "Value 10": + [ { "prover": "qed", + "verdict": "valid" } ], + "Value 11": + [ { "prover": "qed", + "verdict": "valid" } ], + "Value 12": + [ { "prover": "qed", + "verdict": "valid" } ], + "Value 13": + [ { "prover": "qed", + "verdict": "valid" } ], + "Value 14": + [ { "prover": "qed", + "verdict": "valid" } ], + "Value 15": + [ { "prover": "qed", + "verdict": "valid" } ], + "Upper 15": + [ { "prover": "qed", + "verdict": "valid" } ] } } ] } } ] diff --git a/src/plugins/wp/wpAnnot.ml b/src/plugins/wp/wpAnnot.ml index 7af507939a1..b7b5698f643 100644 --- a/src/plugins/wp/wpAnnot.ml +++ b/src/plugins/wp/wpAnnot.ml @@ -105,6 +105,7 @@ let set_unreachable pid = type proof = { target : Property.t ; proved : proofpart array ; + mutable invalid : bool ; mutable dependencies : Property.Set.t ; } and proofpart = | Noproof @@ -112,27 +113,29 @@ type proof = { | Parts of Bitvector.t let target p = p.target -let dependencies p = Property.Set.elements (Property.Set.remove p.target p.dependencies) +let dependencies p = + Property.Set.elements (Property.Set.remove p.target p.dependencies) -let create_proof p = - let n = WpPropId.subproofs p in +let create_proof ip = + let n = WpPropId.subproofs ip in { - target = WpPropId.property_of_id p ; + target = WpPropId.property_of_id ip ; proved = Array.make n Noproof ; dependencies = Property.Set.empty ; + invalid = false ; } -let add_proof pf p hs = +let add_proof pf ip hs = begin - if not (Property.equal (WpPropId.property_of_id p) pf.target) + if not (Property.equal (WpPropId.property_of_id ip) pf.target) then Wp_parameters.fatal "Partial proof inconsistency" ; List.iter (fun iph -> if not (WpPropId.is_requires iph) then pf.dependencies <- Property.Set.add iph pf.dependencies ) hs ; - let k = WpPropId.subproof_idx p in - match WpPropId.parts_of_id p with + let k = WpPropId.subproof_idx ip in + match WpPropId.parts_of_id ip with | None -> pf.proved.(k) <- Complete | Some(p,n) -> match pf.proved.(k) with @@ -148,12 +151,23 @@ let add_proof pf p hs = then pf.proved.(k) <- Complete end +let add_invalid_proof pf = pf.invalid <- true + let is_composed pf = Array.length pf.proved > 1 let is_proved pf = - try Array.iter (fun r -> if r<>Complete then raise Exit) pf.proved ; true - with Exit -> false + Array.for_all (function Complete -> true | _ -> false) pf.proved + +let is_invalid pf = + pf.invalid && not (is_proved pf) + +let status pf = + try + Array.iter (function Complete -> raise Exit | _ -> ()) pf.proved ; + `Proved + with Exit -> + if pf.invalid then `Invalid else `Partial (* -------------------------------------------------------------------------- *) (* --- PID for Functions --- *) @@ -185,22 +199,6 @@ let preconditions_at_call s = function let get_called_preconditions_at kf stmt = List.map snd (call_preconditions kf stmt) -(* -------------------------------------------------------------------------- *) -(* --- Prop Splitter --- *) -(* -------------------------------------------------------------------------- *) - -(* prop-id splitter *) - -let split job pid goals = - let n = Bag.length goals in - if n <= 1 then Bag.iter (job pid) goals else - let k = ref 0 in - Bag.iter - (fun g -> - let pid_k = WpPropId.mk_part pid (!k,n) in - incr k ; job pid_k g) - goals - (*----------------------------------------------------------------------------*) (* Strategy and annotations *) (*----------------------------------------------------------------------------*) @@ -247,6 +245,7 @@ module HdefAnnotBhv = Cil2cfg.HE (struct type t = (stmt * int) end) type strategy_info = { kf : Kernel_function.t; cfg : Cil2cfg.t; + reached : WpReached.reached option ; cur_bhv : asked_bhv; asked_bhvs : asked_bhv list; asked_prop : asked_prop; @@ -374,6 +373,8 @@ let kind_to_select config kind id = match kind with | WpStrategy.AcallPre(goal,fct) -> let goal = goal && goal_to_select config id in Some (WpStrategy.AcallPre(goal,fct)) + | WpStrategy.AcallPost _ -> + if goal_to_select config id then Some kind else None | WpStrategy.Ahyp | WpStrategy.AcallHyp _ -> Some kind let add_prop_loop_inv ~established config acc kind s ca p = @@ -759,6 +760,15 @@ let add_called_post called_kf termination_kind acc = in List.fold_left add_behav acc spec.spec_behavior +let add_call_checks config s kf posts exits = + if cur_fct_default_bhv config + && Wp_parameters.SmokeTests.get () + && Wp_parameters.SmokeDeadcode.get () + then + WpStrategy.add_prop_dead_call kf s posts exits + else + posts , exits + let add_call_annots config s kf l_post (before,(posts,exits)) = let spec = Annotations.funspec kf in let before = add_called_pre config kf s spec before in @@ -766,7 +776,7 @@ let add_call_annots config s kf l_post (before,(posts,exits)) = let posts = WpStrategy.add_call_assigns_hyp posts config.kf s ~called_kf:kf l_post (Some spec) in let exits = add_called_post kf Exits exits in - before , ( posts , exits ) + before , add_call_checks config s kf posts exits let get_call_annots config v s fct = let l_post = Cil2cfg.get_post_label config.cfg v in @@ -793,24 +803,6 @@ let get_call_annots config v s fct = (*----------------------------------------------------------------------------*) -let is_unrolled_completely spec = - match spec.term_node with - | TConst (LStr "completely") -> true - | _ -> false - -let is_unrolled_loop stmt = - let exception Unrolled in - try - Annotations.iter_code_annot (fun _emitter ca -> - match ca.annot_content with - | APragma (Loop_pragma (Unroll_specs [ spec ; _ ])) - when is_unrolled_completely spec -> - raise Unrolled ; - | _ -> () - ) stmt ; - false - with Unrolled -> true - let add_variant_annot config s ca var_exp loop_entry loop_back = let (vpos_id, vpos), (vdecr_id, vdecr) = WpStrategy.mk_variant_properties config.kf s ca var_exp @@ -901,9 +893,11 @@ let get_loop_annots config vloop s = | _ -> acc (* see get_stmt_annots *) in let loop_core = - if Wp_parameters.SmokeTests.get () && cur_fct_default_bhv config - && not (is_unrolled_loop s) - then WpStrategy.add_prop_loop_smoke WpStrategy.empty_acc config.kf s + if cur_fct_default_bhv config + && Wp_parameters.SmokeTests.get () + && Wp_parameters.SmokeDeadloop.get () + && not (WpReached.is_dead_code s) + then WpStrategy.add_prop_dead_loop WpStrategy.empty_acc config.kf s else WpStrategy.empty_acc in let (h_assigns, g_assigns), loop_entry , loop_back , loop_core = Annotations.fold_code_annot do_annot s @@ -917,6 +911,16 @@ let get_loop_annots config vloop s = WpStrategy.add_loop_assigns_hyp loop_core config.kf s h_assigns in (loop_entry , loop_back , loop_core) +let add_stmt_deadcode_smoke config acc s = + if cur_fct_default_bhv config + then + match config.reached with + | Some r when WpReached.smoking r s -> + WpStrategy.add_prop_dead_code acc config.kf s + | _ -> acc + else + acc + let get_stmt_annots config v s = let do_annot _ a ((b_acc, (a_acc, e_acc)) as acc) = match a.annot_content with @@ -965,7 +969,8 @@ let get_stmt_annots config v s = add_stmt_spec_annots config v s b_list spec acc | AExtended _ -> acc in - let before_acc = WpStrategy.empty_acc in + let before_acc = + add_stmt_deadcode_smoke config WpStrategy.empty_acc s in let after_acc = WpStrategy.empty_acc in let exits_acc = WpStrategy.empty_acc in let acc = before_acc, (after_acc, exits_acc) in @@ -1338,16 +1343,21 @@ let build_configs assigns kf model behaviors ki property = "[get_strategies] select stmt %d properties@." s.sid in let cfg = get_cfg kf model in + let reached = + if Wp_parameters.SmokeTests.get () + && Wp_parameters.SmokeDeadcode.get () + then Some (WpReached.reached kf) + else None in let def_annot_bhv, bhvs = find_behaviors kf cfg ki behaviors in if bhvs <> [] then debug "[get_strategies] %d behaviors" (List.length bhvs); - let mk_bhv_config bhv = { kf = kf; - cfg = cfg; - cur_bhv = bhv; - asked_prop = property; - asked_bhvs = bhvs; - assigns_filter = assigns; - def_annots_info = def_annot_bhv } - in List.map mk_bhv_config bhvs + let mk_bhv_config bhv = { + kf; reached; cfg; + cur_bhv = bhv; + asked_prop = property; + asked_bhvs = bhvs; + assigns_filter = assigns; + def_annots_info = def_annot_bhv; + } in List.map mk_bhv_config bhvs let get_strategies assigns kf model behaviors ki property = let configs = build_configs assigns kf model behaviors ki property in diff --git a/src/plugins/wp/wpAnnot.mli b/src/plugins/wp/wpAnnot.mli index 229061167c1..b08aa379c68 100644 --- a/src/plugins/wp/wpAnnot.mli +++ b/src/plugins/wp/wpAnnot.mli @@ -28,10 +28,6 @@ open Cil_types (*----------------------------------------------------------------------------*) -(** splits a prop_id goals into prop_id parts for each sub-goals *) -val split : ( WpPropId.prop_id -> 'a -> unit ) -> WpPropId.prop_id -> - 'a Bag.t -> unit - (** A proof accumulator for a set of related prop_id *) type proof @@ -41,12 +37,20 @@ val create_proof : WpPropId.prop_id -> proof val add_proof : proof -> WpPropId.prop_id -> Property.t list -> unit (** accumulate in the proof the partial proof for this prop_id *) +val add_invalid_proof : proof -> unit +(** add an invalid proof result ; can not revert a complete proof *) + val is_composed : proof -> bool (** whether a proof needs several lemma to be complete *) val is_proved : proof -> bool (** whether all partial proofs have been accumulated or not *) +val is_invalid : proof -> bool +(** whether an invalid proof result has been registered or not *) + +val status : proof -> [ `Proved | `Invalid | `Partial ] + val target : proof -> Property.t val dependencies : proof -> Property.t list diff --git a/src/plugins/wp/wpPropId.ml b/src/plugins/wp/wpPropId.ml index b4cd7d5dd53..9821c657890 100644 --- a/src/plugins/wp/wpPropId.ml +++ b/src/plugins/wp/wpPropId.ml @@ -185,7 +185,7 @@ let mk_smoke kf ~id ?(doomed=[]) ?unreachable () = | Some stmt -> Property.OLStmt(kf,stmt) in { p_kind = PKSmoke; - p_prop = Property.ip_other ("smoke_" ^id) oloc ; + p_prop = Property.ip_other ("wp_smoke_" ^id) oloc ; p_doomed = doomed ; p_unreachable = oloc ; p_part = None ; @@ -957,9 +957,13 @@ let pp_axiom_info fmt (id,thm) = (* --- Prop Splitter --- *) (* -------------------------------------------------------------------------- *) +(* -------------------------------------------------------------------------- *) +(* --- Prop Splitter --- *) +(* -------------------------------------------------------------------------- *) + (* prop-id splitter *) -let _split job pid goals = +let split_bag job pid goals = let n = Bag.length goals in if n <= 1 then Bag.iter (job pid) goals else let k = ref 0 in @@ -969,6 +973,15 @@ let _split job pid goals = incr k ; job pid_k g) goals +let split_map f pid gs = + let n = List.length gs in + if n <= 1 then List.map (f pid) gs else + let k = ref 0 in + List.map (fun g -> + let pid_k = mk_part pid (!k,n) in + incr k ; f pid_k g + ) gs + (*----------------------------------------------------------------------------*) (** About proofs *) (*----------------------------------------------------------------------------*) diff --git a/src/plugins/wp/wpPropId.mli b/src/plugins/wp/wpPropId.mli index 67e720d71c3..c0020de8a10 100644 --- a/src/plugins/wp/wpPropId.mli +++ b/src/plugins/wp/wpPropId.mli @@ -250,6 +250,9 @@ val pp_pred_info : Format.formatter -> pred_info -> unit (*----------------------------------------------------------------------------*) +val split_bag : (prop_id -> 'a -> unit) -> prop_id -> 'a Bag.t -> unit +val split_map : (prop_id -> 'a -> 'b) -> prop_id -> 'a list -> 'b list + (** [mk_part pid (k, n)] build the identification for the [k/n] part of [pid].*) val mk_part : prop_id -> (int * int) -> prop_id diff --git a/src/plugins/wp/wpReached.ml b/src/plugins/wp/wpReached.ml new file mode 100644 index 00000000000..0c970996f35 --- /dev/null +++ b/src/plugins/wp/wpReached.ml @@ -0,0 +1,299 @@ +(**************************************************************************) +(* *) +(* This file is part of WP plug-in of Frama-C. *) +(* *) +(* Copyright (C) 2007-2020 *) +(* CEA (Commissariat a l'energie atomique et aux energies *) +(* alternatives) *) +(* *) +(* you can redistribute it and/or modify it under the terms of the GNU *) +(* Lesser General Public License as published by the Free Software *) +(* Foundation, version 2.1. *) +(* *) +(* It is distributed in the hope that it will be useful, *) +(* but WITHOUT ANY WARRANTY; without even the implied warranty of *) +(* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *) +(* GNU Lesser General Public License for more details. *) +(* *) +(* See the GNU Lesser General Public License version 2.1 *) +(* for more details (enclosed in the file licenses/LGPLv2.1). *) +(* *) +(**************************************************************************) + +open Cil_types +open Cil_datatype + +(* -------------------------------------------------------------------------- *) +(* --- Compute Reachability for Smoke Tests --- *) +(* -------------------------------------------------------------------------- *) + +type flow = + | F_goto (* single successor for node *) + | F_effect (* single successor with must-be-reach effect *) + | F_call (* multiple successors with must-be-reach effect *) + | F_branch (* branching node *) + | F_return (* return node *) + | F_entry (* function or loop entry node *) + | F_dead (* truly dead code *) + +type node = { + id : int ; + mutable flow : flow ; + mutable prev : node list ; + mutable reached : bool option ; +} + +let kid = ref 0 + +let node () = + incr kid ; + { id = !kid ; prev = [] ; reached = None ; flow = F_goto } + +(* -------------------------------------------------------------------------- *) +(* --- Unrolled Loop --- *) +(* -------------------------------------------------------------------------- *) + +let is_unrolled_completely spec = + match spec.term_node with + | TConst (LStr "completely") -> true + | _ -> false + +let rec is_predicate cond p = + match p.pred_content with + | Pfalse -> not cond + | Ptrue -> cond + | Pnot p -> is_predicate (not cond) p + | Pforall(_,p) | Pexists(_,p) | Plet(_,p) -> is_predicate cond p + | Pif(_,p,q) -> is_predicate cond p && is_predicate cond q + | Pat(p,_) -> is_predicate cond p + | Pand(p,q) -> + if cond + then is_predicate true p && is_predicate true q + else is_predicate false p || is_predicate false q + | Por(p,q) -> + if cond + then is_predicate true p && is_predicate true q + else is_predicate false p && is_predicate false q + | Pimplies(p,q) -> + if cond + then is_predicate false p || is_predicate true q + else is_predicate true p && is_predicate false q + | _ -> false + +let is_dead_annot ca = + match ca.annot_content with + | APragma (Loop_pragma (Unroll_specs [ spec ; _ ])) -> + false && is_unrolled_completely spec + | AAssert([],Assert,p) -> is_predicate false p + | AInvariant([],_,p) -> is_predicate false p + | _ -> false + +let is_dead_code stmt = + let exception Deadcode in + try + Annotations.iter_code_annot (fun _emitter ca -> + if is_dead_annot ca then raise Deadcode + ) stmt ; + false + with Deadcode -> true + +(* -------------------------------------------------------------------------- *) +(* --- Compute CFG --- *) +(* -------------------------------------------------------------------------- *) + +type reached = node Stmt.Map.t +type cfg = reached ref + +let of_stmt cfg s = + try Stmt.Map.find s !cfg with Not_found -> + let n = node () in + cfg := Stmt.Map.add s n !cfg ; n + +let goto a b = + b.prev <- a :: b.prev ; + if b.flow = F_dead then F_dead else F_goto + +let flow i f = + if f = F_dead then F_dead else + match i with + | Asm _ | Set _ -> F_effect + | Call _ -> F_call + | Local_init _ | Skip _ | Code_annot _ -> F_goto + +let merge a b = match a,b with + | F_dead , F_dead -> F_dead + | _ -> F_branch + +type env = { + cfg: cfg ; + break: node ; + continue: node ; +} + +let rec stmt env s b = + let a = of_stmt env.cfg s in + if is_dead_code s then + a.flow <- F_dead + else + a.flow <- skind env a b s.skind ; + a + +and skind env a b = function + | Instr i -> flow i (goto a b) + | Return (None,_) -> F_goto + | Return (Some _,_) -> F_return + | Goto (lbl,_) -> goto a (of_stmt env.cfg !lbl) + | Break _ -> goto a env.break + | Continue _ -> goto a env.continue + | If(_,bthen,belse,_) -> + let ft = goto a (block env bthen b) in + let fe = goto a (block env belse b) in + merge ft fe + | Switch(_,body,cases,_) -> + ignore (block { env with break = b } body b) ; + List.fold_left + (fun f s -> merge f (goto a (of_stmt env.cfg s))) + F_dead cases + | Loop(_,body,_,_,_) -> + let continue = node () in + let lenv = { env with continue ; break = b } in + let flow = goto a (block lenv body continue) in + if flow = F_dead then F_dead else F_entry + | Block body -> + goto a (block env body b) + | UnspecifiedSequence s -> + let body = Cil.block_from_unspecified_sequence s in + goto a (block env body b) + | Throw _ | TryCatch _ | TryFinally _ | TryExcept _ -> + Wp_parameters.not_yet_implemented "try-catch blocks" + +and block env blk b = sequence env blk.bstmts b +and sequence env seq b = match seq with + | [] -> b + | s :: seq -> stmt env s (sequence env seq b) + +(* -------------------------------------------------------------------------- *) +(* --- Compute Reachability --- *) +(* -------------------------------------------------------------------------- *) + +let rec reached node = + match node.reached with + | Some r -> r + | None -> + node.reached <- Some true ; (* cut loops *) + let r = List.for_all reached_after node.prev in + node.reached <- Some r ; r + +and reached_after node = + match node.flow with + | F_goto -> reached node + | F_effect | F_entry | F_dead -> true + | F_return | F_branch | F_call -> false + +let smoking_node n = + match n.flow with + | F_effect | F_call | F_return -> not (reached n) + | F_goto | F_branch | F_entry | F_dead -> false + +(* returns true if the stmt requires a reachability smoke test *) +let smoking nodes stmt = + try Stmt.Map.find stmt nodes |> smoking_node + with Not_found -> false + +let compute kf = + try + let f = Kernel_function.get_definition kf in + let cfg = ref Stmt.Map.empty in + let returned = node () in + let continue = node () in + let break = node () in + let entry = node () in + let body = block { cfg ; break ; continue } f.sbody returned in + let _ = goto entry body in + entry.flow <- F_entry ; !cfg + with Kernel_function.No_Definition -> + Stmt.Map.empty + +(* ---------------------------------------------------------------------- *) +(* --- Dump for debugging --- *) +(* ---------------------------------------------------------------------- *) + +module G = Dotgraph +module Nmap = Map.Make(struct type t = node let compare a b = a.id - b.id end) +module N = Dotgraph.Node(Nmap) + +let dump ~dir kf reached = + let name = Kernel_function.get_name kf in + let file = Printf.sprintf "%s/%s.dot" dir name in + let dot = G.open_dot ~file ~name () in + N.define dot + (fun a na -> + let attr = + if smoking_node a + then [`Filled;`Fillcolor "orange"] + else + match a.flow with + | F_entry | F_effect | F_return | F_call -> + [`Filled;`Fillcolor "green"] + | F_dead -> [`Filled;`Fillcolor "red"] + | F_branch | F_goto -> [] + in G.node dot na attr ; + List.iter + (fun b -> + let attr = match b.flow with + | F_call | F_branch | F_return | F_dead -> [`Dotted;`ArrowForward] + | F_effect | F_entry | F_goto -> [`ArrowForward] + in G.edge dot (N.get b) na attr) + a.prev + ) ; + Stmt.Map.iter + (fun s n -> + let label = + let module Pu = Pretty_utils in + let module Pr = Printer in + match s.skind with + | Instr _ | Return _ | Break _ | Continue _ | Goto _ -> + Pu.to_string Pr.pp_stmt s + | If(e,_,_,_) -> Pu.sfprintf "@[<hov 2>if (%a)@]" Pr.pp_exp e + | Switch(e,_,_,_) -> Pu.sfprintf "@[<hov 2>switch (%a)@]" Pr.pp_exp e + | Loop _ -> Printf.sprintf "Loop s%d" s.sid + | Block _ -> Printf.sprintf "Block s%d" s.sid + | UnspecifiedSequence _ -> Printf.sprintf "Seq. s%d" s.sid + | Throw _ | TryExcept _ | TryCatch _ | TryFinally _ -> + Printf.sprintf "Exn. s%d" s.sid + in G.node dot (N.get n) [`Box;`Label label]) + reached ; + G.run dot ; + G.close dot ; + let out = G.layout dot in + Wp_parameters.result "Reached Graph: %s" out + +(* ---------------------------------------------------------------------- *) +(* --- Projectified Analysis Result --- *) +(* ---------------------------------------------------------------------- *) + +module FRmap = Kernel_function.Make_Table + (Datatype.Make + (struct + type t = reached + include Datatype.Serializable_undefined + let reprs = [Stmt.Map.empty] + let name = "WpReachable.reached" + end)) + (struct + let name = "WpReachable.compute" + let dependencies = [Ast.self] + let size = 17 + end) + +let dkey = Wp_parameters.register_category "reached" + +let reached = FRmap.memo + begin fun kf -> + let r = compute kf in + (if Wp_parameters.has_dkey dkey then + let dir = Wp_parameters.get_session_dir ~force:true "reach" in + dump ~dir kf r ) ; r + end + +(* -------------------------------------------------------------------------- *) diff --git a/src/plugins/wp/wpReached.mli b/src/plugins/wp/wpReached.mli new file mode 100644 index 00000000000..3de8854af06 --- /dev/null +++ b/src/plugins/wp/wpReached.mli @@ -0,0 +1,52 @@ +(**************************************************************************) +(* *) +(* This file is part of WP plug-in of Frama-C. *) +(* *) +(* Copyright (C) 2007-2020 *) +(* CEA (Commissariat a l'energie atomique et aux energies *) +(* alternatives) *) +(* *) +(* you can redistribute it and/or modify it under the terms of the GNU *) +(* Lesser General Public License as published by the Free Software *) +(* Foundation, version 2.1. *) +(* *) +(* It is distributed in the hope that it will be useful, *) +(* but WITHOUT ANY WARRANTY; without even the implied warranty of *) +(* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *) +(* GNU Lesser General Public License for more details. *) +(* *) +(* See the GNU Lesser General Public License version 2.1 *) +(* for more details (enclosed in the file licenses/LGPLv2.1). *) +(* *) +(**************************************************************************) + +(* -------------------------------------------------------------------------- *) +(** Reachability for Smoke Tests *) +(* -------------------------------------------------------------------------- *) + +open Cil_types + +type reached +(** control flow graph dedicated to smoke tests *) + +val is_predicate : bool -> predicate -> bool +(** If returns [true] the predicate has always the given boolean value. *) + +val is_dead_annot : code_annotation -> bool +(** False assertions and loop invariant. + Hence, also includes completely unrolled loop. *) + +val is_dead_code : stmt -> bool +(** Checks whether the stmt has a dead-code annotation. *) + +val reached : Kernel_function.t -> reached +(** memoized reached cfg for function *) + +val smoking : reached -> Cil_types.stmt -> bool +(** Returns whether a stmt need a smoke tests to avoid being unreachable. + This is restricted to assignments, returns and calls not dominated + another smoking statement. *) + +val dump : dir:string -> Kernel_function.t -> reached -> unit + +(* -------------------------------------------------------------------------- *) diff --git a/src/plugins/wp/wpReport.ml b/src/plugins/wp/wpReport.ml index 25c34d2e6d9..be5b8151c13 100644 --- a/src/plugins/wp/wpReport.ml +++ b/src/plugins/wp/wpReport.ml @@ -90,12 +90,15 @@ let rank n = type res = VALID | UNSUCCESS | INCONCLUSIVE | NORESULT -let result ~smoke (r:VCS.result) = - match VCS.verdict ~smoke r with - | VCS.NoResult | VCS.Checked | VCS.Computing _ -> NORESULT - | VCS.Failed -> INCONCLUSIVE - | VCS.Invalid | VCS.Unknown | VCS.Timeout | VCS.Stepout -> UNSUCCESS - | VCS.Valid -> VALID +let result ~status ~smoke (r:VCS.result) = + match status with + | `Passed when smoke -> VALID + | _ -> + match VCS.verdict ~smoke r with + | VCS.NoResult | VCS.Computing _ -> NORESULT + | VCS.Failed -> INCONCLUSIVE + | VCS.Invalid | VCS.Unknown | VCS.Timeout | VCS.Stepout -> UNSUCCESS + | VCS.Valid -> VALID let best_result a b = match a,b with | NORESULT,c | c,NORESULT -> c @@ -204,14 +207,14 @@ let get_prover fs prover = let s = stats () in Hashtbl.add fs.prover prover s ; s -let add_results (plist:pstats list) (wpo:Wpo.t) = - let ok = ref NORESULT in +let add_results ~status (plist:pstats list) (wpo:Wpo.t) = + let res = ref NORESULT in let tm = ref 0.0 in let sm = ref 0 in + let smoke = Wpo.is_smoke_test wpo in List.iter (fun (p,r) -> - let smoke = Wpo.is_smoke_test wpo in - let re = result ~smoke r in + let re = result ~status ~smoke r in let st = Wpo.get_steps r in let tc = Wpo.get_time r in let ts = r.VCS.solver_time in @@ -225,11 +228,11 @@ let add_results (plist:pstats list) (wpo:Wpo.t) = (fun fs -> add_qedstat ts (get_prover fs VCS.Qed)) plist ; end ; - ok := best_result !ok re ; + res := best_result !res re ; if tc > !tm then tm := tc ; if st > !sm then sm := st ; ) (Wpo.get_results wpo) ; - List.iter (fun fs -> add_stat !ok !sm !tm fs.main) plist + List.iter (fun fs -> add_stat !res !sm !tm fs.main) plist (* -------------------------------------------------------------------------- *) (* --- Stats by Section --- *) @@ -366,9 +369,10 @@ let add_goal (gs:fcstat) wpo = | Wpo.Function(kf,_) -> Fun kf in let ds : dstats = get_section gs section in - let (ok,prop) = Wpo.get_proof wpo in + let status,prop = Wpo.get_proof wpo in let ps : pstats = get_property ds prop in - add_results [gs.global ; ds.dstats ; ps] wpo ; + add_results status [gs.global ; ds.dstats ; ps] wpo ; + let ok = (status = `Passed) in add_cover gs.gcoverage ok prop ; add_cover ds.dcoverage ok prop ; end diff --git a/src/plugins/wp/wpStrategy.ml b/src/plugins/wp/wpStrategy.ml index c5ba6351d77..ee31dab55e7 100644 --- a/src/plugins/wp/wpStrategy.ml +++ b/src/plugins/wp/wpStrategy.ml @@ -48,6 +48,9 @@ type annot_kind = | AcallPre of bool * kernel_function (* annotation is a called function precondition : to be considered as hyp, and goal if bool=true *) + | AcallPost of kernel_function + (* annotation is a called function post check : + to be considered as goal only *) (* -------------------------------------------------------------------------- *) (* --- Annotations for one program point. --- *) @@ -66,6 +69,7 @@ type annots = { p_cut : (bool * WpPropId.pred_info) list; call_hyp : WpPropId.pred_info list ForCall.t; (* post and pre *) call_pre : (bool * WpPropId.pred_info) list ForCall.t; (* goal only *) + call_post : WpPropId.pred_info list ForCall.t; (* post goals only (not hyp) *) call_asgn : WpPropId.assigns_full_info ForCall.t; a_goal : WpPropId.assigns_full_info; a_hyp : WpPropId.assigns_full_info; @@ -82,6 +86,7 @@ let empty_acc = call_hyp = ForCall.empty; call_pre = ForCall.empty; call_asgn = ForCall.empty; + call_post = ForCall.empty; a_goal = WpPropId.empty_assigns_info; a_hyp = WpPropId.empty_assigns_info; a_call = WpPropId.empty_assigns_info; @@ -112,7 +117,7 @@ let add_prop acc kind id p = | None -> l | Some p -> (goal, p)::l in - let add_hyp_call fct calls = + let add_for_call fct calls = let l = try ForCall.find fct calls with Not_found -> [] in ForCall.add fct (add_hyp l) calls in let add_both_call fct goal calls = @@ -129,9 +134,11 @@ let add_prop acc kind id p = | AcutB goal -> goal, { info with p_cut = add_both goal info.p_cut } | AcallHyp fct -> - false, { info with call_hyp = add_hyp_call fct info.call_hyp } + false, { info with call_hyp = add_for_call fct info.call_hyp } | AcallPre (goal,fct) -> goal, { info with call_pre = add_both_call fct goal info.call_pre } + | AcallPost fct -> + true, { info with call_post = add_for_call fct info.call_post } in let acc = { acc with info = info } in if goal then { acc with has_prop_goal = true} else acc @@ -260,10 +267,17 @@ let add_prop_fct_smoke acc kf bhv = let doomed = Property.ip_requires_of_behavior kf Kglobal bhv in add_smoke acc kf ~id ~doomed () -let add_prop_loop_smoke acc kf stmt = - if not (Wp_parameters.Split.get()) then - add_smoke acc kf ~id:"loop_invariant" ~unreachable:stmt () - else acc +let add_prop_dead_loop acc kf stmt = + add_smoke acc kf ~id:"dead_loop" ~unreachable:stmt () + +let add_prop_dead_code acc kf stmt = + add_smoke acc kf ~id:"dead_code" ~unreachable:stmt () + +let add_prop_dead_call kf stmt acc_posts acc_exits = + let id = WpPropId.mk_smoke kf ~id:"dead_call" ~unreachable:stmt () in + let kind = AcallPost kf in + let pred = Some Logic_const.pfalse in + add_prop acc_posts kind id pred , add_prop acc_exits kind id pred (* -------------------------------------------------------------------------- *) @@ -435,6 +449,10 @@ let get_call_pre annots fct = try filter_both (ForCall.find fct annots.info.call_pre) with Not_found -> [],[] +let get_call_post annots fct = + try ForCall.find fct annots.info.call_post + with Not_found -> [] + let get_call_asgn annots = function | None -> annots.info.a_call | Some fct -> @@ -498,6 +516,7 @@ let merge_acc acc1 acc2 = p_cut = acc1.p_cut @ acc2.p_cut; call_hyp = merge_calls (@) acc1.call_hyp acc2.call_hyp; call_pre = merge_calls (@) acc1.call_pre acc2.call_pre; + call_post = merge_calls (@) acc1.call_post acc2.call_post; call_asgn = merge_calls WpPropId.merge_assign_info acc1.call_asgn acc2.call_asgn; a_goal = WpPropId.merge_assign_info acc1.a_goal acc2.a_goal; a_hyp = WpPropId.merge_assign_info acc1.a_hyp acc2.a_hyp; diff --git a/src/plugins/wp/wpStrategy.mli b/src/plugins/wp/wpStrategy.mli index fa236285eb9..9177f1fe536 100644 --- a/src/plugins/wp/wpStrategy.mli +++ b/src/plugins/wp/wpStrategy.mli @@ -58,6 +58,9 @@ type annot_kind = | AcallPre of bool * kernel_function (** annotation is a called function precondition : to be considered as hyp, and goal if bool=true *) + | AcallPost of kernel_function + (** annotation is a called function post check : + to be considered as goal only (no hyp) *) (** {3 Adding properties (predicates)} *) @@ -87,8 +90,15 @@ val add_prop_fct_bhv_pre : t_annots -> annot_kind -> (** Add Smoke Test behavior *) val add_prop_fct_smoke : t_annots -> kernel_function -> funbehavior -> t_annots -(** Add Smoke Test behavior for loop *) -val add_prop_loop_smoke : t_annots -> kernel_function -> stmt -> t_annots +(** Add Smoke Test for loop *) +val add_prop_dead_loop : t_annots -> kernel_function -> stmt -> t_annots + +(** Add Smoke Test for possibly dead code *) +val add_prop_dead_code : t_annots -> kernel_function -> stmt -> t_annots + +(** Add Smoke Test for possibly dead call : (posts,exits) *) +val add_prop_dead_call : kernel_function -> stmt -> t_annots -> t_annots -> + t_annots * t_annots val add_prop_fct_post : t_annots -> annot_kind -> kernel_function -> funbehavior -> termination_kind -> identified_predicate @@ -182,6 +192,9 @@ val get_call_hyp : t_annots -> kernel_function -> WpPropId.pred_info list * (similar to [get_both_hyp_goals]). *) val get_call_pre : t_annots -> kernel_function -> WpPropId.pred_info list * WpPropId.pred_info list +(** Post-checks of a called function to be considered as goal only *) +val get_call_post : t_annots -> kernel_function -> WpPropId.pred_info list + val get_call_asgn : t_annots -> kernel_function option -> WpPropId.assigns_full_info diff --git a/src/plugins/wp/wp_parameters.ml b/src/plugins/wp/wp_parameters.ml index 630ee22a7c0..c1d7d6ad719 100644 --- a/src/plugins/wp/wp_parameters.ml +++ b/src/plugins/wp/wp_parameters.ml @@ -374,6 +374,27 @@ module SmokeTests = let help = "Smoke-tests : look for inconsistent contracts (best effort)" end) +let () = Parameter_customize.set_group wp_strategy +module SmokeDeadcode = + True(struct + let option_name = "-wp-smoke-dead-code" + let help = "When generating smoke tests, look for unreachable code" + end) + +let () = Parameter_customize.set_group wp_strategy +module SmokeDeadcall = + True(struct + let option_name = "-wp-smoke-dead-call" + let help = "When generating smoke tests, look for non-terminating calls" + end) + +let () = Parameter_customize.set_group wp_strategy +module SmokeDeadloop = + True(struct + let option_name = "-wp-smoke-dead-loop" + let help = "When generating smoke tests, look for inconsistent loop invairants" + end) + let () = Parameter_customize.set_group wp_strategy module Split = False(struct diff --git a/src/plugins/wp/wp_parameters.mli b/src/plugins/wp/wp_parameters.mli index 2d763525c65..3103707f185 100644 --- a/src/plugins/wp/wp_parameters.mli +++ b/src/plugins/wp/wp_parameters.mli @@ -147,6 +147,9 @@ module ReportJson: Parameter_sig.String module ReportName: Parameter_sig.String module MemoryContext: Parameter_sig.Bool module SmokeTests: Parameter_sig.Bool +module SmokeDeadloop: Parameter_sig.Bool +module SmokeDeadcode: Parameter_sig.Bool +module SmokeDeadcall: Parameter_sig.Bool (** {2 Getters} *) diff --git a/src/plugins/wp/wpo.ml b/src/plugins/wp/wpo.ml index b28f9e6b297..c3c6df38b3f 100644 --- a/src/plugins/wp/wpo.ml +++ b/src/plugins/wp/wpo.ml @@ -691,65 +691,49 @@ let warnings = function let get_time = function { prover_time=t } -> t let get_steps= function { prover_steps=n } -> n let get_target g = WpPropId.property_of_id g.po_pid + let get_proof g = let system = SYSTEM.get () in let target = get_target g in let status = try let proof = Hproof.find system.proofs (proof g target) in - WpAnnot.is_proved proof - with Not_found -> false + if is_smoke_test g then + if WpAnnot.is_proved proof then `Failed else + if WpAnnot.is_invalid proof then `Passed else + `Unknown + else + if WpAnnot.is_proved proof then `Passed else `Unknown + with Not_found -> `Unknown in status , target -let doomed_unreachable emitter pid = +let set_invalid emitter tgt = + Property_status.emit emitter ~hyps:[] tgt Property_status.False_if_reachable + +let set_doomed emitter pid = + List.iter (set_invalid emitter) (WpPropId.doomed_if_valid pid) ; match WpPropId.unreachable_if_valid pid with | Property.OLStmt(kf,stmt) -> - let pred_loc = Stmt.loc stmt in - let pred_name = [ "Wp" ; "SmokeTest" ] in - let pf = { Logic_const.pfalse with pred_loc ; pred_name } in - let ca = Logic_const.new_code_annotation (AAssert ([],Assert,pf)) in - Annotations.add_code_annot emitter ~kf stmt ca ; - Property.ip_of_code_annot kf stmt ca - | Property.OLGlob _ | Property.OLContract _ -> [] - -let update_property_status g r = - let system = SYSTEM.get () in - try - let pi = proof g (WpPropId.property_of_id g.po_pid) in - let proof = - try Hproof.find system.proofs pi - with Not_found -> - let proof = WpAnnot.create_proof g.po_pid in - Hproof.add system.proofs pi proof ; proof - in - let emitter = WpContext.get_emitter g.po_model in - let smoke = is_smoke_test g in - let status = - match VCS.verdict ~smoke r with - | Valid -> - WpAnnot.add_proof proof g.po_pid (get_depend g) ; - if WpAnnot.is_proved proof then Property_status.True - else Property_status.Dont_know - | Invalid when smoke -> - let status = Property_status.False_if_reachable in - List.iter - (fun tgt -> Property_status.emit emitter ~hyps:[] tgt status) - (WpPropId.doomed_if_valid g.po_pid) ; - let status = Property_status.True in - List.iter - (fun tgt -> Property_status.emit emitter ~hyps:[] tgt status) - (doomed_unreachable emitter g.po_pid) ; - Property_status.False_if_reachable - | _ -> - if WpAnnot.is_proved proof then Property_status.True - else Property_status.Dont_know - in - let target = WpAnnot.target proof in - let depends = WpAnnot.dependencies proof in - Property_status.emit emitter ~hyps:depends target status ; - with err -> - Wp_parameters.failure "Update-status failed (%s)" (Printexc.to_string err) ; - raise err + let ca = + let filter = WpReached.is_dead_annot in + match Annotations.code_annot ~emitter ~filter stmt with + | ca::_ -> ca + | [] -> + let pred_loc = Stmt.loc stmt in + let pred_name = [ "Wp" ; "SmokeTest" ] in + let pf = { Logic_const.pfalse with pred_loc ; pred_name } in + let ca = Logic_const.new_code_annotation (AAssert ([],Assert,pf)) in + Annotations.add_code_annot emitter ~kf stmt ca ; ca + in + List.iter (set_invalid emitter) (Property.ip_of_code_annot kf stmt ca) + | Property.OLGlob _ | Property.OLContract _ -> () + +let find_proof system g = + let pi = proof g (WpPropId.property_of_id g.po_pid) in + try Hproof.find system.proofs pi + with Not_found -> + let proof = WpAnnot.create_proof g.po_pid in + Hproof.add system.proofs pi proof ; proof let clear_results g = let system = SYSTEM.get () in @@ -769,9 +753,34 @@ let set_result g p r = in Results.replace rs p r ; if not (WpPropId.is_check g.po_pid) && - not (WpPropId.is_tactic g.po_pid) + not (WpPropId.is_tactic g.po_pid) && + VCS.is_verdict r then - update_property_status g r ; + let smoke = is_smoke_test g in + let proof = find_proof system g in + let emitter = WpContext.get_emitter g.po_model in + let target = WpAnnot.target proof in + let unproved = not (WpAnnot.is_proved proof) in + if VCS.is_valid r then + WpAnnot.add_proof proof g.po_pid (get_depend g) + else if smoke then + WpAnnot.add_invalid_proof proof ; + let proved = WpAnnot.is_proved proof in + let status = + if smoke then + if proved + then Property_status.False_if_reachable (* All goals SAT *) + else if WpAnnot.is_invalid proof + then Property_status.True (* Some goal is UNSAT *) + else Property_status.Dont_know (* Not finished yet *) + else + if proved + then Property_status.True + else Property_status.Dont_know + in + let hyps = if smoke then [] else WpAnnot.dependencies proof in + Property_status.emit emitter ~hyps target status ; + if smoke && unproved && proved then set_doomed emitter g.po_pid ; end let has_verdict g p = @@ -803,9 +812,10 @@ let reduce g = let resolve g = let valid = reduce g in if valid then - ( let solver = qed_time g in - set_result g VCS.Qed (VCS.result ~solver VCS.Valid) ) ; - valid + let result = VCS.result ~solver:(qed_time g) VCS.Valid in + ignore (set_result g VCS.Qed result) ; + true + else false let compute g = let ctxt = get_context g in diff --git a/src/plugins/wp/wpo.mli b/src/plugins/wp/wpo.mli index 979ce9c5ce7..4c1981c0fa0 100644 --- a/src/plugins/wp/wpo.mli +++ b/src/plugins/wp/wpo.mli @@ -155,7 +155,7 @@ val compute : t -> Definitions.axioms option * Conditions.sequent val has_verdict : t -> prover -> bool val get_result : t -> prover -> result val get_results : t -> (prover * result) list -val get_proof : t -> bool * Property.t +val get_proof : t -> [`Passed|`Failed|`Unknown] * Property.t val get_target : t -> Property.t val is_trivial : t -> bool (** do not tries simplification, do not check prover results *) val is_proved : t -> bool (** do not tries simplification, check prover results *) -- GitLab From 04ba2fe5bf5cb046f2f58eefacfee5c86c526f96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Loi=CC=88c=20Correnson?= <loic.correnson@cea.fr> Date: Fri, 10 Apr 2020 13:20:49 +0200 Subject: [PATCH 181/218] [wp] changelog since calcium --- src/plugins/wp/Changelog | 45 ++++++++++++++++++++++++---------------- 1 file changed, 27 insertions(+), 18 deletions(-) diff --git a/src/plugins/wp/Changelog b/src/plugins/wp/Changelog index 3329a913f3c..8e42d3b2e3f 100644 --- a/src/plugins/wp/Changelog +++ b/src/plugins/wp/Changelog @@ -20,24 +20,33 @@ # <Prover>: prover ############################################################################### -- WP [2020/03/26] Added support for invalid-pointer predicate -- WP [2020/02/21] Why3 prover version fallback -- WP [2020/02/21] Why3 prover full-names use ':' instead of ',' --* WP [2020/02/20] Fixes handling of LoopCurrent in loop invariants -- WP [2020/02/10] Specify cache mode with FRAMAC_WP_CACHE=<mode> (-wp-cache-env) -- WP [2020/02/10] Update scripts with FRAMAC_WP_SCRIPT=update and -wp-prover script -- WP [2020/02/10] Move frame conditions to Type section for better filtering -- WP [2020/02/10] Extended frame conditions to pointers inside compound -- WP [2020/02/10] Extended frame conditions with global C-types -- WP [2019/17/04] Control splitting with -wp-max-split <n> -- WP [2019/12/04] Added option -wp-run-all-provers -- WP [2019/01/29] Emit a warning when no goal is generated -- Wp [2019/06/04] Checks for inconsistent requires (-wp-smoke-tests) -- TIP [2018/04/03] Create session directory only on demand -- TIP [2018/03/19] Specification of JSON script format -- Wp [2018/03/18] Additional lemma about remainder (mod) -- TIP [2018/03/18] Refactor structure of session directory (remove models) -- Wp [2018/02/18] Additional lemmas about logical shift compositions + - WP [2020/04/10] Full support for Why3 IEEE float library + - WP [2020/04/10] Removed option -wp-check + - WP [2020/04/09] Added smoke tests for dead call (-wp-smoke-dead-call) + - WP [2020/03/23] Added smoke tests for dead code (-wp-smoke-dead-code) + - WP [2020/03/23] Added smoke tests for dead loop (-wp-smoke-dead-loop) + - WP [2020/03/26] Added support for invalid-pointer predicate + - WP [2020/03/04] Fixed scope problem on block outgoing edge + - WP [2020/02/21] Why3 prover version fallback + - WP [2020/02/21] Why3 prover full-names use ':' instead of ',' + - WP [2020/02/20] Fixes handling of LoopCurrent in loop invariants + - WP [2020/02/10] Specify cache mode with FRAMAC_WP_CACHE=<mode> (-wp-cache-env) + - WP [2020/02/10] Update scripts with FRAMAC_WP_SCRIPT=update and -wp-prover script + - WP [2020/02/10] Move frame conditions to Type section for better filtering + - WP [2020/02/10] Extended frame conditions to pointers inside compound + - WP [2020/02/10] Extended frame conditions with global C-types + - WP [2019/17/04] Control splitting with -wp-max-split <n> + - WP [2019/12/19] Fix drivers in different projects + - WP [2019/12/04] Added option -wp-run-all-provers + - WP [2019/06/04] Checks for inconsistent requires (-wp-smoke-tests) + - WP [2019/01/29] Emit a warning when no goal is generated + - WP [2018/04/17] Limit the number of splits (see -wp-max-split) + - TIP [2018/04/03] Create session directory only on demand + - TIP [2018/03/19] Specification of JSON script format + - WP [2018/03/18] Additional lemma about remainder (mod) + - TIP [2018/03/18] Refactor structure of session directory (remove models) + - TIP [2018/02/20] Extends bitwise tactics to dis-equalities + - WP [2018/02/18] Additional lemmas about logical shift compositions ########################## Plugin WP 20.0 (Calcium) -- GitLab From 0a58a02a3a1ab1067f4cfd1618e757015afad10d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Loi=CC=88c=20Correnson?= <loic.correnson@cea.fr> Date: Fri, 10 Apr 2020 13:29:47 +0200 Subject: [PATCH 182/218] [wp] cache updates --- .../cache/af2254c1fa0216f2c678366bdede3b13.json | 1 + .../cache/fa59bf961c2e5397658a695e7a6d70d7.json | 1 + .../cache/3c09d952f228b980bfc7351233bea851.json | 2 ++ .../cache/82f897485c8c7f2dea5812a6e02dc9bc.json | 2 ++ .../cache/1eca675b58cd4c1bd275d6c731157e8d.json | 1 + .../cache/2e52caad3f8b8552be7c703a245947cf.json | 1 + .../cache/434cbeb147419d3a67a7ba9f259979b4.json | 1 + .../cache/a67555f65c0eeddae65ea767feee094b.json | 1 + .../cache/d24d77f4cbf6a953898fc10a000e82ec.json | 1 + .../cache/1eca675b58cd4c1bd275d6c731157e8d.json | 1 + .../cache/2e52caad3f8b8552be7c703a245947cf.json | 1 + .../cache/434cbeb147419d3a67a7ba9f259979b4.json | 1 + .../cache/a67555f65c0eeddae65ea767feee094b.json | 1 + .../cache/d24d77f4cbf6a953898fc10a000e82ec.json | 1 + .../cache/2c0433881c3e7c204fbd933fae94ed2a.json | 1 + .../cache/2e52caad3f8b8552be7c703a245947cf.json | 1 + .../cache/434cbeb147419d3a67a7ba9f259979b4.json | 1 + .../cache/6de0af457f7b1f3d82b27400e43a68aa.json | 1 + .../cache/e8b77cbcc3a78b598f47a9de28727817.json | 1 + .../cache/0eff509260291b913afca26f97217593.json | 1 + .../cache/2c0433881c3e7c204fbd933fae94ed2a.json | 1 + .../cache/2e52caad3f8b8552be7c703a245947cf.json | 1 + .../cache/434cbeb147419d3a67a7ba9f259979b4.json | 1 + .../cache/6de0af457f7b1f3d82b27400e43a68aa.json | 1 + .../cache/e8b77cbcc3a78b598f47a9de28727817.json | 1 + .../cache/3c09d952f228b980bfc7351233bea851.json | 2 ++ .../cache/82f897485c8c7f2dea5812a6e02dc9bc.json | 2 ++ .../cache/62a7cbaba5d3871e1ed28541c6fe7028.json | 1 + .../cache/75e1dbec55b6df45c46dfa1e74531a0c.json | 1 + .../cache/2e52caad3f8b8552be7c703a245947cf.json | 1 + 30 files changed, 34 insertions(+) create mode 100644 src/plugins/wp/tests/wp_plugin/oracle_qualif/bit_test.0.session/cache/af2254c1fa0216f2c678366bdede3b13.json create mode 100644 src/plugins/wp/tests/wp_plugin/oracle_qualif/bit_test.0.session/cache/fa59bf961c2e5397658a695e7a6d70d7.json create mode 100644 src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_axioms.0.session/cache/3c09d952f228b980bfc7351233bea851.json create mode 100644 src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_axioms.0.session/cache/82f897485c8c7f2dea5812a6e02dc9bc.json create mode 100644 src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_call.1.session/cache/1eca675b58cd4c1bd275d6c731157e8d.json create mode 100644 src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_call.1.session/cache/2e52caad3f8b8552be7c703a245947cf.json create mode 100644 src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_call.1.session/cache/434cbeb147419d3a67a7ba9f259979b4.json create mode 100644 src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_call.1.session/cache/a67555f65c0eeddae65ea767feee094b.json create mode 100644 src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_call.1.session/cache/d24d77f4cbf6a953898fc10a000e82ec.json create mode 100644 src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_call.2.session/cache/1eca675b58cd4c1bd275d6c731157e8d.json create mode 100644 src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_call.2.session/cache/2e52caad3f8b8552be7c703a245947cf.json create mode 100644 src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_call.2.session/cache/434cbeb147419d3a67a7ba9f259979b4.json create mode 100644 src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_call.2.session/cache/a67555f65c0eeddae65ea767feee094b.json create mode 100644 src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_call.2.session/cache/d24d77f4cbf6a953898fc10a000e82ec.json create mode 100644 src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_dead.0.session/cache/2c0433881c3e7c204fbd933fae94ed2a.json create mode 100644 src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_dead.0.session/cache/2e52caad3f8b8552be7c703a245947cf.json create mode 100644 src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_dead.0.session/cache/434cbeb147419d3a67a7ba9f259979b4.json create mode 100644 src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_dead.0.session/cache/6de0af457f7b1f3d82b27400e43a68aa.json create mode 100644 src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_dead.0.session/cache/e8b77cbcc3a78b598f47a9de28727817.json create mode 100644 src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_dead.1.session/cache/0eff509260291b913afca26f97217593.json create mode 100644 src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_dead.1.session/cache/2c0433881c3e7c204fbd933fae94ed2a.json create mode 100644 src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_dead.1.session/cache/2e52caad3f8b8552be7c703a245947cf.json create mode 100644 src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_dead.1.session/cache/434cbeb147419d3a67a7ba9f259979b4.json create mode 100644 src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_dead.1.session/cache/6de0af457f7b1f3d82b27400e43a68aa.json create mode 100644 src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_dead.1.session/cache/e8b77cbcc3a78b598f47a9de28727817.json create mode 100644 src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_report_ko.0.session/cache/3c09d952f228b980bfc7351233bea851.json create mode 100644 src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_report_ko.0.session/cache/82f897485c8c7f2dea5812a6e02dc9bc.json create mode 100644 src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_report_ok.0.session/cache/62a7cbaba5d3871e1ed28541c6fe7028.json create mode 100644 src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_report_ok.0.session/cache/75e1dbec55b6df45c46dfa1e74531a0c.json create mode 100644 src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_unroll.0.session/cache/2e52caad3f8b8552be7c703a245947cf.json diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/bit_test.0.session/cache/af2254c1fa0216f2c678366bdede3b13.json b/src/plugins/wp/tests/wp_plugin/oracle_qualif/bit_test.0.session/cache/af2254c1fa0216f2c678366bdede3b13.json new file mode 100644 index 00000000000..b8e36e2803f --- /dev/null +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/bit_test.0.session/cache/af2254c1fa0216f2c678366bdede3b13.json @@ -0,0 +1 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "timeout", "time": 10. } diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/bit_test.0.session/cache/fa59bf961c2e5397658a695e7a6d70d7.json b/src/plugins/wp/tests/wp_plugin/oracle_qualif/bit_test.0.session/cache/fa59bf961c2e5397658a695e7a6d70d7.json new file mode 100644 index 00000000000..b8e36e2803f --- /dev/null +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/bit_test.0.session/cache/fa59bf961c2e5397658a695e7a6d70d7.json @@ -0,0 +1 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "timeout", "time": 10. } diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_axioms.0.session/cache/3c09d952f228b980bfc7351233bea851.json b/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_axioms.0.session/cache/3c09d952f228b980bfc7351233bea851.json new file mode 100644 index 00000000000..e9448532068 --- /dev/null +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_axioms.0.session/cache/3c09d952f228b980bfc7351233bea851.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0072, + "steps": 15 } diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_axioms.0.session/cache/82f897485c8c7f2dea5812a6e02dc9bc.json b/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_axioms.0.session/cache/82f897485c8c7f2dea5812a6e02dc9bc.json new file mode 100644 index 00000000000..9910b14f695 --- /dev/null +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_axioms.0.session/cache/82f897485c8c7f2dea5812a6e02dc9bc.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0074, + "steps": 15 } diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_call.1.session/cache/1eca675b58cd4c1bd275d6c731157e8d.json b/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_call.1.session/cache/1eca675b58cd4c1bd275d6c731157e8d.json new file mode 100644 index 00000000000..e66c1e560c3 --- /dev/null +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_call.1.session/cache/1eca675b58cd4c1bd275d6c731157e8d.json @@ -0,0 +1 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "timeout", "time": 2. } diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_call.1.session/cache/2e52caad3f8b8552be7c703a245947cf.json b/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_call.1.session/cache/2e52caad3f8b8552be7c703a245947cf.json new file mode 100644 index 00000000000..56c39550428 --- /dev/null +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_call.1.session/cache/2e52caad3f8b8552be7c703a245947cf.json @@ -0,0 +1 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "unknown" } diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_call.1.session/cache/434cbeb147419d3a67a7ba9f259979b4.json b/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_call.1.session/cache/434cbeb147419d3a67a7ba9f259979b4.json new file mode 100644 index 00000000000..e66c1e560c3 --- /dev/null +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_call.1.session/cache/434cbeb147419d3a67a7ba9f259979b4.json @@ -0,0 +1 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "timeout", "time": 2. } diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_call.1.session/cache/a67555f65c0eeddae65ea767feee094b.json b/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_call.1.session/cache/a67555f65c0eeddae65ea767feee094b.json new file mode 100644 index 00000000000..e66c1e560c3 --- /dev/null +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_call.1.session/cache/a67555f65c0eeddae65ea767feee094b.json @@ -0,0 +1 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "timeout", "time": 2. } diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_call.1.session/cache/d24d77f4cbf6a953898fc10a000e82ec.json b/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_call.1.session/cache/d24d77f4cbf6a953898fc10a000e82ec.json new file mode 100644 index 00000000000..e66c1e560c3 --- /dev/null +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_call.1.session/cache/d24d77f4cbf6a953898fc10a000e82ec.json @@ -0,0 +1 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "timeout", "time": 2. } diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_call.2.session/cache/1eca675b58cd4c1bd275d6c731157e8d.json b/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_call.2.session/cache/1eca675b58cd4c1bd275d6c731157e8d.json new file mode 100644 index 00000000000..e66c1e560c3 --- /dev/null +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_call.2.session/cache/1eca675b58cd4c1bd275d6c731157e8d.json @@ -0,0 +1 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "timeout", "time": 2. } diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_call.2.session/cache/2e52caad3f8b8552be7c703a245947cf.json b/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_call.2.session/cache/2e52caad3f8b8552be7c703a245947cf.json new file mode 100644 index 00000000000..56c39550428 --- /dev/null +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_call.2.session/cache/2e52caad3f8b8552be7c703a245947cf.json @@ -0,0 +1 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "unknown" } diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_call.2.session/cache/434cbeb147419d3a67a7ba9f259979b4.json b/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_call.2.session/cache/434cbeb147419d3a67a7ba9f259979b4.json new file mode 100644 index 00000000000..e66c1e560c3 --- /dev/null +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_call.2.session/cache/434cbeb147419d3a67a7ba9f259979b4.json @@ -0,0 +1 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "timeout", "time": 2. } diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_call.2.session/cache/a67555f65c0eeddae65ea767feee094b.json b/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_call.2.session/cache/a67555f65c0eeddae65ea767feee094b.json new file mode 100644 index 00000000000..e66c1e560c3 --- /dev/null +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_call.2.session/cache/a67555f65c0eeddae65ea767feee094b.json @@ -0,0 +1 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "timeout", "time": 2. } diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_call.2.session/cache/d24d77f4cbf6a953898fc10a000e82ec.json b/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_call.2.session/cache/d24d77f4cbf6a953898fc10a000e82ec.json new file mode 100644 index 00000000000..e66c1e560c3 --- /dev/null +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_call.2.session/cache/d24d77f4cbf6a953898fc10a000e82ec.json @@ -0,0 +1 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "timeout", "time": 2. } diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_dead.0.session/cache/2c0433881c3e7c204fbd933fae94ed2a.json b/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_dead.0.session/cache/2c0433881c3e7c204fbd933fae94ed2a.json new file mode 100644 index 00000000000..e66c1e560c3 --- /dev/null +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_dead.0.session/cache/2c0433881c3e7c204fbd933fae94ed2a.json @@ -0,0 +1 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "timeout", "time": 2. } diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_dead.0.session/cache/2e52caad3f8b8552be7c703a245947cf.json b/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_dead.0.session/cache/2e52caad3f8b8552be7c703a245947cf.json new file mode 100644 index 00000000000..56c39550428 --- /dev/null +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_dead.0.session/cache/2e52caad3f8b8552be7c703a245947cf.json @@ -0,0 +1 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "unknown" } diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_dead.0.session/cache/434cbeb147419d3a67a7ba9f259979b4.json b/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_dead.0.session/cache/434cbeb147419d3a67a7ba9f259979b4.json new file mode 100644 index 00000000000..e66c1e560c3 --- /dev/null +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_dead.0.session/cache/434cbeb147419d3a67a7ba9f259979b4.json @@ -0,0 +1 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "timeout", "time": 2. } diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_dead.0.session/cache/6de0af457f7b1f3d82b27400e43a68aa.json b/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_dead.0.session/cache/6de0af457f7b1f3d82b27400e43a68aa.json new file mode 100644 index 00000000000..e66c1e560c3 --- /dev/null +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_dead.0.session/cache/6de0af457f7b1f3d82b27400e43a68aa.json @@ -0,0 +1 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "timeout", "time": 2. } diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_dead.0.session/cache/e8b77cbcc3a78b598f47a9de28727817.json b/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_dead.0.session/cache/e8b77cbcc3a78b598f47a9de28727817.json new file mode 100644 index 00000000000..e66c1e560c3 --- /dev/null +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_dead.0.session/cache/e8b77cbcc3a78b598f47a9de28727817.json @@ -0,0 +1 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "timeout", "time": 2. } diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_dead.1.session/cache/0eff509260291b913afca26f97217593.json b/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_dead.1.session/cache/0eff509260291b913afca26f97217593.json new file mode 100644 index 00000000000..e66c1e560c3 --- /dev/null +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_dead.1.session/cache/0eff509260291b913afca26f97217593.json @@ -0,0 +1 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "timeout", "time": 2. } diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_dead.1.session/cache/2c0433881c3e7c204fbd933fae94ed2a.json b/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_dead.1.session/cache/2c0433881c3e7c204fbd933fae94ed2a.json new file mode 100644 index 00000000000..e66c1e560c3 --- /dev/null +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_dead.1.session/cache/2c0433881c3e7c204fbd933fae94ed2a.json @@ -0,0 +1 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "timeout", "time": 2. } diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_dead.1.session/cache/2e52caad3f8b8552be7c703a245947cf.json b/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_dead.1.session/cache/2e52caad3f8b8552be7c703a245947cf.json new file mode 100644 index 00000000000..56c39550428 --- /dev/null +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_dead.1.session/cache/2e52caad3f8b8552be7c703a245947cf.json @@ -0,0 +1 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "unknown" } diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_dead.1.session/cache/434cbeb147419d3a67a7ba9f259979b4.json b/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_dead.1.session/cache/434cbeb147419d3a67a7ba9f259979b4.json new file mode 100644 index 00000000000..e66c1e560c3 --- /dev/null +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_dead.1.session/cache/434cbeb147419d3a67a7ba9f259979b4.json @@ -0,0 +1 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "timeout", "time": 2. } diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_dead.1.session/cache/6de0af457f7b1f3d82b27400e43a68aa.json b/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_dead.1.session/cache/6de0af457f7b1f3d82b27400e43a68aa.json new file mode 100644 index 00000000000..e66c1e560c3 --- /dev/null +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_dead.1.session/cache/6de0af457f7b1f3d82b27400e43a68aa.json @@ -0,0 +1 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "timeout", "time": 2. } diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_dead.1.session/cache/e8b77cbcc3a78b598f47a9de28727817.json b/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_dead.1.session/cache/e8b77cbcc3a78b598f47a9de28727817.json new file mode 100644 index 00000000000..e66c1e560c3 --- /dev/null +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_dead.1.session/cache/e8b77cbcc3a78b598f47a9de28727817.json @@ -0,0 +1 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "timeout", "time": 2. } diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_report_ko.0.session/cache/3c09d952f228b980bfc7351233bea851.json b/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_report_ko.0.session/cache/3c09d952f228b980bfc7351233bea851.json new file mode 100644 index 00000000000..9f3147e2a68 --- /dev/null +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_report_ko.0.session/cache/3c09d952f228b980bfc7351233bea851.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0109, + "steps": 15 } diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_report_ko.0.session/cache/82f897485c8c7f2dea5812a6e02dc9bc.json b/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_report_ko.0.session/cache/82f897485c8c7f2dea5812a6e02dc9bc.json new file mode 100644 index 00000000000..d4e438038a9 --- /dev/null +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_report_ko.0.session/cache/82f897485c8c7f2dea5812a6e02dc9bc.json @@ -0,0 +1,2 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "valid", "time": 0.0116, + "steps": 15 } diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_report_ok.0.session/cache/62a7cbaba5d3871e1ed28541c6fe7028.json b/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_report_ok.0.session/cache/62a7cbaba5d3871e1ed28541c6fe7028.json new file mode 100644 index 00000000000..e66c1e560c3 --- /dev/null +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_report_ok.0.session/cache/62a7cbaba5d3871e1ed28541c6fe7028.json @@ -0,0 +1 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "timeout", "time": 2. } diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_report_ok.0.session/cache/75e1dbec55b6df45c46dfa1e74531a0c.json b/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_report_ok.0.session/cache/75e1dbec55b6df45c46dfa1e74531a0c.json new file mode 100644 index 00000000000..e66c1e560c3 --- /dev/null +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_report_ok.0.session/cache/75e1dbec55b6df45c46dfa1e74531a0c.json @@ -0,0 +1 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "timeout", "time": 2. } diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_unroll.0.session/cache/2e52caad3f8b8552be7c703a245947cf.json b/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_unroll.0.session/cache/2e52caad3f8b8552be7c703a245947cf.json new file mode 100644 index 00000000000..56c39550428 --- /dev/null +++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/doomed_unroll.0.session/cache/2e52caad3f8b8552be7c703a245947cf.json @@ -0,0 +1 @@ +{ "prover": "Alt-Ergo:2.0.0", "verdict": "unknown" } -- GitLab From 1b8f0b87650d6ccfb750f75155d4ce779b1f9975 Mon Sep 17 00:00:00 2001 From: Michele Alberti <michele.alberti@cea.fr> Date: Fri, 10 Apr 2020 13:31:44 +0200 Subject: [PATCH 183/218] [Eva] Export Eval_terms functions needed by incoming changes in InOut. --- src/plugins/value/Eva.mli | 19 +++++++++++++++++++ src/plugins/value/legacy/eval_terms.ml | 14 +++++++------- src/plugins/value/legacy/eval_terms.mli | 2 +- 3 files changed, 27 insertions(+), 8 deletions(-) diff --git a/src/plugins/value/Eva.mli b/src/plugins/value/Eva.mli index 462e5bdab03..27f069ce7ee 100644 --- a/src/plugins/value/Eva.mli +++ b/src/plugins/value/Eva.mli @@ -36,3 +36,22 @@ module Value_parameters: sig (** Returns the list (name, descr) of currently enabled abstract domains. *) val enabled_domains: unit -> (string * string) list end + +module Eval_terms: sig + (** Evaluation environment, built by [env_annot]. *) + type eval_env + + (** Dependencies needed to evaluate a term or a predicate. *) + type logic_deps = Locations.Zone.t Cil_datatype.Logic_label.Map.t + + type labels_states = Db.Value.state Cil_datatype.Logic_label.Map.t + + val env_annot : + ?c_labels:labels_states -> pre:Db.Value.state -> here:Db.Value.state -> + unit -> eval_env + + (** [predicate_deps env p] computes the logic dependencies needed to evaluate + [p] in the given evaluation environment [env]. + @return None on either an evaluation error or on unsupported construct. *) + val predicate_deps: eval_env -> Cil_types.predicate -> logic_deps option +end diff --git a/src/plugins/value/legacy/eval_terms.ml b/src/plugins/value/legacy/eval_terms.ml index 0ae0bdbcced..088057d16ed 100644 --- a/src/plugins/value/legacy/eval_terms.ml +++ b/src/plugins/value/legacy/eval_terms.ml @@ -2587,8 +2587,6 @@ and eval_predicate env pred = (* --- Dependencies of predicates --- *) (* -------------------------------------------------------------------------- *) -(* Currently unused (and untested *) - let predicate_deps env pred = let alarm_mode = Ignore in let rec do_eval env p = @@ -2639,18 +2637,20 @@ let predicate_deps env pred = | Papp (li, _labels, _args) -> begin if is_known_predicate li.l_var_info then - assert false (* TODO! Must evaluate the arguments, plus the - dependencies of the predicate itself. *) + (* TODO! Must evaluate the arguments, plus the dependencies of the + predicate itself. *) + unsupported (Format.asprintf "%a" Cil_datatype.Predicate.pretty p) else match Inline.inline_predicate ~inline ~current:env.e_cur p with - | None -> assert false + | None -> unsupported (Format.asprintf "%a" Cil_datatype.Predicate.pretty p) | Some p' -> do_eval env p' end | Pfresh _ | Pallocable _ | Pfreeable _ - -> assert false + -> unsupported (Format.asprintf "%a" Cil_datatype.Predicate.pretty p) in - do_eval env pred + try Some (do_eval env pred) + with LogicEvalError _ -> None (* -------------------------------------------------------------------------- *) diff --git a/src/plugins/value/legacy/eval_terms.mli b/src/plugins/value/legacy/eval_terms.mli index 548bba93436..4e61b9d1ad3 100644 --- a/src/plugins/value/legacy/eval_terms.mli +++ b/src/plugins/value/legacy/eval_terms.mli @@ -110,7 +110,7 @@ val eval_tlval_as_zone : val eval_predicate : eval_env -> predicate -> predicate_status -val predicate_deps: eval_env -> predicate -> logic_deps +val predicate_deps: eval_env -> predicate -> logic_deps option val reduce_by_predicate : eval_env -> bool -> predicate -> eval_env -- GitLab From a6a9ae83704c1dd88d52ca2b474bdd4dd9f41c31 Mon Sep 17 00:00:00 2001 From: Michele Alberti <michele.alberti@cea.fr> Date: Fri, 10 Apr 2020 13:33:19 +0200 Subject: [PATCH 184/218] [InOut] Support logic inputs in assertions and normal loop-invariants. --- src/plugins/inout/operational_inputs.ml | 80 +++++++++++++++++++++---- src/plugins/value_types/inout_type.ml | 24 +++++++- src/plugins/value_types/inout_type.mli | 1 + 3 files changed, 92 insertions(+), 13 deletions(-) diff --git a/src/plugins/inout/operational_inputs.ml b/src/plugins/inout/operational_inputs.ml index a40b5c3b43d..777c7ce0892 100644 --- a/src/plugins/inout/operational_inputs.ml +++ b/src/plugins/inout/operational_inputs.ml @@ -31,6 +31,9 @@ open Locations type t = Inout_type.t = { over_inputs: Locations.Zone.t; over_inputs_if_termination: Locations.Zone.t; + over_logic_inputs: Locations.Zone.t; + (* [over_logic_inputs] is used internally by Eva to make memexec consider also + the logic inputs of the function. Computed in [transfer_annotations]. *) under_outputs_if_termination: Locations.Zone.t; over_outputs: Locations.Zone.t; over_outputs_if_termination: Locations.Zone.t; @@ -39,6 +42,7 @@ type t = Inout_type.t = { let top = { over_inputs = Zone.top; over_inputs_if_termination = Zone.top; + over_logic_inputs = Zone.top; under_outputs_if_termination = Zone.bottom; over_outputs = Zone.top; over_outputs_if_termination = Zone.top; @@ -79,9 +83,9 @@ let join c1 c2 = { } let is_included c1 c2 = - Zone.is_included c1.over_inputs_d c2.over_inputs_d && + Zone.is_included c1.over_inputs_d c2.over_inputs_d && Zone.is_included c2.under_outputs_d c1.under_outputs_d && - Zone.is_included c1.over_outputs_d c2.over_outputs_d + Zone.is_included c1.over_outputs_d c2.over_outputs_d let join_and_is_included smaller larger = let join = join smaller larger in @@ -178,6 +182,7 @@ let eval_assigns kf state assigns = let init = { bottom with under_outputs_d = Zone.bottom } in let r = List.fold_left treat_one_zone init l in { over_inputs = r.over_inputs_d; + over_logic_inputs = r.over_inputs_d; over_inputs_if_termination = r.over_inputs_d; under_outputs_if_termination = r.under_outputs_d; over_outputs = r.over_outputs_d; @@ -209,7 +214,7 @@ module Internals = module CallsiteHash = Value_types.Callsite.Hashtbl -(* Results of an an entire call, represented by a pair (stmt, kernel_function]). +(* Results of an an entire call, represented by a pair (stmt, kernel_function). This table is filled by the [-inout-callwise] option, or for functions for which only the specification is used. *) module CallwiseResults = @@ -226,6 +231,7 @@ module CallwiseResults = module Computer(Fenv:Dataflows.FUNCTION_ENV)(X:sig val _version: string (* Debug: Callwise or functionwise *) val _kf: kernel_function (* Debug: Function being analyzed *) + val kf_pre_state: Db.Value.state (* Memory pre-state of the function. *) val stmt_state: stmt -> Db.Value.state (* Memory state at the given stmt *) val at_call: stmt -> kernel_function -> Inout_type.t (* Results of the analysis for the given call. Must not contain locals or formals *) @@ -239,11 +245,16 @@ end) = struct all partial results. *) let non_terminating_inputs = ref Zone.bottom let non_terminating_outputs = ref Zone.bottom + let non_terminating_logic_inputs = ref Zone.bottom let store_non_terminating_inputs inputs = non_terminating_inputs := Zone.join !non_terminating_inputs inputs; ;; + let store_non_terminating_logic_inputs logic_inputs = + non_terminating_logic_inputs := + Zone.join !non_terminating_logic_inputs logic_inputs + let store_non_terminating_outputs outputs = non_terminating_outputs := Zone.join !non_terminating_outputs outputs; ;; @@ -355,6 +366,40 @@ end) = struct | Some lv -> add_out ~for_writing state lv Zone.bottom result) in result + (* Propagate all zones in predicates for the given statement, only in the case + of assertions and loop-invariants. For the time being, we do not treat + terminating and non-terminating points of the function differently. *) + let transfer_annotations stmt = + Annotations.iter_code_annot + (fun _ ca -> + match ca.annot_content with + | AAssert (_, _, p) + | AInvariant (_, true, p) -> + begin + let env = + Eva.Eval_terms.env_annot + ~pre:X.kf_pre_state + ~here:(X.stmt_state stmt) + () + in + match Eva.Eval_terms.predicate_deps env p with + | None -> + (* To be sound, we should perform a join with the top zone here. + We do nothing instead because the latter behavior would + directly disable memexec. *) + () + | Some logic_deps -> + let p_zone = + Cil_datatype.Logic_label.Map.fold + (fun _ -> Zone.join) + logic_deps + Zone.bottom + in + store_non_terminating_logic_inputs p_zone + end + | _ -> ()) + stmt + (* Transfer function on instructions. *) let transfer_instr stmt (i: instr) (data: t) = match i with @@ -436,12 +481,12 @@ end) = struct -> map_on_all_succs data ;; - (* Note: Not sure this adds anything to the precision (or - efficiency) once we have tested the guards. The difference does - not show up in the tests. *) let transfer_stmt s data = if Db.Value.is_reachable (X.stmt_state s) - then transfer_stmt s data + then begin + transfer_annotations s; + transfer_stmt s data + end else [] ;; @@ -454,6 +499,7 @@ end) = struct over_outputs_if_termination = res_if_termination.over_outputs_d; over_inputs = Zone.join !non_terminating_inputs res_if_termination.over_inputs_d; + over_logic_inputs = !non_terminating_logic_inputs; over_outputs = Zone.join !non_terminating_outputs res_if_termination.over_outputs_d; } @@ -572,6 +618,7 @@ module Callwise = struct let inout = { over_inputs_if_termination = in_; over_inputs = in_; + over_logic_inputs = Zone.bottom; over_outputs_if_termination = out_ ; over_outputs = out_; under_outputs_if_termination = sure_out; @@ -620,13 +667,25 @@ module Callwise = struct call_inout_stack := []; CallwiseResults.mark_as_computed () - let compute_call_from_value_states kf states = + let compute_call_from_value_states kf call_stack states = let module Fenv = (val Dataflows.function_env kf: Dataflows.FUNCTION_ENV) in let module Computer = Computer(Fenv)( struct let _version = "callwise" let _kf = kf + (* Returns the [kf] pre-state with respect to the single [call_stack]. *) + let kf_pre_state = + match Db.Value.get_initial_state_callstack kf with + | None -> + Cvalue.Model.bottom + | Some cs -> + begin + match Value_types.Callstack.Hashtbl.find_opt cs call_stack with + | None -> Cvalue.Model.bottom + | Some state -> state + end + let stmt_state stmt = try Cil_datatype.Stmt.Hashtbl.find states stmt with Not_found -> Cvalue.Model.bottom @@ -656,13 +715,13 @@ module Callwise = struct let inout = match value_res with | Value_types.Normal (states, _after_states) | Value_types.NormalStore ((states, _after_states), _) -> - let kf = fst (List.hd call_stack) in + let kf, _ = List.hd call_stack in let inout = try if !Db.Value.no_results (Kernel_function.get_definition kf) then top else - compute_call_from_value_states kf (Lazy.force states) + compute_call_from_value_states kf call_stack (Lazy.force states) with Kernel_function.No_Definition -> top in (match value_res with @@ -702,6 +761,7 @@ module FunctionWise = struct let module Computer = Computer(Fenv)(struct let _version = "functionwise" let _kf = kf + let kf_pre_state = Db.Value.get_initial_state kf let stmt_state s = Db.Value.get_stmt_state s let at_call stmt kf = get_external_aux ~stmt kf end) in diff --git a/src/plugins/value_types/inout_type.ml b/src/plugins/value_types/inout_type.ml index 164e6693fad..3d51f3fc5e6 100644 --- a/src/plugins/value_types/inout_type.ml +++ b/src/plugins/value_types/inout_type.ml @@ -23,6 +23,7 @@ type t = { over_inputs: Locations.Zone.t; over_inputs_if_termination: Locations.Zone.t; + over_logic_inputs: Locations.Zone.t; under_outputs_if_termination: Locations.Zone.t; over_outputs: Locations.Zone.t; over_outputs_if_termination: Locations.Zone.t; @@ -68,13 +69,14 @@ include let structural_descr = let z = Locations.Zone.packed_descr in - Structural_descr.t_record [| z; z; z; z; z |] + Structural_descr.t_record [| z; z; z; z; z; z |] let reprs = List.map (fun z -> { over_inputs_if_termination = z; under_outputs_if_termination = z; over_inputs = z; + over_logic_inputs = z; over_outputs = z; over_outputs_if_termination = z; }) Locations.Zone.reprs @@ -85,22 +87,35 @@ include over_inputs = c; over_outputs = d; over_outputs_if_termination = e; + over_logic_inputs = f; } = - Zone.hash a + 17 * Zone.hash b + 587 * Zone.hash c + 1077 * Zone.hash d + 13119 * Zone.hash e + Zone.hash a + + 17 * Zone.hash b + + 587 * Zone.hash c + + 1077 * Zone.hash d + + 13119 * Zone.hash e + + 15823 * Zone.hash f let equal { over_inputs_if_termination = a; under_outputs_if_termination = b; over_inputs = c; over_outputs = d; over_outputs_if_termination = e; + over_logic_inputs = f; } { over_inputs_if_termination = a'; under_outputs_if_termination = b'; over_inputs = c'; over_outputs = d'; over_outputs_if_termination = e'; + over_logic_inputs = f'; } = - Zone.equal a a' && Zone.equal b b' && Zone.equal c c' && Zone.equal d d' && Zone.equal e e' + Zone.equal a a' + && Zone.equal b b' + && Zone.equal c c' + && Zone.equal d d' + && Zone.equal e e' + && Zone.equal f f' let mem_project = Datatype.never_any_project end) : Datatype.S with type t := t) @@ -109,6 +124,7 @@ let map f v = { over_inputs_if_termination = f v.over_inputs_if_termination; under_outputs_if_termination = f v.under_outputs_if_termination; over_inputs = f v.over_inputs; + over_logic_inputs = f v.over_logic_inputs; over_outputs = f v.over_outputs; over_outputs_if_termination = f v.over_outputs_if_termination; } @@ -116,6 +132,7 @@ let map f v = { let bottom = { over_inputs = Zone.bottom; over_inputs_if_termination = Zone.bottom; + over_logic_inputs = Zone.bottom; under_outputs_if_termination = Zone.top; over_outputs = Zone.bottom; over_outputs_if_termination = Zone.bottom; @@ -125,6 +142,7 @@ let join c1 c2 = { over_inputs = Zone.join c1.over_inputs c2.over_inputs; over_inputs_if_termination = Zone.join c1.over_inputs_if_termination c2.over_inputs_if_termination; + over_logic_inputs = Zone.join c1.over_logic_inputs c2.over_logic_inputs; over_outputs = Zone.join c1.over_outputs c2.over_outputs; over_outputs_if_termination = Zone.join c1.over_outputs_if_termination c2.over_outputs_if_termination; diff --git a/src/plugins/value_types/inout_type.mli b/src/plugins/value_types/inout_type.mli index e9c828607a1..70cdd0134e6 100644 --- a/src/plugins/value_types/inout_type.mli +++ b/src/plugins/value_types/inout_type.mli @@ -23,6 +23,7 @@ type t = { over_inputs: Locations.Zone.t; over_inputs_if_termination: Locations.Zone.t; + over_logic_inputs: Locations.Zone.t; under_outputs_if_termination: Locations.Zone.t; over_outputs: Locations.Zone.t; over_outputs_if_termination: Locations.Zone.t; -- GitLab From 046f27f07bc99a6dc3541086a063eb1c2e60130b Mon Sep 17 00:00:00 2001 From: Michele Alberti <michele.alberti@cea.fr> Date: Fri, 10 Apr 2020 13:34:07 +0200 Subject: [PATCH 185/218] [Eva] Make memexec also consider logic inputs as input bases. --- src/plugins/value/engine/mem_exec.ml | 8 ++++++-- tests/value/oracle/memexec.res.oracle | 7 +++---- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/plugins/value/engine/mem_exec.ml b/src/plugins/value/engine/mem_exec.ml index b70a4bc3d01..423bf04634f 100644 --- a/src/plugins/value/engine/mem_exec.ml +++ b/src/plugins/value/engine/mem_exec.ml @@ -156,8 +156,12 @@ module Make | None -> () | Some inout -> try - let output_bases = bases inout.Inout_type.over_outputs_if_termination - and input_bases = bases inout.Inout_type.over_inputs in + let output_bases = bases inout.Inout_type.over_outputs_if_termination in + let input_bases = + let input_bases = bases inout.Inout_type.over_inputs in + let logic_input_bases = bases inout.Inout_type.over_logic_inputs in + Base.Hptset.union input_bases logic_input_bases + in (* There are two strategies to compute the 'inputs' for a memexec function: either we take all inputs_bases+outputs_bases (outputs_bases are important because of weak updates), or we diff --git a/tests/value/oracle/memexec.res.oracle b/tests/value/oracle/memexec.res.oracle index a27eebd316e..f24a2a45c79 100644 --- a/tests/value/oracle/memexec.res.oracle +++ b/tests/value/oracle/memexec.res.oracle @@ -103,8 +103,7 @@ Frama_C_show_each_f5: [9..2147483647], [-2147483648..6], [-2147483648..7] [eva] tests/value/memexec.c:113: Reusing old results for call to f5_aux [eva] tests/value/memexec.c:114: - Frama_C_show_each_f5: - [9..2147483647], [-2147483648..2147483647], [-2147483648..7] + Frama_C_show_each_f5: [9..2147483647], [-2147483648..6], [-2147483648..7] [eva] Recording results for f5 [eva] Done for function f5 [eva] computing for function f6 <- main. @@ -192,7 +191,7 @@ [eva:final-states] Values at end of function f5_aux: v ∈ [--..--] [eva:final-states] Values at end of function f5: - g_f5_1 ∈ [--..--] + g_f5_1 ∈ [-2147483648..6] g_f5_2 ∈ [-2147483648..7] arg ∈ [9..2147483647] [eva:final-states] Values at end of function f6_1: @@ -228,7 +227,7 @@ S[0..7] ∈ {0} [8].i ∈ {0; 6} [9] ∈ {0} - g_f5_1 ∈ [--..--] + g_f5_1 ∈ [-2147483648..6] g_f5_2 ∈ [-2147483648..7] two_fields.x ∈ {1} .y ∈ {3} -- GitLab From f587fe2b84d80d638b7bb3544e1b4f10d859e401 Mon Sep 17 00:00:00 2001 From: Michele Alberti <michele.alberti@cea.fr> Date: Thu, 9 Apr 2020 18:05:58 +0200 Subject: [PATCH 186/218] [Eva] Add test case on logic inputs for memexec. --- tests/value/memexec.c | 16 ++++++- tests/value/oracle/memexec.res.oracle | 63 ++++++++++++++++++++++----- 2 files changed, 65 insertions(+), 14 deletions(-) diff --git a/tests/value/memexec.c b/tests/value/memexec.c index 092a4180c8d..e68abd5fbbd 100644 --- a/tests/value/memexec.c +++ b/tests/value/memexec.c @@ -2,7 +2,7 @@ STDOPT: #" -no-eva -rte-select fbug -rte -then -eva" */ -int x1, y1, z1; volatile int c; +int x1, y1, z1, z2; volatile int c, nondet; void f11() { x1 = 1; @@ -111,7 +111,7 @@ void f5() { g_f5_2 = c; arg = c; f5_aux(arg); - Frama_C_show_each_f5(arg, g_f5_1, g_f5_2); // Cache, but reduce g_f5_* and arg after the call. Currently does not work for g_f5_1, because dependencies are not taken into account + Frama_C_show_each_f5(arg, g_f5_1, g_f5_2); // Cache, but reduce g_f5_* and arg after the call. } struct two_fields { int x; int y; } two_fields; @@ -150,6 +150,17 @@ void f8() { f8_1(&x); } +void f9_1() { + /*@ assert z2 == 0; */ +} + +void f9() { + z2 = 1; + if (nondet) f9_1(); + z2 = 0; + f9_1(); +} + void main () { f1 (); f2 (); @@ -160,4 +171,5 @@ void main () { f6(); f7(); f8(); + f9(); } diff --git a/tests/value/oracle/memexec.res.oracle b/tests/value/oracle/memexec.res.oracle index f24a2a45c79..8390c51eeb4 100644 --- a/tests/value/oracle/memexec.res.oracle +++ b/tests/value/oracle/memexec.res.oracle @@ -7,7 +7,9 @@ x1 ∈ {0} y1 ∈ {0} z1 ∈ {0} + z2 ∈ {0} c ∈ [--..--] + nondet ∈ [--..--] p ∈ {0} i ∈ {0} t[0..9] ∈ {0} @@ -17,7 +19,7 @@ g_f5_2 ∈ {0} two_fields ∈ {0} [eva] computing for function f1 <- main. - Called from tests/value/memexec.c:154. + Called from tests/value/memexec.c:165. [eva] computing for function f11 <- f1 <- main. Called from tests/value/memexec.c:12. [eva] Recording results for f11 @@ -31,15 +33,15 @@ [eva] Recording results for f1 [eva] Done for function f1 [eva] computing for function f2 <- main. - Called from tests/value/memexec.c:155. + Called from tests/value/memexec.c:166. [eva] Recording results for f2 [eva] Done for function f2 [eva] computing for function f3 <- main. - Called from tests/value/memexec.c:156. + Called from tests/value/memexec.c:167. [eva] Recording results for f3 [eva] Done for function f3 [eva] computing for function bug <- main. - Called from tests/value/memexec.c:157. + Called from tests/value/memexec.c:168. [eva] computing for function fbug <- bug <- main. Called from tests/value/memexec.c:40. [eva:alarm] tests/value/memexec.c:33: Warning: @@ -53,10 +55,10 @@ [eva] Done for function fbug [eva] Recording results for bug [eva] Done for function bug -[eva:locals-escaping] tests/value/memexec.c:157: Warning: +[eva:locals-escaping] tests/value/memexec.c:168: Warning: locals {x} escaping the scope of bug through p [eva] computing for function f4 <- main. - Called from tests/value/memexec.c:158. + Called from tests/value/memexec.c:169. [eva] computing for function f4_2 <- f4 <- main. Called from tests/value/memexec.c:84. [eva] computing for function f4_11 <- f4_2 <- f4 <- main. @@ -92,7 +94,7 @@ [eva] Recording results for f4 [eva] Done for function f4 [eva] computing for function f5 <- main. - Called from tests/value/memexec.c:159. + Called from tests/value/memexec.c:170. [eva] computing for function f5_aux <- f5 <- main. Called from tests/value/memexec.c:107. [eva:alarm] tests/value/memexec.c:94: Warning: assertion got status unknown. @@ -107,7 +109,7 @@ [eva] Recording results for f5 [eva] Done for function f5 [eva] computing for function f6 <- main. - Called from tests/value/memexec.c:160. + Called from tests/value/memexec.c:171. [eva] computing for function f6_1 <- f6 <- main. Called from tests/value/memexec.c:123. [eva] Recording results for f6_1 @@ -119,7 +121,7 @@ [eva] Recording results for f6 [eva] Done for function f6 [eva] computing for function f7 <- main. - Called from tests/value/memexec.c:161. + Called from tests/value/memexec.c:172. [eva] computing for function f7_1 <- f7 <- main. Called from tests/value/memexec.c:136. [eva] Recording results for f7_1 @@ -128,7 +130,7 @@ [eva] Recording results for f7 [eva] Done for function f7 [eva] computing for function f8 <- main. - Called from tests/value/memexec.c:162. + Called from tests/value/memexec.c:173. [eva] computing for function f8_1 <- f8 <- main. Called from tests/value/memexec.c:147. [eva:alarm] tests/value/memexec.c:141: Warning: @@ -142,6 +144,21 @@ [eva] tests/value/memexec.c:150: Reusing old results for call to f8_1 [eva] Recording results for f8 [eva] Done for function f8 +[eva] computing for function f9 <- main. + Called from tests/value/memexec.c:174. +[eva] computing for function f9_1 <- f9 <- main. + Called from tests/value/memexec.c:159. +[eva:alarm] tests/value/memexec.c:154: Warning: + assertion got status invalid (stopping propagation). +[eva] Recording results for f9_1 +[eva] Done for function f9_1 +[eva] computing for function f9_1 <- f9 <- main. + Called from tests/value/memexec.c:161. +[eva] tests/value/memexec.c:154: assertion got status valid. +[eva] Recording results for f9_1 +[eva] Done for function f9_1 +[eva] Recording results for f9 +[eva] Done for function f9 [eva] Recording results for main [eva] done for function main [eva] ====== VALUES COMPUTED ====== @@ -208,6 +225,10 @@ q ∈ {0} [eva:final-states] Values at end of function f8: x ∈ {1} +[eva:final-states] Values at end of function f9_1: + +[eva:final-states] Values at end of function f9: + z2 ∈ {0} [eva:final-states] Values at end of function fbug: __retres ∈ {1} [eva:final-states] Values at end of function bug: @@ -215,6 +236,7 @@ x ∈ {1} [eva:final-states] Values at end of function main: x1 ∈ {1} + z2 ∈ {0} p ∈ ESCAPINGADDR i ∈ {0; 5} t[0..1] ∈ {0} @@ -263,6 +285,10 @@ [from] Done for function f8_1 [from] Computing for function f8 [from] Done for function f8 +[from] Computing for function f9_1 +[from] Done for function f9_1 +[from] Computing for function f9 +[from] Done for function f9 [from] Computing for function fbug [from] Done for function fbug [from] Computing for function bug @@ -310,12 +336,17 @@ NO EFFECTS [from] Function f8: NO EFFECTS +[from] Function f9_1: + NO EFFECTS +[from] Function f9: + z2 FROM \nothing [from] Function fbug: \result FROM p; x [from] Function bug: p FROM \nothing [from] Function main: x1 FROM \nothing + z2 FROM \nothing p FROM \nothing i FROM c (and SELF) t{[2]; [5..6]} FROM c (and SELF) @@ -389,6 +420,14 @@ x [inout] Inputs for function f8: c +[inout] Out (internal) for function f9_1: + \nothing +[inout] Inputs for function f9_1: + \nothing +[inout] Out (internal) for function f9: + z2 +[inout] Inputs for function f9: + nondet [inout] Out (internal) for function fbug: __retres [inout] Inputs for function fbug: @@ -398,6 +437,6 @@ [inout] Inputs for function bug: c; p [inout] Out (internal) for function main: - x1; p; i; t{[2]; [5..6]}; ps; S[8]; g_f5_1; g_f5_2; two_fields + x1; z2; p; i; t{[2]; [5..6]}; ps; S[8]; g_f5_1; g_f5_2; two_fields [inout] Inputs for function main: - c; p; i; ps; S[8]; g_f5_1; g_f5_2 + c; nondet; p; i; ps; S[8]; g_f5_1; g_f5_2 -- GitLab From dd632da8ebf9dbcba3b07178e3fa8dcf3f691b69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20B=C3=BChler?= <david.buhler@cea.fr> Date: Thu, 9 Apr 2020 15:57:33 +0200 Subject: [PATCH 187/218] [Eva] Eval_terms: fixes [predicate_deps]. Used by the Inout plugin, and then indirectly by Memexec. --- src/plugins/value/legacy/eval_terms.ml | 45 +++++++++++++------------- 1 file changed, 22 insertions(+), 23 deletions(-) diff --git a/src/plugins/value/legacy/eval_terms.ml b/src/plugins/value/legacy/eval_terms.ml index 088057d16ed..0be07bebce0 100644 --- a/src/plugins/value/legacy/eval_terms.ml +++ b/src/plugins/value/legacy/eval_terms.ml @@ -1534,12 +1534,6 @@ let eval_tlval_as_location ~alarm_mode env t = let s = Eval_typ.sizeof_lval_typ r.etype in make_loc r.eover s -let eval_tlval_as_location_with_deps ~alarm_mode env t = - let r = eval_term_as_lval ~alarm_mode env t in - let s = Eval_typ.sizeof_lval_typ r.etype in - (make_loc r.eover s, r.ldeps) - - (* Return a pair of (under-approximating, over-approximating) zones. *) let eval_tlval_as_zone_under_over ~alarm_mode access env t = let r = eval_term_as_lval ~alarm_mode env t in @@ -2587,9 +2581,19 @@ and eval_predicate env pred = (* --- Dependencies of predicates --- *) (* -------------------------------------------------------------------------- *) +let eval_tsets_deps ~alarm_mode env lbl tsets = + let star_tsets = deref_tsets tsets in + let r = eval_tlval ~alarm_mode env star_tsets in + let size_bits = Eval_typ.sizeof_lval_typ r.etype in + let loc = make_loc r.eover size_bits in + let zone = enumerate_valid_bits Locations.Read loc in + Logic_label.Map.add lbl zone r.ldeps + let predicate_deps env pred = let alarm_mode = Ignore in let rec do_eval env p = + let term_deps term = (eval_term ~alarm_mode env term).ldeps in + let tsets_deps lbl tsets = eval_tsets_deps ~alarm_mode env lbl tsets in match p.pred_content with | Ptrue | Pfalse -> empty_logic_deps @@ -2598,11 +2602,10 @@ let predicate_deps env pred = join_logic_deps (do_eval env p1) (do_eval env p2) | Prel (_, t1, t2) -> - join_logic_deps (eval_term ~alarm_mode env t1).ldeps - (eval_term ~alarm_mode env t2).ldeps + join_logic_deps (term_deps t1) (term_deps t2) | Pif (c, p1, p2) -> - join_logic_deps (eval_term ~alarm_mode env c).ldeps + join_logic_deps (term_deps c) (join_logic_deps (do_eval env p1) (do_eval env p2)) | Pat (p, lbl) -> @@ -2610,21 +2613,17 @@ let predicate_deps env pred = | Pvalid (_, tsets) | Pvalid_read (_, tsets) | Pobject_pointer (_, tsets) | Pvalid_function tsets -> - (eval_term_as_lval ~alarm_mode env tsets).ldeps + term_deps tsets | Pinitialized (lbl, tsets) | Pdangling (lbl, tsets) -> - let loc, deploc = - eval_tlval_as_location_with_deps ~alarm_mode env tsets in - let zone = enumerate_valid_bits Locations.Read loc in - Logic_label.Map.add lbl zone deploc + tsets_deps lbl tsets | Pnot p -> do_eval env p | Pseparated ltsets -> - let evaled = List.map (eval_term_as_lval ~alarm_mode env) ltsets in List.fold_left - (fun acc e -> join_logic_deps acc e.ldeps) - empty_logic_deps evaled + (fun acc tsets -> join_logic_deps acc (tsets_deps lbl_here tsets)) + empty_logic_deps ltsets | Pexists (l, p) | Pforall (l, p) -> let env = bind_logic_vars env l in @@ -2635,19 +2634,19 @@ let predicate_deps env pred = | Plet (_v, p) -> do_eval env p (* will this work when when we need [_v] to evaluate [p] ?.. *) - | Papp (li, _labels, _args) -> begin + | Papp (li, _labels, args) -> begin if is_known_predicate li.l_var_info then - (* TODO! Must evaluate the arguments, plus the dependencies of the - predicate itself. *) - unsupported (Format.asprintf "%a" Cil_datatype.Predicate.pretty p) + List.fold_left + (fun acc arg -> join_logic_deps acc (term_deps arg)) + empty_logic_deps args else match Inline.inline_predicate ~inline ~current:env.e_cur p with - | None -> unsupported (Format.asprintf "%a" Cil_datatype.Predicate.pretty p) + | None -> unsupported (Format.asprintf "%a" Predicate.pretty p) | Some p' -> do_eval env p' end | Pfresh _ | Pallocable _ | Pfreeable _ - -> unsupported (Format.asprintf "%a" Cil_datatype.Predicate.pretty p) + -> unsupported (Format.asprintf "%a" Predicate.pretty p) in try Some (do_eval env pred) with LogicEvalError _ -> None -- GitLab From 106f202a0fc36a95724acafc91cf7669db262f04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20B=C3=BChler?= <david.buhler@cea.fr> Date: Fri, 10 Apr 2020 11:22:13 +0200 Subject: [PATCH 188/218] [Eva] Adds more test cases of memexec with logical dependencies. --- tests/value/memexec.c | 28 +++++++- tests/value/oracle/memexec.res.oracle | 100 +++++++++++++++++++++----- 2 files changed, 110 insertions(+), 18 deletions(-) diff --git a/tests/value/memexec.c b/tests/value/memexec.c index e68abd5fbbd..36b1a450f3b 100644 --- a/tests/value/memexec.c +++ b/tests/value/memexec.c @@ -154,11 +154,35 @@ void f9_1() { /*@ assert z2 == 0; */ } +void f9_2() { + /*@ assert \valid(p); */ +} + +void f9_3() { + /*@ assert \initialized(p); */ +} + +void f9_4() { + /*@ assert \at(z2, Pre) > 0; */ +} + void f9() { z2 = 1; - if (nondet) f9_1(); + if (nondet) f9_1(); // Non terminating. z2 = 0; - f9_1(); + f9_1(); // This call must be terminating. + int x; + p = 0; + if (nondet) f9_2(); // Non terminating. + p = &x; + f9_2(); // This call must be terminating. + if (nondet) f9_3(); // Non terminating. + x = 1; + f9_3(); // This call must be terminating. + z2 = 0; + if (nondet) f9_4(); // Non terminating. + z2 = 1; + f9_4(); // This call must be terminating. } void main () { diff --git a/tests/value/oracle/memexec.res.oracle b/tests/value/oracle/memexec.res.oracle index 8390c51eeb4..0369d95d24a 100644 --- a/tests/value/oracle/memexec.res.oracle +++ b/tests/value/oracle/memexec.res.oracle @@ -19,7 +19,7 @@ g_f5_2 ∈ {0} two_fields ∈ {0} [eva] computing for function f1 <- main. - Called from tests/value/memexec.c:165. + Called from tests/value/memexec.c:189. [eva] computing for function f11 <- f1 <- main. Called from tests/value/memexec.c:12. [eva] Recording results for f11 @@ -33,15 +33,15 @@ [eva] Recording results for f1 [eva] Done for function f1 [eva] computing for function f2 <- main. - Called from tests/value/memexec.c:166. + Called from tests/value/memexec.c:190. [eva] Recording results for f2 [eva] Done for function f2 [eva] computing for function f3 <- main. - Called from tests/value/memexec.c:167. + Called from tests/value/memexec.c:191. [eva] Recording results for f3 [eva] Done for function f3 [eva] computing for function bug <- main. - Called from tests/value/memexec.c:168. + Called from tests/value/memexec.c:192. [eva] computing for function fbug <- bug <- main. Called from tests/value/memexec.c:40. [eva:alarm] tests/value/memexec.c:33: Warning: @@ -55,10 +55,10 @@ [eva] Done for function fbug [eva] Recording results for bug [eva] Done for function bug -[eva:locals-escaping] tests/value/memexec.c:168: Warning: +[eva:locals-escaping] tests/value/memexec.c:192: Warning: locals {x} escaping the scope of bug through p [eva] computing for function f4 <- main. - Called from tests/value/memexec.c:169. + Called from tests/value/memexec.c:193. [eva] computing for function f4_2 <- f4 <- main. Called from tests/value/memexec.c:84. [eva] computing for function f4_11 <- f4_2 <- f4 <- main. @@ -94,7 +94,7 @@ [eva] Recording results for f4 [eva] Done for function f4 [eva] computing for function f5 <- main. - Called from tests/value/memexec.c:170. + Called from tests/value/memexec.c:194. [eva] computing for function f5_aux <- f5 <- main. Called from tests/value/memexec.c:107. [eva:alarm] tests/value/memexec.c:94: Warning: assertion got status unknown. @@ -109,7 +109,7 @@ [eva] Recording results for f5 [eva] Done for function f5 [eva] computing for function f6 <- main. - Called from tests/value/memexec.c:171. + Called from tests/value/memexec.c:195. [eva] computing for function f6_1 <- f6 <- main. Called from tests/value/memexec.c:123. [eva] Recording results for f6_1 @@ -121,7 +121,7 @@ [eva] Recording results for f6 [eva] Done for function f6 [eva] computing for function f7 <- main. - Called from tests/value/memexec.c:172. + Called from tests/value/memexec.c:196. [eva] computing for function f7_1 <- f7 <- main. Called from tests/value/memexec.c:136. [eva] Recording results for f7_1 @@ -130,7 +130,7 @@ [eva] Recording results for f7 [eva] Done for function f7 [eva] computing for function f8 <- main. - Called from tests/value/memexec.c:173. + Called from tests/value/memexec.c:197. [eva] computing for function f8_1 <- f8 <- main. Called from tests/value/memexec.c:147. [eva:alarm] tests/value/memexec.c:141: Warning: @@ -145,20 +145,55 @@ [eva] Recording results for f8 [eva] Done for function f8 [eva] computing for function f9 <- main. - Called from tests/value/memexec.c:174. + Called from tests/value/memexec.c:198. [eva] computing for function f9_1 <- f9 <- main. - Called from tests/value/memexec.c:159. + Called from tests/value/memexec.c:171. [eva:alarm] tests/value/memexec.c:154: Warning: assertion got status invalid (stopping propagation). [eva] Recording results for f9_1 [eva] Done for function f9_1 [eva] computing for function f9_1 <- f9 <- main. - Called from tests/value/memexec.c:161. + Called from tests/value/memexec.c:173. [eva] tests/value/memexec.c:154: assertion got status valid. [eva] Recording results for f9_1 [eva] Done for function f9_1 +[eva] computing for function f9_2 <- f9 <- main. + Called from tests/value/memexec.c:176. +[eva:alarm] tests/value/memexec.c:158: Warning: + assertion got status invalid (stopping propagation). +[eva] Recording results for f9_2 +[eva] Done for function f9_2 +[eva] computing for function f9_2 <- f9 <- main. + Called from tests/value/memexec.c:178. +[eva] tests/value/memexec.c:158: assertion got status valid. +[eva] Recording results for f9_2 +[eva] Done for function f9_2 +[eva] computing for function f9_3 <- f9 <- main. + Called from tests/value/memexec.c:179. +[eva:alarm] tests/value/memexec.c:162: Warning: + assertion got status invalid (stopping propagation). +[eva] Recording results for f9_3 +[eva] Done for function f9_3 +[eva] computing for function f9_3 <- f9 <- main. + Called from tests/value/memexec.c:181. +[eva] tests/value/memexec.c:162: assertion got status valid. +[eva] Recording results for f9_3 +[eva] Done for function f9_3 +[eva] computing for function f9_4 <- f9 <- main. + Called from tests/value/memexec.c:183. +[eva:alarm] tests/value/memexec.c:166: Warning: + assertion got status invalid (stopping propagation). +[eva] Recording results for f9_4 +[eva] Done for function f9_4 +[eva] computing for function f9_4 <- f9 <- main. + Called from tests/value/memexec.c:185. +[eva] tests/value/memexec.c:166: assertion got status valid. +[eva] Recording results for f9_4 +[eva] Done for function f9_4 [eva] Recording results for f9 [eva] Done for function f9 +[eva:locals-escaping] tests/value/memexec.c:198: Warning: + locals {x} escaping the scope of f9 through p [eva] Recording results for main [eva] done for function main [eva] ====== VALUES COMPUTED ====== @@ -227,8 +262,16 @@ x ∈ {1} [eva:final-states] Values at end of function f9_1: +[eva:final-states] Values at end of function f9_2: + +[eva:final-states] Values at end of function f9_3: + +[eva:final-states] Values at end of function f9_4: + [eva:final-states] Values at end of function f9: - z2 ∈ {0} + z2 ∈ {1} + p ∈ {{ &x }} + x ∈ {1} [eva:final-states] Values at end of function fbug: __retres ∈ {1} [eva:final-states] Values at end of function bug: @@ -236,7 +279,7 @@ x ∈ {1} [eva:final-states] Values at end of function main: x1 ∈ {1} - z2 ∈ {0} + z2 ∈ {1} p ∈ ESCAPINGADDR i ∈ {0; 5} t[0..1] ∈ {0} @@ -287,6 +330,12 @@ [from] Done for function f8 [from] Computing for function f9_1 [from] Done for function f9_1 +[from] Computing for function f9_2 +[from] Done for function f9_2 +[from] Computing for function f9_3 +[from] Done for function f9_3 +[from] Computing for function f9_4 +[from] Done for function f9_4 [from] Computing for function f9 [from] Done for function f9 [from] Computing for function fbug @@ -338,8 +387,15 @@ NO EFFECTS [from] Function f9_1: NO EFFECTS +[from] Function f9_2: + NO EFFECTS +[from] Function f9_3: + NO EFFECTS +[from] Function f9_4: + NO EFFECTS [from] Function f9: z2 FROM \nothing + p FROM \nothing [from] Function fbug: \result FROM p; x [from] Function bug: @@ -424,8 +480,20 @@ \nothing [inout] Inputs for function f9_1: \nothing +[inout] Out (internal) for function f9_2: + \nothing +[inout] Inputs for function f9_2: + \nothing +[inout] Out (internal) for function f9_3: + \nothing +[inout] Inputs for function f9_3: + \nothing +[inout] Out (internal) for function f9_4: + \nothing +[inout] Inputs for function f9_4: + \nothing [inout] Out (internal) for function f9: - z2 + z2; p; x [inout] Inputs for function f9: nondet [inout] Out (internal) for function fbug: -- GitLab From 3d0cb0ad8ff75ffa6c774125de2dd1fc8083022b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20B=C3=BChler?= <david.buhler@cea.fr> Date: Fri, 10 Apr 2020 15:35:04 +0200 Subject: [PATCH 189/218] Updates the Changelog for MR !2599. --- Changelog | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Changelog b/Changelog index 5f91ac2bd11..1a24b1ee345 100644 --- a/Changelog +++ b/Changelog @@ -17,6 +17,8 @@ Open Source Release <next-release> ################################## +- Eva [2020/04/10] Fixes the Memexec cache on functions with logical + annotations about variables unused in the C body of the function. - Eva [2020/04/06] New option -eva-domains-function to enable domains only on given functions. Argument <d:f> enables the domain [d] on function [f], while <d:f+> also enables it on all functions -- GitLab From 21d1d6c295e14e4e80554f09b8b1d0d6e94066f3 Mon Sep 17 00:00:00 2001 From: Andre Maroneze <andre.oliveiramaroneze@cea.fr> Date: Fri, 10 Apr 2020 20:57:51 +0200 Subject: [PATCH 190/218] [analysis-scripts] remove deprecated .loop-related rules --- share/analysis-scripts/frama-c.mk | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/share/analysis-scripts/frama-c.mk b/share/analysis-scripts/frama-c.mk index bdd84071a7d..db18e0999fe 100644 --- a/share/analysis-scripts/frama-c.mk +++ b/share/analysis-scripts/frama-c.mk @@ -124,7 +124,7 @@ export LIBOVERLAY_SCROLLBAR=0 .PHONY: clean clean:: - $(RM) -r *.parse *.eva *.loop + $(RM) -r *.parse *.eva clean-backups: find . -regextype posix-extended \ @@ -219,14 +219,6 @@ SHELL := /bin/bash %.gui: % $(FRAMAC_GUI) $(FCGUIFLAGS) -load $^/framac.sav & -# Run loop bound analysis plug-in and store result in *.loop -%.loop: % - @ - { - $(FRAMAC) $(FCFLAGS) -load $^/framac.sav -loop -loop-no-branches | - sed -e '1,/Add this to your command line:/d' - } > $@ - # Produce and open an SVG + HTML from raw flamegraph data produced by Eva %/flamegraph: %/flamegraph.html @ -- GitLab From 9cfa34290505971547d6a87bb5c9cc57910a8c44 Mon Sep 17 00:00:00 2001 From: Michele Alberti <michele.alberti@cea.fr> Date: Tue, 21 Apr 2020 22:14:48 +0200 Subject: [PATCH 191/218] [kernel] Rework Specific_dir API. --- .../cmdline_parameters/parameter_sig.mli | 36 ++--- .../plugin_entry_points/kernel.ml | 4 +- .../plugin_entry_points/plugin.ml | 137 +++++++++++------- src/plugins/e-acsl/src/libraries/misc.ml | 2 +- src/plugins/e-acsl/src/main.ml | 2 +- src/plugins/gui/gtk_helper.ml | 3 +- src/plugins/wp/ProverErgo.ml | 2 +- src/plugins/wp/ProverWhy3.ml | 4 +- src/plugins/wp/driver.mll | 8 +- src/plugins/wp/register.ml | 2 +- src/plugins/wp/wp_parameters.ml | 12 +- 11 files changed, 111 insertions(+), 101 deletions(-) diff --git a/src/kernel_services/cmdline_parameters/parameter_sig.mli b/src/kernel_services/cmdline_parameters/parameter_sig.mli index 060ea584248..4906addb827 100644 --- a/src/kernel_services/cmdline_parameters/parameter_sig.mli +++ b/src/kernel_services/cmdline_parameters/parameter_sig.mli @@ -295,33 +295,19 @@ module type Filepath = S with type t = Filepath.Normalized.t (** signature for searching files in a specific directory. *) module type Specific_dir = sig - exception No_dir - - val force_dir: bool - (** For functions below: if [force_dir] is true: if [error] is [false], then - creates the directory if it does not exist (or raises No_dir if the - directory cannot be created). Otherwise ([force_dir = - false]), raise No_dir if [error] is [false]. - @since Neon-20140301 *) - - val dir: ?error:bool -> unit -> Filepath.Normalized.t - (** [dir ~error ()] returns the specific directory name, if - any. Otherwise, Frama-C halts on an user error if [error] or if the - behavior depends on [force_dir]. Default of [error] is [true]. - @raise No_dir if there is no share directory for this plug-in and [not - error] and [not force_dir]. *) - - val file: ?error:bool -> string -> Filepath.Normalized.t - (** [file basename] returns the complete filename of a file stored in [dir - ()]. If there is no such directory, Frama-C halts on an user error if - [error] or if the behavior depends on [force_dir]. Default of [error] is - [true]. - @raise No_dir if there is no share directory for this plug-in and [not - error] and [not force_dir]. *) + val set: Filepath.Normalized.t -> unit + val get: unit -> Filepath.Normalized.t + val is_set: unit -> bool - module Dir_name: Filepath - (** Option [-<short-name>-<specific-dir>]. *) + val get_dir: + ?mode:[`Create_path | `Normalize_only | `Must_exist ] -> + string -> + Filepath.Normalized.t + val get_file: + ?mode:[`Create_path | `Normalize_only | `Must_exist ] -> + string -> + Filepath.Normalized.t end (* ************************************************************************** *) diff --git a/src/kernel_services/plugin_entry_points/kernel.ml b/src/kernel_services/plugin_entry_points/kernel.ml index d437277a6da..41bde48cfc5 100644 --- a/src/kernel_services/plugin_entry_points/kernel.ml +++ b/src/kernel_services/plugin_entry_points/kernel.ml @@ -837,9 +837,9 @@ module Journal = struct let default = let dir = (* duplicate code from Plugin.Session *) - if Session.Dir_name.is_set () + if Session.is_set () then - (Session.Dir_name.get () :> string) + (Session.get () :> string) else try Sys.getenv "FRAMAC_SESSION" with Not_found -> "./.frama-c" diff --git a/src/kernel_services/plugin_entry_points/plugin.ml b/src/kernel_services/plugin_entry_points/plugin.ml index 4b7b4a2de3b..ecc78065fc3 100644 --- a/src/kernel_services/plugin_entry_points/plugin.ml +++ b/src/kernel_services/plugin_entry_points/plugin.ml @@ -299,13 +299,11 @@ struct (D: sig val dirs: unit -> string list val visible_ref: bool - val force_dir: bool end) = struct let is_visible = D.visible_ref - let force_dir = D.force_dir let is_kernel = is_kernel () (* the side effect must be applied right now *) let () = @@ -323,65 +321,95 @@ struct let file_kind = "" end) - exception No_dir - let mk_dir d = try Extlib.mkdir ~parents:true d 0o755; L.warning "creating %s directory `%s'" O.option_name d; d with Unix.Unix_error _ -> - L.warning "cannot create %s directory `%s'" O.option_name d; - raise No_dir - - let rec get_and_check_dirs error = function - | [] -> - raise No_dir - | d::l -> - if (try Sys.is_directory d with Sys_error _ -> false) then d - else - get_and_check_dirs error l - - let get_and_check_dirs ?(error=true) = function - | [] -> - if error then - L.abort "no %s directories to look into" O.option_name - else - raise No_dir - | (first::_) as l -> - try - get_and_check_dirs error l - with - | No_dir when error -> - L.abort "no %s directory for plug-in `%s' among %a" - O.option_name - P.name - Pretty_utils.(pp_list ~sep:",@ " Format.pp_print_string) l - | No_dir when force_dir -> - (* create the parent, if it does not exist *) - let p = Filename.dirname first in - if not (try Sys.is_directory p with Sys_error _ -> false) then - ignore (mk_dir p); - mk_dir first - - let dir ?error () = - (* get the specified dir if any *) - let d = if is_visible then (Dir_name.get () :> string) else empty_string in - let dirs = - if d = empty_string + L.abort "cannot create %s directory `%s'" O.option_name d + + let set filepath = Dir_name.set filepath + let get () = Dir_name.get () + let is_set () = Dir_name.is_set () + + let base_dirs () = + (* Get the specified dir if any. *) + let plugin_base_dir = + if is_visible + then Dir_name.get () + else Datatype.Filepath.dummy + in + if not (plugin_base_dir = Datatype.Filepath.dummy) + then [plugin_base_dir] + else begin + (* No specified dir: look for the default one. *) + let dirs = D.dirs () in + assert (dirs <> []); + if is_kernel then - (* no specified dir: look for the default one. *) - if is_kernel - then D.dirs () - else List.map (fun x -> x ^ "/" ^ plugin_subpath) (D.dirs ()) + List.map Datatype.Filepath.of_string dirs else - [d] - in - Datatype.Filepath.of_string (get_and_check_dirs ?error dirs) + List.map + (fun x -> Datatype.Filepath.of_string (x ^ "/" ^ plugin_subpath)) + dirs + end - let file ?error f = - let dir = dir ?error () in - Datatype.Filepath.concat dir ("/" ^ f) + let get_dir ?(mode=`Normalize_only) s = + match mode with + | `Must_exist -> + begin + let dir = + let exception Found of Datatype.Filepath.t in + try + List.fold_left + (fun dummy d -> + let name = Datatype.Filepath.concat d ("/" ^ s) in + if Sys.file_exists (name :> string) + then raise (Found name) + else dummy) + None + (base_dirs ()) + with Found d -> + Some d + in + match dir with + | None -> + L.abort "no directory %s exist in %s directories" s O.option_name + | Some d -> d + end + | _ -> + begin + let filepath = + match base_dirs () with + | [] -> assert false + | d :: _ -> Datatype.Filepath.concat d ("/" ^ s) + in + match mode with + | `Must_exist -> + (* Already taken care of. *) + assert false + | `Normalize_only -> + filepath + | `Create_path -> + ignore (mk_dir (filepath :> string)); + filepath + end + + let get_file ?(mode=`Normalize_only) s = + let s_dirname = Filename.dirname s in + let base_dir = get_dir ~mode s_dirname in + let s_basename = Filename.basename s in + let filepath = Datatype.Filepath.concat base_dir ("/" ^ s_basename) in + match mode with + | `Must_exist -> + if Sys.file_exists (filepath :> string) + then filepath + else L.abort "no file %s exist in %s directories" s O.option_name + | `Normalize_only -> + filepath + | `Create_path -> + filepath end @@ -396,7 +424,6 @@ struct (struct let dirs () = Fc_config.datadirs let visible_ref = !share_visible_ref - let force_dir = false end) module Session = @@ -413,11 +440,10 @@ struct try Sys.getenv "FRAMAC_SESSION" with Not_found -> "./.frama-c"] let visible_ref = !session_visible_ref - let force_dir = true end) let () = if is_kernel () - then Journal.get_session_file := (fun s -> Session.file ~error:false s) + then Journal.get_session_file := (fun s -> Session.get_file s) module Config = Make_specific_dir @@ -445,7 +471,6 @@ struct d ^ if vis then "/frama-c" else "/.frama-c" ] let visible_ref = !config_visible_ref - let force_dir = true end) let help = add_group "Getting Information" diff --git a/src/plugins/e-acsl/src/libraries/misc.ml b/src/plugins/e-acsl/src/libraries/misc.ml index 285438e7d87..0f4d38ef3fb 100644 --- a/src/plugins/e-acsl/src/libraries/misc.ml +++ b/src/plugins/e-acsl/src/libraries/misc.ml @@ -30,7 +30,7 @@ open Cil_datatype let library_files () = List.map - (fun d -> Options.Share.file ~error:true d) + (fun d -> Options.Share.get_file ~mode:`Must_exist d) [ "e_acsl_gmp_api.h"; "e_acsl.h" ] diff --git a/src/plugins/e-acsl/src/main.ml b/src/plugins/e-acsl/src/main.ml index c8027aa8d6f..a7f26523d4c 100644 --- a/src/plugins/e-acsl/src/main.ml +++ b/src/plugins/e-acsl/src/main.ml @@ -38,7 +38,7 @@ let extended_ast_project: extended_project ref = ref To_be_extended let unmemoized_extend_ast () = let extend () = - let share = Options.Share.dir ~error:true () in + let share = Options.Share.get_dir ~mode:`Must_exist "." in Options.feedback ~level:3 "setting kernel options for E-ACSL."; Kernel.CppExtraArgs.add (Format.asprintf " -DE_ACSL_MACHDEP=%s -I%a/memory_model" diff --git a/src/plugins/gui/gtk_helper.ml b/src/plugins/gui/gtk_helper.ml index 298d75d184f..9253046cb29 100644 --- a/src/plugins/gui/gtk_helper.ml +++ b/src/plugins/gui/gtk_helper.ml @@ -47,8 +47,7 @@ let framac_logo, framac_icon = module Configuration = struct include Cilconfig let configuration_file () = - try (Gui_parameters.Config.file ~error:false "frama-c-gui.config") - with Gui_parameters.Config.No_dir -> Datatype.Filepath.dummy + Gui_parameters.Config.get_file "frama-c-gui.config" let load () = loadConfiguration (configuration_file ()) let save () = saveConfiguration (configuration_file ()) let reset () = Extlib.safe_remove (configuration_file () :> string); diff --git a/src/plugins/wp/ProverErgo.ml b/src/plugins/wp/ProverErgo.ml index 9ad747a9afb..a1f4594ddba 100644 --- a/src/plugins/wp/ProverErgo.ml +++ b/src/plugins/wp/ProverErgo.ml @@ -165,7 +165,7 @@ class visitor fmt c = let df = D_file f in if not (List.mem df deps) then deps <- df :: deps - method add_shared f = self#add_dfile ((Wp_parameters.Share.file ~error:true f) :> string) + method add_shared f = self#add_dfile ((Wp_parameters.Share.get_file ~mode:`Must_exist f) :> string) method add_library f = self#add_dfile f method on_cluster c = deps <- (D_cluster c) :: deps diff --git a/src/plugins/wp/ProverWhy3.ml b/src/plugins/wp/ProverWhy3.ml index b4074ed1bb1..2b31bf272f2 100644 --- a/src/plugins/wp/ProverWhy3.ml +++ b/src/plugins/wp/ProverWhy3.ml @@ -51,7 +51,7 @@ let get_why3_env = Env.memoize let main = Why3.Whyconf.get_main config in let ld = (WpContext.directory ()):: - ((Wp_parameters.Share.file "why3") :> string):: + ((Wp_parameters.Share.get_file "why3") :> string):: (Why3.Whyconf.loadpath main) in Why3.Env.create_env ld end @@ -786,7 +786,7 @@ class visitor (ctx:context) c = let copy_file source = if not (Datatype.Filepath.equal (Datatype.Filepath.of_string (Filename.dirname source)) - (Wp_parameters.Share.dir ())) + (Wp_parameters.Share.get_dir ".")) then let tgtdir = WpContext.directory () in let why3src = Filename.basename source in diff --git a/src/plugins/wp/driver.mll b/src/plugins/wp/driver.mll index d541988a966..1a13f28d9e6 100644 --- a/src/plugins/wp/driver.mll +++ b/src/plugins/wp/driver.mll @@ -501,8 +501,8 @@ and bal = parse let descr = String.concat "," drvs in let includes = let directories = - try [(Wp_parameters.Share.dir ~error:false () :> string)] - with Wp_parameters.Share.No_dir -> [] in + [(Wp_parameters.Share.get_dir "." :> string)] + in if Wp_parameters.has_dkey dkey then Wp_parameters.debug ~dkey "Included directories:%t" (fun fmt -> @@ -519,8 +519,8 @@ and bal = parse then Filepath.normalize file else LogicBuiltins.find_lib file) drivers in - let default = Wp_parameters.Share.file ~error:true "wp.driver" in - let feedback = Wp_parameters.Share.Dir_name.is_set () in + let default = Wp_parameters.Share.get_file ~mode:`Must_exist "wp.driver" in + let feedback = Wp_parameters.Share.is_set () in let ontty = if feedback then `Message else `Transient in load_file ~ontty (default :> string); List.iter load_file drivers diff --git a/src/plugins/wp/register.ml b/src/plugins/wp/register.ml index bc0cf0c9d05..b6c45ae76c0 100644 --- a/src/plugins/wp/register.ml +++ b/src/plugins/wp/register.ml @@ -557,7 +557,7 @@ let spawn_wp_proofs_iter ~mode iter_on_goals = if mode.tactical || mode.provers<>[] then begin let server = ProverTask.server () in - ignore (Wp_parameters.Share.dir ()); (* To prevent further errors *) + ignore (Wp_parameters.Share.get_dir "."); (* To prevent further errors *) iter_on_goals (fun goal -> if mode.tactical diff --git a/src/plugins/wp/wp_parameters.ml b/src/plugins/wp/wp_parameters.ml index c1d7d6ad719..7d8a2e381c2 100644 --- a/src/plugins/wp/wp_parameters.ml +++ b/src/plugins/wp/wp_parameters.ml @@ -1118,21 +1118,21 @@ let get_output_dir d = let default = Sys.getcwd () ^ "/.frama-c" let has_session () = - Session.Dir_name.is_set () || + Session.is_set () || ( Sys.file_exists default && Sys.is_directory default ) let get_session ~force () = if force then - Session.dir ~error:false () + Session.get_dir "." else - if Session.Dir_name.is_set () then - Session.Dir_name.get () + if Session.is_set () then + Session.get () else - Session.dir ~error:false () + Session.get_dir "." let get_session_dir ~force d = let base = get_session ~force () in - let path = Format.asprintf "%a/%s" Datatype.Filepath.pp_abs base d in + let path = Format.asprintf "%s/%s" (base :> string) d in if force then make_output_dir path ; path (* -------------------------------------------------------------------------- *) -- GitLab From 0ecf30a0d38306f6b259bdb85b9713ae25101d26 Mon Sep 17 00:00:00 2001 From: Michele Alberti <michele.alberti@cea.fr> Date: Wed, 22 Apr 2020 15:07:41 +0200 Subject: [PATCH 192/218] [kernel] Some comments. --- .../cmdline_parameters/parameter_sig.mli | 21 +++++++++++++++++++ .../plugin_entry_points/plugin.ml | 7 ++++++- 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/src/kernel_services/cmdline_parameters/parameter_sig.mli b/src/kernel_services/cmdline_parameters/parameter_sig.mli index 4906addb827..2dd81a0d804 100644 --- a/src/kernel_services/cmdline_parameters/parameter_sig.mli +++ b/src/kernel_services/cmdline_parameters/parameter_sig.mli @@ -296,18 +296,39 @@ module type Filepath = S with type t = Filepath.Normalized.t module type Specific_dir = sig val set: Filepath.Normalized.t -> unit + (** Sets the plugin <specific-dir> directory (without creating it). *) + val get: unit -> Filepath.Normalized.t + (** @return the plugin <specific-dir> directory (without creating it). *) + val is_set: unit -> bool + (** @return whether the plugin <specific-dir> has been set. *) val get_dir: ?mode:[`Create_path | `Normalize_only | `Must_exist ] -> string -> Filepath.Normalized.t + (**[get_dir ?mode p] returns a local-path [p], relative to the plugin + <specific-dir> directory, to a sub-directory of the plugin <specific-dir> + directory. + @param mode determines how to handle the resulting path: + + [Create_path] creates the resulting path, if does not exist. + + [Normalize_only] just normalizes the resulting path. + + [Must_exist] aborts if the resulting path does not exist. + *) val get_file: ?mode:[`Create_path | `Normalize_only | `Must_exist ] -> string -> Filepath.Normalized.t + (**[get_file ?mode p] returns a local-path [p], relative to the plugin + <specific-dir> directory, to a file in the plugin <specific-dir> + directory. + @param mode determines how to handle the resulting path: + + [Create_path] creates the dirname of resulting path, if does not exist. + + [Normalize_only] just normalizes the resulting path. + + [Must_exist] aborts if the resulting path does not exist. + *) end (* ************************************************************************** *) diff --git a/src/kernel_services/plugin_entry_points/plugin.ml b/src/kernel_services/plugin_entry_points/plugin.ml index ecc78065fc3..3e4c529f2b6 100644 --- a/src/kernel_services/plugin_entry_points/plugin.ml +++ b/src/kernel_services/plugin_entry_points/plugin.ml @@ -343,7 +343,8 @@ struct if not (plugin_base_dir = Datatype.Filepath.dummy) then [plugin_base_dir] else begin - (* No specified dir: look for the default one. *) + (* No specified dir: look for the default ones. + At least one default value must be in place. *) let dirs = D.dirs () in assert (dirs <> []); if is_kernel @@ -380,6 +381,8 @@ struct end | _ -> begin + (* In presence of more than one base directory, consider the first to + form the resulting [filepath]. *) let filepath = match base_dirs () with | [] -> assert false @@ -409,6 +412,8 @@ struct | `Normalize_only -> filepath | `Create_path -> + (* No need to create anything here, as the path of sub-directories has + been already created by [get_dir] for computing [base_dir]. *) filepath end -- GitLab From 2f10c9d25fc4ca48edce8248a799d1e6164e8a69 Mon Sep 17 00:00:00 2001 From: Michele Alberti <michele.alberti@cea.fr> Date: Wed, 22 Apr 2020 15:17:28 +0200 Subject: [PATCH 193/218] [kernel] Fix indentation. --- .../cmdline_parameters/parameter_sig.mli | 30 +++++++++---------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/src/kernel_services/cmdline_parameters/parameter_sig.mli b/src/kernel_services/cmdline_parameters/parameter_sig.mli index 2dd81a0d804..9df2908bf46 100644 --- a/src/kernel_services/cmdline_parameters/parameter_sig.mli +++ b/src/kernel_services/cmdline_parameters/parameter_sig.mli @@ -308,27 +308,25 @@ module type Specific_dir = sig ?mode:[`Create_path | `Normalize_only | `Must_exist ] -> string -> Filepath.Normalized.t - (**[get_dir ?mode p] returns a local-path [p], relative to the plugin - <specific-dir> directory, to a sub-directory of the plugin <specific-dir> - directory. - @param mode determines how to handle the resulting path: - + [Create_path] creates the resulting path, if does not exist. - + [Normalize_only] just normalizes the resulting path. - + [Must_exist] aborts if the resulting path does not exist. - *) + (** [get_dir ?mode p] returns a local-path [p], relative to the plugin + <specific-dir> directory, to a sub-directory of the plugin <specific-dir> + directory. + @param mode determines how to handle the resulting path: + + [Create_path] creates the resulting path, if does not exist. + + [Normalize_only] just normalizes the resulting path. + + [Must_exist] aborts if the resulting path does not exist. *) val get_file: ?mode:[`Create_path | `Normalize_only | `Must_exist ] -> string -> Filepath.Normalized.t - (**[get_file ?mode p] returns a local-path [p], relative to the plugin - <specific-dir> directory, to a file in the plugin <specific-dir> - directory. - @param mode determines how to handle the resulting path: - + [Create_path] creates the dirname of resulting path, if does not exist. - + [Normalize_only] just normalizes the resulting path. - + [Must_exist] aborts if the resulting path does not exist. - *) + (** [get_file ?mode p] returns a local-path [p], relative to the plugin + <specific-dir> directory, to a file in the plugin <specific-dir> + directory. + @param mode determines how to handle the resulting path: + + [Create_path] creates the dirname of resulting path, if does not exist. + + [Normalize_only] just normalizes the resulting path. + + [Must_exist] aborts if the resulting path does not exist. *) end (* ************************************************************************** *) -- GitLab From b186aab0e83719df1359fc36bfeea0ee96678a9a Mon Sep 17 00:00:00 2001 From: Lionel Blatter <Lionel.BLATTER@cea.fr> Date: Thu, 23 Apr 2020 13:53:33 +0200 Subject: [PATCH 194/218] Add full completion for "-wp-prover" Fix typos --- share/autocomplete_frama-c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/share/autocomplete_frama-c b/share/autocomplete_frama-c index 86fbd0ab6c1..e067d035e17 100644 --- a/share/autocomplete_frama-c +++ b/share/autocomplete_frama-c @@ -31,7 +31,7 @@ # If you want to enable Frama-C completion only for your account, append # this file to ~/.bash_completion. # -# For a less verbose completition for options with comma-separated values, +# For a less verbose completion for options with comma-separated values, # put "set show-all-if-ambiguous on" in your "~/.inputrc". # # Assuming frama-c is in your PATH, @@ -93,14 +93,13 @@ _frama-c () elif [[ "${COMP_WORDS[COMP_CWORD -1]}" == "-wp-prover" ]] then local prefix=; [[ $cur == *,* ]] && prefix="${cur%,*}," - # The current output of -wp-detect is not suitable for an easy grep using regular expressions, - # so the possible completions are not added to $COMPREPLY. - advance_options="none scritp tip alt-ergo altgr-ergo coq native:alt-ergo native:coq native:coqide" + advance_options="$(frama-c -wp-detect | grep -E -o " \[.*" | grep -E -o "[^\[-\|]*")" local ambigous="$(bind -v | grep show-all-if-ambiguous)" ambigous="${ambigous##* }" if [[ "$ambigous" == "on" ]] then COMPREPLY=( $( compgen -W "${advance_options}" -- "${cur##*,}" ) ) + COMPREPLY+=( $( compgen -W "none script tip native:alt-ergo native:coq native:coqide" -- "${cur##*,}" ) ) [[ ${#COMPREPLY[@]} -eq 1 ]] && COMPREPLY=( ${COMPREPLY/#/$prefix} ) else COMPREPLY=( $( compgen -P "$prefix" -W "${advance_options}" -- "${cur##*,}" ) ) -- GitLab From abea8d06adc8f07aa5d8510c041211b7f4d97c15 Mon Sep 17 00:00:00 2001 From: Virgile Prevosto <virgile.prevosto@m4x.org> Date: Thu, 23 Apr 2020 14:45:06 +0200 Subject: [PATCH 195/218] [autocomplete] don't mess with COMPREPLY variable... --- share/autocomplete_frama-c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/share/autocomplete_frama-c b/share/autocomplete_frama-c index e067d035e17..db940aff16c 100644 --- a/share/autocomplete_frama-c +++ b/share/autocomplete_frama-c @@ -94,12 +94,12 @@ _frama-c () then local prefix=; [[ $cur == *,* ]] && prefix="${cur%,*}," advance_options="$(frama-c -wp-detect | grep -E -o " \[.*" | grep -E -o "[^\[-\|]*")" + advance_options+="none script tip native:alt-ergo native:coq native:coqide" local ambigous="$(bind -v | grep show-all-if-ambiguous)" ambigous="${ambigous##* }" if [[ "$ambigous" == "on" ]] then COMPREPLY=( $( compgen -W "${advance_options}" -- "${cur##*,}" ) ) - COMPREPLY+=( $( compgen -W "none script tip native:alt-ergo native:coq native:coqide" -- "${cur##*,}" ) ) [[ ${#COMPREPLY[@]} -eq 1 ]] && COMPREPLY=( ${COMPREPLY/#/$prefix} ) else COMPREPLY=( $( compgen -P "$prefix" -W "${advance_options}" -- "${cur##*,}" ) ) -- GitLab From 77cec487254c3756b87e8fa0e8d4e3189fd71c40 Mon Sep 17 00:00:00 2001 From: Virgile Prevosto <virgile.prevosto@m4x.org> Date: Thu, 23 Apr 2020 14:51:42 +0200 Subject: [PATCH 196/218] [autocomplete] better regexp for identifying provers --- share/autocomplete_frama-c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/share/autocomplete_frama-c b/share/autocomplete_frama-c index db940aff16c..02b607be099 100644 --- a/share/autocomplete_frama-c +++ b/share/autocomplete_frama-c @@ -93,8 +93,8 @@ _frama-c () elif [[ "${COMP_WORDS[COMP_CWORD -1]}" == "-wp-prover" ]] then local prefix=; [[ $cur == *,* ]] && prefix="${cur%,*}," - advance_options="$(frama-c -wp-detect | grep -E -o " \[.*" | grep -E -o "[^\[-\|]*")" - advance_options+="none script tip native:alt-ergo native:coq native:coqide" + advance_options="$(frama-c -wp-detect | grep -E -o " \[.*" | grep -E -o "[^]\[-\|]*")" + advance_options+=" none script tip native:alt-ergo native:coq native:coqide" local ambigous="$(bind -v | grep show-all-if-ambiguous)" ambigous="${ambigous##* }" if [[ "$ambigous" == "on" ]] -- GitLab From 1c354577ff239a7a4ba2547da13f819f44461b3d Mon Sep 17 00:00:00 2001 From: Michele Alberti <michele.alberti@cea.fr> Date: Thu, 23 Apr 2020 17:08:50 +0200 Subject: [PATCH 197/218] [kernel] Make explicit that Normalize_only is the default mode. --- src/kernel_services/cmdline_parameters/parameter_sig.mli | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/kernel_services/cmdline_parameters/parameter_sig.mli b/src/kernel_services/cmdline_parameters/parameter_sig.mli index 9df2908bf46..15e512e3278 100644 --- a/src/kernel_services/cmdline_parameters/parameter_sig.mli +++ b/src/kernel_services/cmdline_parameters/parameter_sig.mli @@ -305,27 +305,27 @@ module type Specific_dir = sig (** @return whether the plugin <specific-dir> has been set. *) val get_dir: - ?mode:[`Create_path | `Normalize_only | `Must_exist ] -> + ?mode:[`Normalize_only | `Create_path | `Must_exist ] -> string -> Filepath.Normalized.t (** [get_dir ?mode p] returns a local-path [p], relative to the plugin <specific-dir> directory, to a sub-directory of the plugin <specific-dir> directory. @param mode determines how to handle the resulting path: + + [Normalize_only] just normalizes the resulting path (default). + [Create_path] creates the resulting path, if does not exist. - + [Normalize_only] just normalizes the resulting path. + [Must_exist] aborts if the resulting path does not exist. *) val get_file: - ?mode:[`Create_path | `Normalize_only | `Must_exist ] -> + ?mode:[`Normalize_only | `Create_path | `Must_exist ] -> string -> Filepath.Normalized.t (** [get_file ?mode p] returns a local-path [p], relative to the plugin <specific-dir> directory, to a file in the plugin <specific-dir> directory. @param mode determines how to handle the resulting path: + + [Normalize_only] just normalizes the resulting path (default). + [Create_path] creates the dirname of resulting path, if does not exist. - + [Normalize_only] just normalizes the resulting path. + [Must_exist] aborts if the resulting path does not exist. *) end -- GitLab From 0499144ddd71427fe48d873d41e6362ab0744197 Mon Sep 17 00:00:00 2001 From: Michele Alberti <michele.alberti@cea.fr> Date: Thu, 23 Apr 2020 17:11:18 +0200 Subject: [PATCH 198/218] [kernel] Some rephrasing in Specific_dir doc. --- src/kernel_services/cmdline_parameters/parameter_sig.mli | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/kernel_services/cmdline_parameters/parameter_sig.mli b/src/kernel_services/cmdline_parameters/parameter_sig.mli index 15e512e3278..9ab4f1cca7e 100644 --- a/src/kernel_services/cmdline_parameters/parameter_sig.mli +++ b/src/kernel_services/cmdline_parameters/parameter_sig.mli @@ -308,8 +308,8 @@ module type Specific_dir = sig ?mode:[`Normalize_only | `Create_path | `Must_exist ] -> string -> Filepath.Normalized.t - (** [get_dir ?mode p] returns a local-path [p], relative to the plugin - <specific-dir> directory, to a sub-directory of the plugin <specific-dir> + (** [get_dir ?mode p] returns a (local) path [p], i.e. relative to the plugin + <specific-dir> directory, of a sub-directory of the plugin <specific-dir> directory. @param mode determines how to handle the resulting path: + [Normalize_only] just normalizes the resulting path (default). @@ -320,8 +320,8 @@ module type Specific_dir = sig ?mode:[`Normalize_only | `Create_path | `Must_exist ] -> string -> Filepath.Normalized.t - (** [get_file ?mode p] returns a local-path [p], relative to the plugin - <specific-dir> directory, to a file in the plugin <specific-dir> + (** [get_file ?mode p] returns a (local) path [p], i.e. relative to the + plugin <specific-dir> directory, of a file in the plugin <specific-dir> directory. @param mode determines how to handle the resulting path: + [Normalize_only] just normalizes the resulting path (default). -- GitLab From b4d9934ff971f11dd140edac31d21a18b368eab4 Mon Sep 17 00:00:00 2001 From: Lionel Blatter <Lionel.BLATTER@cea.fr> Date: Thu, 23 Apr 2020 17:41:05 +0200 Subject: [PATCH 199/218] [autocomplete] Simplified regular expression and remove space --- share/autocomplete_frama-c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/share/autocomplete_frama-c b/share/autocomplete_frama-c index 02b607be099..1b4610d4d33 100644 --- a/share/autocomplete_frama-c +++ b/share/autocomplete_frama-c @@ -93,8 +93,8 @@ _frama-c () elif [[ "${COMP_WORDS[COMP_CWORD -1]}" == "-wp-prover" ]] then local prefix=; [[ $cur == *,* ]] && prefix="${cur%,*}," - advance_options="$(frama-c -wp-detect | grep -E -o " \[.*" | grep -E -o "[^]\[-\|]*")" - advance_options+=" none script tip native:alt-ergo native:coq native:coqide" + advance_options="$(frama-c -wp-detect | grep -E -o " \[.*" | grep -E -o "[^][|]*")" + advance_options+="none script tip native:alt-ergo native:coq native:coqide" local ambigous="$(bind -v | grep show-all-if-ambiguous)" ambigous="${ambigous##* }" if [[ "$ambigous" == "on" ]] -- GitLab From 3ea180f0b3272bbbc4b1feced021627b7ed9c52b Mon Sep 17 00:00:00 2001 From: Lionel Blatter <Lionel.BLATTER@cea.fr> Date: Fri, 24 Apr 2020 14:00:56 +0200 Subject: [PATCH 200/218] [autocomplete] Adding a space to separate options --- share/autocomplete_frama-c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/share/autocomplete_frama-c b/share/autocomplete_frama-c index 1b4610d4d33..423c17506bf 100644 --- a/share/autocomplete_frama-c +++ b/share/autocomplete_frama-c @@ -94,7 +94,7 @@ _frama-c () then local prefix=; [[ $cur == *,* ]] && prefix="${cur%,*}," advance_options="$(frama-c -wp-detect | grep -E -o " \[.*" | grep -E -o "[^][|]*")" - advance_options+="none script tip native:alt-ergo native:coq native:coqide" + advance_options+=" none script tip native:alt-ergo native:coq native:coqide" local ambigous="$(bind -v | grep show-all-if-ambiguous)" ambigous="${ambigous##* }" if [[ "$ambigous" == "on" ]] -- GitLab From e74ac27bf36cea743be6026011691b06a2c21f80 Mon Sep 17 00:00:00 2001 From: Michele Alberti <michele.alberti@cea.fr> Date: Thu, 23 Apr 2020 17:19:49 +0200 Subject: [PATCH 201/218] Review the usage of mode. --- src/plugins/gui/gtk_helper.ml | 2 +- src/plugins/wp/ProverWhy3.ml | 2 +- src/plugins/wp/driver.mll | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/plugins/gui/gtk_helper.ml b/src/plugins/gui/gtk_helper.ml index 9253046cb29..a3b75c3b142 100644 --- a/src/plugins/gui/gtk_helper.ml +++ b/src/plugins/gui/gtk_helper.ml @@ -47,7 +47,7 @@ let framac_logo, framac_icon = module Configuration = struct include Cilconfig let configuration_file () = - Gui_parameters.Config.get_file "frama-c-gui.config" + Gui_parameters.Config.get_file ~mode:`Create_path "frama-c-gui.config" let load () = loadConfiguration (configuration_file ()) let save () = saveConfiguration (configuration_file ()) let reset () = Extlib.safe_remove (configuration_file () :> string); diff --git a/src/plugins/wp/ProverWhy3.ml b/src/plugins/wp/ProverWhy3.ml index 2b31bf272f2..299e199eefd 100644 --- a/src/plugins/wp/ProverWhy3.ml +++ b/src/plugins/wp/ProverWhy3.ml @@ -51,7 +51,7 @@ let get_why3_env = Env.memoize let main = Why3.Whyconf.get_main config in let ld = (WpContext.directory ()):: - ((Wp_parameters.Share.get_file "why3") :> string):: + ((Wp_parameters.Share.get_dir ~mode:`Must_exist "why3") :> string):: (Why3.Whyconf.loadpath main) in Why3.Env.create_env ld end diff --git a/src/plugins/wp/driver.mll b/src/plugins/wp/driver.mll index 1a13f28d9e6..06fc29c30ff 100644 --- a/src/plugins/wp/driver.mll +++ b/src/plugins/wp/driver.mll @@ -501,7 +501,7 @@ and bal = parse let descr = String.concat "," drvs in let includes = let directories = - [(Wp_parameters.Share.get_dir "." :> string)] + [(Wp_parameters.Share.get_dir ~mode:`Must_exist "." :> string)] in if Wp_parameters.has_dkey dkey then Wp_parameters.debug ~dkey "Included directories:%t" -- GitLab From 226a7c21173a8e93edaf509513834231c1847464 Mon Sep 17 00:00:00 2001 From: Michele Alberti <michele.alberti@cea.fr> Date: Thu, 23 Apr 2020 18:23:14 +0200 Subject: [PATCH 202/218] [kernel] Avoid to create an already existing directory. Abort if a file with same path already exists. --- .../plugin_entry_points/plugin.ml | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/src/kernel_services/plugin_entry_points/plugin.ml b/src/kernel_services/plugin_entry_points/plugin.ml index 3e4c529f2b6..40e1c3b1699 100644 --- a/src/kernel_services/plugin_entry_points/plugin.ml +++ b/src/kernel_services/plugin_entry_points/plugin.ml @@ -395,8 +395,19 @@ struct | `Normalize_only -> filepath | `Create_path -> - ignore (mk_dir (filepath :> string)); - filepath + begin + (try + if not (Sys.is_directory (filepath :> string)) + then + (* [filepath] already exists, and it is a file. *) + L.abort + "cannot create directory as file %a already exists" + Datatype.Filepath.pretty filepath + with Sys_error _ -> + (* [filepath] does not exist: create the directory path. *) + ignore (mk_dir (filepath :> string))); + filepath + end end let get_file ?(mode=`Normalize_only) s = @@ -448,7 +459,9 @@ struct end) let () = if is_kernel () - then Journal.get_session_file := (fun s -> Session.get_file s) + then + Journal.get_session_file := + (fun s -> Session.get_file ~mode:`Create_path s) module Config = Make_specific_dir -- GitLab From f6675139f3de234a5de97d707419a803b4ad2a76 Mon Sep 17 00:00:00 2001 From: Michele Alberti <michele.alberti@cea.fr> Date: Mon, 27 Apr 2020 19:19:32 +0200 Subject: [PATCH 203/218] [wp] Use Filepath instead of mere strings. --- src/plugins/wp/ProofSession.ml | 3 ++- src/plugins/wp/ProverCoq.ml | 10 +++++----- src/plugins/wp/ProverErgo.ml | 2 +- src/plugins/wp/ProverWhy3.ml | 10 ++++++---- src/plugins/wp/RegionDump.ml | 4 +++- src/plugins/wp/RegionDump.mli | 2 +- src/plugins/wp/cfgDump.ml | 2 +- src/plugins/wp/wpContext.mli | 3 ++- src/plugins/wp/wpReached.ml | 2 +- src/plugins/wp/wpReached.mli | 2 +- src/plugins/wp/wp_parameters.ml | 16 ++++++++-------- src/plugins/wp/wp_parameters.mli | 6 +++--- src/plugins/wp/wpo.ml | 6 +++--- 13 files changed, 37 insertions(+), 31 deletions(-) diff --git a/src/plugins/wp/ProofSession.ml b/src/plugins/wp/ProofSession.ml index 9545120970c..05e69ee8fa4 100644 --- a/src/plugins/wp/ProofSession.ml +++ b/src/plugins/wp/ProofSession.ml @@ -29,7 +29,8 @@ type script = let files : (string,script) Hashtbl.t = Hashtbl.create 32 -let jsonfile = Printf.sprintf "%s/%s.json" +let jsonfile (dir:Datatype.Filepath.t) = + Format.sprintf "%s/%s.json" (dir :> string) let filename ~force wpo = let dscript = Wp_parameters.get_session_dir ~force "script" in diff --git a/src/plugins/wp/ProverCoq.ml b/src/plugins/wp/ProverCoq.ml index 446fceadc1b..4e864a4579f 100644 --- a/src/plugins/wp/ProverCoq.ml +++ b/src/plugins/wp/ProverCoq.ml @@ -34,7 +34,7 @@ let dkey = Wp_parameters.register_category "prover" let cluster_file c = let dir = WpContext.directory () in let base = cluster_id c in - Printf.sprintf "%s/%s.v" dir base + Printf.sprintf "%s/%s.v" (dir :> string) base (* -------------------------------------------------------------------------- *) (* --- External Coq Libraries --- *) @@ -314,8 +314,8 @@ and assemble_coqlib coqcc c = begin let tgtdir = Wp_parameters.get_output_dir "coqwp" in let source = Printf.sprintf "%s/%s" c.c_source c.c_file in - let target = Printf.sprintf "%s/%s" tgtdir c.c_file in - let dir = Printf.sprintf "%s/%s" tgtdir c.c_path in + let target = Printf.sprintf "%s/%s" (tgtdir :> string) c.c_file in + let dir = Printf.sprintf "%s/%s" (tgtdir :> string) c.c_path in if need_recompile ~source ~target then begin Wp_parameters.make_output_dir dir ; @@ -333,7 +333,7 @@ let assemble_goal ~pid axioms prop = let title = Pretty_utils.to_string WpPropId.pretty pid in let model = WpContext.directory () in let id = WpPropId.get_propid pid in - let file = Printf.sprintf "%s/%s.coq" model id in + let file = Printf.sprintf "%s/%s.coq" (model :> string) id in let goal = cluster ~id ~title () in let deps = Command.print_file file begin fun fmt -> @@ -359,7 +359,7 @@ let assemble_goal ~pid axioms prop = end in let coqcc = { marked = Marked.empty ; includes = [] ; sources = [] } in List.iter (assemble coqcc) deps ; - let includes = (model , "") :: List.rev coqcc.includes in + let includes = ((model :> string) , "") :: List.rev coqcc.includes in let sources = List.rev coqcc.sources in includes , sources , file diff --git a/src/plugins/wp/ProverErgo.ml b/src/plugins/wp/ProverErgo.ml index a1f4594ddba..e18c2ffc06e 100644 --- a/src/plugins/wp/ProverErgo.ml +++ b/src/plugins/wp/ProverErgo.ml @@ -72,7 +72,7 @@ let rec locate_error files file line = let cluster_file c = let dir = WpContext.directory () in let base = cluster_id c in - Printf.sprintf "%s/%s.ergo" dir base + Format.sprintf "%s/%s.ergo" (dir :> string) base (* -------------------------------------------------------------------------- *) (* --- Exporting Formulae to Alt-Ergo --- *) diff --git a/src/plugins/wp/ProverWhy3.ml b/src/plugins/wp/ProverWhy3.ml index 299e199eefd..b92024e34de 100644 --- a/src/plugins/wp/ProverWhy3.ml +++ b/src/plugins/wp/ProverWhy3.ml @@ -50,7 +50,7 @@ let get_why3_env = Env.memoize let config = Why3Provers.config () in let main = Why3.Whyconf.get_main config in let ld = - (WpContext.directory ()):: + (WpContext.directory () :> string):: ((Wp_parameters.Share.get_dir ~mode:`Must_exist "why3") :> string):: (Why3.Whyconf.loadpath main) in Why3.Env.create_env ld @@ -790,7 +790,7 @@ class visitor (ctx:context) c = then let tgtdir = WpContext.directory () in let why3src = Filename.basename source in - let target = Printf.sprintf "%s/%s" tgtdir why3src in + let target = Printf.sprintf "%s/%s" (tgtdir :> string) why3src in Command.copy source target in let iter_file opt = @@ -1238,6 +1238,7 @@ let mark_cache ~mode hash = let cleanup_cache ~mode = if mode = Cleanup && (!hits > 0 || !miss > 0) then let dir = Wp_parameters.get_session_dir ~force:false "cache" in + let dir = (dir :> string) in try if Sys.file_exists dir && Sys.is_directory dir then Array.iter @@ -1361,6 +1362,7 @@ let get_cache_result ~mode hash = | NoCache | Rebuild -> VCS.no_result | Update | Cleanup | Replay | Offline -> let dir = Wp_parameters.get_session_dir ~force:false "cache" in + let dir = (dir :> string) in if not (Sys.file_exists dir && Sys.is_directory dir) then VCS.no_result else @@ -1382,11 +1384,11 @@ let set_cache_result ~mode hash prover result = | Rebuild | Update | Cleanup -> let dir = Wp_parameters.get_session_dir ~force:true "cache" in let hash = Lazy.force hash in - let file = Printf.sprintf "%s/%s.json" dir hash in + let file = Format.sprintf "%s/%s.json" (dir :> string) hash in try mark_cache ~mode hash ; ProofScript.json_of_result (VCS.Why3 prover) result - |> Json.save_file file + |> Json.save_file (file :> string) with err -> Wp_parameters.warning ~current:false ~once:true "can not update cache (%s)" (Printexc.to_string err) diff --git a/src/plugins/wp/RegionDump.ml b/src/plugins/wp/RegionDump.ml index a52e783d163..0a476427ebd 100644 --- a/src/plugins/wp/RegionDump.ml +++ b/src/plugins/wp/RegionDump.ml @@ -283,7 +283,9 @@ let dump ~dir kf map = if Wp.has_dkey dot_key || Wp.has_dkey pdf_key then begin let name = Kf.get_name kf in - let file = Printf.sprintf "%s/%s.dot" dir name in + let file = + Format.asprintf "%a/%s.dot" Datatype.Filepath.pretty dir name + in let dot = Dotgraph.open_dot ~attr:[`LR] ~name ~file () in dotgraph dot map ; Dotgraph.close dot ; diff --git a/src/plugins/wp/RegionDump.mli b/src/plugins/wp/RegionDump.mli index fc77043cb8d..d332b9cb40c 100644 --- a/src/plugins/wp/RegionDump.mli +++ b/src/plugins/wp/RegionDump.mli @@ -23,4 +23,4 @@ (* Dump region graphs to dir according to -wp options. By default, does nothing. *) -val dump : dir:string -> Kernel_function.t -> Region.map -> unit +val dump : dir:Datatype.Filepath.t -> Kernel_function.t -> Region.map -> unit diff --git a/src/plugins/wp/cfgDump.ml b/src/plugins/wp/cfgDump.ml index b09e210f1b6..90c0924ba5d 100644 --- a/src/plugins/wp/cfgDump.ml +++ b/src/plugins/wp/cfgDump.ml @@ -40,7 +40,7 @@ struct | None -> Kernel_function.get_name kf | Some bname -> Kernel_function.get_name kf ^ "_" ^ bname in - let file = Filename.concat (Wp_parameters.get_output ()) name in + let file = Filename.concat (Wp_parameters.get_output () :> string) name in Wp_parameters.feedback "CFG %a -> %s@." Kernel_function.pretty kf name ; let fout = open_out (file ^ ".dot") in fc := Some (fout,file) ; diff --git a/src/plugins/wp/wpContext.mli b/src/plugins/wp/wpContext.mli index 356eeaf759c..7693815595f 100644 --- a/src/plugins/wp/wpContext.mli +++ b/src/plugins/wp/wpContext.mli @@ -84,7 +84,8 @@ val get_model : unit -> model val get_scope : unit -> scope val get_context : unit -> context -val directory : unit -> string (** Current model in ["-wp-out"] directory *) +val directory : unit -> Datatype.Filepath.t +(** Current model in ["-wp-out"] directory *) module type Entries = sig diff --git a/src/plugins/wp/wpReached.ml b/src/plugins/wp/wpReached.ml index 0c970996f35..98acfad8ecb 100644 --- a/src/plugins/wp/wpReached.ml +++ b/src/plugins/wp/wpReached.ml @@ -224,7 +224,7 @@ module N = Dotgraph.Node(Nmap) let dump ~dir kf reached = let name = Kernel_function.get_name kf in - let file = Printf.sprintf "%s/%s.dot" dir name in + let file = Format.asprintf "%a/%s.dot" Datatype.Filepath.pretty dir name in let dot = G.open_dot ~file ~name () in N.define dot (fun a na -> diff --git a/src/plugins/wp/wpReached.mli b/src/plugins/wp/wpReached.mli index 3de8854af06..2f7bc0283bc 100644 --- a/src/plugins/wp/wpReached.mli +++ b/src/plugins/wp/wpReached.mli @@ -47,6 +47,6 @@ val smoking : reached -> Cil_types.stmt -> bool This is restricted to assignments, returns and calls not dominated another smoking statement. *) -val dump : dir:string -> Kernel_function.t -> reached -> unit +val dump : dir:Datatype.Filepath.t -> Kernel_function.t -> reached -> unit (* -------------------------------------------------------------------------- *) diff --git a/src/plugins/wp/wp_parameters.ml b/src/plugins/wp/wp_parameters.ml index 7d8a2e381c2..8755b87107f 100644 --- a/src/plugins/wp/wp_parameters.ml +++ b/src/plugins/wp/wp_parameters.ml @@ -1094,8 +1094,8 @@ let base_output () = make_output_dir dir ; dir in base_output := Some output; Fc_Filepath.add_symbolic_dir "WPOUT" output ; - output - | Some output -> output + Datatype.Filepath.of_string output + | Some output -> Datatype.Filepath.of_string output let get_output () = let base = base_output () in @@ -1103,13 +1103,13 @@ let get_output () = let name = Project.get_unique_name project in if name = "default" then base else - let dir = base ^ "/" ^ name in - make_output_dir dir ; dir + let dir = Datatype.Filepath.concat base ("/" ^ name) in + make_output_dir (dir :> string) ; dir let get_output_dir d = let base = get_output () in - let path = Printf.sprintf "%s/%s" base d in - make_output_dir path ; path + let path = Datatype.Filepath.concat base ("/" ^ d) in + make_output_dir (path :> string) ; path (* -------------------------------------------------------------------------- *) (* --- Session dir --- *) @@ -1132,8 +1132,8 @@ let get_session ~force () = let get_session_dir ~force d = let base = get_session ~force () in - let path = Format.asprintf "%s/%s" (base :> string) d in - if force then make_output_dir path ; path + let path = Datatype.Filepath.concat base ("/" ^ d) in + if force then make_output_dir (path :> string) ; path (* -------------------------------------------------------------------------- *) (* --- Print Generated --- *) diff --git a/src/plugins/wp/wp_parameters.mli b/src/plugins/wp/wp_parameters.mli index 3103707f185..fd0df0a2628 100644 --- a/src/plugins/wp/wp_parameters.mli +++ b/src/plugins/wp/wp_parameters.mli @@ -156,9 +156,9 @@ module SmokeDeadcall: Parameter_sig.Bool val has_out : unit -> bool val has_session : unit -> bool val get_session : force:bool -> unit -> Datatype.Filepath.t -val get_session_dir : force:bool -> string -> string -val get_output : unit -> string -val get_output_dir : string -> string +val get_session_dir : force:bool -> string -> Datatype.Filepath.t +val get_output : unit -> Datatype.Filepath.t +val get_output_dir : string -> Datatype.Filepath.t val make_output_dir : string -> unit val get_overflows : unit -> bool diff --git a/src/plugins/wp/wpo.ml b/src/plugins/wp/wpo.ml index c3c6df38b3f..21f7f3a9fa1 100644 --- a/src/plugins/wp/wpo.ml +++ b/src/plugins/wp/wpo.ml @@ -88,7 +88,7 @@ struct let mid = Wp_parameters.get_output_dir (WpContext.MODEL.id model) in let buffer = Buffer.create 80 in let fmt = Format.formatter_of_buffer buffer in - Format.fprintf fmt "%s/%s" mid id ; + Format.fprintf fmt "%s/%s" (mid :> string) id ; (match prover with None -> () | Some p -> Format.fprintf fmt "_%s" (filename_for_prover p)) ; (match suffix with None -> () | Some s -> @@ -143,14 +143,14 @@ struct let cache_log ~pid ~model ~prover ~result = (*TODO: put a cache here *) let dir = Wp_parameters.get_output () in - let file = Printf.sprintf "%s/log.txt" dir in + let file = Printf.sprintf "%s/log.txt" (dir :> string) in Command.print_file file (pretty ~pid ~model ~prover ~result) ; file let cache_descr pretty = (*TODO: put a cache here *) let dir = Wp_parameters.get_output () in - let file = Printf.sprintf "%s/goal.txt" dir in + let file = Printf.sprintf "%s/goal.txt" (dir :> string) in Command.print_file file (fun fmt -> pretty fmt) ; file end -- GitLab From 2e13eccd3c12f7e172c96c9340af2fbaa721f1c3 Mon Sep 17 00:00:00 2001 From: Virgile Prevosto <virgile.prevosto@cea.fr> Date: Tue, 28 Apr 2020 08:55:38 +0200 Subject: [PATCH 204/218] Update Changelog after !2629 --- Changelog | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Changelog b/Changelog index 1a24b1ee345..e64dc833070 100644 --- a/Changelog +++ b/Changelog @@ -17,6 +17,8 @@ Open Source Release <next-release> ################################## +o Kernel [2020/04/27] Plug-ins specific dirs now use Filepath instead of + mere strings. - Eva [2020/04/10] Fixes the Memexec cache on functions with logical annotations about variables unused in the C body of the function. - Eva [2020/04/06] New option -eva-domains-function to enable domains -- GitLab From 94643712598fbf6201eed1a9f876a2fd6ea19395 Mon Sep 17 00:00:00 2001 From: Andre Maroneze <andre.oliveiramaroneze@cea.fr> Date: Wed, 29 Apr 2020 09:48:25 +0200 Subject: [PATCH 205/218] [Doc/Devman] Update ptests section in developer manual --- doc/developer/advance.tex | 18 ++++-------------- doc/developer/architecture.tex | 7 ------- ptests/ptests.ml | 2 +- 3 files changed, 5 insertions(+), 22 deletions(-) diff --git a/doc/developer/advance.tex b/doc/developer/advance.tex index 3aa40e5f9d3..b776b213076 100644 --- a/doc/developer/advance.tex +++ b/doc/developer/advance.tex @@ -709,19 +709,6 @@ There is exactly one directive by line. The different directives (\emph{i.e.} possibilities for \texttt{CONFIG\_OPTION}) are detailed in Section~\ref{ptests:directives}. -\begin{important} -Note that some specific configurations require dynamic linking, which -is not available on all platforms for native code. {\tt ptests} takes -care of reverting to bytecode when it detects that the {\tt OPT}, -{\tt EXECNOW}, or \texttt{EXEC} options of a test require dynamic linking. This -occurs currently in the following cases: -\begin{itemize} -\item {\tt OPT} contains the option {\tt -load-script} -\item {\tt OPT} contains the option {\tt -load-module} -\item {\tt EXECNOW} and \texttt{EXEC} use {\tt make} to create a {\tt .cmxs} -\end{itemize} -\end{important} - \begin{important} \textbf{Concurrency issues:} tests using compiled modules ({\tt -load-script} or {\tt -load-module}) may @@ -740,6 +727,7 @@ occurs currently in the following cases: In addition, if the same script {\tt tests/suite/script.ml} is shared by several test files, the {\tt EXECNOW} directive should be put into {\tt tests/suite/test\_config}. + Check the {\tt MODULE} directive for a common solution to this issue. \end{important} @@ -832,9 +820,11 @@ Figure~\ref{fig:ptests-options} details the options of \ptests. & \texttt{-byte} & Use bytecode toplevel & no \\ & \texttt{-opt} & Use native toplevel & yes \\ & \texttt{-gui} & Use GUI instead of console-based toplevel & no \\ -\hline \multirow{4}{16mm}{\centering{Behavior}} +\hline \multirow{5}{16mm}{\centering{Behavior}} & \texttt{-run} & Delete current results; run tests and examine results & yes \\ +& \texttt{-dry-run} & Print commands, but do not execute them & no +\\ & \texttt{-examine} & Only examine current results; do not run tests & no \\ & \texttt{-show} & Run tests and show results, but do not examine them; implies \texttt{-byte} & diff --git a/doc/developer/architecture.tex b/doc/developer/architecture.tex index 0d01872a0df..6d9f6b197d1 100644 --- a/doc/developer/architecture.tex +++ b/doc/developer/architecture.tex @@ -203,13 +203,6 @@ only possible one to define mutually dependent plug-ins while the third one (through module \texttt{Db}) is now fully deprecated even if most of the older \framac plug-ins are still defined this way. -Plug-ins are usually dynamically linked when \framac is booting, even if some -older \framac plug-ins are still statically linked. However it is still possible -to statically link a dynamic plug-in if wanted or required. In particular, -\ocaml does not support dynamic linking on some hardware -architecture~\cite{caml}: in this case, you have to statically link all -plug-ins. - %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \section{Libraries}\label{archi:libraries} diff --git a/ptests/ptests.ml b/ptests/ptests.ml index 8343b8cc01a..27af94c1569 100644 --- a/ptests/ptests.ml +++ b/ptests/ptests.ml @@ -338,7 +338,7 @@ let rec argspec = "-xunit", Arg.Set xunit, " Create a xUnit file named xunit.xml collecting results"; "-error-code", Arg.Set do_error_code, - " Exit with error code 1 if tests failed (useful for scripts"; + " Exit with error code 1 if tests failed (useful for scripts)"; ] and help_msg () = Arg.usage (Arg.align argspec) umsg;; -- GitLab From 780b14de726f0da7516f8cc29b3c9ed7d39a8f23 Mon Sep 17 00:00:00 2001 From: Virgile Prevosto <virgile.prevosto@m4x.org> Date: Thu, 30 Apr 2020 09:33:24 +0200 Subject: [PATCH 206/218] [devman] fix compilation of example script --- doc/developer/examples/syntactic_check.ml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/developer/examples/syntactic_check.ml b/doc/developer/examples/syntactic_check.ml index 7fd91ded169..74c141bde19 100644 --- a/doc/developer/examples/syntactic_check.ml +++ b/doc/developer/examples/syntactic_check.ml @@ -31,7 +31,7 @@ class non_zero_divisor prj = object (self) (* A division is an expression: we override the vexpr method *) method! vexpr e = match e.enode with | BinOp((Div|Mod), _, denom, _) -> - let logic_denom = Logic_utils.expr_to_term ~cast:true denom in + let logic_denom = Logic_utils.expr_to_term ~coerce:false denom in let assertion = Logic_const.prel (Rneq, logic_denom, Cil.lzero ()) in (* At this point, we have built the assertion we want to insert. It remains to attach it to the correct statement. The cil visitor maintains the @@ -43,7 +43,7 @@ class non_zero_divisor prj = object (self) | Kglobal -> assert false | Kstmt s -> s in - let kf = Extlib.the self#current_kf in + let kf = Extlib.the self#current_kf in (* The above statement and function are related to the original project. We need to attach the new assertion to the corresponding statement and function of the new project. Cil provides functions to convert a -- GitLab From 90e200d2b9de0190f0ae43a0464c2f9a18756f50 Mon Sep 17 00:00:00 2001 From: Virgile Prevosto <virgile.prevosto@m4x.org> Date: Thu, 30 Apr 2020 13:21:42 +0200 Subject: [PATCH 207/218] [devman] introduce PTESTS_OPTS variable and put emphasis on MODULE directive --- doc/developer/advance.tex | 41 ++++++++++++++++++++++++++++++--------- 1 file changed, 32 insertions(+), 9 deletions(-) diff --git a/doc/developer/advance.tex b/doc/developer/advance.tex index b776b213076..459e80d888a 100644 --- a/doc/developer/advance.tex +++ b/doc/developer/advance.tex @@ -612,6 +612,18 @@ A specific target \texttt{\$(PLUGIN\_NAME)\_TESTS} will specifically run the tes of the plugin. One can add new tests as dependencies of this target. The default tests are run by the target \texttt{\$(PLUGIN\_NAME)\_DEFAULT\_TESTS}. +Additionally, when running \texttt{make tests} or +\texttt{make \$(PLUGIN\_NAME)\_TESTS} +it is possible to pass options to \texttt{ptests.opt} through the +\texttt{PTESTS\_OPTS} variable. + +\begin{example} +The following command will update the oracles of all tests of the Aoraï plug-in: +\begin{shell} +\$ make PTESTS_OPTS=-update Aorai_TESTS +\end{shell} +\end{example} + \texttt{ptests.opt} runs tests belonging to a sub-directory of directory \texttt{tests}\codeidx{tests} that is specified in \ptests configuration file. This configuration file, @@ -714,20 +726,31 @@ Section~\ref{ptests:directives}. tests using compiled modules ({\tt -load-script} or {\tt -load-module}) may lead to concurrency issues when the same module is used in different test files, or in different test cases within the same file. One way to avoid - issues is to serialize tests via \texttt{EXECNOW} directives, e.g. by using - \texttt{make} to compile a \texttt{.cmxs} from the \texttt{.ml} file, and - then loading the \texttt{.cmxs} in the test cases, as in the example below. + issues is to serialize tests via \texttt{MODULE} directives, which will + take care of the compilation and of adding the corresponding + \texttt{-load-module} option to further \texttt{OPT} and + \texttt{STDOPT} directives: \begin{listing-nonumber} - EXECNOW: make -s @PTEST_DIR@/@PTEST_NAME@.cmxs - STDOPT: #"-load-module @PTEST_DIR@/@PTEST_NAME.cmxs" ... - STDOPT: #"-load-module @PTEST_DIR@/@PTEST_NAME.cmxs" ... + MODULE: @PTEST_DIR@/@PTEST_NAME@.cmxs + STDOPT: +"-opt1" ... + STDOPT: #"-opt2" ... \end{listing-nonumber} In addition, if the same script {\tt tests/suite/script.ml} - is shared by several test files, the {\tt EXECNOW} directive should be put - into {\tt tests/suite/test\_config}. - Check the {\tt MODULE} directive for a common solution to this issue. + is shared by several test files in {\tt tests/suite}, + it is necessary to compile the script once + when entering the directory hosting the suite. The {\tt MODULE} directive is + not well suited for that, and it is thus needed to resort to an {\tt EXECNOW} + directive in {\tt tests/suite/test\_config}: + + \begin{listing-nonumber} + EXECNOW: make -s @PTEST_DIR@/common_module.cmxs + \end{listing-nonumber} + + It is then necessary to explicitly use + {\tt -load-module @PTEST\_DIR@/common\_module.cmxs} in the appropriate + {\tt OPT} and {\tt STDOPT} directives. \end{important} -- GitLab From 4ca2d9abccfc2c6647df22f83a2a6224c2e10fdf Mon Sep 17 00:00:00 2001 From: Virgile Prevosto <virgile.prevosto@m4x.org> Date: Thu, 30 Apr 2020 13:22:38 +0200 Subject: [PATCH 208/218] [ptests] fix typo in comment --- ptests/ptests.ml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ptests/ptests.ml b/ptests/ptests.ml index 27af94c1569..aa521c40b17 100644 --- a/ptests/ptests.ml +++ b/ptests/ptests.ml @@ -163,7 +163,7 @@ let unlink ?(silent = true) file = Unix.unlink file with | Unix_error _ when silent -> () - | Unix_error (ENOENT,_,_) -> () (* Ignore "Not such file or directory" *) + | Unix_error (ENOENT,_,_) -> () (* Ignore "No such file or directory" *) | Unix_error _ as e -> output_unix_error e let is_file_empty_or_nonexisting filename = -- GitLab From ed21b7163146b25d2a9d28a7b7570449339eb648 Mon Sep 17 00:00:00 2001 From: Andre Maroneze <andre.oliveiramaroneze@cea.fr> Date: Tue, 23 Jul 2019 17:12:40 +0200 Subject: [PATCH 209/218] [Kernel][Libc] add specifications for some GCC builtins --- share/libc/__fc_gcc_builtins.h | 61 +++++++ share/libc/__fc_machdep.h | 21 ++- src/kernel_services/ast_queries/cil.ml | 10 - .../tests/arith/oracle_ci/gen_functions.c | 110 +++++------ .../tests/arith/oracle_ci/gen_functions_rec.c | 164 ++++++++--------- .../tests/gmp-only/oracle_ci/gen_functions.c | 172 +++++++++--------- tests/libc/more_gcc_builtins.c | 29 ++- tests/libc/oracle/fc_libc.0.res.oracle | 31 ++-- tests/libc/oracle/fc_libc.1.res.oracle | 60 ++++++ .../libc/oracle/more_gcc_builtins.res.oracle | 71 +++++++- .../oracle/check_builtin_bts1440.res.oracle | 18 -- 11 files changed, 470 insertions(+), 277 deletions(-) diff --git a/share/libc/__fc_gcc_builtins.h b/share/libc/__fc_gcc_builtins.h index df845fa24bd..aef4f536c80 100644 --- a/share/libc/__fc_gcc_builtins.h +++ b/share/libc/__fc_gcc_builtins.h @@ -26,6 +26,7 @@ #ifndef __FC_GCC_BUILTINS #define __FC_GCC_BUILTINS #include "features.h" +#include "__fc_machdep.h" __PUSH_FC_STDLIB @@ -193,6 +194,66 @@ _Bool __builtin_umull_overflow (unsigned long a, unsigned long b, unsigned long */ _Bool __builtin_umulll_overflow (unsigned long long a, unsigned long long b, unsigned long long *res); +/*@ + requires x_nonzero: x != 0; + assigns \result \from indirect:x; + ensures result_is_bit_count: 0 <= \result < __CHAR_BIT * sizeof(x); + */ +int __builtin_clz (unsigned int x); + +/*@ + requires x_nonzero: x != 0; + assigns \result \from indirect:x; + ensures result_is_bit_count: 0 <= \result < __CHAR_BIT * sizeof(x); + */ +int __builtin_clzl (unsigned long x); + +/*@ + requires x_nonzero: x != 0; + assigns \result \from indirect:x; + ensures result_is_bit_count: 0 <= \result < __CHAR_BIT * sizeof(x); + */ +int __builtin_clzll (unsigned long long x); + +/*@ + requires x_nonzero: x != 0; + assigns \result \from indirect:x; + ensures result_is_bit_count: 0 <= \result < __CHAR_BIT * sizeof(x); + */ +int __builtin_ctz (unsigned int x); + +/*@ + requires x_nonzero: x != 0; + assigns \result \from indirect:x; + ensures result_is_bit_count: 0 <= \result < __CHAR_BIT * sizeof(x); + */ +int __builtin_ctzl (unsigned long x); + +/*@ + requires x_nonzero: x != 0; + assigns \result \from indirect:x; + ensures result_is_bit_count: 0 <= \result < __CHAR_BIT * sizeof(x); + */ +int __builtin_ctzll (unsigned long long x); + +/*@ + assigns \result \from indirect:x; + ensures result_is_bit_count: 0 <= \result <= __CHAR_BIT * sizeof(x); + */ +int __builtin_popcount (unsigned int x); + +/*@ + assigns \result \from indirect:x; + ensures result_is_bit_count: 0 <= \result <= __CHAR_BIT * sizeof(x); + */ +int __builtin_popcountl (unsigned long x); + +/*@ + assigns \result \from indirect:x; + ensures result_is_bit_count: 0 <= \result <= __CHAR_BIT * sizeof(x); + */ +int __builtin_popcountll (unsigned long long x); + __END_DECLS __POP_FC_STDLIB diff --git a/share/libc/__fc_machdep.h b/share/libc/__fc_machdep.h index 6411df164b8..39a8c7b78a4 100644 --- a/share/libc/__fc_machdep.h +++ b/share/libc/__fc_machdep.h @@ -26,9 +26,6 @@ #if defined(__FC_MACHDEP_X86_32) || defined(__FC_MACHDEP_GCC_X86_32) #define __FC_FORCE_INCLUDE_MACHDEP__ #include "__fc_machdep_linux_shared.h" -#ifdef __FC_MACHDEP_GCC_X86_32 -#include "__fc_gcc_builtins.h" -#endif #undef __FC_FORCE_INCLUDE_MACHDEP__ #define __FC_BYTE_ORDER __LITTLE_ENDIAN /* Required */ @@ -112,14 +109,15 @@ #define __FC_WINT_MIN 0 #define __FC_WINT_MAX __FC_UINT_MAX +#ifdef __FC_MACHDEP_GCC_X86_32 +#include "__fc_gcc_builtins.h" +#endif + // End of X86_32 || GCC_X86_32 #else #if defined(__FC_MACHDEP_X86_64) || defined(__FC_MACHDEP_GCC_X86_64) #define __FC_FORCE_INCLUDE_MACHDEP__ #include "__fc_machdep_linux_shared.h" -#ifdef __FC_MACHDEP_GCC_X86_64 -#include "__fc_gcc_builtins.h" -#endif #undef __FC_FORCE_INCLUDE_MACHDEP__ #define __FC_BYTE_ORDER __LITTLE_ENDIAN /* Required */ @@ -212,14 +210,15 @@ #define __FC_WINT_MIN 0 #define __FC_WINT_MAX __FC_UINT_MAX +#ifdef __FC_MACHDEP_GCC_X86_64 +#include "__fc_gcc_builtins.h" +#endif + // End of X86_64 || GCC_X86_64 #else #if defined(__FC_MACHDEP_X86_16) || defined(__FC_MACHDEP_GCC_X86_16) #define __FC_FORCE_INCLUDE_MACHDEP__ #include "__fc_machdep_linux_shared.h" -#ifdef __FC_MACHDEP_GCC_X86_16 -#include "__fc_gcc_builtins.h" -#endif #undef __FC_FORCE_INCLUDE_MACHDEP__ #define __FC_BYTE_ORDER __LITTLE_ENDIAN /* Required */ @@ -315,6 +314,10 @@ #define __FC_WINT_MIN 0 #define __FC_WINT_MAX __FC_ULONG_MAX +#ifdef __FC_MACHDEP_GCC_X86_16 +#include "__fc_gcc_builtins.h" +#endif + // End of X86_16 || GCC_X86_16 #else #ifdef __FC_MACHDEP_PPC_32 diff --git a/src/kernel_services/ast_queries/cil.ml b/src/kernel_services/ast_queries/cil.ml index e8ae6d48605..544e912ca69 100644 --- a/src/kernel_services/ast_queries/cil.ml +++ b/src/kernel_services/ast_queries/cil.ml @@ -4994,13 +4994,7 @@ let initGccBuiltins () : unit = add "coshf" floatType [ floatType ] false; add "coshl" longDoubleType [ longDoubleType ] false; - add "clz" intType [ uintType ] false; - add "clzl" intType [ ulongType ] false; - add "clzll" intType [ ulongLongType ] false; add "constant_p" intType [ intType ] false; - add "ctz" intType [ uintType ] false; - add "ctzl" intType [ ulongType ] false; - add "ctzll" intType [ ulongLongType ] false; add "exp" doubleType [ doubleType ] false; add "expf" floatType [ floatType ] false; @@ -5071,10 +5065,6 @@ let initGccBuiltins () : unit = add "parityl" intType [ ulongType ] false; add "parityll" intType [ ulongLongType ] false; - add "popcount" intType [ uintType ] false; - add "popcountl" intType [ ulongType ] false; - add "popcountll" intType [ ulongLongType ] false; - add "powi" doubleType [ doubleType; intType ] false; add "powif" floatType [ floatType; intType ] false; add "powil" longDoubleType [ longDoubleType; intType ] false; diff --git a/src/plugins/e-acsl/tests/arith/oracle_ci/gen_functions.c b/src/plugins/e-acsl/tests/arith/oracle_ci/gen_functions.c index 42381d641e8..8a80b252478 100644 --- a/src/plugins/e-acsl/tests/arith/oracle_ci/gen_functions.c +++ b/src/plugins/e-acsl/tests/arith/oracle_ci/gen_functions.c @@ -232,61 +232,6 @@ void __gen_e_acsl_k(int x) return; } -int __gen_e_acsl_h_short(int s) -{ - return s; -} - -int __gen_e_acsl_g_hidden(int x) -{ - return x; -} - -double __gen_e_acsl_f2(double x) -{ - __e_acsl_mpq_t __gen_e_acsl__8; - __e_acsl_mpq_t __gen_e_acsl__9; - __e_acsl_mpq_t __gen_e_acsl_div; - double __gen_e_acsl__10; - __gmpq_init(__gen_e_acsl__8); - __gmpq_set_str(__gen_e_acsl__8,"1",10); - __gmpq_init(__gen_e_acsl__9); - __gmpq_set_d(__gen_e_acsl__9,x); - __gmpq_init(__gen_e_acsl_div); - __gmpq_div(__gen_e_acsl_div,(__e_acsl_mpq_struct const *)(__gen_e_acsl__8), - (__e_acsl_mpq_struct const *)(__gen_e_acsl__9)); - __gen_e_acsl__10 = __gmpq_get_d((__e_acsl_mpq_struct const *)(__gen_e_acsl_div)); - __gmpq_clear(__gen_e_acsl__8); - __gmpq_clear(__gen_e_acsl__9); - __gmpq_clear(__gen_e_acsl_div); - /*@ assert Eva: is_nan_or_infinite: \is_finite(__gen_e_acsl__10); */ - return __gen_e_acsl__10; -} - -int __gen_e_acsl_g(int x) -{ - int __gen_e_acsl_g_hidden_2; - __gen_e_acsl_g_hidden_2 = __gen_e_acsl_g_hidden(x); - return __gen_e_acsl_g_hidden_2; -} - -mystruct __gen_e_acsl_t1(mystruct m) -{ - return m; -} - -int __gen_e_acsl_p1(int x, int y) -{ - int __retres = x + (long)y > 0L; - return __retres; -} - -long __gen_e_acsl_t2(mystruct m) -{ - long __retres = m.k + (long)m.l; - return __retres; -} - int __gen_e_acsl_p2(int x, int y) { int __retres = x + (long)y > 0L; @@ -384,4 +329,59 @@ int __gen_e_acsl_h_char(int c) return c; } +int __gen_e_acsl_h_short(int s) +{ + return s; +} + +int __gen_e_acsl_g_hidden(int x) +{ + return x; +} + +double __gen_e_acsl_f2(double x) +{ + __e_acsl_mpq_t __gen_e_acsl__8; + __e_acsl_mpq_t __gen_e_acsl__9; + __e_acsl_mpq_t __gen_e_acsl_div; + double __gen_e_acsl__10; + __gmpq_init(__gen_e_acsl__8); + __gmpq_set_str(__gen_e_acsl__8,"1",10); + __gmpq_init(__gen_e_acsl__9); + __gmpq_set_d(__gen_e_acsl__9,x); + __gmpq_init(__gen_e_acsl_div); + __gmpq_div(__gen_e_acsl_div,(__e_acsl_mpq_struct const *)(__gen_e_acsl__8), + (__e_acsl_mpq_struct const *)(__gen_e_acsl__9)); + __gen_e_acsl__10 = __gmpq_get_d((__e_acsl_mpq_struct const *)(__gen_e_acsl_div)); + __gmpq_clear(__gen_e_acsl__8); + __gmpq_clear(__gen_e_acsl__9); + __gmpq_clear(__gen_e_acsl_div); + /*@ assert Eva: is_nan_or_infinite: \is_finite(__gen_e_acsl__10); */ + return __gen_e_acsl__10; +} + +int __gen_e_acsl_g(int x) +{ + int __gen_e_acsl_g_hidden_2; + __gen_e_acsl_g_hidden_2 = __gen_e_acsl_g_hidden(x); + return __gen_e_acsl_g_hidden_2; +} + +mystruct __gen_e_acsl_t1(mystruct m) +{ + return m; +} + +int __gen_e_acsl_p1(int x, int y) +{ + int __retres = x + (long)y > 0L; + return __retres; +} + +long __gen_e_acsl_t2(mystruct m) +{ + long __retres = m.k + (long)m.l; + return __retres; +} + diff --git a/src/plugins/e-acsl/tests/arith/oracle_ci/gen_functions_rec.c b/src/plugins/e-acsl/tests/arith/oracle_ci/gen_functions_rec.c index b9015c95933..d7e6ba9cda3 100644 --- a/src/plugins/e-acsl/tests/arith/oracle_ci/gen_functions_rec.c +++ b/src/plugins/e-acsl/tests/arith/oracle_ci/gen_functions_rec.c @@ -105,6 +105,88 @@ int main(void) return __retres; } +int __gen_e_acsl_g(int n) +{ + int __retres = 0; + return __retres; +} + +int __gen_e_acsl_g_5(long n) +{ + int __retres = 0; + return __retres; +} + +int __gen_e_acsl_f3(int n) +{ + int __gen_e_acsl_if_6; + if (n > 0) { + int __gen_e_acsl_g_2; + int __gen_e_acsl_f3_5; + __gen_e_acsl_g_2 = __gen_e_acsl_g(n); + __gen_e_acsl_f3_5 = __gen_e_acsl_f3_2(n - 1L); + __gen_e_acsl_if_6 = __gen_e_acsl_g_2 * __gen_e_acsl_f3_5 - 5; + } + else { + int __gen_e_acsl_g_8; + __gen_e_acsl_g_8 = __gen_e_acsl_g_5(n + 1L); + __gen_e_acsl_if_6 = __gen_e_acsl_g_8; + } + return __gen_e_acsl_if_6; +} + +int __gen_e_acsl_f3_2(long n) +{ + int __gen_e_acsl_if_5; + if (n > 0L) { + int __gen_e_acsl_g_4; + int __gen_e_acsl_f3_4; + __gen_e_acsl_g_4 = __gen_e_acsl_g((int)n); + __gen_e_acsl_f3_4 = __gen_e_acsl_f3_2(n - 1L); + __gen_e_acsl_if_5 = __gen_e_acsl_g_4 * __gen_e_acsl_f3_4 - 5; + } + else { + int __gen_e_acsl_g_6; + __gen_e_acsl_g_6 = __gen_e_acsl_g_5(n + 1L); + __gen_e_acsl_if_5 = __gen_e_acsl_g_6; + } + return __gen_e_acsl_if_5; +} + +unsigned long __gen_e_acsl_f4(int n) +{ + unsigned long __gen_e_acsl_if_10; + if (n < 100) { + unsigned long __gen_e_acsl_f4_5; + __gen_e_acsl_f4_5 = __gen_e_acsl_f4_2(n + 1L); + __gen_e_acsl_if_10 = __gen_e_acsl_f4_5; + } + else { + unsigned long __gen_e_acsl_if_9; + if ((long)n < 9223372036854775807L) __gen_e_acsl_if_9 = 9223372036854775807UL; + else __gen_e_acsl_if_9 = 6UL; + __gen_e_acsl_if_10 = __gen_e_acsl_if_9; + } + return __gen_e_acsl_if_10; +} + +unsigned long __gen_e_acsl_f4_2(long n) +{ + unsigned long __gen_e_acsl_if_8; + if (n < 100L) { + unsigned long __gen_e_acsl_f4_4; + __gen_e_acsl_f4_4 = __gen_e_acsl_f4_2(n + 1L); + __gen_e_acsl_if_8 = __gen_e_acsl_f4_4; + } + else { + unsigned long __gen_e_acsl_if_7; + if (n < 9223372036854775807L) __gen_e_acsl_if_7 = 9223372036854775807UL; + else __gen_e_acsl_if_7 = 6UL; + __gen_e_acsl_if_8 = __gen_e_acsl_if_7; + } + return __gen_e_acsl_if_8; +} + void __gen_e_acsl_f1(__e_acsl_mpz_t *__retres_arg, int n) { __e_acsl_mpz_t __gen_e_acsl_if_2; @@ -235,86 +317,4 @@ int __gen_e_acsl_f2_2(long n) return __gen_e_acsl_if_3; } -int __gen_e_acsl_g(int n) -{ - int __retres = 0; - return __retres; -} - -int __gen_e_acsl_g_5(long n) -{ - int __retres = 0; - return __retres; -} - -int __gen_e_acsl_f3(int n) -{ - int __gen_e_acsl_if_6; - if (n > 0) { - int __gen_e_acsl_g_2; - int __gen_e_acsl_f3_5; - __gen_e_acsl_g_2 = __gen_e_acsl_g(n); - __gen_e_acsl_f3_5 = __gen_e_acsl_f3_2(n - 1L); - __gen_e_acsl_if_6 = __gen_e_acsl_g_2 * __gen_e_acsl_f3_5 - 5; - } - else { - int __gen_e_acsl_g_8; - __gen_e_acsl_g_8 = __gen_e_acsl_g_5(n + 1L); - __gen_e_acsl_if_6 = __gen_e_acsl_g_8; - } - return __gen_e_acsl_if_6; -} - -int __gen_e_acsl_f3_2(long n) -{ - int __gen_e_acsl_if_5; - if (n > 0L) { - int __gen_e_acsl_g_4; - int __gen_e_acsl_f3_4; - __gen_e_acsl_g_4 = __gen_e_acsl_g((int)n); - __gen_e_acsl_f3_4 = __gen_e_acsl_f3_2(n - 1L); - __gen_e_acsl_if_5 = __gen_e_acsl_g_4 * __gen_e_acsl_f3_4 - 5; - } - else { - int __gen_e_acsl_g_6; - __gen_e_acsl_g_6 = __gen_e_acsl_g_5(n + 1L); - __gen_e_acsl_if_5 = __gen_e_acsl_g_6; - } - return __gen_e_acsl_if_5; -} - -unsigned long __gen_e_acsl_f4(int n) -{ - unsigned long __gen_e_acsl_if_10; - if (n < 100) { - unsigned long __gen_e_acsl_f4_5; - __gen_e_acsl_f4_5 = __gen_e_acsl_f4_2(n + 1L); - __gen_e_acsl_if_10 = __gen_e_acsl_f4_5; - } - else { - unsigned long __gen_e_acsl_if_9; - if ((long)n < 9223372036854775807L) __gen_e_acsl_if_9 = 9223372036854775807UL; - else __gen_e_acsl_if_9 = 6UL; - __gen_e_acsl_if_10 = __gen_e_acsl_if_9; - } - return __gen_e_acsl_if_10; -} - -unsigned long __gen_e_acsl_f4_2(long n) -{ - unsigned long __gen_e_acsl_if_8; - if (n < 100L) { - unsigned long __gen_e_acsl_f4_4; - __gen_e_acsl_f4_4 = __gen_e_acsl_f4_2(n + 1L); - __gen_e_acsl_if_8 = __gen_e_acsl_f4_4; - } - else { - unsigned long __gen_e_acsl_if_7; - if (n < 9223372036854775807L) __gen_e_acsl_if_7 = 9223372036854775807UL; - else __gen_e_acsl_if_7 = 6UL; - __gen_e_acsl_if_8 = __gen_e_acsl_if_7; - } - return __gen_e_acsl_if_8; -} - diff --git a/src/plugins/e-acsl/tests/gmp-only/oracle_ci/gen_functions.c b/src/plugins/e-acsl/tests/gmp-only/oracle_ci/gen_functions.c index 2bdf4cd9f28..91010d0c7a4 100644 --- a/src/plugins/e-acsl/tests/gmp-only/oracle_ci/gen_functions.c +++ b/src/plugins/e-acsl/tests/gmp-only/oracle_ci/gen_functions.c @@ -277,92 +277,6 @@ void __gen_e_acsl_k(int x) return; } -int __gen_e_acsl_h_short(int s) -{ - return s; -} - -int __gen_e_acsl_g_hidden(int x) -{ - return x; -} - -double __gen_e_acsl_f2(double x) -{ - __e_acsl_mpq_t __gen_e_acsl__13; - __e_acsl_mpq_t __gen_e_acsl__14; - __e_acsl_mpq_t __gen_e_acsl_div; - double __gen_e_acsl__15; - __gmpq_init(__gen_e_acsl__13); - __gmpq_set_str(__gen_e_acsl__13,"1",10); - __gmpq_init(__gen_e_acsl__14); - __gmpq_set_d(__gen_e_acsl__14,x); - __gmpq_init(__gen_e_acsl_div); - __gmpq_div(__gen_e_acsl_div, - (__e_acsl_mpq_struct const *)(__gen_e_acsl__13), - (__e_acsl_mpq_struct const *)(__gen_e_acsl__14)); - __gen_e_acsl__15 = __gmpq_get_d((__e_acsl_mpq_struct const *)(__gen_e_acsl_div)); - __gmpq_clear(__gen_e_acsl__13); - __gmpq_clear(__gen_e_acsl__14); - __gmpq_clear(__gen_e_acsl_div); - /*@ assert Eva: is_nan_or_infinite: \is_finite(__gen_e_acsl__15); */ - return __gen_e_acsl__15; -} - -int __gen_e_acsl_g(int x) -{ - int __gen_e_acsl_g_hidden_2; - __gen_e_acsl_g_hidden_2 = __gen_e_acsl_g_hidden(x); - return __gen_e_acsl_g_hidden_2; -} - -mystruct __gen_e_acsl_t1(mystruct m) -{ - return m; -} - -int __gen_e_acsl_p1(int x, int y) -{ - __e_acsl_mpz_t __gen_e_acsl_x; - __e_acsl_mpz_t __gen_e_acsl_y; - __e_acsl_mpz_t __gen_e_acsl_add; - __e_acsl_mpz_t __gen_e_acsl_; - int __gen_e_acsl_gt; - __gmpz_init_set_si(__gen_e_acsl_x,(long)x); - __gmpz_init_set_si(__gen_e_acsl_y,(long)y); - __gmpz_init(__gen_e_acsl_add); - __gmpz_add(__gen_e_acsl_add,(__e_acsl_mpz_struct const *)(__gen_e_acsl_x), - (__e_acsl_mpz_struct const *)(__gen_e_acsl_y)); - __gmpz_init_set_si(__gen_e_acsl_,0L); - __gen_e_acsl_gt = __gmpz_cmp((__e_acsl_mpz_struct const *)(__gen_e_acsl_add), - (__e_acsl_mpz_struct const *)(__gen_e_acsl_)); - int __retres = __gen_e_acsl_gt > 0; - __gmpz_clear(__gen_e_acsl_x); - __gmpz_clear(__gen_e_acsl_y); - __gmpz_clear(__gen_e_acsl_add); - __gmpz_clear(__gen_e_acsl_); - return __retres; -} - -void __gen_e_acsl_t2(__e_acsl_mpz_t *__retres_arg, mystruct m) -{ - __e_acsl_mpz_t __gen_e_acsl__10; - __e_acsl_mpz_t __gen_e_acsl__11; - __e_acsl_mpz_t __gen_e_acsl_add_7; - __gmpz_init_set_si(__gen_e_acsl__10,(long)m.k); - __gmpz_init_set_si(__gen_e_acsl__11,(long)m.l); - __gmpz_init(__gen_e_acsl_add_7); - __gmpz_add(__gen_e_acsl_add_7, - (__e_acsl_mpz_struct const *)(__gen_e_acsl__10), - (__e_acsl_mpz_struct const *)(__gen_e_acsl__11)); - __gmpz_init_set(*__retres_arg, - (__e_acsl_mpz_struct const *)(__gen_e_acsl_add_7)); - __gmpz_clear(__gen_e_acsl__10); - __gmpz_clear(__gen_e_acsl__11); - __gmpz_clear(__gen_e_acsl_add_7); - return; -} - int __gen_e_acsl_p2(int x, int y) { __e_acsl_mpz_t __gen_e_acsl_x_2; @@ -477,4 +391,90 @@ int __gen_e_acsl_h_char(int c) return c; } +int __gen_e_acsl_h_short(int s) +{ + return s; +} + +int __gen_e_acsl_g_hidden(int x) +{ + return x; +} + +double __gen_e_acsl_f2(double x) +{ + __e_acsl_mpq_t __gen_e_acsl__13; + __e_acsl_mpq_t __gen_e_acsl__14; + __e_acsl_mpq_t __gen_e_acsl_div; + double __gen_e_acsl__15; + __gmpq_init(__gen_e_acsl__13); + __gmpq_set_str(__gen_e_acsl__13,"1",10); + __gmpq_init(__gen_e_acsl__14); + __gmpq_set_d(__gen_e_acsl__14,x); + __gmpq_init(__gen_e_acsl_div); + __gmpq_div(__gen_e_acsl_div, + (__e_acsl_mpq_struct const *)(__gen_e_acsl__13), + (__e_acsl_mpq_struct const *)(__gen_e_acsl__14)); + __gen_e_acsl__15 = __gmpq_get_d((__e_acsl_mpq_struct const *)(__gen_e_acsl_div)); + __gmpq_clear(__gen_e_acsl__13); + __gmpq_clear(__gen_e_acsl__14); + __gmpq_clear(__gen_e_acsl_div); + /*@ assert Eva: is_nan_or_infinite: \is_finite(__gen_e_acsl__15); */ + return __gen_e_acsl__15; +} + +int __gen_e_acsl_g(int x) +{ + int __gen_e_acsl_g_hidden_2; + __gen_e_acsl_g_hidden_2 = __gen_e_acsl_g_hidden(x); + return __gen_e_acsl_g_hidden_2; +} + +mystruct __gen_e_acsl_t1(mystruct m) +{ + return m; +} + +int __gen_e_acsl_p1(int x, int y) +{ + __e_acsl_mpz_t __gen_e_acsl_x; + __e_acsl_mpz_t __gen_e_acsl_y; + __e_acsl_mpz_t __gen_e_acsl_add; + __e_acsl_mpz_t __gen_e_acsl_; + int __gen_e_acsl_gt; + __gmpz_init_set_si(__gen_e_acsl_x,(long)x); + __gmpz_init_set_si(__gen_e_acsl_y,(long)y); + __gmpz_init(__gen_e_acsl_add); + __gmpz_add(__gen_e_acsl_add,(__e_acsl_mpz_struct const *)(__gen_e_acsl_x), + (__e_acsl_mpz_struct const *)(__gen_e_acsl_y)); + __gmpz_init_set_si(__gen_e_acsl_,0L); + __gen_e_acsl_gt = __gmpz_cmp((__e_acsl_mpz_struct const *)(__gen_e_acsl_add), + (__e_acsl_mpz_struct const *)(__gen_e_acsl_)); + int __retres = __gen_e_acsl_gt > 0; + __gmpz_clear(__gen_e_acsl_x); + __gmpz_clear(__gen_e_acsl_y); + __gmpz_clear(__gen_e_acsl_add); + __gmpz_clear(__gen_e_acsl_); + return __retres; +} + +void __gen_e_acsl_t2(__e_acsl_mpz_t *__retres_arg, mystruct m) +{ + __e_acsl_mpz_t __gen_e_acsl__10; + __e_acsl_mpz_t __gen_e_acsl__11; + __e_acsl_mpz_t __gen_e_acsl_add_7; + __gmpz_init_set_si(__gen_e_acsl__10,(long)m.k); + __gmpz_init_set_si(__gen_e_acsl__11,(long)m.l); + __gmpz_init(__gen_e_acsl_add_7); + __gmpz_add(__gen_e_acsl_add_7, + (__e_acsl_mpz_struct const *)(__gen_e_acsl__10), + (__e_acsl_mpz_struct const *)(__gen_e_acsl__11)); + __gmpz_init_set(*__retres_arg, + (__e_acsl_mpz_struct const *)(__gen_e_acsl_add_7)); + __gmpz_clear(__gen_e_acsl__10); + __gmpz_clear(__gen_e_acsl__11); + __gmpz_clear(__gen_e_acsl_add_7); + return; +} + diff --git a/tests/libc/more_gcc_builtins.c b/tests/libc/more_gcc_builtins.c index 835f64e8cc8..d3d023ac786 100644 --- a/tests/libc/more_gcc_builtins.c +++ b/tests/libc/more_gcc_builtins.c @@ -2,7 +2,7 @@ STDOPT: #"-machdep gcc_x86_32" */ - +volatile int v; #include <limits.h> int main() { @@ -42,5 +42,32 @@ int main() { r = __builtin_smulll_overflow(-1, LLONG_MIN, &llres); //@ assert llres == (long long)(-1 * LLONG_MIN); //@ assert r == 1; + if (v) { + __builtin_clz(0); + //@ assert unreachable:\false; + } + res = __builtin_clz(1); + //@ assert 0 <= res < CHAR_BIT * sizeof(int); + res = __builtin_clzl(ULONG_MAX); + //@ assert 0 <= res < CHAR_BIT * sizeof(long); + res = __builtin_clzll(ULLONG_MAX); + //@ assert 0 <= res < CHAR_BIT * sizeof(long long); + if (v) { + __builtin_ctz(0); + //@ assert unreachable:\false; + } + res = __builtin_ctz(42); + //@ assert 0 <= res < CHAR_BIT * sizeof(int); + res = __builtin_ctzl(1234567); + //@ assert 0 <= res < CHAR_BIT * sizeof(long); + res = __builtin_ctzll(1); + //@ assert 0 <= res < CHAR_BIT * sizeof(long long); + + res = __builtin_popcount(0); + //@ assert 0 <= res <= CHAR_BIT * sizeof(int); + res = __builtin_popcountl(ULONG_MAX); + //@ assert 0 <= res <= CHAR_BIT * sizeof(long); + res = __builtin_popcountll(ULLONG_MAX); + //@ assert 0 <= res <= CHAR_BIT * sizeof(long long); return 0; } diff --git a/tests/libc/oracle/fc_libc.0.res.oracle b/tests/libc/oracle/fc_libc.0.res.oracle index f0d8a56d9da..fefd9fce133 100644 --- a/tests/libc/oracle/fc_libc.0.res.oracle +++ b/tests/libc/oracle/fc_libc.0.res.oracle @@ -40,7 +40,7 @@ unsetenv (0 call); wcscat (0 call); wcscpy (0 call); wcslen (2 calls); wcsncat (0 call); wcsncpy (0 call); wmemcpy (0 call); wmemset (0 call); - Undefined functions (397) + Undefined functions (406) ========================= FD_CLR (0 call); FD_ISSET (0 call); FD_SET (0 call); FD_ZERO (0 call); Frama_C_int_interval (0 call); Frama_C_long_interval (0 call); @@ -51,18 +51,21 @@ Frama_C_unsigned_long_interval (0 call); Frama_C_unsigned_long_long_interval (0 call); Frama_C_unsigned_short_interval (0 call); _Exit (0 call); - __builtin_abort (1 call); __builtin_sadd_overflow (0 call); - __builtin_saddl_overflow (0 call); __builtin_saddll_overflow (0 call); - __builtin_smul_overflow (0 call); __builtin_smull_overflow (0 call); - __builtin_smulll_overflow (0 call); __builtin_ssub_overflow (0 call); - __builtin_ssubl_overflow (0 call); __builtin_ssubll_overflow (0 call); - __builtin_uadd_overflow (0 call); __builtin_uaddl_overflow (0 call); - __builtin_uaddll_overflow (0 call); __builtin_umul_overflow (0 call); - __builtin_umull_overflow (0 call); __builtin_umulll_overflow (0 call); - __builtin_usub_overflow (0 call); __builtin_usubl_overflow (0 call); - __builtin_usubll_overflow (0 call); __fc_fpclassify (0 call); - __fc_fpclassifyf (0 call); __fc_infinity (0 call); __fc_nan (0 call); - __va_fcntl_flock (0 call); __va_fcntl_int (0 call); + __builtin_abort (1 call); __builtin_clz (0 call); __builtin_clzl (0 call); + __builtin_clzll (0 call); __builtin_ctz (0 call); __builtin_ctzl (0 call); + __builtin_ctzll (0 call); __builtin_popcount (0 call); + __builtin_popcountl (0 call); __builtin_popcountll (0 call); + __builtin_sadd_overflow (0 call); __builtin_saddl_overflow (0 call); + __builtin_saddll_overflow (0 call); __builtin_smul_overflow (0 call); + __builtin_smull_overflow (0 call); __builtin_smulll_overflow (0 call); + __builtin_ssub_overflow (0 call); __builtin_ssubl_overflow (0 call); + __builtin_ssubll_overflow (0 call); __builtin_uadd_overflow (0 call); + __builtin_uaddl_overflow (0 call); __builtin_uaddll_overflow (0 call); + __builtin_umul_overflow (0 call); __builtin_umull_overflow (0 call); + __builtin_umulll_overflow (0 call); __builtin_usub_overflow (0 call); + __builtin_usubl_overflow (0 call); __builtin_usubll_overflow (0 call); + __fc_fpclassify (0 call); __fc_fpclassifyf (0 call); __fc_infinity (0 call); + __fc_nan (0 call); __va_fcntl_flock (0 call); __va_fcntl_int (0 call); __va_fcntl_void (0 call); __va_ioctl_int (0 call); __va_ioctl_ptr (0 call); __va_ioctl_void (0 call); __va_open_mode_t (0 call); __va_open_void (0 call); __va_openat_mode_t (0 call); @@ -181,7 +184,7 @@ Goto = 89 Assignment = 438 Exit point = 82 - Function = 479 + Function = 488 Function call = 89 Pointer dereferencing = 158 Cyclomatic complexity = 286 diff --git a/tests/libc/oracle/fc_libc.1.res.oracle b/tests/libc/oracle/fc_libc.1.res.oracle index c4e0a539a60..f940ecca0a0 100644 --- a/tests/libc/oracle/fc_libc.1.res.oracle +++ b/tests/libc/oracle/fc_libc.1.res.oracle @@ -7238,6 +7238,66 @@ _Bool __builtin_umull_overflow(unsigned long a, unsigned long b, _Bool __builtin_umulll_overflow(unsigned long long a, unsigned long long b, unsigned long long *res); +/*@ requires x_nonzero: x ≢ 0; + ensures result_is_bit_count: 0 ≤ \result < 8 * sizeof(\old(x)); + assigns \result; + assigns \result \from (indirect: x); + */ +int __builtin_clz(unsigned int x); + +/*@ requires x_nonzero: x ≢ 0; + ensures result_is_bit_count: 0 ≤ \result < 8 * sizeof(\old(x)); + assigns \result; + assigns \result \from (indirect: x); + */ +int __builtin_clzl(unsigned long x); + +/*@ requires x_nonzero: x ≢ 0; + ensures result_is_bit_count: 0 ≤ \result < 8 * sizeof(\old(x)); + assigns \result; + assigns \result \from (indirect: x); + */ +int __builtin_clzll(unsigned long long x); + +/*@ requires x_nonzero: x ≢ 0; + ensures result_is_bit_count: 0 ≤ \result < 8 * sizeof(\old(x)); + assigns \result; + assigns \result \from (indirect: x); + */ +int __builtin_ctz(unsigned int x); + +/*@ requires x_nonzero: x ≢ 0; + ensures result_is_bit_count: 0 ≤ \result < 8 * sizeof(\old(x)); + assigns \result; + assigns \result \from (indirect: x); + */ +int __builtin_ctzl(unsigned long x); + +/*@ requires x_nonzero: x ≢ 0; + ensures result_is_bit_count: 0 ≤ \result < 8 * sizeof(\old(x)); + assigns \result; + assigns \result \from (indirect: x); + */ +int __builtin_ctzll(unsigned long long x); + +/*@ ensures result_is_bit_count: 0 ≤ \result ≤ 8 * sizeof(\old(x)); + assigns \result; + assigns \result \from (indirect: x); + */ +int __builtin_popcount(unsigned int x); + +/*@ ensures result_is_bit_count: 0 ≤ \result ≤ 8 * sizeof(\old(x)); + assigns \result; + assigns \result \from (indirect: x); + */ +int __builtin_popcountl(unsigned long x); + +/*@ ensures result_is_bit_count: 0 ≤ \result ≤ 8 * sizeof(\old(x)); + assigns \result; + assigns \result \from (indirect: x); + */ +int __builtin_popcountll(unsigned long long x); + /*@ requires valid_filename: valid_read_string(filename); assigns \result; assigns \result \from (indirect: *(filename + (0 ..))), (indirect: mode); diff --git a/tests/libc/oracle/more_gcc_builtins.res.oracle b/tests/libc/oracle/more_gcc_builtins.res.oracle index 0ad30701226..91b6a0d432d 100644 --- a/tests/libc/oracle/more_gcc_builtins.res.oracle +++ b/tests/libc/oracle/more_gcc_builtins.res.oracle @@ -3,7 +3,7 @@ [eva] Computing initial state [eva] Initial state computed [eva:initial-state] Values of globals at initialization - + v ∈ [--..--] [eva] computing for function __builtin_sadd_overflow <- main. Called from tests/libc/more_gcc_builtins.c:10. [eva] using specification for function __builtin_sadd_overflow @@ -82,11 +82,78 @@ [eva] Done for function __builtin_smulll_overflow [eva] tests/libc/more_gcc_builtins.c:43: assertion got status valid. [eva] tests/libc/more_gcc_builtins.c:44: assertion got status valid. +[eva] computing for function __builtin_clz <- main. + Called from tests/libc/more_gcc_builtins.c:46. +[eva] using specification for function __builtin_clz +[eva:alarm] tests/libc/more_gcc_builtins.c:46: Warning: + function __builtin_clz: precondition 'x_nonzero' got status invalid. +[eva] Done for function __builtin_clz +[eva] computing for function __builtin_clz <- main. + Called from tests/libc/more_gcc_builtins.c:49. +[eva] tests/libc/more_gcc_builtins.c:49: + function __builtin_clz: precondition 'x_nonzero' got status valid. +[eva] Done for function __builtin_clz +[eva] tests/libc/more_gcc_builtins.c:50: assertion got status valid. +[eva] computing for function __builtin_clzl <- main. + Called from tests/libc/more_gcc_builtins.c:51. +[eva] using specification for function __builtin_clzl +[eva] tests/libc/more_gcc_builtins.c:51: + function __builtin_clzl: precondition 'x_nonzero' got status valid. +[eva] Done for function __builtin_clzl +[eva] tests/libc/more_gcc_builtins.c:52: assertion got status valid. +[eva] computing for function __builtin_clzll <- main. + Called from tests/libc/more_gcc_builtins.c:53. +[eva] using specification for function __builtin_clzll +[eva] tests/libc/more_gcc_builtins.c:53: + function __builtin_clzll: precondition 'x_nonzero' got status valid. +[eva] Done for function __builtin_clzll +[eva] tests/libc/more_gcc_builtins.c:54: assertion got status valid. +[eva] computing for function __builtin_ctz <- main. + Called from tests/libc/more_gcc_builtins.c:56. +[eva] using specification for function __builtin_ctz +[eva:alarm] tests/libc/more_gcc_builtins.c:56: Warning: + function __builtin_ctz: precondition 'x_nonzero' got status invalid. +[eva] Done for function __builtin_ctz +[eva] computing for function __builtin_ctz <- main. + Called from tests/libc/more_gcc_builtins.c:59. +[eva] tests/libc/more_gcc_builtins.c:59: + function __builtin_ctz: precondition 'x_nonzero' got status valid. +[eva] Done for function __builtin_ctz +[eva] tests/libc/more_gcc_builtins.c:60: assertion got status valid. +[eva] computing for function __builtin_ctzl <- main. + Called from tests/libc/more_gcc_builtins.c:61. +[eva] using specification for function __builtin_ctzl +[eva] tests/libc/more_gcc_builtins.c:61: + function __builtin_ctzl: precondition 'x_nonzero' got status valid. +[eva] Done for function __builtin_ctzl +[eva] tests/libc/more_gcc_builtins.c:62: assertion got status valid. +[eva] computing for function __builtin_ctzll <- main. + Called from tests/libc/more_gcc_builtins.c:63. +[eva] using specification for function __builtin_ctzll +[eva] tests/libc/more_gcc_builtins.c:63: + function __builtin_ctzll: precondition 'x_nonzero' got status valid. +[eva] Done for function __builtin_ctzll +[eva] tests/libc/more_gcc_builtins.c:64: assertion got status valid. +[eva] computing for function __builtin_popcount <- main. + Called from tests/libc/more_gcc_builtins.c:66. +[eva] using specification for function __builtin_popcount +[eva] Done for function __builtin_popcount +[eva] tests/libc/more_gcc_builtins.c:67: assertion got status valid. +[eva] computing for function __builtin_popcountl <- main. + Called from tests/libc/more_gcc_builtins.c:68. +[eva] using specification for function __builtin_popcountl +[eva] Done for function __builtin_popcountl +[eva] tests/libc/more_gcc_builtins.c:69: assertion got status valid. +[eva] computing for function __builtin_popcountll <- main. + Called from tests/libc/more_gcc_builtins.c:70. +[eva] using specification for function __builtin_popcountll +[eva] Done for function __builtin_popcountll +[eva] tests/libc/more_gcc_builtins.c:71: assertion got status valid. [eva] Recording results for main [eva] done for function main [eva] ====== VALUES COMPUTED ====== [eva:final-states] Values at end of function main: - res ∈ {-2147483607} + res ∈ [0..64] r ∈ {1} lres ∈ {2147483647} llres ∈ {-9223372036854775808} diff --git a/tests/syntax/oracle/check_builtin_bts1440.res.oracle b/tests/syntax/oracle/check_builtin_bts1440.res.oracle index 4e0e7ae6c6a..091c7d8002d 100644 --- a/tests/syntax/oracle/check_builtin_bts1440.res.oracle +++ b/tests/syntax/oracle/check_builtin_bts1440.res.oracle @@ -81,12 +81,6 @@ long double __builtin_ceill(long double); - int __builtin_clz(unsigned int); - - int __builtin_clzl(unsigned long); - - int __builtin_clzll(unsigned long long); - int __builtin_constant_p(int); double __builtin_cos(double); @@ -101,12 +95,6 @@ long double __builtin_cosl(long double); - int __builtin_ctz(unsigned int); - - int __builtin_ctzl(unsigned long); - - int __builtin_ctzll(unsigned long long); - double __builtin_exp(double); long __builtin_expect(long, long); @@ -217,12 +205,6 @@ int __builtin_parityll(unsigned long long); - int __builtin_popcount(unsigned int); - - int __builtin_popcountl(unsigned long); - - int __builtin_popcountll(unsigned long long); - double __builtin_powi(double, int); float __builtin_powif(float, int); -- GitLab From e784b4107b343ff8a2f2d25a0ee24c4a4b4ac365 Mon Sep 17 00:00:00 2001 From: Andre Maroneze <andre.oliveiramaroneze@cea.fr> Date: Thu, 30 Apr 2020 21:17:12 +0200 Subject: [PATCH 210/218] [analysis-scripts] Ensure argv array is properly terminated --- share/analysis-scripts/fc_stubs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/share/analysis-scripts/fc_stubs.c b/share/analysis-scripts/fc_stubs.c index ca1ed39a3ba..fad866f2160 100644 --- a/share/analysis-scripts/fc_stubs.c +++ b/share/analysis-scripts/fc_stubs.c @@ -12,7 +12,7 @@ static volatile int nondet; int eva_main() { int argc = Frama_C_interval(0, 5); char argv0[256], argv1[256], argv2[256], argv3[256], argv4[256]; - char *argv[5] = {argv0, argv1, argv2, argv3, argv4}; + char *argv[6] = {argv0, argv1, argv2, argv3, argv4, 0}; //@ loop unroll 5; for (int i = 0; i < 5; i++) { Frama_C_make_unknown(argv[i], 255); -- GitLab From 989018d826b12df5d636f58b0e5a2fe3de3b9e05 Mon Sep 17 00:00:00 2001 From: Virgile Prevosto <virgile.prevosto@m4x.org> Date: Wed, 29 Apr 2020 22:33:54 +0200 Subject: [PATCH 211/218] [lexer] Accept UCN characters as well as corresponding UTF-8 encoding --- src/kernel_internals/parsing/logic_lexer.mll | 48 +++++++++++++++----- src/libraries/utils/utf8_logic.mli | 3 ++ 2 files changed, 39 insertions(+), 12 deletions(-) diff --git a/src/kernel_internals/parsing/logic_lexer.mll b/src/kernel_internals/parsing/logic_lexer.mll index bc63b51001c..ca329de4aef 100644 --- a/src/kernel_internals/parsing/logic_lexer.mll +++ b/src/kernel_internals/parsing/logic_lexer.mll @@ -71,6 +71,37 @@ fun s -> try Hashtbl.find h s with Not_found -> IDENTIFIER s + let all_digits s = + let is_digit = + function + | '0'..'9' | 'a'..'f' | 'A'..'F' -> () + | _ -> raise Exit + in + try String.iter is_digit s; true with Exit -> false + + let is_ucn s = + if String.length s <= 2 || s.[0] <> '\\' then false else begin + match s.[1] with + | 'U' -> String.length s = 10 && all_digits (String.sub s 2 8) + | 'u' -> String.length s = 6 && all_digits (String.sub s 2 4) + | _ -> false + end + + let int_of_digit chr = + match chr with + | '0'..'9' -> (Char.code chr) - (Char.code '0') + | 'a'..'f' -> (Char.code chr) - (Char.code 'a') + 10 + | 'A'..'F' -> (Char.code chr) - (Char.code 'A') + 10 + | _ -> assert false + + (* assumes is_ucn s *) + let unicode_char s = + let code = ref 0 in + let add_digit c = code := 16 * !code + int_of_digit c in + String.iter add_digit (String.sub s 2 (String.length s - 2)); + let c = Utf8_logic.from_unichar !code in + find_utf8 c + let identifier, is_acsl_keyword = let all_kw = Hashtbl.create 37 in let c_kw = Hashtbl.create 37 in @@ -242,18 +273,11 @@ ]; fun lexbuf -> let s = lexeme lexbuf in - try Hashtbl.find h s with Not_found -> - if Logic_env.typename_status s then TYPENAME s - else - IDENTIFIER s - - - let int_of_digit chr = - match chr with - '0'..'9' -> (Char.code chr) - (Char.code '0') - | 'a'..'f' -> (Char.code chr) - (Char.code 'a') + 10 - | 'A'..'F' -> (Char.code chr) - (Char.code 'A') + 10 - | _ -> assert false + if is_ucn s then unicode_char s else begin + try Hashtbl.find h s with Not_found -> + if Logic_env.typename_status s then TYPENAME s + else IDENTIFIER s + end (* Update lexer buffer. *) let update_line_loc lexbuf line = diff --git a/src/libraries/utils/utf8_logic.mli b/src/libraries/utils/utf8_logic.mli index 2a3cd4d3d9c..449e20476bd 100644 --- a/src/libraries/utils/utf8_logic.mli +++ b/src/libraries/utils/utf8_logic.mli @@ -24,6 +24,9 @@ (** UTF-8 string for logic symbols. *) +(** given an unicode code point, returns the corresponding utf-8 encoding. *) +val from_unichar: int -> string + val forall : string val exists : string val eq : string -- GitLab From 96f9cdb753bf3e6e759348b358c3eec27ceee292 Mon Sep 17 00:00:00 2001 From: Virgile Prevosto <virgile.prevosto@m4x.org> Date: Wed, 29 Apr 2020 22:44:35 +0200 Subject: [PATCH 212/218] [tests] add test for ucn parsing --- tests/spec/oracle/ucn.res.oracle | 5 +++++ tests/spec/ucn.c | 1 + 2 files changed, 6 insertions(+) create mode 100644 tests/spec/oracle/ucn.res.oracle create mode 100644 tests/spec/ucn.c diff --git a/tests/spec/oracle/ucn.res.oracle b/tests/spec/oracle/ucn.res.oracle new file mode 100644 index 00000000000..ed305c24911 --- /dev/null +++ b/tests/spec/oracle/ucn.res.oracle @@ -0,0 +1,5 @@ +[kernel] Parsing tests/spec/ucn.c (with preprocessing) +/* Generated by Frama-C */ +/*@ lemma test_ucn: ∀ 𔹠b; b ≡ \true ⇔ b ≡ \true; + */ + diff --git a/tests/spec/ucn.c b/tests/spec/ucn.c new file mode 100644 index 00000000000..a57ceaed8d6 --- /dev/null +++ b/tests/spec/ucn.c @@ -0,0 +1 @@ +/*@ lemma test_ucn: \U00002200 \U0001D539 b; b \u21D4 \u00AC \U000000AC b; */ -- GitLab From 5aac7db6d2e0d27a9763609e100f8b7f84285cf1 Mon Sep 17 00:00:00 2001 From: Andre Maroneze <andre.maroneze@cea.fr> Date: Tue, 5 May 2020 10:16:04 +0200 Subject: [PATCH 213/218] Change default branch --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 28f5c441c2c..59d2c4b66b0 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -7,7 +7,7 @@ stages: variables: CURRENT: $CI_COMMIT_REF_NAME - DEFAULT: "master" + DEFAULT: "stable/scandium" FRAMA_CI_OPT: "--override frama-c:$CI_COMMIT_REF_NAME,$CI_COMMIT_SHA" check-no-old-frama-c: -- GitLab From 5c0d126d7c467a80fe47c5e52ab37e33c3032d2c Mon Sep 17 00:00:00 2001 From: Andre Maroneze <andre.oliveiramaroneze@cea.fr> Date: Tue, 5 May 2020 10:35:48 +0200 Subject: [PATCH 214/218] [Release/Doc] update release instructions --- doc/release/branch.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/release/branch.tex b/doc/release/branch.tex index a7c25e31dc2..ac7bb4a8631 100644 --- a/doc/release/branch.tex +++ b/doc/release/branch.tex @@ -32,7 +32,7 @@ opam pin add frama-ci-tools git@git.frama-c.com:frama-c/Frama-CI.git \item Run the command \begin{shell} frama-ci-create-branch --token=\$TOKEN \ ---new-branch=stable/release --default-branch +--name=stable/release --default-branch \end{shell} This command creates a branch \texttt{stable/release} for frama-c and for each plugin tested by the CI — and configures the CI to use these branches -- GitLab From 555096d90cd4170413e7f75250aa89b0e23f264f Mon Sep 17 00:00:00 2001 From: Andre Maroneze <andre.oliveiramaroneze@cea.fr> Date: Thu, 7 May 2020 08:58:44 +0200 Subject: [PATCH 215/218] [Doc] fix minor page number issue with hyperref Suggested by jens (https://bts.frama-c.com/view.php?id=2505) --- doc/frama-c-book.cls | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/frama-c-book.cls b/doc/frama-c-book.cls index 4e8120ed789..5cd0cc0e7df 100644 --- a/doc/frama-c-book.cls +++ b/doc/frama-c-book.cls @@ -34,7 +34,6 @@ prefix=framacbook@, \RequirePackage{lmodern} \RequirePackage[T1]{fontenc} \RequirePackage[utf8]{inputenc} -\RequirePackage[pdftex,pdfstartview=FitH]{hyperref} \RequirePackage{amssymb} \RequirePackage{xcolor} \RequirePackage[pdftex]{graphicx} @@ -45,6 +44,7 @@ prefix=framacbook@, \RequirePackage{fancyhdr} \RequirePackage{titlesec} \RequirePackage{upquote} +\RequirePackage[pdftex,pdfstartview=FitH]{hyperref} \ifusecc\RequirePackage{doclicense}\else\fi % -------------------------------------------------------------------------- % --- Page Layout --- -- GitLab From 2c2d4580dce7952be57a1b5b157a1364b3b56892 Mon Sep 17 00:00:00 2001 From: Andre Maroneze <andre.oliveiramaroneze@cea.fr> Date: Wed, 6 May 2020 21:38:46 +0200 Subject: [PATCH 216/218] [Plugins] fix experimental status of some plugins --- src/plugins/impact/options.ml | 2 +- src/plugins/report/report_parameters.ml | 2 +- src/plugins/server/server_parameters.ml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/plugins/impact/options.ml b/src/plugins/impact/options.ml index 4f837357460..57be52bd1a5 100644 --- a/src/plugins/impact/options.ml +++ b/src/plugins/impact/options.ml @@ -24,7 +24,7 @@ include Plugin.Register (struct let name = "impact" let shortname = "impact" - let help = "impact analysis (experimental)" + let help = "impact analysis" end) module Pragma = diff --git a/src/plugins/report/report_parameters.ml b/src/plugins/report/report_parameters.ml index 5b0cda998d8..6d20e0933f3 100644 --- a/src/plugins/report/report_parameters.ml +++ b/src/plugins/report/report_parameters.ml @@ -24,7 +24,7 @@ include Plugin.Register (struct let name = "report" let shortname = "report" - let help = "Properties Status Report (experimental)" + let help = "Properties Status Report" end) module Print = diff --git a/src/plugins/server/server_parameters.ml b/src/plugins/server/server_parameters.ml index 85c087ec0a2..be9b5da15c6 100644 --- a/src/plugins/server/server_parameters.ml +++ b/src/plugins/server/server_parameters.ml @@ -28,7 +28,7 @@ module P = Plugin.Register (struct let name = "Server" let shortname = "server" - let help = "Frama-C Request Server" + let help = "Frama-C Request Server (experimental)" end) include P -- GitLab From 58f216b90bb84e66308ad1400ea9bb960ae1aca2 Mon Sep 17 00:00:00 2001 From: Virgile Prevosto <virgile.prevosto@cea.fr> Date: Thu, 7 May 2020 11:16:35 +0200 Subject: [PATCH 217/218] Update Changelog following !2644 --- Changelog | 1 + 1 file changed, 1 insertion(+) diff --git a/Changelog b/Changelog index e64dc833070..6d873bd5647 100644 --- a/Changelog +++ b/Changelog @@ -17,6 +17,7 @@ Open Source Release <next-release> ################################## +-* Doc [2020/05/07] Fixes internal refs in generated pdfs (fixes #2505) o Kernel [2020/04/27] Plug-ins specific dirs now use Filepath instead of mere strings. - Eva [2020/04/10] Fixes the Memexec cache on functions with logical -- GitLab From bffdb276df4a06a11bc71dee02e8401ee0099de1 Mon Sep 17 00:00:00 2001 From: Virgile Prevosto <virgile.prevosto@cea.fr> Date: Thu, 7 May 2020 14:45:47 +0200 Subject: [PATCH 218/218] =?UTF-8?q?Missing=20Changelog=20entry=20from=20!2?= =?UTF-8?q?637=20(boo=20@buhler=20=F0=9F=98=AC)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Changelog | 1 + 1 file changed, 1 insertion(+) diff --git a/Changelog b/Changelog index 6d873bd5647..ea9cfbe042e 100644 --- a/Changelog +++ b/Changelog @@ -18,6 +18,7 @@ Open Source Release <next-release> ################################## -* Doc [2020/05/07] Fixes internal refs in generated pdfs (fixes #2505) +-* Kernel [2020/05/04] Accept UCN-encoded unicode char in ACSL (fixes #@849) o Kernel [2020/04/27] Plug-ins specific dirs now use Filepath instead of mere strings. - Eva [2020/04/10] Fixes the Memexec cache on functions with logical -- GitLab