From 00d652d1145f727493338642eb963a177e334af5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Bobot?= <francois.bobot@cea.fr> Date: Wed, 27 Sep 2017 01:08:16 +0200 Subject: [PATCH] [Eva] fix logic assigns - TODO mark not defined functions particularly --- .../value/domains/traces/traces_domain.ml | 57 +++++--- tests/value/traces/oracle/test1.res.oracle | 136 +++++++++++------- tests/value/traces/oracle/test2.res.oracle | 4 +- tests/value/traces/test1.i | 5 +- 4 files changed, 124 insertions(+), 78 deletions(-) diff --git a/src/plugins/value/domains/traces/traces_domain.ml b/src/plugins/value/domains/traces/traces_domain.ml index 334f722ea51..9a00862d791 100644 --- a/src/plugins/value/domains/traces/traces_domain.ml +++ b/src/plugins/value/domains/traces/traces_domain.ml @@ -135,6 +135,10 @@ type t = { start : int; current : int; graph : Graph.t} (* Lattice structure for the abstract state above *) module Traces = struct + (** impossible for normal values start must be bigger than current *) + let empty = { start = 0; current = 0; graph = Graph.empty } + let top = { start = 0; current = -1; graph = Graph.empty } + (* Frama-C "datatype" for type [inout] *) include Datatype.Make_with_collections(struct include Datatype.Serializable_undefined @@ -161,7 +165,9 @@ module Traces = struct let equal = Datatype.from_compare let pretty fmt m = - Format.fprintf fmt "@[<hv>@[start: %i@]@ %a@ @[current: %i]" m.start Graph.pretty m.graph m.current + if m == top then Format.fprintf fmt "TOP" + else + Format.fprintf fmt "@[<hv>@[start: %i@]@ %a@ @[current: %i]" m.start Graph.pretty m.graph m.current let hash m = Hashtbl.seeded_hash m.start (Hashtbl.seeded_hash m.current (Graph.hash m.graph)) @@ -170,10 +176,6 @@ module Traces = struct end) - (** impossible for normal values start must be bigger than current *) - let empty = { start = 0; current = 0; graph = Graph.empty } - let top = { start = 0; current = -1; graph = Graph.empty } - let view m = if m == top then `Top else @@ -202,18 +204,20 @@ module Traces = struct ~decide:merge_edge g1 g2 let add_edge c edge = - let n = Edge.Counter.next () in - let e = match edge with - | Assign (_,loc,typ,exp) -> Assign(n,loc,typ,exp) - | Assume (_,a,b) -> Assume(n,a,b) - | EnterScope (_,vs) -> EnterScope(n,vs) - | LeaveScope (_,vs) -> LeaveScope(n,vs) - | Msg (_,s) -> Msg(n,s) - | Top -> Top - in - let m = Graph.singleton c.current [e] in - let g = join_graph m c.graph in - { start = c.start; current = n; graph = g} + if c == top then c + else + let n = Edge.Counter.next () in + let e = match edge with + | Assign (_,loc,typ,exp) -> Assign(n,loc,typ,exp) + | Assume (_,a,b) -> Assume(n,a,b) + | EnterScope (_,vs) -> EnterScope(n,vs) + | LeaveScope (_,vs) -> LeaveScope(n,vs) + | Msg (_,s) -> Msg(n,s) + | Top -> Top + in + let m = Graph.singleton c.current [e] in + let g = join_graph m c.graph in + { start = c.start; current = n; graph = g} let is_included c1 c2 = @@ -330,7 +334,8 @@ module Internal = struct `Value(Traces.add_edge state (Assume(0,e,pos))) let start_call _stmt call _valuation state = - let msg = Format.asprintf "start_call: %s" (Kernel_function.get_name call.Eval.kf) in + let msg = Format.asprintf "start_call: %s (%b)" (Kernel_function.get_name call.Eval.kf) + (Kernel_function.is_definition call.Eval.kf) in let state = Traces.add_edge state (Msg(0,msg)) in let formals = List.map (fun arg -> arg.Eval.formal) call.Eval.arguments in let state = Traces.add_edge state (EnterScope(0,formals)) in @@ -369,11 +374,21 @@ module Internal = struct let introduce_globals _vars state = Traces.add_edge state (Msg(0,"introduce globals")) let initialize_variable lv _ ~initialized:_ _ state = Traces.add_edge state (Msg(0,Format.asprintf "initialize variable: %a" Printer.pp_lval lv )) - let initialize_variable_using_type _ _ state = - Traces.add_edge state (Msg(0,"initialize variable using type")) + let initialize_variable_using_type init_kind varinfo state = + let msg = Format.asprintf "initialize@ variable@ using@ type@ %a@ %a" + (fun fmt init_kind -> + match init_kind with + | Abstract_domain.Main_Formal -> Format.pp_print_string fmt "Main_Formal" + | Abstract_domain.Library_Global -> Format.pp_print_string fmt "Library_Global" + | Abstract_domain.Spec_Return kf -> Format.fprintf fmt "Spec_Return(%s)" (Kernel_function.get_name kf)) + init_kind + Cil_datatype.Varinfo.pretty varinfo + in + Traces.add_edge state (Msg(0,msg)) (* TODO *) - let logic_assign _assign _location ~pre:_ _state = top + let logic_assign _assign _location ~pre:_ state = + Traces.add_edge state (Msg(0,"logic assign")) (* Logic *) let evaluate_predicate _ _ _ = Alarmset.Unknown diff --git a/tests/value/traces/oracle/test1.res.oracle b/tests/value/traces/oracle/test1.res.oracle index ab55a710790..48b3a822116 100644 --- a/tests/value/traces/oracle/test1.res.oracle +++ b/tests/value/traces/oracle/test1.res.oracle @@ -1,76 +1,104 @@ [kernel] Parsing tests/value/traces/test1.i (no preprocessing) +tests/value/traces/test1.i:8:[kernel] warning: Calling undeclared function Frama_C_interval. Old style K&R code? [value] Analyzing a complete application starting at main [value] Computing initial state [value] Initial state computed [value:initial-state] Values of globals at initialization - -tests/value/traces/test1.i:14:[value] Frama_C_dump_each: + g ∈ {42} +[value] computing for function Frama_C_interval <- main. + Called from tests/value/traces/test1.i:8. +tests/value/traces/test1.i:8:[kernel] warning: Neither code nor specification for function Frama_C_interval, generating default assigns from the prototype +[value] using specification for function Frama_C_interval +[value] Done for function Frama_C_interval +tests/value/traces/test1.i:17:[value] Frama_C_dump_each: # Cvalue domain: + g ∈ {42} c ∈ [--..--] - tmp ∈ {4; 5} + tmp ∈ {5; 45} # Value.Traces_domain.Traces.t: start: 0 - {[ 0 -> ([ initialize variable using type -> 1 ]) - 1 -> ([ EnterScope: tmp -> 2 ]) - 2 -> ([ Assign: tmp = 0 -> 3 ]) - 3 -> ([ Assume: c false -> 4; Assume: c true -> 5 ]) - 4 -> ([ Assign: tmp = 2 -> 8 ]) - 5 -> ([ Assign: tmp = 1 -> 7 ]) - 7 -> ([ EnterScope: i -> 13 ]) - 8 -> ([ EnterScope: i -> 10 ]) - 10 -> ([ initialize variable: i -> 11 ]) - 11 -> ([ Assign: i = 0 -> 12 ]) - 12 -> ([ enter_loop -> 18 ]) - 13 -> ([ initialize variable: i -> 14 ]) - 14 -> ([ Assign: i = 0 -> 15 ]) - 15 -> ([ enter_loop -> 17 ]) - 17 -> ([ Assume: i < 3 true -> 20 ]) - 18 -> ([ Assume: i < 3 true -> 21 ]) - 20 -> ([ Assign: tmp = tmp + 1 -> 23 ]) - 21 -> ([ Assign: tmp = tmp + 1 -> 22 ]) - 22 -> ([ Assign: i = i + 1 -> 24 ]) - 23 -> ([ Assign: i = i + 1 -> 25 ]) - 24 -> ([ incr_loop_counter -> 28 ]) - 25 -> ([ incr_loop_counter -> 27 ]) - 27 -> ([ Assume: i < 3 true -> 31 ]) - 28 -> ([ Assume: i < 3 true -> 32 ]) - 31 -> ([ Assign: tmp = tmp + 1 -> 34 ]) - 32 -> ([ Assign: tmp = tmp + 1 -> 33 ]) - 33 -> ([ Assign: i = i + 1 -> 36 ]) - 34 -> ([ Assign: i = i + 1 -> 35 ]) - 35 -> ([ incr_loop_counter -> 40 ]) - 36 -> ([ incr_loop_counter -> 39 ]) - 39 -> ([ Assume: i < 3 true -> 43 ]) - 40 -> ([ Assume: i < 3 true -> 44 ]) - 43 -> ([ Assign: tmp = tmp + 1 -> 46 ]) - 44 -> ([ Assign: tmp = tmp + 1 -> 45 ]) - 45 -> ([ Assign: i = i + 1 -> 48 ]) - 46 -> ([ Assign: i = i + 1 -> 47 ]) - 47 -> ([ incr_loop_counter -> 52 ]) - 48 -> ([ incr_loop_counter -> 51 ]) - 51 -> ([ Assume: i < 3 false -> 55 ]) - 52 -> ([ Assume: i < 3 false -> 56 ]) - 55 -> ([ leave_loop -> 58 ]) - 56 -> ([ leave_loop -> 57 ]) - 57 -> ([ LeaveScope: i -> 60 ]) - 58 -> ([ LeaveScope: i -> 59 ]) - 59 -> ([ join -> 61 ]) - 60 -> ([ join -> 61 ]) ]} - current: 61] + {[ 0 -> ([ introduce globals -> 1 ]) + 1 -> ([ initialize variable: g -> 2 ]) + 2 -> ([ Assign: g = 42 -> 3 ]) + 3 -> ([ initialize variable using type Main_Formal + c -> 4 ]) + 4 -> ([ EnterScope: tmp -> 5 ]) + 5 -> ([ start_call: Frama_C_interval (false) -> 6 ]) + 6 -> ([ EnterScope: x_0 x_1 -> 7 ]) + 7 -> ([ Assign: x_0 = 0 -> 8 ]) + 8 -> ([ Assign: x_1 = 1 -> 9 ]) + 9 -> ([ EnterScope: \result<Frama_C_interval> -> 10 ]) + 10 -> ([ initialize variable using type Spec_Return(Frama_C_interval) + \result<Frama_C_interval> -> 11 ]) + 11 -> ([ logic assign -> 12 ]) + 12 -> ([ LeaveScope: x_0 x_1 -> 13 ]) + 13 -> ([ finalize_call: Frama_C_interval -> 14 ]) + 14 -> ([ Assign: c = \result<Frama_C_interval> -> 15 ]) + 15 -> ([ LeaveScope: \result<Frama_C_interval> -> 16 ]) + 16 -> ([ Assign: tmp = 0 -> 17 ]) + 17 -> ([ Assume: c false -> 18; Assume: c true -> 19 ]) + 18 -> ([ Assign: tmp = 2 -> 22 ]) + 19 -> ([ Assign: tmp = g -> 21 ]) + 21 -> ([ EnterScope: i -> 27 ]) + 22 -> ([ EnterScope: i -> 24 ]) + 24 -> ([ initialize variable: i -> 25 ]) + 25 -> ([ Assign: i = 0 -> 26 ]) + 26 -> ([ enter_loop -> 32 ]) + 27 -> ([ initialize variable: i -> 28 ]) + 28 -> ([ Assign: i = 0 -> 29 ]) + 29 -> ([ enter_loop -> 31 ]) + 31 -> ([ Assume: i < 3 true -> 34 ]) + 32 -> ([ Assume: i < 3 true -> 35 ]) + 34 -> ([ Assign: tmp = tmp + 1 -> 37 ]) + 35 -> ([ Assign: tmp = tmp + 1 -> 36 ]) + 36 -> ([ Assign: i = i + 1 -> 38 ]) + 37 -> ([ Assign: i = i + 1 -> 39 ]) + 38 -> ([ incr_loop_counter -> 42 ]) + 39 -> ([ incr_loop_counter -> 41 ]) + 41 -> ([ Assume: i < 3 true -> 45 ]) + 42 -> ([ Assume: i < 3 true -> 46 ]) + 45 -> ([ Assign: tmp = tmp + 1 -> 48 ]) + 46 -> ([ Assign: tmp = tmp + 1 -> 47 ]) + 47 -> ([ Assign: i = i + 1 -> 50 ]) + 48 -> ([ Assign: i = i + 1 -> 49 ]) + 49 -> ([ incr_loop_counter -> 54 ]) + 50 -> ([ incr_loop_counter -> 53 ]) + 53 -> ([ Assume: i < 3 true -> 57 ]) + 54 -> ([ Assume: i < 3 true -> 58 ]) + 57 -> ([ Assign: tmp = tmp + 1 -> 60 ]) + 58 -> ([ Assign: tmp = tmp + 1 -> 59 ]) + 59 -> ([ Assign: i = i + 1 -> 62 ]) + 60 -> ([ Assign: i = i + 1 -> 61 ]) + 61 -> ([ incr_loop_counter -> 66 ]) + 62 -> ([ incr_loop_counter -> 65 ]) + 65 -> ([ Assume: i < 3 false -> 69 ]) + 66 -> ([ Assume: i < 3 false -> 70 ]) + 69 -> ([ leave_loop -> 72 ]) + 70 -> ([ leave_loop -> 71 ]) + 71 -> ([ LeaveScope: i -> 74 ]) + 72 -> ([ LeaveScope: i -> 73 ]) + 73 -> ([ join -> 75 ]) + 74 -> ([ join -> 75 ]) ]} + current: 75] ==END OF DUMP== [value] Recording results for main [value] done for function main [value] ====== VALUES COMPUTED ====== [value:final-states] Values at end of function main: - tmp ∈ {4; 5} + c ∈ [--..--] + tmp ∈ {5; 45} [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: + \result FROM x_0; x_1 [from] Function main: - \result FROM c + \result FROM \nothing [from] ====== END OF DEPENDENCIES ====== [inout] Out (internal) for function main: - tmp; i + c; tmp; i [inout] Inputs for function main: - \nothing + g diff --git a/tests/value/traces/oracle/test2.res.oracle b/tests/value/traces/oracle/test2.res.oracle index 7a40e8f876e..4bb771e5685 100644 --- a/tests/value/traces/oracle/test2.res.oracle +++ b/tests/value/traces/oracle/test2.res.oracle @@ -24,8 +24,8 @@ tests/value/traces/test2.i:20:[value] Frama_C_dump_each: 3 -> ([ Assume: c false -> 4; Assume: c true -> 5 ]) 4 -> ([ Assign: tmp = 2 -> 8 ]) 5 -> ([ Assign: tmp = 1 -> 7 ]) - 7 -> ([ start_call: loop -> 9 ]) - 8 -> ([ start_call: loop -> 55 ]) + 7 -> ([ start_call: loop (true) -> 9 ]) + 8 -> ([ start_call: loop (true) -> 55 ]) 9 -> ([ EnterScope: j -> 10 ]) 10 -> ([ Assign: j = tmp -> 11 ]) 11 -> ([ EnterScope: i -> 12 ]) diff --git a/tests/value/traces/test1.i b/tests/value/traces/test1.i index 968a978ea61..5cedf0de7d9 100644 --- a/tests/value/traces/test1.i +++ b/tests/value/traces/test1.i @@ -2,10 +2,13 @@ STDOPT: #"-eva-traces-domain -value-msg-key d-traces -slevel 10" */ +int g = 42; + int main(int c){ + c = Frama_C_interval(0,1); int tmp; tmp = 0; - if (c) tmp = 1; + if (c) tmp = g; else tmp = 2; for(int i = 0; i < 3; i++){ tmp ++; -- GitLab