From 7a91deafcf4b7903bed8f1d4334e5abe4e286816 Mon Sep 17 00:00:00 2001 From: Julien Signoles <julien.signoles@cea.fr> Date: Thu, 19 May 2016 20:09:47 +0200 Subject: [PATCH] [typing] mutable environment in inference system [typing] fix bug in on-the-fly typing when translating quantification [typing] update a few oracles --- src/plugins/e-acsl/interval.ml | 58 ++-- src/plugins/e-acsl/interval.mli | 7 +- src/plugins/e-acsl/quantif.ml | 44 +-- .../e-acsl-runtime/oracle/gen_linear_search.c | 6 +- .../e-acsl-runtime/oracle/gen_mainargs.c | 54 ++-- .../e-acsl-runtime/oracle/mainargs.res.oracle | 9 +- .../e-acsl/tests/gmp/oracle/gen_quantif2.c | 156 +++++----- .../tests/gmp/oracle/quantif.1.res.oracle | 3 +- src/plugins/e-acsl/translate.ml | 7 +- src/plugins/e-acsl/typing.ml | 283 +++++++++--------- src/plugins/e-acsl/typing.mli | 8 +- 11 files changed, 329 insertions(+), 306 deletions(-) diff --git a/src/plugins/e-acsl/interval.ml b/src/plugins/e-acsl/interval.ml index 225eae850ca..edadf8f7b5b 100644 --- a/src/plugins/e-acsl/interval.ml +++ b/src/plugins/e-acsl/interval.ml @@ -85,10 +85,10 @@ let join i1 i2 = module Env = struct open Cil_datatype - type t = interv Logic_var.Map.t - let empty = Logic_var.Map.empty - let add = Logic_var.Map.add - let find = Logic_var.Map.find + let tbl: interv Logic_var.Hashtbl.t = Logic_var.Hashtbl.create 7 + let clear () = Logic_var.Hashtbl.clear tbl + let add = Logic_var.Hashtbl.add tbl + let find = Logic_var.Hashtbl.find tbl end (* ********************************************************************* *) @@ -112,7 +112,7 @@ let infer_sizeof ty = let infer_alignof ty = singleton_of_int (Cil.bytesAlignOf ty) -let rec infer env t = +let rec infer t = let get_cty t = match t.term_type with Ctype ty -> ty | _ -> assert false in match t.term_node with | TConst (Integer (n,_)) -> make n n @@ -126,7 +126,7 @@ let rec infer env t = in let n = Integer.of_int (find_idx 0 enumitem.eihost.eitems) in make n n - | TLval lv -> infer_term_lval env lv + | TLval lv -> infer_term_lval lv | TSizeOf ty -> infer_sizeof ty | TSizeOfE t -> infer_sizeof (get_cty t) | TSizeOfStr str -> singleton_of_int (String.length str + 1 (* '\0' *)) @@ -134,10 +134,10 @@ let rec infer env t = | TAlignOfE t -> infer_alignof (get_cty t) | TUnOp (Neg, t) -> - let { lower; upper } = infer env t in + let { lower; upper } = infer t in make (Integer.neg upper) (Integer.neg lower) | TUnOp (BNot, t) -> - let { lower; upper } = infer env t in + let { lower; upper } = infer t in let nl = Integer.lognot lower in let nu = Integer.lognot upper in make (Integer.min nl nu) (Integer.max nl nu) @@ -146,20 +146,20 @@ let rec infer env t = | TBinOp ((Lt | Gt | Le | Ge | Eq | Ne | LAnd | LOr), _, _) -> make Integer.zero Integer.one | TBinOp (PlusA, t1, t2) -> - let i1 = infer env t1 in - let i2 = infer env t2 in + let i1 = infer t1 in + let i2 = infer t2 in make (Integer.add i1.lower i2.lower) (Integer.add i1.upper i2.upper) | TBinOp (MinusA, t1, t2) -> - let i1 = infer env t1 in - let i2 = infer env t2 in + let i1 = infer t1 in + let i2 = infer t2 in make (Integer.sub i1.lower i2.upper) (Integer.sub i1.upper i2.lower) | TBinOp (Mult, t1, t2) -> - let i1 = infer env t1 in - let i2 = infer env t2 in + let i1 = infer t1 in + let i2 = infer t2 in combine Integer.mul i1 i2 | TBinOp (Div, t1, t2) -> - let i1 = infer env t1 in - let i2 = infer env t2 in + let i1 = infer t1 in + let i2 = infer t2 in if Integer.le i2.lower Integer.zero && Integer.ge i2.upper Integer.zero then (* 0 \in i2 *) let l = Integer.min i1.lower (Integer.neg i1.upper) in @@ -172,8 +172,8 @@ let rec infer env t = in combine div i1 i2 | TBinOp (Mod, t1, t2) -> - let i1 = infer env t1 in - let i2 = infer env t2 in + let i1 = infer t1 in + let i2 = infer t2 in (* the sign of the result is the sign of [t1]; also no more elements than [t2-1] and no more than [t1] *) let nb1 = Integer.max (Integer.abs i1.lower) (Integer.abs i1.upper) in @@ -198,14 +198,14 @@ let rec infer env t = | TCastE (ty, t) | TCoerce (t, ty) -> - let it = infer env t in + let it = infer t in let ity = interv_of_typ ty in meet it ity | Tif (_, t2, t3) -> - let i2 = infer env t2 in - let i3 = infer env t3 in + let i2 = infer t2 in + let i3 = infer t3 in join i2 i3 - | Tat (t, _) -> infer env t + | Tat (t, _) -> infer t | TBinOp (MinusPP, t, _) -> (match Cil.unrollType (get_cty t) with | TArray(_, _, { scache = Computed n }, _) -> @@ -221,10 +221,10 @@ let rec infer env t = | TArray _ | TPtr _ -> Lazy.force interv_of_unknown_block | _ -> assert false) | Tnull -> singleton_of_int 0 - | TLogic_coerce (_, t) -> infer env t + | TLogic_coerce (_, t) -> infer t | TCoerceE (t1, t2) -> - let i1 = infer env t1 in - let i2 = infer env t2 in + let i1 = infer t1 in + let i2 = infer t2 in meet i1 i2 | Tapp (_,_,_) -> Error.not_yet "logic function application" @@ -248,16 +248,16 @@ let rec infer env t = | Ttype _ | Tempty_set -> raise Not_an_integer -and infer_term_lval env (host, offset as tlv) = +and infer_term_lval (host, offset as tlv) = match offset with - | TNoOffset -> infer_term_host env host + | TNoOffset -> infer_term_host host | _ -> let ty = Logic_utils.logicCType (Cil.typeOfTermLval tlv) in interv_of_typ ty -and infer_term_host env = function +and infer_term_host = function | TVar v -> - (try Env.find v env + (try Env.find v with Not_found -> interv_of_typ (Logic_utils.logicCType v.lv_type)) | TResult ty -> interv_of_typ ty | TMem t -> diff --git a/src/plugins/e-acsl/interval.mli b/src/plugins/e-acsl/interval.mli index f6a906c3c2b..456310f5833 100644 --- a/src/plugins/e-acsl/interval.mli +++ b/src/plugins/e-acsl/interval.mli @@ -29,9 +29,8 @@ type interv = private { lower: Integer.t; upper: Integer.t } include Datatype.S with type t = interv module Env: sig - type t - val empty: t - val add: Cil_types.logic_var -> interv -> t -> t + val clear: unit -> unit + val add: Cil_types.logic_var -> interv -> unit end val interv_of_typ: Cil_types.typ -> t @@ -41,7 +40,7 @@ val join: t -> t -> t val meet: t -> t -> t exception Not_an_integer -val infer: Env.t -> Cil_types.term -> t +val infer: Cil_types.term -> t (** [infer t] infers the smallest possible integer interval which the values of the term can fit in. Assume than the type of [t] is an integral type. @raise Not_an_integer if the type of the term is not a subtype of diff --git a/src/plugins/e-acsl/quantif.ml b/src/plugins/e-acsl/quantif.ml index b6daa15f265..e4a9e47fbf3 100644 --- a/src/plugins/e-acsl/quantif.ml +++ b/src/plugins/e-acsl/quantif.ml @@ -168,7 +168,6 @@ let convert kf env loc is_forall p bounded_vars hyps goal = let ty2 = Typing.get_integer_ty t2 in Typing.join ty1 ty2 in - let ty = Typing.typ_of_integer_ty ctx in let t_plus_one t = Logic_const.term ~loc (TBinOp(PlusA, t, Logic_const.tinteger ~loc 1)) @@ -177,7 +176,7 @@ let convert kf env loc is_forall p bounded_vars hyps goal = let t1 = match rel1 with | Rlt -> let t = t_plus_one t1 in - Typing.type_term ~ctx t; + Typing.type_term ~force:true ~ctx t; t | Rle -> t1 | Rgt | Rge | Req | Rneq -> assert false @@ -186,35 +185,46 @@ let convert kf env loc is_forall p bounded_vars hyps goal = | Rlt -> t2, Lt | Rle -> (* we increment the loop counter one more time (at the end of the - loop). Thus to prevent overflow, check the type of [t2 + 1] + loop). Thus to prevent overflow, check the type of [t2+1] instead of [t2]. *) t_plus_one t2, Le | Rgt | Rge | Req | Rneq -> assert false in - Typing.type_term ~ctx t2_one; + Typing.type_term ~force:true ~ctx t2_one; + let ctx_one = + let ty1 = Typing.get_integer_ty t1 in + let ty2 = Typing.get_integer_ty t2_one in + Typing.join ty1 ty2 + in + let ty = Typing.typ_of_integer_ty ctx_one in (* loop counter corresponding to the quantified variable *) let var_x, x, env = Env.Logic_binding.add ~ty env logic_x in let lv_x = var var_x in - let env = - if Gmpz.is_t ty then Env.add_stmt env (Gmpz.init ~loc x) else env + let env = match ctx_one with + | Typing.C_type _ -> env + | Typing.Gmp -> Env.add_stmt env (Gmpz.init ~loc x) + | Typing.Other -> assert false in - let llv = cvar_to_lvar var_x in (* build the inner loops and loop body *) let body, env = mk_for_loop env tl in (* initialize the loop counter to [t1] *) let e1, env = term_to_exp kf (Env.push env) t1 in - let init_blk, env = - Env.pop_and_get - env - (Gmpz.affect ~loc:e1.eloc lv_x x e1) - ~global_clear:false - Env.Middle + let init_blk, env = + Env.pop_and_get + env + (Gmpz.affect ~loc:e1.eloc lv_x x e1) + ~global_clear:false + Env.Middle in (* generate the guard [x bop t2] *) let stmts_block b = [ mkStmt ~valid_sid:true (Block b) ] in - let tlv = Logic_const.tvar ~loc llv in - let guard = Logic_const.term ~loc (TBinOp(bop2, tlv, t2)) Linteger in - Typing.type_term ~ctx:Typing.c_int guard; + let tlv = Logic_const.tvar ~loc logic_x in + let guard = + (* must copy [t2] to force being typed again *) + Logic_const.term ~loc + (TBinOp(bop2, tlv, { t2 with term_node = t2.term_node } )) Linteger + in + Typing.type_term ~force:true ~ctx:Typing.c_int guard; let guard_exp, env = term_to_exp kf (Env.push env) guard in let break_stmt = mkStmt ~valid_sid:true (Break guard_exp.eloc) in let guard_blk, env = @@ -232,7 +242,7 @@ let convert kf env loc is_forall p bounded_vars hyps goal = (* increment the loop counter [x++] *) let tlv_one = t_plus_one tlv in (* previous typing ensures that [x++] fits type [ty] *) - Typing.type_term ~ctx tlv_one; + Typing.type_term ~force:true ~ctx:ctx_one tlv_one; let incr, env = term_to_exp kf (Env.push env) tlv_one in let next_blk, env = Env.pop_and_get diff --git a/src/plugins/e-acsl/tests/e-acsl-runtime/oracle/gen_linear_search.c b/src/plugins/e-acsl/tests/e-acsl-runtime/oracle/gen_linear_search.c index 95fee64be9e..22b41d67d4e 100644 --- a/src/plugins/e-acsl/tests/e-acsl-runtime/oracle/gen_linear_search.c +++ b/src/plugins/e-acsl/tests/e-acsl-runtime/oracle/gen_linear_search.c @@ -161,7 +161,7 @@ int __gen_e_acsl_search(int elt) __gen_e_acsl_forall = 0; goto e_acsl_end_loop3; } - __gen_e_acsl_i = (int)(__gen_e_acsl_i + 1L); + __gen_e_acsl_i ++; } e_acsl_end_loop3: ; __e_acsl_assert(__gen_e_acsl_forall,(char *)"Precondition", @@ -184,7 +184,7 @@ int __gen_e_acsl_search(int elt) __gen_e_acsl_forall_2 = 0; goto e_acsl_end_loop5; } - __gen_e_acsl_j_2 = (int)(__gen_e_acsl_j_2 + 1L); + __gen_e_acsl_j_2 ++; } e_acsl_end_loop5: ; __gen_e_acsl_at_2 = __gen_e_acsl_forall_2; @@ -205,7 +205,7 @@ int __gen_e_acsl_search(int elt) __gen_e_acsl_exists = 1; goto e_acsl_end_loop4; } - __gen_e_acsl_j = (int)(__gen_e_acsl_j + 1L); + __gen_e_acsl_j ++; } e_acsl_end_loop4: ; __gen_e_acsl_at = __gen_e_acsl_exists; diff --git a/src/plugins/e-acsl/tests/e-acsl-runtime/oracle/gen_mainargs.c b/src/plugins/e-acsl/tests/e-acsl-runtime/oracle/gen_mainargs.c index c0192f76823..fb58b0114e3 100644 --- a/src/plugins/e-acsl/tests/e-acsl-runtime/oracle/gen_mainargs.c +++ b/src/plugins/e-acsl/tests/e-acsl-runtime/oracle/gen_mainargs.c @@ -30,7 +30,7 @@ int main(int argc, char **argv) if (__gen_e_acsl_k < argc) ; else break; { int __gen_e_acsl_valid_3; - __gen_e_acsl_valid_3 = __e_acsl_valid((void *)(argv + __gen_e_acsl_k), + __gen_e_acsl_valid_3 = __e_acsl_valid((void *)(argv + (unsigned long)__gen_e_acsl_k), sizeof(char *)); if (__gen_e_acsl_valid_3) ; else { @@ -38,7 +38,7 @@ int main(int argc, char **argv) goto e_acsl_end_loop1; } } - __gen_e_acsl_k ++; + __gen_e_acsl_k = (int)(__gen_e_acsl_k + 1L); } e_acsl_end_loop1: ; __e_acsl_assert(__gen_e_acsl_forall,(char *)"Assertion",(char *)"main", @@ -53,7 +53,7 @@ int main(int argc, char **argv) int __gen_e_acsl_eq; __gen_e_acsl_block_length = __e_acsl_block_length((void *)argv); __gmpz_init_set_ui(__gen_e_acsl_block_length_2,__gen_e_acsl_block_length); - __gmpz_init_set_si(__gen_e_acsl_,((long)argc + (long)1) * 8L); + __gmpz_init_set_si(__gen_e_acsl_,(argc + 1) * 8); __gen_e_acsl_eq = __gmpz_cmp((__mpz_struct const *)(__gen_e_acsl_block_length_2), (__mpz_struct const *)(__gen_e_acsl_)); __e_acsl_assert(__gen_e_acsl_eq == 0,(char *)"Assertion",(char *)"main", @@ -65,29 +65,32 @@ int main(int argc, char **argv) /*@ assert *(argv+argc) ≡ \null; */ { int __gen_e_acsl_valid_read; - __gen_e_acsl_valid_read = __e_acsl_valid_read((void *)(argv + argc), + __gen_e_acsl_valid_read = __e_acsl_valid_read((void *)(argv + (unsigned long)argc), sizeof(char *)); __e_acsl_assert(__gen_e_acsl_valid_read,(char *)"RTE",(char *)"main", - (char *)"mem_access: \\valid_read(argv+argc)",15); - /*@ assert Value: mem_access: \valid_read(argv+argc); */ - __e_acsl_assert(*(argv + argc) == (void *)0,(char *)"Assertion", - (char *)"main",(char *)"*(argv+argc) == \\null",15); + (char *)"mem_access: \\valid_read(argv+(unsigned long)argc)", + 15); + /*@ assert Value: mem_access: \valid_read(argv+(unsigned long)argc); */ + __e_acsl_assert(*(argv + (unsigned long)argc) == (void *)0, + (char *)"Assertion",(char *)"main", + (char *)"*(argv+argc) == \\null",15); } /*@ assert ¬\valid(*(argv+argc)); */ { int __gen_e_acsl_initialized; int __gen_e_acsl_and; - __gen_e_acsl_initialized = __e_acsl_initialized((void *)(argv + argc), + __gen_e_acsl_initialized = __e_acsl_initialized((void *)(argv + (unsigned long)argc), sizeof(char *)); if (__gen_e_acsl_initialized) { int __gen_e_acsl_valid_read_2; int __gen_e_acsl_valid_4; - __gen_e_acsl_valid_read_2 = __e_acsl_valid_read((void *)(argv + argc), + __gen_e_acsl_valid_read_2 = __e_acsl_valid_read((void *)(argv + (unsigned long)argc), sizeof(char *)); __e_acsl_assert(__gen_e_acsl_valid_read_2,(char *)"RTE",(char *)"main", - (char *)"mem_access: \\valid_read(argv+argc)",16); - /*@ assert Value: mem_access: \valid_read(argv+argc); */ - __gen_e_acsl_valid_4 = __e_acsl_valid((void *)*(argv + argc), + (char *)"mem_access: \\valid_read(argv+(unsigned long)argc)", + 16); + /*@ assert Value: mem_access: \valid_read(argv+(unsigned long)argc); */ + __gen_e_acsl_valid_4 = __e_acsl_valid((void *)*(argv + (unsigned long)argc), sizeof(char)); __gen_e_acsl_and = __gen_e_acsl_valid_4; } @@ -100,23 +103,27 @@ int main(int argc, char **argv) { int len; size_t tmp; + /*@ assert Value: mem_access: \valid_read(argv+i); */ tmp = __gen_e_acsl_strlen((char const *)*(argv + i)); len = (int)tmp; /*@ assert \valid(*(argv+i)); */ { int __gen_e_acsl_initialized_2; int __gen_e_acsl_and_2; - __gen_e_acsl_initialized_2 = __e_acsl_initialized((void *)(argv + i), + __gen_e_acsl_initialized_2 = __e_acsl_initialized((void *)(argv + (unsigned long)i), sizeof(char *)); if (__gen_e_acsl_initialized_2) { int __gen_e_acsl_valid_read_3; int __gen_e_acsl_valid_5; - __gen_e_acsl_valid_read_3 = __e_acsl_valid_read((void *)(argv + i), + __gen_e_acsl_valid_read_3 = __e_acsl_valid_read((void *)(argv + (unsigned long)i), sizeof(char *)); __e_acsl_assert(__gen_e_acsl_valid_read_3,(char *)"RTE", (char *)"main", - (char *)"mem_access: \\valid_read(argv+i)",19); - __gen_e_acsl_valid_5 = __e_acsl_valid((void *)*(argv + i), + (char *)"mem_access: \\valid_read(argv+(unsigned long)i)", + 19); + /*@ assert Value: mem_access: \valid_read(argv+(unsigned long)i); + */ + __gen_e_acsl_valid_5 = __e_acsl_valid((void *)*(argv + (unsigned long)i), sizeof(char)); __gen_e_acsl_and_2 = __gen_e_acsl_valid_5; } @@ -129,19 +136,22 @@ int main(int argc, char **argv) int __gen_e_acsl_forall_2; long __gen_e_acsl_k_2; __gen_e_acsl_forall_2 = 1; - __gen_e_acsl_k_2 = (long)0; + __gen_e_acsl_k_2 = 0; while (1) { - if (__gen_e_acsl_k_2 <= (long)len) ; else break; + if (__gen_e_acsl_k_2 <= len) ; else break; { int __gen_e_acsl_valid_read_4; int __gen_e_acsl_valid_6; __gen_e_acsl_valid_read_4 = __e_acsl_valid_read((void *)( - argv + i), + argv + (unsigned long)i), sizeof(char *)); __e_acsl_assert(__gen_e_acsl_valid_read_4,(char *)"RTE", (char *)"main", - (char *)"mem_access: \\valid_read(argv+i)",20); - __gen_e_acsl_valid_6 = __e_acsl_valid((void *)(*(argv + i) + __gen_e_acsl_k_2), + (char *)"mem_access: \\valid_read(argv+(unsigned long)i)", + 20); + /*@ assert Value: mem_access: \valid_read(argv+(unsigned long)i); + */ + __gen_e_acsl_valid_6 = __e_acsl_valid((void *)(*(argv + (unsigned long)i) + (unsigned long)__gen_e_acsl_k_2), sizeof(char)); if (__gen_e_acsl_valid_6) ; else { diff --git a/src/plugins/e-acsl/tests/e-acsl-runtime/oracle/mainargs.res.oracle b/src/plugins/e-acsl/tests/e-acsl-runtime/oracle/mainargs.res.oracle index b07a36e3922..c6326144037 100644 --- a/src/plugins/e-acsl/tests/e-acsl-runtime/oracle/mainargs.res.oracle +++ b/src/plugins/e-acsl/tests/e-acsl-runtime/oracle/mainargs.res.oracle @@ -6,18 +6,21 @@ FRAMAC_SHARE/libc/string.h:91:[e-acsl] warning: E-ACSL construct `logic function Ignoring annotation. FRAMAC_SHARE/libc/string.h:91:[e-acsl] warning: E-ACSL construct `assigns clause in behavior' is not yet supported. Ignoring annotation. -FRAMAC_SHARE/libc/string.h:93:[e-acsl] warning: E-ACSL construct `applying logic function' is not yet supported. +FRAMAC_SHARE/libc/string.h:93:[e-acsl] warning: E-ACSL construct `logic function application' is not yet supported. Ignoring annotation. [e-acsl] translation done in project "e-acsl". FRAMAC_SHARE/e-acsl/e_acsl.h:43:[value] warning: function __e_acsl_assert: precondition got status unknown. tests/e-acsl-runtime/mainargs.c:12:[value] warning: assertion got status unknown. tests/e-acsl-runtime/mainargs.c:13:[value] warning: assertion got status unknown. tests/e-acsl-runtime/mainargs.c:15:[value] warning: assertion got status unknown. -tests/e-acsl-runtime/mainargs.c:15:[value] warning: out of bounds read. assert \valid_read(argv+argc); +tests/e-acsl-runtime/mainargs.c:15:[kernel] warning: out of bounds read. assert \valid_read(argv+(unsigned long)argc); tests/e-acsl-runtime/mainargs.c:16:[value] warning: assertion got status unknown. -tests/e-acsl-runtime/mainargs.c:16:[value] warning: out of bounds read. assert \valid_read(argv+argc); +tests/e-acsl-runtime/mainargs.c:16:[kernel] warning: out of bounds read. assert \valid_read(argv+(unsigned long)argc); FRAMAC_SHARE/libc/string.h:91:[value] warning: function __gen_e_acsl_strlen: precondition 'valid_string_src' got status unknown. FRAMAC_SHARE/libc/string.h:91:[value] warning: function strlen: precondition 'valid_string_src' got status unknown. FRAMAC_SHARE/libc/string.h:93:[value] warning: function __gen_e_acsl_strlen: postcondition got status unknown. tests/e-acsl-runtime/mainargs.c:19:[value] warning: assertion got status unknown. tests/e-acsl-runtime/mainargs.c:20:[value] warning: assertion got status unknown. +tests/e-acsl-runtime/mainargs.c:18:[kernel] warning: out of bounds read. assert \valid_read(argv+i); +tests/e-acsl-runtime/mainargs.c:19:[kernel] warning: out of bounds read. assert \valid_read(argv+(unsigned long)i); +tests/e-acsl-runtime/mainargs.c:20:[kernel] warning: out of bounds read. assert \valid_read(argv+(unsigned long)i); diff --git a/src/plugins/e-acsl/tests/gmp/oracle/gen_quantif2.c b/src/plugins/e-acsl/tests/gmp/oracle/gen_quantif2.c index 14ccacd711a..cb4a5be8286 100644 --- a/src/plugins/e-acsl/tests/gmp/oracle/gen_quantif2.c +++ b/src/plugins/e-acsl/tests/gmp/oracle/gen_quantif2.c @@ -10,7 +10,7 @@ int main(void) __gmpz_init(__gen_e_acsl_x); { mpz_t __gen_e_acsl__3; - __gmpz_init_set_si(__gen_e_acsl__3,(long)0); + __gmpz_init_set_ui(__gen_e_acsl__3,(unsigned long)0); __gmpz_set(__gen_e_acsl_x,(__mpz_struct const *)(__gen_e_acsl__3)); __gmpz_clear(__gen_e_acsl__3); } @@ -18,7 +18,7 @@ int main(void) { mpz_t __gen_e_acsl__4; int __gen_e_acsl_le; - __gmpz_init_set_si(__gen_e_acsl__4,(long)1); + __gmpz_init_set_ui(__gen_e_acsl__4,(unsigned long)1); __gen_e_acsl_le = __gmpz_cmp((__mpz_struct const *)(__gen_e_acsl_x), (__mpz_struct const *)(__gen_e_acsl__4)); if (__gen_e_acsl_le <= 0) ; else break; @@ -28,14 +28,14 @@ int main(void) mpz_t __gen_e_acsl_; int __gen_e_acsl_eq; int __gen_e_acsl_or; - __gmpz_init_set_si(__gen_e_acsl_,(long)0); + __gmpz_init_set_ui(__gen_e_acsl_,(unsigned long)0); __gen_e_acsl_eq = __gmpz_cmp((__mpz_struct const *)(__gen_e_acsl_x), (__mpz_struct const *)(__gen_e_acsl_)); if (__gen_e_acsl_eq == 0) __gen_e_acsl_or = 1; else { mpz_t __gen_e_acsl__2; int __gen_e_acsl_eq_2; - __gmpz_init_set_si(__gen_e_acsl__2,(long)1); + __gmpz_init_set_ui(__gen_e_acsl__2,(unsigned long)1); __gen_e_acsl_eq_2 = __gmpz_cmp((__mpz_struct const *)(__gen_e_acsl_x), (__mpz_struct const *)(__gen_e_acsl__2)); __gen_e_acsl_or = __gen_e_acsl_eq_2 == 0; @@ -51,7 +51,7 @@ int main(void) { mpz_t __gen_e_acsl__5; mpz_t __gen_e_acsl_add; - __gmpz_init_set_si(__gen_e_acsl__5,1L); + __gmpz_init_set_ui(__gen_e_acsl__5,1UL); __gmpz_init(__gen_e_acsl_add); __gmpz_add(__gen_e_acsl_add,(__mpz_struct const *)(__gen_e_acsl_x), (__mpz_struct const *)(__gen_e_acsl__5)); @@ -76,8 +76,8 @@ int main(void) mpz_t __gen_e_acsl__7; mpz_t __gen_e_acsl__8; mpz_t __gen_e_acsl_add_2; - __gmpz_init_set_si(__gen_e_acsl__7,(long)0); - __gmpz_init_set_si(__gen_e_acsl__8,1L); + __gmpz_init_set_ui(__gen_e_acsl__7,(unsigned long)0); + __gmpz_init_set_ui(__gen_e_acsl__8,1UL); __gmpz_init(__gen_e_acsl_add_2); __gmpz_add(__gen_e_acsl_add_2,(__mpz_struct const *)(__gen_e_acsl__7), (__mpz_struct const *)(__gen_e_acsl__8)); @@ -90,7 +90,7 @@ int main(void) { mpz_t __gen_e_acsl__9; int __gen_e_acsl_le_2; - __gmpz_init_set_si(__gen_e_acsl__9,(long)1); + __gmpz_init_set_ui(__gen_e_acsl__9,(unsigned long)1); __gen_e_acsl_le_2 = __gmpz_cmp((__mpz_struct const *)(__gen_e_acsl_x_2), (__mpz_struct const *)(__gen_e_acsl__9)); if (__gen_e_acsl_le_2 <= 0) ; else break; @@ -99,7 +99,7 @@ int main(void) { mpz_t __gen_e_acsl__6; int __gen_e_acsl_eq_3; - __gmpz_init_set_si(__gen_e_acsl__6,(long)1); + __gmpz_init_set_ui(__gen_e_acsl__6,(unsigned long)1); __gen_e_acsl_eq_3 = __gmpz_cmp((__mpz_struct const *)(__gen_e_acsl_x_2), (__mpz_struct const *)(__gen_e_acsl__6)); __gmpz_clear(__gen_e_acsl__6); @@ -112,7 +112,7 @@ int main(void) { mpz_t __gen_e_acsl__10; mpz_t __gen_e_acsl_add_3; - __gmpz_init_set_si(__gen_e_acsl__10,1L); + __gmpz_init_set_ui(__gen_e_acsl__10,1UL); __gmpz_init(__gen_e_acsl_add_3); __gmpz_add(__gen_e_acsl_add_3, (__mpz_struct const *)(__gen_e_acsl_x_2), @@ -138,8 +138,8 @@ int main(void) mpz_t __gen_e_acsl__11; mpz_t __gen_e_acsl__12; mpz_t __gen_e_acsl_add_4; - __gmpz_init_set_si(__gen_e_acsl__11,(long)0); - __gmpz_init_set_si(__gen_e_acsl__12,1L); + __gmpz_init_set_ui(__gen_e_acsl__11,(unsigned long)0); + __gmpz_init_set_ui(__gen_e_acsl__12,1UL); __gmpz_init(__gen_e_acsl_add_4); __gmpz_add(__gen_e_acsl_add_4,(__mpz_struct const *)(__gen_e_acsl__11), (__mpz_struct const *)(__gen_e_acsl__12)); @@ -152,7 +152,7 @@ int main(void) { mpz_t __gen_e_acsl__13; int __gen_e_acsl_lt; - __gmpz_init_set_si(__gen_e_acsl__13,(long)1); + __gmpz_init_set_ui(__gen_e_acsl__13,(unsigned long)1); __gen_e_acsl_lt = __gmpz_cmp((__mpz_struct const *)(__gen_e_acsl_x_3), (__mpz_struct const *)(__gen_e_acsl__13)); if (__gen_e_acsl_lt < 0) ; else break; @@ -166,7 +166,7 @@ int main(void) { mpz_t __gen_e_acsl__14; mpz_t __gen_e_acsl_add_5; - __gmpz_init_set_si(__gen_e_acsl__14,1L); + __gmpz_init_set_ui(__gen_e_acsl__14,1UL); __gmpz_init(__gen_e_acsl_add_5); __gmpz_add(__gen_e_acsl_add_5, (__mpz_struct const *)(__gen_e_acsl_x_3), @@ -190,7 +190,7 @@ int main(void) __gmpz_init(__gen_e_acsl_x_4); { mpz_t __gen_e_acsl__16; - __gmpz_init_set_si(__gen_e_acsl__16,(long)0); + __gmpz_init_set_ui(__gen_e_acsl__16,(unsigned long)0); __gmpz_set(__gen_e_acsl_x_4,(__mpz_struct const *)(__gen_e_acsl__16)); __gmpz_clear(__gen_e_acsl__16); } @@ -198,7 +198,7 @@ int main(void) { mpz_t __gen_e_acsl__17; int __gen_e_acsl_lt_2; - __gmpz_init_set_si(__gen_e_acsl__17,(long)1); + __gmpz_init_set_ui(__gen_e_acsl__17,(unsigned long)1); __gen_e_acsl_lt_2 = __gmpz_cmp((__mpz_struct const *)(__gen_e_acsl_x_4), (__mpz_struct const *)(__gen_e_acsl__17)); if (__gen_e_acsl_lt_2 < 0) ; else break; @@ -207,7 +207,7 @@ int main(void) { mpz_t __gen_e_acsl__15; int __gen_e_acsl_eq_4; - __gmpz_init_set_si(__gen_e_acsl__15,(long)0); + __gmpz_init_set_ui(__gen_e_acsl__15,(unsigned long)0); __gen_e_acsl_eq_4 = __gmpz_cmp((__mpz_struct const *)(__gen_e_acsl_x_4), (__mpz_struct const *)(__gen_e_acsl__15)); __gmpz_clear(__gen_e_acsl__15); @@ -220,7 +220,7 @@ int main(void) { mpz_t __gen_e_acsl__18; mpz_t __gen_e_acsl_add_6; - __gmpz_init_set_si(__gen_e_acsl__18,1L); + __gmpz_init_set_ui(__gen_e_acsl__18,1UL); __gmpz_init(__gen_e_acsl_add_6); __gmpz_add(__gen_e_acsl_add_6, (__mpz_struct const *)(__gen_e_acsl_x_4), @@ -251,7 +251,7 @@ int main(void) __gmpz_init(__gen_e_acsl_z); { mpz_t __gen_e_acsl__25; - __gmpz_init_set_si(__gen_e_acsl__25,(long)0); + __gmpz_init_set_ui(__gen_e_acsl__25,(unsigned long)0); __gmpz_set(__gen_e_acsl_x_5,(__mpz_struct const *)(__gen_e_acsl__25)); __gmpz_clear(__gen_e_acsl__25); } @@ -259,7 +259,7 @@ int main(void) { mpz_t __gen_e_acsl__26; int __gen_e_acsl_lt_4; - __gmpz_init_set_si(__gen_e_acsl__26,(long)2); + __gmpz_init_set_ui(__gen_e_acsl__26,(unsigned long)2); __gen_e_acsl_lt_4 = __gmpz_cmp((__mpz_struct const *)(__gen_e_acsl_x_5), (__mpz_struct const *)(__gen_e_acsl__26)); if (__gen_e_acsl_lt_4 < 0) ; else break; @@ -267,7 +267,7 @@ int main(void) } { mpz_t __gen_e_acsl__22; - __gmpz_init_set_si(__gen_e_acsl__22,(long)0); + __gmpz_init_set_ui(__gen_e_acsl__22,(unsigned long)0); __gmpz_set(__gen_e_acsl_y,(__mpz_struct const *)(__gen_e_acsl__22)); __gmpz_clear(__gen_e_acsl__22); } @@ -275,7 +275,7 @@ int main(void) { mpz_t __gen_e_acsl__23; int __gen_e_acsl_lt_3; - __gmpz_init_set_si(__gen_e_acsl__23,(long)5); + __gmpz_init_set_ui(__gen_e_acsl__23,(unsigned long)5); __gen_e_acsl_lt_3 = __gmpz_cmp((__mpz_struct const *)(__gen_e_acsl_y), (__mpz_struct const *)(__gen_e_acsl__23)); if (__gen_e_acsl_lt_3 < 0) ; else break; @@ -283,7 +283,7 @@ int main(void) } { mpz_t __gen_e_acsl__20; - __gmpz_init_set_si(__gen_e_acsl__20,(long)0); + __gmpz_init_set_ui(__gen_e_acsl__20,(unsigned long)0); __gmpz_set(__gen_e_acsl_z,(__mpz_struct const *)(__gen_e_acsl__20)); __gmpz_clear(__gen_e_acsl__20); } @@ -303,7 +303,7 @@ int main(void) __gmpz_add(__gen_e_acsl_add_7, (__mpz_struct const *)(__gen_e_acsl_x_5), (__mpz_struct const *)(__gen_e_acsl_z)); - __gmpz_init_set_si(__gen_e_acsl__19,(long)1); + __gmpz_init_set_ui(__gen_e_acsl__19,(unsigned long)1); __gmpz_init(__gen_e_acsl_add_8); __gmpz_add(__gen_e_acsl_add_8, (__mpz_struct const *)(__gen_e_acsl_y), @@ -322,7 +322,7 @@ int main(void) { mpz_t __gen_e_acsl__21; mpz_t __gen_e_acsl_add_9; - __gmpz_init_set_si(__gen_e_acsl__21,1L); + __gmpz_init_set_ui(__gen_e_acsl__21,1UL); __gmpz_init(__gen_e_acsl_add_9); __gmpz_add(__gen_e_acsl_add_9, (__mpz_struct const *)(__gen_e_acsl_z), @@ -336,7 +336,7 @@ int main(void) { mpz_t __gen_e_acsl__24; mpz_t __gen_e_acsl_add_10; - __gmpz_init_set_si(__gen_e_acsl__24,1L); + __gmpz_init_set_ui(__gen_e_acsl__24,1UL); __gmpz_init(__gen_e_acsl_add_10); __gmpz_add(__gen_e_acsl_add_10, (__mpz_struct const *)(__gen_e_acsl_y), @@ -350,7 +350,7 @@ int main(void) { mpz_t __gen_e_acsl__27; mpz_t __gen_e_acsl_add_11; - __gmpz_init_set_si(__gen_e_acsl__27,1L); + __gmpz_init_set_ui(__gen_e_acsl__27,1UL); __gmpz_init(__gen_e_acsl_add_11); __gmpz_add(__gen_e_acsl_add_11, (__mpz_struct const *)(__gen_e_acsl_x_5), @@ -375,26 +375,21 @@ int main(void) mpz_t __gen_e_acsl_x_6; __gen_e_acsl_exists = 0; __gmpz_init(__gen_e_acsl_x_6); - { - mpz_t __gen_e_acsl__29; - __gmpz_init_set_si(__gen_e_acsl__29,(long)0); - __gmpz_set(__gen_e_acsl_x_6,(__mpz_struct const *)(__gen_e_acsl__29)); - __gmpz_clear(__gen_e_acsl__29); - } + __gmpz_set_si(__gen_e_acsl_x_6,(long)0); while (1) { { - mpz_t __gen_e_acsl__30; + mpz_t __gen_e_acsl__29; int __gen_e_acsl_lt_5; - __gmpz_init_set_si(__gen_e_acsl__30,(long)10); + __gmpz_init_set_ui(__gen_e_acsl__29,(unsigned long)10); __gen_e_acsl_lt_5 = __gmpz_cmp((__mpz_struct const *)(__gen_e_acsl_x_6), - (__mpz_struct const *)(__gen_e_acsl__30)); + (__mpz_struct const *)(__gen_e_acsl__29)); if (__gen_e_acsl_lt_5 < 0) ; else break; - __gmpz_clear(__gen_e_acsl__30); + __gmpz_clear(__gen_e_acsl__29); } { mpz_t __gen_e_acsl__28; int __gen_e_acsl_eq_5; - __gmpz_init_set_si(__gen_e_acsl__28,(long)5); + __gmpz_init_set_ui(__gen_e_acsl__28,(unsigned long)5); __gen_e_acsl_eq_5 = __gmpz_cmp((__mpz_struct const *)(__gen_e_acsl_x_6), (__mpz_struct const *)(__gen_e_acsl__28)); __gmpz_clear(__gen_e_acsl__28); @@ -405,16 +400,16 @@ int main(void) } } { - mpz_t __gen_e_acsl__31; + mpz_t __gen_e_acsl__30; mpz_t __gen_e_acsl_add_12; - __gmpz_init_set_si(__gen_e_acsl__31,1L); + __gmpz_init_set_ui(__gen_e_acsl__30,1UL); __gmpz_init(__gen_e_acsl_add_12); __gmpz_add(__gen_e_acsl_add_12, (__mpz_struct const *)(__gen_e_acsl_x_6), - (__mpz_struct const *)(__gen_e_acsl__31)); + (__mpz_struct const *)(__gen_e_acsl__30)); __gmpz_set(__gen_e_acsl_x_6, (__mpz_struct const *)(__gen_e_acsl_add_12)); - __gmpz_clear(__gen_e_acsl__31); + __gmpz_clear(__gen_e_acsl__30); __gmpz_clear(__gen_e_acsl_add_12); } } @@ -433,42 +428,37 @@ int main(void) mpz_t __gen_e_acsl_x_7; __gen_e_acsl_forall_6 = 1; __gmpz_init(__gen_e_acsl_x_7); - { - mpz_t __gen_e_acsl__39; - __gmpz_init_set_si(__gen_e_acsl__39,(long)0); - __gmpz_set(__gen_e_acsl_x_7,(__mpz_struct const *)(__gen_e_acsl__39)); - __gmpz_clear(__gen_e_acsl__39); - } + __gmpz_set_si(__gen_e_acsl_x_7,(long)0); while (1) { { - mpz_t __gen_e_acsl__40; + mpz_t __gen_e_acsl__38; int __gen_e_acsl_lt_6; - __gmpz_init_set_si(__gen_e_acsl__40,(long)10); + __gmpz_init_set_ui(__gen_e_acsl__38,(unsigned long)10); __gen_e_acsl_lt_6 = __gmpz_cmp((__mpz_struct const *)(__gen_e_acsl_x_7), - (__mpz_struct const *)(__gen_e_acsl__40)); + (__mpz_struct const *)(__gen_e_acsl__38)); if (__gen_e_acsl_lt_6 < 0) ; else break; - __gmpz_clear(__gen_e_acsl__40); + __gmpz_clear(__gen_e_acsl__38); } { + mpz_t __gen_e_acsl__31; mpz_t __gen_e_acsl__32; - mpz_t __gen_e_acsl__33; int __gen_e_acsl_mod_guard; mpz_t __gen_e_acsl_mod; int __gen_e_acsl_eq_6; int __gen_e_acsl_implies; - __gmpz_init_set_si(__gen_e_acsl__32,(long)2); - __gmpz_init_set_si(__gen_e_acsl__33,0L); - __gen_e_acsl_mod_guard = __gmpz_cmp((__mpz_struct const *)(__gen_e_acsl__32), - (__mpz_struct const *)(__gen_e_acsl__33)); + __gmpz_init_set_ui(__gen_e_acsl__31,(unsigned long)2); + __gmpz_init_set_ui(__gen_e_acsl__32,0UL); + __gen_e_acsl_mod_guard = __gmpz_cmp((__mpz_struct const *)(__gen_e_acsl__31), + (__mpz_struct const *)(__gen_e_acsl__32)); __gmpz_init(__gen_e_acsl_mod); /*@ assert E_ACSL: 2 ≢ 0; */ __e_acsl_assert(! (__gen_e_acsl_mod_guard == 0),(char *)"Assertion", (char *)"main",(char *)"2 == 0",26); __gmpz_tdiv_r(__gen_e_acsl_mod, (__mpz_struct const *)(__gen_e_acsl_x_7), - (__mpz_struct const *)(__gen_e_acsl__32)); + (__mpz_struct const *)(__gen_e_acsl__31)); __gen_e_acsl_eq_6 = __gmpz_cmp((__mpz_struct const *)(__gen_e_acsl_mod), - (__mpz_struct const *)(__gen_e_acsl__33)); + (__mpz_struct const *)(__gen_e_acsl__32)); if (! (__gen_e_acsl_eq_6 == 0)) __gen_e_acsl_implies = 1; else { int __gen_e_acsl_exists_2; @@ -476,23 +466,23 @@ int main(void) __gen_e_acsl_exists_2 = 0; __gmpz_init(__gen_e_acsl_y_2); { - mpz_t __gen_e_acsl__35; - __gmpz_init_set_si(__gen_e_acsl__35,(long)0); + mpz_t __gen_e_acsl__34; + __gmpz_init_set_ui(__gen_e_acsl__34,(unsigned long)0); __gmpz_set(__gen_e_acsl_y_2, - (__mpz_struct const *)(__gen_e_acsl__35)); - __gmpz_clear(__gen_e_acsl__35); + (__mpz_struct const *)(__gen_e_acsl__34)); + __gmpz_clear(__gen_e_acsl__34); } while (1) { { + mpz_t __gen_e_acsl__35; mpz_t __gen_e_acsl__36; - mpz_t __gen_e_acsl__37; int __gen_e_acsl_div_guard; mpz_t __gen_e_acsl_div; int __gen_e_acsl_le_5; - __gmpz_init_set_si(__gen_e_acsl__36,(long)2); - __gmpz_init_set_si(__gen_e_acsl__37,0L); - __gen_e_acsl_div_guard = __gmpz_cmp((__mpz_struct const *)(__gen_e_acsl__36), - (__mpz_struct const *)(__gen_e_acsl__37)); + __gmpz_init_set_ui(__gen_e_acsl__35,(unsigned long)2); + __gmpz_init_set_ui(__gen_e_acsl__36,0UL); + __gen_e_acsl_div_guard = __gmpz_cmp((__mpz_struct const *)(__gen_e_acsl__35), + (__mpz_struct const *)(__gen_e_acsl__36)); __gmpz_init(__gen_e_acsl_div); /*@ assert E_ACSL: 2 ≢ 0; */ __e_acsl_assert(! (__gen_e_acsl_div_guard == 0), @@ -500,26 +490,26 @@ int main(void) (char *)"2 == 0",26); __gmpz_tdiv_q(__gen_e_acsl_div, (__mpz_struct const *)(__gen_e_acsl_x_7), - (__mpz_struct const *)(__gen_e_acsl__36)); + (__mpz_struct const *)(__gen_e_acsl__35)); __gen_e_acsl_le_5 = __gmpz_cmp((__mpz_struct const *)(__gen_e_acsl_y_2), (__mpz_struct const *)(__gen_e_acsl_div)); if (__gen_e_acsl_le_5 <= 0) ; else break; + __gmpz_clear(__gen_e_acsl__35); __gmpz_clear(__gen_e_acsl__36); - __gmpz_clear(__gen_e_acsl__37); __gmpz_clear(__gen_e_acsl_div); } { - mpz_t __gen_e_acsl__34; + mpz_t __gen_e_acsl__33; mpz_t __gen_e_acsl_mul; int __gen_e_acsl_eq_7; - __gmpz_init_set_si(__gen_e_acsl__34,(long)2); + __gmpz_init_set_ui(__gen_e_acsl__33,(unsigned long)2); __gmpz_init(__gen_e_acsl_mul); __gmpz_mul(__gen_e_acsl_mul, - (__mpz_struct const *)(__gen_e_acsl__34), + (__mpz_struct const *)(__gen_e_acsl__33), (__mpz_struct const *)(__gen_e_acsl_y_2)); __gen_e_acsl_eq_7 = __gmpz_cmp((__mpz_struct const *)(__gen_e_acsl_x_7), (__mpz_struct const *)(__gen_e_acsl_mul)); - __gmpz_clear(__gen_e_acsl__34); + __gmpz_clear(__gen_e_acsl__33); __gmpz_clear(__gen_e_acsl_mul); if (! (__gen_e_acsl_eq_7 == 0)) ; else { @@ -528,16 +518,16 @@ int main(void) } } { - mpz_t __gen_e_acsl__38; + mpz_t __gen_e_acsl__37; mpz_t __gen_e_acsl_add_13; - __gmpz_init_set_si(__gen_e_acsl__38,1L); + __gmpz_init_set_ui(__gen_e_acsl__37,1UL); __gmpz_init(__gen_e_acsl_add_13); __gmpz_add(__gen_e_acsl_add_13, (__mpz_struct const *)(__gen_e_acsl_y_2), - (__mpz_struct const *)(__gen_e_acsl__38)); + (__mpz_struct const *)(__gen_e_acsl__37)); __gmpz_set(__gen_e_acsl_y_2, (__mpz_struct const *)(__gen_e_acsl_add_13)); - __gmpz_clear(__gen_e_acsl__38); + __gmpz_clear(__gen_e_acsl__37); __gmpz_clear(__gen_e_acsl_add_13); } } @@ -545,8 +535,8 @@ int main(void) __gen_e_acsl_implies = __gen_e_acsl_exists_2; __gmpz_clear(__gen_e_acsl_y_2); } + __gmpz_clear(__gen_e_acsl__31); __gmpz_clear(__gen_e_acsl__32); - __gmpz_clear(__gen_e_acsl__33); __gmpz_clear(__gen_e_acsl_mod); if (__gen_e_acsl_implies) ; else { @@ -555,16 +545,16 @@ int main(void) } } { - mpz_t __gen_e_acsl__41; + mpz_t __gen_e_acsl__39; mpz_t __gen_e_acsl_add_14; - __gmpz_init_set_si(__gen_e_acsl__41,1L); + __gmpz_init_set_ui(__gen_e_acsl__39,1UL); __gmpz_init(__gen_e_acsl_add_14); __gmpz_add(__gen_e_acsl_add_14, (__mpz_struct const *)(__gen_e_acsl_x_7), - (__mpz_struct const *)(__gen_e_acsl__41)); + (__mpz_struct const *)(__gen_e_acsl__39)); __gmpz_set(__gen_e_acsl_x_7, (__mpz_struct const *)(__gen_e_acsl_add_14)); - __gmpz_clear(__gen_e_acsl__41); + __gmpz_clear(__gen_e_acsl__39); __gmpz_clear(__gen_e_acsl_add_14); } } diff --git a/src/plugins/e-acsl/tests/gmp/oracle/quantif.1.res.oracle b/src/plugins/e-acsl/tests/gmp/oracle/quantif.1.res.oracle index 1c898816ecc..9a921a8df6a 100644 --- a/src/plugins/e-acsl/tests/gmp/oracle/quantif.1.res.oracle +++ b/src/plugins/e-acsl/tests/gmp/oracle/quantif.1.res.oracle @@ -12,7 +12,7 @@ __e_acsl_heap_size ∈ [--..--] tests/gmp/quantif.i:9:[value] warning: assertion got status unknown. [value] using specification for function __gmpz_init -[value] using specification for function __gmpz_init_set_si +[value] using specification for function __gmpz_init_set_ui [value] using specification for function __gmpz_set [value] using specification for function __gmpz_clear tests/gmp/quantif.i:9:[value] entering loop for the first time @@ -29,6 +29,7 @@ tests/gmp/quantif.i:12:[value] entering loop for the first time tests/gmp/quantif.i:16:[value] warning: assertion got status unknown. tests/gmp/quantif.i:16:[value] entering loop for the first time tests/gmp/quantif.i:21:[value] warning: assertion got status unknown. +[value] using specification for function __gmpz_set_si tests/gmp/quantif.i:21:[value] entering loop for the first time tests/gmp/quantif.i:25:[value] warning: assertion got status unknown. tests/gmp/quantif.i:25:[value] entering loop for the first time diff --git a/src/plugins/e-acsl/translate.ml b/src/plugins/e-acsl/translate.ml index 4588a8391ad..cafde44823e 100644 --- a/src/plugins/e-acsl/translate.ml +++ b/src/plugins/e-acsl/translate.ml @@ -151,6 +151,7 @@ let constant_to_exp ~loc t = function raise Cil.Not_representable | (None | Some _), _ -> Cil.kinteger64 ~loc ~kind ?repr n, false with Cil.Not_representable -> + (* too big integer *) Cil.mkString ~loc (Integer.to_string n), true) | LStr s -> Cil.new_exp ~loc (Const (CStr s)), false @@ -297,7 +298,7 @@ and context_insensitive_term_to_exp kf env t = (* [!t] is converted into [t == 0] *) let zero = Logic_const.tinteger 0 in let ctx = Typing.get_integer_ty t in - Typing.type_term ~ctx zero; + Typing.type_term ~force:false ~ctx zero; let e, env = comparison_to_exp kf ~loc ~name:"not" env Typing.gmp Eq t zero (Some t) in @@ -341,7 +342,7 @@ and context_insensitive_term_to_exp kf env t = possible values of [t2] *) (* guarding divisions and modulos *) let zero = Logic_const.tinteger 0 in - Typing.type_term ~ctx zero; + Typing.type_term ~force:false ~ctx zero; (* do not generate [e2] from [t2] twice *) let guard, env = let name = name_of_binop bop ^ "_guard" in @@ -805,7 +806,7 @@ let term_to_exp typ t = | TInt(ik, _) -> Typing.ikind ik | _ -> Typing.c_int (* useless, but required *) in - Typing.type_term ~ctx t; + Typing.type_term ~force:false ~ctx t; let env = Env.empty (new Visitor.frama_c_copy Project_skeleton.dummy) in let env = Env.push env in let env = Env.rte env false in diff --git a/src/plugins/e-acsl/typing.ml b/src/plugins/e-acsl/typing.ml index 0144e50010c..b50e6c300c6 100644 --- a/src/plugins/e-acsl/typing.ml +++ b/src/plugins/e-acsl/typing.ml @@ -45,18 +45,21 @@ let gmp = Gmp let c_int = C_type IInt let ikind ik = C_type ik -let join ty1 ty2 = match ty1, ty2 with - | Other, Other -> Other - | Other, (Gmp | C_type _) | (Gmp | C_type _), Other -> - Options.fatal "[typing] join failure: integer and non integer type" - | Gmp, _ | _, Gmp -> Gmp - | C_type i1, C_type i2 -> - let ty = Cil.arithmeticConversion (TInt(i1, [])) (TInt(i2, [])) in - match ty with - | TInt(i, _) -> C_type i - | _ -> - Options.fatal "[typing] join failure: unexpected result %a" - Printer.pp_typ ty +let join ty1 ty2 = + if Options.Gmp_only.get () then Gmp + else + match ty1, ty2 with + | Other, Other -> Other + | Other, (Gmp | C_type _) | (Gmp | C_type _), Other -> + Options.fatal "[typing] join failure: integer and non integer type" + | Gmp, _ | _, Gmp -> Gmp + | C_type i1, C_type i2 -> + let ty = Cil.arithmeticConversion (TInt(i1, [])) (TInt(i2, [])) in + match ty with + | TInt(i, _) -> C_type i + | _ -> + Options.fatal "[typing] join failure: unexpected result %a" + Printer.pp_typ ty exception Not_an_integer let typ_of_integer_ty = function @@ -165,14 +168,14 @@ let coerce ~ctx ~op ty = (** {2 Type system} *) (******************************************************************************) -let mk_ctx ?(force=false) c = +let mk_ctx ~force c = if force then c else match c with | Other -> Other | Gmp | C_type _ -> if Options.Gmp_only.get () then Gmp else c -let rec type_term env ?force ~ctx t = - let ctx = mk_ctx ?force ctx in +let rec type_term ~force ~ctx t = + let ctx = mk_ctx ~force ctx in let dup ty = ty, ty in let infer t = Cil.CurrentLoc.set t.term_loc; @@ -183,22 +186,21 @@ let rec type_term env ?force ~ctx t = | TAlignOf _ -> let ty = try - let i = Interval.infer env t in + let i = Interval.infer t in ty_of_interv ~ctx i with Interval.Not_an_integer -> Other in dup ty - | TLval tlv -> let ty = try - let i = Interval.infer env t in + let i = Interval.infer t in ty_of_interv ~ctx i with Interval.Not_an_integer -> Other in - type_term_lval env tlv; + type_term_lval tlv; dup ty | Toffset(_, t') @@ -207,9 +209,9 @@ let rec type_term env ?force ~ctx t = | TAlignOfE t' -> let ty = try - let i = Interval.infer env t in + let i = Interval.infer t in (* [t'] must be typed, but it is a pointer *) - ignore (type_term env ~ctx:Other t'); + ignore (type_term ~force:false ~ctx:Other t'); ty_of_interv ~ctx i with Interval.Not_an_integer -> assert false @@ -219,10 +221,10 @@ let rec type_term env ?force ~ctx t = | TBinOp (MinusPP, t1, t2) -> let ty = try - let i = Interval.infer env t in + let i = Interval.infer t in (* [t1] and [t2] must be typed, but they are pointers *) - ignore (type_term env ~ctx:Other t1); - ignore (type_term env ~ctx:Other t2); + ignore (type_term ~force:false ~ctx:Other t1); + ignore (type_term ~force:false ~ctx:Other t2); ty_of_interv ~ctx i with Interval.Not_an_integer -> assert false @@ -232,13 +234,13 @@ let rec type_term env ?force ~ctx t = | TUnOp (unop, t') -> let ctx = try - let i = Interval.infer env t in - let i' = Interval.infer env t' in - mk_ctx (ty_of_interv ~ctx (Interval.join i i')) + let i = Interval.infer t in + let i' = Interval.infer t' in + mk_ctx ~force:false (ty_of_interv ~ctx (Interval.join i i')) with Interval.Not_an_integer -> Other (* real *) in - ignore (type_term env ~ctx t'); + ignore (type_term ~force:false ~ctx t'); (match unop with | LNot -> c_int, ctx (* converted into [t == 0] in casse of GMP *) | Neg | BNot -> dup ctx) @@ -246,29 +248,30 @@ let rec type_term env ?force ~ctx t = | TBinOp((PlusA | MinusA | Mult | Div | Mod | Shiftlt | Shiftrt), t1, t2) -> let ctx = try - let i = Interval.infer env t in - let i1 = Interval.infer env t1 in - let i2 = Interval.infer env t2 in - mk_ctx (ty_of_interv ~ctx (Interval.join i (Interval.join i1 i2))) + let i = Interval.infer t in + let i1 = Interval.infer t1 in + let i2 = Interval.infer t2 in + let ctx = ty_of_interv ~ctx (Interval.join i (Interval.join i1 i2)) in + mk_ctx ~force:false ctx with Interval.Not_an_integer -> Other (* real *) in - ignore (type_term env ~ctx t1); - ignore (type_term env ~ctx t2); + ignore (type_term ~force ~ctx t1); + ignore (type_term ~force ~ctx t2); dup ctx | TBinOp ((Lt | Gt | Le | Ge | Eq | Ne), t1, t2) -> assert (compare ctx c_int >= 0); let ctx = try - let i1 = Interval.infer env t1 in - let i2 = Interval.infer env t2 in - mk_ctx (ty_of_interv ~ctx (Interval.join i1 i2)) + let i1 = Interval.infer t1 in + let i2 = Interval.infer t2 in + mk_ctx ~force:false (ty_of_interv ~ctx (Interval.join i1 i2)) with Interval.Not_an_integer -> Other in - ignore (type_term env ~ctx t1); - ignore (type_term env ~ctx t2); + ignore (type_term ~force:false ~ctx t1); + ignore (type_term ~force:false ~ctx t2); let ty = match ctx with | Other -> c_int | Gmp | C_type _ -> ctx @@ -278,15 +281,15 @@ let rec type_term env ?force ~ctx t = | TBinOp ((LAnd | LOr), t1, t2) -> let ty = try - let i1 = Interval.infer env t1 in - let i2 = Interval.infer env t2 in + let i1 = Interval.infer t1 in + let i2 = Interval.infer t2 in ty_of_interv ~ctx (Interval.join i1 i2) with Interval.Not_an_integer -> Other in (* both operands fit in an int. *) - ignore (type_term env ~ctx:c_int t1); - ignore (type_term env ~ctx:c_int t2); + ignore (type_term ~force:false ~ctx:c_int t1); + ignore (type_term ~force:false ~ctx:c_int t2); dup ty | TBinOp (BAnd, _, _) -> Error.not_yet "bitwise and" @@ -297,7 +300,7 @@ let rec type_term env ?force ~ctx t = | TCoerce(t', _) -> let ctx = try - let i = Interval.infer env t' in + let i = Interval.infer t' in (* nothing more to do: [i] is already more precise than what we could infer from the arguments of the cast. Also, do not type the internal term: possibly it is not even an integer *) @@ -305,58 +308,59 @@ let rec type_term env ?force ~ctx t = with Interval.Not_an_integer -> Other in - ignore (type_term env ~ctx t'); + ignore (type_term ~force:false ~ctx t'); dup ctx | Tif (t1, t2, t3) -> - let ctx = mk_ctx c_int in - ignore (type_term env ~ctx t1); - let i = Interval.infer env t in + let ctx1 = mk_ctx ~force:true c_int in + ignore (type_term ~force:true ~ctx:ctx1 t1); + let i = Interval.infer t in let ctx = try - let i2 = Interval.infer env t2 in - let i3 = Interval.infer env t3 in - mk_ctx (ty_of_interv ~ctx (Interval.join i (Interval.join i2 i3))) + let i2 = Interval.infer t2 in + let i3 = Interval.infer t3 in + let ctx = ty_of_interv ~ctx (Interval.join i (Interval.join i2 i3)) in + mk_ctx ~force:false ctx with Interval.Not_an_integer -> Other in - ignore (type_term env ~ctx t2); - ignore (type_term env ~ctx t3); + ignore (type_term ~force:false ~ctx t2); + ignore (type_term ~force:false ~ctx t3); dup ctx | Tat (t, _) - | TLogic_coerce (_, t) -> dup (type_term env ~ctx t).ty + | TLogic_coerce (_, t) -> dup (type_term ~force:false ~ctx t).ty | TCoerceE (t1, t2) -> let ctx = try - let i = Interval.infer env t in - let i1 = Interval.infer env t1 in - let i2 = Interval.infer env t2 in + let i = Interval.infer t in + let i1 = Interval.infer t1 in + let i2 = Interval.infer t2 in ty_of_interv ~ctx (Interval.join i (Interval.join i1 i2)) with Interval.Not_an_integer -> Other in - ignore (type_term env ~ctx t1); - ignore (type_term env ~ctx t2); + ignore (type_term ~force:true ~ctx t1); + ignore (type_term ~force:true ~ctx t2); dup ctx | TAddrOf tlv | TStartOf tlv -> (* it is a pointer, as well as [t], but [t] must be typed. *) - type_term_lval env tlv; + type_term_lval tlv; dup Other | Tbase_addr (_, t) -> (* it is a pointer, as well as [t], but [t] must be typed. *) - ignore (type_term env ~ctx:Other t); + ignore (type_term ~force:false ~ctx:Other t); dup Other | TBinOp ((PlusPI | IndexPI | MinusPI), t1, t2) -> (* it is a pointer, as well as [t1], while [t2] is a size_t. Both [t1] and [t2] must be typed. *) - ignore (type_term env ~ctx:Other t1); - ignore (type_term env ~force:true ~ctx:(size_t ()) t2); + ignore (type_term ~force:false ~ctx:Other t1); + ignore (type_term ~force:true ~ctx:(size_t ()) t2); dup Other | Tapp (_,_,_) -> Error.not_yet "logic function application" @@ -377,25 +381,25 @@ let rec type_term env ?force ~ctx t = in Memo.memo (fun t -> let ty, op = infer t in coerce ~ctx ~op ty) t -and type_term_lval env (host, offset) = - type_term_lhost env host; - type_term_offset env offset +and type_term_lval (host, offset) = + type_term_lhost host; + type_term_offset offset -and type_term_lhost env = function +and type_term_lhost = function | TVar _ | TResult _ -> () - | TMem t -> ignore (type_term env ~ctx:Other t) + | TMem t -> ignore (type_term ~force:false ~ctx:Other t) -and type_term_offset env = function +and type_term_offset = function | TNoOffset -> () | TField(_, toff) - | TModel(_, toff) -> type_term_offset env toff + | TModel(_, toff) -> type_term_offset toff | TIndex(t, toff) -> - (* [t] is an array index which must fits into size_t *) - ignore (type_term env ~force:true ~ctx:(size_t ()) t); - type_term_offset env toff + (* [t] is an array index which must fit into size_t *) + ignore (type_term ~force:true ~ctx:(size_t ()) t); + type_term_offset toff -let rec type_predicate_named env p = +let rec type_predicate_named p = Cil.CurrentLoc.set p.loc; let op = match p.content with | Pfalse | Ptrue -> c_int @@ -405,15 +409,15 @@ let rec type_predicate_named env p = | Prel(_, t1, t2) -> let ctx = try - let i1 = Interval.infer env t1 in - let i2 = Interval.infer env t2 in + let i1 = Interval.infer t1 in + let i2 = Interval.infer t2 in let i = Interval.join i1 i2 in - mk_ctx (ty_of_interv ~ctx:c_int i) + mk_ctx ~force:false (ty_of_interv ~ctx:c_int i) with Interval.Not_an_integer -> Other in - ignore (type_term env ~ctx t1); - ignore (type_term env ~ctx t2); + ignore (type_term ~force:false ~ctx t1); + ignore (type_term ~force:false ~ctx t2); (match ctx with | Other -> c_int | Gmp | C_type _ -> ctx) @@ -422,62 +426,59 @@ let rec type_predicate_named env p = | Pxor(p1, p2) | Pimplies(p1, p2) | Piff(p1, p2) -> - ignore (type_predicate_named env p1); - ignore (type_predicate_named env p2); + ignore (type_predicate_named p1); + ignore (type_predicate_named p2); c_int | Pnot p -> - ignore (type_predicate_named env p); + ignore (type_predicate_named p); c_int | Pif(t, p1, p2) -> - let ctx = mk_ctx c_int in - ignore (type_term env ~ctx t); - ignore (type_predicate_named env p1); - ignore (type_predicate_named env p2); + let ctx = mk_ctx ~force:true c_int in + ignore (type_term ~force:true ~ctx t); + ignore (type_predicate_named p1); + ignore (type_predicate_named p2); c_int | Plet _ -> Error.not_yet "let _ = _ in _" + | Pforall(bounded_vars, { content = Pimplies(hyps, goal) }) | Pexists(bounded_vars, { content = Pand(hyps, goal) }) -> let guards = !compute_quantif_guards_ref p bounded_vars hyps in - let env = - List.fold_left - (fun env (t1, r1, x, r2, t2) -> - let i1 = Interval.infer env t1 in - let i1 = match r1 with - | Rlt -> Interval.add i1 Integer.one - | Rle -> i1 - | _ -> assert false - in - let i2 = Interval.infer env t2 in + List.iter + (fun (t1, r1, x, r2, t2) -> + let i1 = Interval.infer t1 in + let i1 = match r1 with + | Rlt -> Interval.add i1 Integer.one + | Rle -> i1 + | _ -> assert false + in + let i2 = Interval.infer t2 in (* add one to [i2], since we increment the loop counter one more - time before going out the loop. *) - let i2 = match r2 with - | Rlt -> i2 - | Rle -> Interval.add i2 Integer.one - | _ -> assert false - in - let i = Interval.join i1 i2 in - let ctx = match x.lv_type with - | Linteger -> Gmp - | Ctype ty -> - (match Cil.unrollType ty with - | TInt(ik, _) -> C_type ik - | ty -> - Options.fatal "unexpected type %a for quantified variable %a" - Printer.pp_typ ty - Printer.pp_logic_var x) - | lty -> + time before going outside the loop. *) + let i2 = match r2 with + | Rlt -> i2 + | Rle -> Interval.add i2 Integer.one + | _ -> assert false + in + let i = Interval.join i1 i2 in + let ctx = match x.lv_type with + | Linteger -> mk_ctx ~force:false (ty_of_interv ~ctx:Gmp i) + | Ctype ty -> + (match Cil.unrollType ty with + | TInt(ik, _) -> C_type ik + | ty -> Options.fatal "unexpected type %a for quantified variable %a" - Printer.pp_logic_type lty - Printer.pp_logic_var x - in - let ctx = mk_ctx (ty_of_interv ~ctx i) in - ignore (type_term env ~ctx t1); - ignore (type_term env ~ctx t2); - Interval.Env.add x i env) - env - guards - in - (type_predicate_named env goal).ty + Printer.pp_typ ty + Printer.pp_logic_var x) + | lty -> + Options.fatal "unexpected type %a for quantified variable %a" + Printer.pp_logic_type lty + Printer.pp_logic_var x + in + ignore (type_term ~force:true ~ctx t1); + ignore (type_term ~force:true ~ctx t2); + Interval.Env.add x i) + guards; + (type_predicate_named goal).ty | Pinitialized(_, t) | Pfreeable(_, t) @@ -485,27 +486,30 @@ let rec type_predicate_named env p = | Pvalid(_, t) | Pvalid_read(_, t) | Pvalid_function t -> - ignore (type_term env ~ctx:Other t); + ignore (type_term ~force:false ~ctx:Other t); c_int | Pforall _ -> Error.not_yet "unguarded \\forall quantification" | Pexists _ -> Error.not_yet "unguarded \\exists quantification" - | Pat(p, _) -> (type_predicate_named env p).ty + | Pat(p, _) -> (type_predicate_named p).ty | Pfresh _ -> Error.not_yet "\\fresh" | Psubtype _ -> Error.not_yet "subtyping relation" (* Jessie specific *) in coerce ~ctx:c_int ~op c_int -let type_term ~ctx t = +let type_term ~force ~ctx t = Options.feedback ~dkey ~level:4 "typing term '%a' in ctx '%a'." Printer.pp_term t pretty ctx; - ignore (type_term Interval.Env.empty ~ctx t) + ignore (type_term ~force ~ctx t) let type_named_predicate ?(must_clear=true) p = Options.feedback ~dkey ~level:3 "typing predicate '%a'." Printer.pp_predicate_named p; - if must_clear then Memo.clear (); - ignore (type_predicate_named Interval.Env.empty p) + if must_clear then begin + Interval.Env.clear (); + Memo.clear () + end; + ignore (type_predicate_named p) (******************************************************************************) (** {2 Getters} *) @@ -513,17 +517,19 @@ let type_named_predicate ?(must_clear=true) p = let get_integer_ty t = (Memo.get t).ty let get_integer_op t = (Memo.get t).op - -let get_integer_op_of_predicate p = - (type_predicate_named Interval.Env.empty (* the env is useless *) p).op +let get_integer_op_of_predicate p = (type_predicate_named p).op let extract_typ t ty = try typ_of_integer_ty ty with Not_an_integer -> - let ty = t.term_type in - if Cil.isLogicRealType ty then TFloat(FLongDouble, []) - else if Cil.isLogicFloatType ty then Logic_utils.logicCType ty - else assert false + let lty = t.term_type in + if Cil.isLogicRealType lty then TFloat(FLongDouble, []) + else if Cil.isLogicFloatType lty then Logic_utils.logicCType lty + else + Kernel.fatal "unexpected types %a and %a for term %a" + Printer.pp_logic_type lty + pretty ty + Printer.pp_term t let get_typ t = let info = Memo.get t in @@ -540,8 +546,7 @@ let get_cast t = with Not_an_integer -> None let get_cast_of_predicate p = - (* the env is useless *) - let info = type_predicate_named Interval.Env.empty p in + let info = type_predicate_named p in try Extlib.opt_map typ_of_integer_ty info.cast with Not_an_integer -> assert false diff --git a/src/plugins/e-acsl/typing.mli b/src/plugins/e-acsl/typing.mli index 93b80b960c4..2d90b0ec691 100644 --- a/src/plugins/e-acsl/typing.mli +++ b/src/plugins/e-acsl/typing.mli @@ -35,6 +35,8 @@ type integer_ty = private | C_type of ikind | Other +include Datatype.S with type t = integer_ty + val gmp: integer_ty val c_int: integer_ty val ikind: ikind -> integer_ty @@ -47,8 +49,10 @@ val join: integer_ty -> integer_ty -> integer_ty (** {2 Typing} *) (******************************************************************************) -val type_term: ctx:integer_ty -> term -> unit -(** Compute the type of each subterm of the given term. *) +val type_term: force:bool -> ctx:integer_ty -> term -> unit +(** Compute the type of each subterm of the given term in the given context. If + [force] is true, then the conversion to the given context is done even if + -e-acsl-gmp-only is set. *) val type_named_predicate: ?must_clear:bool -> predicate named -> unit (** Compute the type of each term of the given predicate. *) -- GitLab