From 355b49dbab836b24bd51a2fbae562eb73fa24526 Mon Sep 17 00:00:00 2001 From: Virgile Prevosto <virgile.prevosto@m4x.org> Date: Thu, 5 Jul 2018 10:33:20 +0200 Subject: [PATCH] Favor standard visitor mechanism for updating gotos labels.ml was broken since quite some time. --- src/plugins/e-acsl/label.ml | 21 +++++---------------- src/plugins/e-acsl/visit.ml | 8 +++++++- 2 files changed, 12 insertions(+), 17 deletions(-) diff --git a/src/plugins/e-acsl/label.ml b/src/plugins/e-acsl/label.ml index 73d143221fc..9887ef2a37a 100644 --- a/src/plugins/e-acsl/label.ml +++ b/src/plugins/e-acsl/label.ml @@ -51,22 +51,11 @@ let move (vis:Visitor.generic_frama_c_visitor) ~old new_stmt = inherit Visitor.frama_c_inplace (* invariant of this method: [s = Cil.memo_stmt vis#behavior orig_stmt] *) method !vstmt_aux s = match s.skind, orig_stmt.skind with - | Goto(s_ref, loc), Goto(orig_ref, _) -> - if Cil_datatype.Stmt.equal !s_ref old then - if s_ref == orig_ref then - (* The memo_stmt and its origin [orig_stmt] contain a shared - reference because [orig_stmt] has not yet been visited by [vis] - (forward goto). Consequently, do not modify the ref directly but - replace the corresponding stmt in the memoisation table. When - [orig_stmt] will be visited, the visitor will automatically - substitute it with the updated stmt. *) - Cil.set_stmt vis#behavior - orig_stmt - { s with skind = Goto(ref new_stmt, loc) } - else - (* Backward goto: it has already been visited and there is no more - sharing. Directly update the reference. *) - s_ref := new_stmt; + | Goto(s_ref, _), Goto(orig_ref, _) -> + if Cil_datatype.Stmt.equal !s_ref old && s_ref != orig_ref then + (* Forward goto: it has already been visited and there is no more + sharing. Must update the reference. *) + s_ref := new_stmt; Cil.SkipChildren | _ -> Cil.DoChildren (* improve efficiency: skip childrens which cannot contain any label *) diff --git a/src/plugins/e-acsl/visit.ml b/src/plugins/e-acsl/visit.ml index 75debee5e06..c2c928a4161 100644 --- a/src/plugins/e-acsl/visit.ml +++ b/src/plugins/e-acsl/visit.ml @@ -623,6 +623,9 @@ you must call function `%s' and `__e_acsl_memory_clean by yourself.@]" in (* handle loop invariants *) let new_stmt, env, must_mv = Loops.preserve_invariant prj env kf stmt in + let orig = Cil.get_original_stmt self#behavior stmt in + Cil.set_orig_stmt self#behavior new_stmt orig; + Cil.set_stmt self#behavior orig new_stmt; let new_stmt, env = (* Remove local variables which scopes ended via goto/break/continue. *) let del_vars = Exit_points.delete_vars stmt in @@ -708,13 +711,16 @@ you must call function `%s' and `__e_acsl_memory_clean by yourself.@]" Env.Before in let post_block = - if post_block.blocals = [] then Cil.transient_block post_block + if post_block.blocals = [] && new_stmt.labels = [] + then Cil.transient_block post_block else post_block in let res = Misc.mk_block prj new_stmt post_block in if not (Cil_datatype.Stmt.equal new_stmt res) then E_acsl_label.move (self :> Visitor.generic_frama_c_visitor) new_stmt res; + Cil.set_stmt self#behavior orig res; + Cil.set_orig_stmt self#behavior res orig; res, env end else stmt, env -- GitLab