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

- support of -e-acsl-check

- reject \valid
- improve efficiency for vstmt_aux
parent 5510359d
No related branches found
No related tags found
No related merge requests found
...@@ -18,13 +18,13 @@ ...@@ -18,13 +18,13 @@
(* for more details (enclosed in the file licenses/LGPLv2.1). *) (* for more details (enclosed in the file licenses/LGPLv2.1). *)
(* *) (* *)
(**************************************************************************) (**************************************************************************)
(*
let check () = let check () =
try try
ignore (Visit.do_visit false); Visitor.visitFramacFileSameGlobals (Visit.do_visit false) (Ast.get ());
true true
with Visit.Typing_error s -> with Visit.Typing_error s ->
Options.error "%s" s; Options.error ~current:true "%s" s;
false false
let check = let check =
...@@ -36,8 +36,8 @@ let check = ...@@ -36,8 +36,8 @@ let check =
check check
let fail_check () = let fail_check () =
try ignore (Visit.do_visit false) try Visitor.visitFramacFileSameGlobals (Visit.do_visit false) (Ast.get ());
with Visit.Typing_error s -> Options.abort "%s" s with Visit.Typing_error s -> Options.abort ~current:true "%s" s
let fail_check = let fail_check =
Dynamic.register Dynamic.register
...@@ -46,7 +46,7 @@ let fail_check = ...@@ -46,7 +46,7 @@ let fail_check =
"fail_check" "fail_check"
(Datatype.func Datatype.unit Datatype.unit) (Datatype.func Datatype.unit Datatype.unit)
fail_check fail_check
*)
module Resulting_projects = module Resulting_projects =
State_builder.Hashtbl State_builder.Hashtbl
(Datatype.String.Hashtbl) (Datatype.String.Hashtbl)
...@@ -65,7 +65,7 @@ let generate_code = ...@@ -65,7 +65,7 @@ let generate_code =
let visit prj = Visit.do_visit ~prj true in let visit prj = Visit.do_visit ~prj true in
File.create_rebuilt_project_from_visitor name visit File.create_rebuilt_project_from_visitor name visit
with Visit.Typing_error s -> with Visit.Typing_error s ->
Options.abort "%s" s) Options.abort ~current:true "%s" s)
let generate_code = let generate_code =
Dynamic.register Dynamic.register
...@@ -77,7 +77,7 @@ let generate_code = ...@@ -77,7 +77,7 @@ let generate_code =
let main () = let main () =
let s = Options.Project_name.get () in let s = Options.Project_name.get () in
if s = "" then begin(* if Options.Check.get () then fail_check ()*) end if s = "" then begin if Options.Check.get () then fail_check () end
else ignore (generate_code s) else ignore (generate_code s)
let () = Db.Main.extend main let () = Db.Main.extend main
......
...@@ -32,7 +32,7 @@ module Check = ...@@ -32,7 +32,7 @@ module Check =
False False
(struct (struct
let option_name = "-e-acsl-check" let option_name = "-e-acsl-check"
let help = "only perform E-ACSL type checking" let help = "abort on E-ACSL type checking error"
let kind = `Correctness let kind = `Correctness
end) end)
......
tests/e-acsl-reject/valid.i:5:[e-acsl] user error: invalid E-ACSL construct \valid.
[kernel] Plug-in e-acsl aborted because of invalid user input.
/* run.config
COMMENT: \valid */
void main(int *x) {
/*@ assert \valid(x); */
return;
}
/* run.config /* run.config
COMMENT: TODO: this test is incomplete COMMENT: TODO: this test is incomplete
COMMENT: comparison operators */ COMMENT: comparison operators */
void main() { void main() {
/* /\*@ assert "toto" < "titi"; *\/ */ /* /\*@ assert "toto" < "titi"; *\/ */
/* /\*@ assert "toto" > "titi"; *\/ */ /* /\*@ assert "toto" > "titi"; *\/ */
......
...@@ -33,7 +33,8 @@ let mk_call ?result fname args = ...@@ -33,7 +33,8 @@ let mk_call ?result fname args =
mkStmt ~valid_sid:true (Instr(Call(result, f, args, unknown_loc))) mkStmt ~valid_sid:true (Instr(Call(result, f, args, unknown_loc)))
exception Typing_error of string exception Typing_error of string
let error s = raise (Typing_error s) let type_error s = raise (Typing_error s)
let not_yet s = let not_yet s =
Options.not_yet_implemented "construct `%s' is not yet supported" s Options.not_yet_implemented "construct `%s' is not yet supported" s
...@@ -77,8 +78,7 @@ let apply_mpz_set v cst = ...@@ -77,8 +78,7 @@ let apply_mpz_set v cst =
"set_str", "set_str",
[ mkString ~loc:unknown_loc (Int64.to_string n); [ mkString ~loc:unknown_loc (Int64.to_string n);
integer ~loc:unknown_loc 10 (* decimal base for the number given as integer ~loc:unknown_loc 10 (* decimal base for the number given as
string *) ] string *) ])
)
| CStr _ | CWStr _ | CChr _ | CReal _ | CEnum _ -> | CStr _ | CWStr _ | CChr _ | CReal _ | CEnum _ ->
assert false assert false
in in
...@@ -280,7 +280,7 @@ let rec named_predicate_to_revexp is_global p = match p.content with ...@@ -280,7 +280,7 @@ let rec named_predicate_to_revexp is_global p = match p.content with
| Pexists _ -> not_yet "\\exists" | Pexists _ -> not_yet "\\exists"
| Pold _ -> not_yet "\\old" | Pold _ -> not_yet "\\old"
| Pat _ -> not_yet "\\at" | Pat _ -> not_yet "\\at"
| Pvalid _ -> not_yet "\\valid" | Pvalid _ -> type_error "\\valid"
| Pvalid_index _ -> not_yet "\\valid_index" | Pvalid_index _ -> not_yet "\\valid_index"
| Pvalid_range _ -> not_yet "\\valid_range" | Pvalid_range _ -> not_yet "\\valid_range"
| Pfresh _ -> not_yet "\\fresh" | Pfresh _ -> not_yet "\\fresh"
...@@ -291,24 +291,29 @@ let rec named_predicate_to_revexp is_global p = match p.content with ...@@ -291,24 +291,29 @@ let rec named_predicate_to_revexp is_global p = match p.content with
statement (if any) for runtime assertion checking *) statement (if any) for runtime assertion checking *)
(* ************************************************************************** *) (* ************************************************************************** *)
let convert_named_predicate is_global generate p = let convert_named_predicate is_global p =
if generate then let e = named_predicate_to_revexp is_global p in
let e = named_predicate_to_revexp is_global p in New_block.push_at_end (mk_if e p)
New_block.push_at_end (mk_if e p)
let convert_annotation is_global annot =
let convert_annotation is_global generate annot = match annot.annot_content with try
| AAssert(_l, p) -> convert_named_predicate is_global generate p match annot.annot_content with
| AStmtSpec _ -> not_yet "stmt spec" | AAssert(_l, p) -> convert_named_predicate is_global p
| AInvariant _ -> not_yet "invariant" | AStmtSpec _ -> not_yet "stmt spec"
| AVariant _ -> not_yet "variant" | AInvariant _ -> not_yet "invariant"
| AAssigns _ -> not_yet "assigns" | AVariant _ -> not_yet "variant"
| APragma _ -> not_yet "pragma" | AAssigns _ -> not_yet "assigns"
| APragma _ -> not_yet "pragma"
let convert_rooted is_global generate (User a | AI(_, a)) = with Typing_error s ->
convert_annotation is_global generate a let msg = Format.sprintf "invalid E-ACSL construct %s." s in
if Options.Check.get () then raise (Typing_error msg)
let convert_before_after is_global generate (Before r | After r) = else Options.warning ~current:true "%s@\nignoring annotation." msg
convert_rooted is_global generate r
let convert_rooted is_global (User a | AI(_, a)) =
convert_annotation is_global a
let convert_before_after is_global (Before r | After r) =
convert_rooted is_global r
(* ************************************************************************** *) (* ************************************************************************** *)
(* Visitor *) (* Visitor *)
...@@ -327,27 +332,29 @@ class e_acsl_visitor prj generate = object (self) ...@@ -327,27 +332,29 @@ class e_acsl_visitor prj generate = object (self)
val mutable gen_vars = [] val mutable gen_vars = []
method vglob g = method vglob g =
(* [TODO] must handle constant expression and global variables
(mpz_init and clear [and mpz_set_* for constants]) *)
if !first_global then begin if !first_global then begin
first_global := false; first_global := false;
ChangeDoChildrenPost([ g ], fun l -> e_acsl_header () :: l) ChangeDoChildrenPost([ g ], fun l -> e_acsl_header () :: l)
end else end else
DoChildren DoChildren
(* [TODO] handle integer constants in initializer
BUT almost impossible without a main entry point *)
(* method vinit v off i = assert false *)
method vfundec f = method vfundec f =
let add_gen_vars f = f.slocals <- gen_vars @ f.slocals; f in let add_gen_vars f = f.slocals <- gen_vars @ f.slocals; f in
ChangeDoChildrenPost(f, add_gen_vars) ChangeDoChildrenPost(f, add_gen_vars)
method vstmt_aux stmt = method vstmt_aux stmt =
Options.debug ~level:2 "proceeding stmt %d@." stmt.sid; (* Options.debug ~level:2 "proceeding stmt %d@." stmt.sid;*)
let is_global = match self#current_kinstr with let is_global = match self#current_kinstr with
| Kglobal -> true | Kglobal -> true
| Kstmt _ -> false | Kstmt _ -> false
in in
List.iter Annotations.single_iter_stmt
(fun ba -> convert_before_after is_global generate ba) (fun ba -> convert_before_after is_global ba)
(Annotations.get_all_annotations stmt); stmt;
(* new_block and new_vars is set by convert_before_after *) (* new_block and new_vars is set by convert_before_after *)
let is_empty_block = New_block.is_empty () in let is_empty_block = New_block.is_empty () in
let new_vars = New_vars.finalize () in let new_vars = New_vars.finalize () in
...@@ -379,9 +386,9 @@ class e_acsl_visitor prj generate = object (self) ...@@ -379,9 +386,9 @@ class e_acsl_visitor prj generate = object (self)
end end
let do_visit ?(prj=Project.current ()) generate = let do_visit ?(prj=Project.current ()) generate =
let prj = new e_acsl_visitor prj generate in let vis = new e_acsl_visitor prj generate in
first_global := true; first_global := true;
(prj :> Visitor.frama_c_visitor) (vis :> Visitor.frama_c_visitor)
(* (*
Local Variables: Local Variables:
......
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