Skip to content
Snippets Groups Projects
Commit 5c25260d authored by Allan Blanchard's avatar Allan Blanchard Committed by Virgile Prevosto
Browse files

[ghost] Simplify function copy for ghost CFG checking

parent 33ae1831
No related branches found
No related tags found
No related merge requests found
...@@ -32,14 +32,16 @@ let error = Kernel.warning ~wkey:Kernel.wkey_ghost_bad_use ...@@ -32,14 +32,16 @@ let error = Kernel.warning ~wkey:Kernel.wkey_ghost_bad_use
let annot_attr = "has_annot" let annot_attr = "has_annot"
(* For no ghost project, we add an attribute each stmt that has annotations. *) (* During the creation of the no ghost AST, when a stmt has some annotation,
we add an attribute to its copy.
*)
let has_annot stmt = let has_annot stmt =
Annotations.code_annot stmt <> [] || Annotations.code_annot stmt <> [] ||
Cil.hasAttribute annot_attr stmt.sattr Cil.hasAttribute annot_attr stmt.sattr
let noGhostBlock b = let noGhostFD prj fd =
let noGhostVisitor = object (self) let visitor = object (self)
inherit genericCilVisitor (refresh (Project.current())) inherit genericCilVisitor (refresh prj)
method private original = Get_orig.stmt self#behavior method private original = Get_orig.stmt self#behavior
...@@ -53,19 +55,19 @@ let noGhostBlock b = ...@@ -53,19 +55,19 @@ let noGhostBlock b =
begin match s.skind with begin match s.skind with
| Switch(e, block, cases, loc) -> | Switch(e, block, cases, loc) ->
let cases = List.filter let cases = List.filter
(fun s -> not (self#original s).ghost) cases (fun s -> not (self#original s).ghost) cases
in in
s.skind <- Switch(e, block, cases, loc) ; s.skind <- Switch(e, block, cases, loc) ;
DoChildren DoChildren
| _ -> | _ ->
let original = self#original s in let o = self#original s in
s.sattr <- if has_annot original then [AttrAnnot annot_attr] else [] ; s.sattr <- if has_annot o then [AttrAnnot annot_attr] else [] ;
DoChildren DoChildren
end end
method getBehavior () = self#behavior method getBehavior () = self#behavior
end in end in
(visitCilBlock (noGhostVisitor :> cilVisitor) b), (noGhostVisitor#getBehavior ()) (visitCilFunction (visitor :> cilVisitor) fd), (visitor#getBehavior ())
type follower = type follower =
(* For a stmt, an "Infinite" follower means that following skip instructions (* For a stmt, an "Infinite" follower means that following skip instructions
...@@ -74,7 +76,11 @@ type follower = ...@@ -74,7 +76,11 @@ type follower =
let sync stmt = let sync stmt =
match stmt.skind with match stmt.skind with
(* We ignore blocks: their successors are their 1st stmt so we visit them *) (* We do not synchronize on a block: its successor is the first statement that
it contains. Thus, we will synchronize later, on the first interesting stmt
we can reach when we enter the block.
*)
(* Note that a stmt with an annotation is always interesting. *)
| Instr(Skip(_)) | Block(_) | Continue(_) | Break(_) -> has_annot stmt | Instr(Skip(_)) | Block(_) | Continue(_) | Break(_) -> has_annot stmt
| _ -> true | _ -> true
...@@ -150,26 +156,21 @@ let checkGhostCFG bhv withGhostStart noGhost = ...@@ -150,26 +156,21 @@ let checkGhostCFG bhv withGhostStart noGhost =
in in
ignore (do_check StmtSet.empty withGhostStart noGhost) ignore (do_check StmtSet.empty withGhostStart noGhost)
let checkGhostCFGInFun (fd : fundec) = let checkGhostCFGInFun prj fd =
if fd.svar.vghost then () if fd.svar.vghost then ()
else begin else begin
let noGhost, bhv = noGhostBlock fd.sbody in let noGhostFD, bhv = noGhostFD prj fd in
let vname = "__ghost_cfg_handler_" ^ fd.svar.vname in
let vi = { fd.svar with vid = -1 ; vname ; vsource = false } in
let noGhostFD = {
svar = vi ; smaxid = 0; slocals = []; sformals = [];
smaxstmtid = None; sallstmts = []; sspec = empty_funspec();
sbody = noGhost;
} in
Cfg.clearCFGinfo ~clear_id:false noGhostFD ; Cfg.clearCFGinfo ~clear_id:false noGhostFD ;
Cfg.cfgFun noGhostFD ; Cfg.cfgFun noGhostFD ;
checkGhostCFG bhv (List.hd fd.sbody.bstmts) (List.hd noGhostFD.sbody.bstmts) checkGhostCFG bhv (List.hd fd.sbody.bstmts) (List.hd noGhostFD.sbody.bstmts)
end end
let checkGhostCFGInFile (f : file) = let checkGhostCFGInFile (f : file) =
let project = Project.create "NO_GHOST" in
Cil.iterGlobals f (function Cil.iterGlobals f (function
| GFun (fd, _) -> checkGhostCFGInFun fd | GFun (fd, _) -> checkGhostCFGInFun project fd
| _ -> ()) | _ -> ()) ;
Project.remove ~project ()
let transform_category = let transform_category =
File.register_code_transformation_category "Ghost CFG checking" File.register_code_transformation_category "Ghost CFG checking"
......
...@@ -30,10 +30,10 @@ void g(void); ...@@ -30,10 +30,10 @@ void g(void);
/*@ logic ℤ l= 1; /*@ logic ℤ l= 1;
*/ */
int x; int x;
/*@ logic ℤ k= l;
*/
/*@ logic ℤ j= l; /*@ logic ℤ j= l;
*/ */
/*@ logic ℤ k= l;
*/
/*@ logic ℤ i= j + k; /*@ logic ℤ i= j + k;
*/ */
/*@ ensures i ≡ i; */ /*@ ensures i ≡ i; */
......
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