Skip to content
Snippets Groups Projects
Commit d7616871 authored by Julien Signoles's avatar Julien Signoles
Browse files

[e-acsl] ensure that terms of the E-ACSL ast are never shared before code...

[e-acsl] ensure that terms of the E-ACSL ast are never shared before code injection. This invariant is required for E-ACSL typing soundness
parent 89741173
No related branches found
No related tags found
No related merge requests found
...@@ -19,6 +19,8 @@ ...@@ -19,6 +19,8 @@
# configure configure # configure configure
############################################################################### ###############################################################################
-* E-ACSL [2020/01/06] Fix typing bug in presence of variable-length
arrays that may lead to incorrect generated code.
-* E-ACSL [2019/12/04] Fix bug with compiler built-ins. -* E-ACSL [2019/12/04] Fix bug with compiler built-ins.
############################ ############################
......
...@@ -182,42 +182,37 @@ module Memo: sig ...@@ -182,42 +182,37 @@ module Memo: sig
val clear: unit -> unit val clear: unit -> unit
end = struct end = struct
module H = Hashtbl.Make(struct (* The comparison over terms is the physical equality. It cannot be the
type t = term structural one (given by [Cil_datatype.Term.equal]) because the very same
(* The comparison over terms is the physical equality. It cannot be the term can be used in 2 different contexts which lead to different casts.
structural one (given by [Cil_datatype.Term.equal]) because the very
same term can be used in 2 different contexts which lead to different By construction (see prepare_ast.ml), there are no physically equal terms
casts. in the E-ACSL's generated AST. Consequently the memoisation should be fully
useless. However:
By construction, there are no physically equal terms in the AST - type info of many terms are accessed several times
built by Cil. Consequently the memoisation should be fully - the translation of E-ACSL guarded quantifications generates
useless. However the translation of E-ACSL guarded quantification new terms (see module {!Quantif}) which must be typed. The term
generates new terms (see module {!Quantif}) which must be typed. The corresponding to the bound variable [x] is actually used twice: once in the
term corresponding to the bound variable [x] is actually used twice: guard and once for encoding [x+1] when incrementing it. The memoization is
once in the guard and once for encoding [x+1] when incrementing it. The only useful here and indeed prevent the generation of one extra variable in
memoization is only useful here and indeed prevent the generation of some cases. *)
one extra variable in some cases. *) let tbl = Misc.Id_term.Hashtbl.create 97
let equal (t1:term) t2 = t1 == t2
let hash = Cil_datatype.Term.hash
end)
let tbl = H.create 97
let get t = let get t =
try H.find tbl t try Misc.Id_term.Hashtbl.find tbl t
with Not_found -> with Not_found ->
Options.fatal Options.fatal
"[typing] type of term '%a' was never computed." "[typing] type of term '%a' was never computed."
Printer.pp_term t Printer.pp_term t
let memo f t = let memo f t =
try H.find tbl t try Misc.Id_term.Hashtbl.find tbl t
with Not_found -> with Not_found ->
let x = f t in let x = f t in
H.add tbl t x; Misc.Id_term.Hashtbl.add tbl t x;
x x
let clear () = H.clear tbl let clear () = Misc.Id_term.Hashtbl.clear tbl
end end
......
...@@ -219,6 +219,19 @@ let name_of_binop = function ...@@ -219,6 +219,19 @@ let name_of_binop = function
| MinusA -> "sub" | MinusA -> "sub"
| MinusPP | MinusPI | IndexPI | PlusPI -> assert false | MinusPP | MinusPI | IndexPI | PlusPI -> assert false
module Id_term =
Datatype.Make_with_collections
(struct
include Cil_datatype.Term
let name = "E_ACSL.Id_term"
let compare (t1:term) t2 =
if t1 == t2 then 0 else Cil_datatype.Term.compare t1 t2
let equal (t1:term) t2 = t1 == t2
let structural_descr = Structural_descr.t_abstract
let rehash = Datatype.identity
let mem_project = Datatype.never_any_project
end)
(* (*
Local Variables: Local Variables:
compile-command: "make -C ../../../../.." compile-command: "make -C ../../../../.."
......
...@@ -102,6 +102,9 @@ val name_of_binop: binop -> string ...@@ -102,6 +102,9 @@ val name_of_binop: binop -> string
val finite_min_and_max: Ival.t -> Integer.t * Integer.t val finite_min_and_max: Ival.t -> Integer.t * Integer.t
(** [finite_min_and_max i] takes the finite ival [i] and returns its bounds *) (** [finite_min_and_max i] takes the finite ival [i] and returns its bounds *)
module Id_term: Datatype.S_with_collections with type t = term
(** datatype for terms that relies on physical equality *)
(* (*
Local Variables: Local Variables:
compile-command: "make -C ../../../../.." compile-command: "make -C ../../../../.."
......
...@@ -69,6 +69,17 @@ class prepare_visitor = object (self) ...@@ -69,6 +69,17 @@ class prepare_visitor = object (self)
val mutable has_new_stmt_in_fundec = false val mutable has_new_stmt_in_fundec = false
val mutable has_new_stmt = false val mutable has_new_stmt = false
val terms = Misc.Id_term.Hashtbl.create 7
method !vterm _t =
Cil.DoChildrenPost
(fun t ->
if Misc.Id_term.Hashtbl.mem terms t then
(* remove term sharing for soundness of E-ACSL typing
(see typing.ml) *)
{ t with term_node = t.term_node }
else
t)
(* Add align attributes to local variables (required by temporal analysis) *) (* Add align attributes to local variables (required by temporal analysis) *)
method !vblock _ = method !vblock _ =
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
(** Prepare AST for E-ACSL generation. (** Prepare AST for E-ACSL generation.
So for this module performs the following tasks: So for this module performs the following tasks:
- remove term sharing
- move declarations of variables declared in the bodies of switch - move declarations of variables declared in the bodies of switch
statements to upper scopes; statements to upper scopes;
- store what is necessary to translate in [Keep_status] - store what is necessary to translate in [Keep_status]
......
/* run.config /* run.config
COMMENT: Check variable-length arrays COMMENT: check variable-length arrays
*/ */
int LEN = 10; int LEN = 10;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment