From 287f6d074845e1de1bb4735ae98512332ebb6a05 Mon Sep 17 00:00:00 2001 From: Thibaut Benjamin <thibaut.benjamin@gmail.com> Date: Wed, 1 Dec 2021 16:34:57 +0100 Subject: [PATCH] [e-acsl] better recursion during interval phase --- src/plugins/e-acsl/src/analyses/interval.ml | 68 +++++++++++++++---- src/plugins/e-acsl/src/analyses/typing.ml | 3 +- .../e-acsl/src/code_generator/loops.ml | 3 +- 3 files changed, 58 insertions(+), 16 deletions(-) diff --git a/src/plugins/e-acsl/src/analyses/interval.ml b/src/plugins/e-acsl/src/analyses/interval.ml index 6bcf893511c..302c588ada6 100644 --- a/src/plugins/e-acsl/src/analyses/interval.ml +++ b/src/plugins/e-acsl/src/analyses/interval.ml @@ -495,7 +495,8 @@ end = struct try Misc.Id_term.Hashtbl.find tbl t with Not_found -> let x = - try Error.Res (f t) + try + Error.Res (f t); with Error.Not_yet _ | Error.Typing_error _ as exn -> Error.Err exn in Misc.Id_term.Hashtbl.add tbl t x; @@ -650,10 +651,14 @@ let rec infer ~logic_env t = singleton n | TLval lv -> infer_term_lval ~logic_env lv | TSizeOf ty -> infer_sizeof ty - | TSizeOfE t -> infer_sizeof (get_cty t) + | TSizeOfE t -> + ignore (infer ~logic_env t); + infer_sizeof (get_cty t) | TSizeOfStr str -> singleton_of_int (String.length str + 1 (* '\0' *)) | TAlignOf ty -> infer_alignof ty - | TAlignOfE t -> infer_alignof (get_cty t) + | TAlignOfE t -> + ignore (infer ~logic_env t); + infer_alignof (get_cty t) | TUnOp (Neg, t) -> let i = infer ~logic_env t in @@ -714,13 +719,16 @@ let rec infer ~logic_env t = let src = infer ~logic_env t in let dst = interv_of_typ ty in Error.map (fun src -> cast ~src ~dst) src - | Tif (_, t2, t3) -> + | Tif (t1, t2, t3) -> + ignore (infer ~logic_env t1); let i2 = infer ~logic_env t2 in let i3 = infer ~logic_env t3 in Error.map2 join i2 i3 | Tat (t, _) -> get_res (infer ~logic_env t) - | TBinOp (MinusPP, t, _) -> + | TBinOp (MinusPP, t, t2) -> + ignore(infer ~logic_env t); + ignore(infer ~logic_env t2); (match Cil.unrollType (get_cty t) with | TArray(_, _, _) as ta -> begin @@ -738,6 +746,7 @@ let rec infer ~logic_env t = | _ -> assert false) | Tblock_length (_, t) | Toffset(_, t) -> + ignore (infer ~logic_env t); (match Cil.unrollType (get_cty t) with | TArray(_, _, _) as ta -> begin @@ -770,17 +779,35 @@ let rec infer ~logic_env t = else Rational | Tlambda ([ _ ],lt) -> get_res (infer ~logic_env lt) + + | TStartOf lv + | TAddrOf lv -> + ignore (infer_term_lval ~logic_env lv); + Nan + + | TBinOp (PlusPI, t1 ,t2) + | TBinOp (MinusPI, t1, t2) -> + ignore(infer ~logic_env t1); + ignore(infer ~logic_env t2); + Nan + + | Tbase_addr (_,t) + | Ttypeof t -> + ignore(infer ~logic_env t); + Nan + + |TDataCons(_,l) -> + List.iter (fun t -> ignore (infer ~logic_env t)) l; + Nan + + | TUpdate(t1, toff, t2) -> + ignore (infer ~logic_env t1); + ignore (infer ~logic_env t2); + infer_term_offset ~logic_env toff; + Nan + | Tlambda (_,_) | TConst (LStr _ | LWStr _) - | TBinOp (PlusPI,_,_) - | TBinOp (IndexPI,_,_) - | TBinOp (MinusPI,_,_) - | TAddrOf _ - | TStartOf _ - | TDataCons (_,_) - | Tbase_addr (_,_) - | TUpdate (_,_,_) - | Ttypeof _ | Ttype _ | Tempty_set -> Nan @@ -790,6 +817,8 @@ and infer_term_lval ~logic_env (host, offset as tlv) = match offset with | TNoOffset -> infer_term_host ~logic_env host | _ -> + ignore(infer_term_host ~logic_env host); + infer_term_offset ~logic_env offset; let ty = Logic_utils.logicCType (Cil.typeOfTermLval tlv) in interv_of_typ ty @@ -806,6 +835,7 @@ and infer_term_host ~logic_env thost = | TResult ty -> interv_of_typ ty | TMem t -> + ignore(infer ~logic_env t); let ty = Logic_utils.logicCType t.term_type in match Cil.unrollType ty with | TPtr(ty, _) | TArray(ty, _, _) -> @@ -815,6 +845,16 @@ and infer_term_host ~logic_env thost = Printer.pp_typ ty Printer.pp_term t + +and infer_term_offset ~logic_env t = + match t with + | TNoOffset -> () + | TField(_, toff) + | TModel(_, toff) -> infer_term_offset ~logic_env toff + | TIndex(t, toff) -> + ignore (infer ~logic_env t); + infer_term_offset ~logic_env toff + let rec infer_predicate ~logic_env p = match Logic_normalizer.get_pred p with | PoT_term t -> ignore (infer ~logic_env t) diff --git a/src/plugins/e-acsl/src/analyses/typing.ml b/src/plugins/e-acsl/src/analyses/typing.ml index 4197e0974c2..b33f484873c 100644 --- a/src/plugins/e-acsl/src/analyses/typing.ml +++ b/src/plugins/e-acsl/src/analyses/typing.ml @@ -690,7 +690,8 @@ and type_term_lval ~profile (host, offset) = and type_term_lhost ~profile t = match t with | TVar _ | TResult _ -> () - | TMem t -> ignore (type_term ~use_gmp_opt:false ~ctx:Nan ~profile t) + | TMem t -> + ignore (type_term ~use_gmp_opt:false ~ctx:Nan ~profile t) and type_term_offset ~profile t = match t with | TNoOffset -> () diff --git a/src/plugins/e-acsl/src/code_generator/loops.ml b/src/plugins/e-acsl/src/code_generator/loops.ml index 395a78d31ee..3858ada7c49 100644 --- a/src/plugins/e-acsl/src/code_generator/loops.ml +++ b/src/plugins/e-acsl/src/code_generator/loops.ml @@ -333,7 +333,8 @@ let rec mk_nested_loops ~loc mk_innermost_block kf env lscope_vars = to avoid the extra addition (relevant when computing with GMP) *) let guard = match t2.term_node with - | TBinOp (PlusA, t2_minus_one, {term_node = TConst(Integer (n, _))}) when Integer.is_one n -> + | TBinOp (PlusA, t2_minus_one, {term_node = TConst(Integer (n, _))}) when + Integer.is_one n -> Logic_const.term ~loc (TBinOp(Le, tlv, { t2_minus_one with term_node = t2_minus_one.term_node })) Linteger -- GitLab