Skip to content

Commit

Permalink
Add termination analysis success messages for loop bounds (closes #1577)
Browse files Browse the repository at this point in the history
  • Loading branch information
sim642 committed Sep 27, 2024
1 parent e77b41c commit 56c3a93
Showing 1 changed file with 14 additions and 9 deletions.
23 changes: 14 additions & 9 deletions src/analyses/loopTermination.ml
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,13 @@ open TerminationPreprocessing
let loop_counters : stmt VarToStmt.t ref = ref VarToStmt.empty

(** Checks whether a variable can be bounded. *)
let check_bounded ctx varinfo =
let ask_bound ctx varinfo =
let open IntDomain.IntDomTuple in
let exp = Lval (Var varinfo, NoOffset) in
match ctx.ask (EvalInt exp) with
| `Top -> false
| `Lifted v -> not (is_top_of (ikind v) v)
| `Top -> `Top
| `Lifted v when is_top_of (ikind v) v -> `Top
| `Lifted v -> `Lifted v
| `Bot -> failwith "Loop counter variable is Bot."

(** We want to record termination information of loops and use the loop
Expand Down Expand Up @@ -52,13 +53,17 @@ struct
"__goblint_bounded", [Lval (Var loop_counter, NoOffset)] ->
(try
let loop_statement = find_loop ~loop_counter in
let is_bounded = check_bounded ctx loop_counter in
let bound = ask_bound ctx loop_counter in
let is_bounded = bound <> `Top in
ctx.sideg () (G.add (`Lifted loop_statement) is_bounded (ctx.global ()));
(* In case the loop is not bounded, a warning is created. *)
if not (is_bounded) then (
M.warn ~loc:(M.Location.CilLocation (Cilfacade.get_stmtLoc loop_statement)) ~category:Termination "The program might not terminate! (Loop analysis)"
);
()
let loc = M.Location.CilLocation (Cilfacade.get_stmtLoc loop_statement) in
begin match bound with
| `Top ->
M.warn ~category:Termination ~loc "The program might not terminate! (Loop analysis)"
| `Lifted bound ->
(* TODO: aggregate these per loop (if unrolled) and warn using WarnGlobal? *)
M.success ~category:Termination ~loc "Loop terminates: bounded by %a iteration(s)" IntDomain.IntDomTuple.pretty bound;
end
with Not_found ->
failwith "Encountered a call to __goblint_bounded with an unknown loop counter variable.")
| _ -> ()
Expand Down

0 comments on commit 56c3a93

Please sign in to comment.