From b25866a735412442ed4dff0dd47b2dcc397ff22a Mon Sep 17 00:00:00 2001 From: Julien Signoles <julien.signoles@cea.fr> Date: Mon, 27 Feb 2017 13:56:11 +0100 Subject: [PATCH] [typing] fix issue with -e-acsl-gmp-only and quantifier --- .../e-acsl/tests/gmp/oracle/gen_quantif.c | 35 ++++++++++ .../e-acsl/tests/gmp/oracle/gen_quantif2.c | 65 +++++++++++++++++++ .../tests/gmp/oracle/quantif.0.res.oracle | 7 ++ .../tests/gmp/oracle/quantif.1.res.oracle | 8 +++ src/plugins/e-acsl/tests/gmp/quantif.i | 5 ++ src/plugins/e-acsl/typing.ml | 17 +++-- src/plugins/e-acsl/typing.mli | 2 + 7 files changed, 135 insertions(+), 4 deletions(-) diff --git a/src/plugins/e-acsl/tests/gmp/oracle/gen_quantif.c b/src/plugins/e-acsl/tests/gmp/oracle/gen_quantif.c index cd49f58f7fe..05fec071e8b 100644 --- a/src/plugins/e-acsl/tests/gmp/oracle/gen_quantif.c +++ b/src/plugins/e-acsl/tests/gmp/oracle/gen_quantif.c @@ -3,6 +3,7 @@ int main(void) { int __retres; + __e_acsl_memory_init((int *)0,(char ***)0,(size_t)8); /*@ assert ∀ ℤ x; 0 ≤ x ≤ 1 ⇒ x ≡ 0 ∨ x ≡ 1; */ { { @@ -204,7 +205,41 @@ int main(void) 25); } } + { + int buf[10]; + __e_acsl_store_block((void *)(buf),(size_t)40); + /*@ assert ∀ ℤ i; 0 ≤ i < 10 ⇒ \valid(&buf[i]); */ + { + { + int __gen_e_acsl_forall_7; + int __gen_e_acsl_i; + __gen_e_acsl_forall_7 = 1; + __gen_e_acsl_i = 0; + while (1) { + if (__gen_e_acsl_i < 10) ; else break; + { + int __gen_e_acsl_valid; + __gen_e_acsl_valid = __e_acsl_valid((void *)(& buf[__gen_e_acsl_i]), + sizeof(int)); + if (__gen_e_acsl_valid) ; + else { + __gen_e_acsl_forall_7 = 0; + goto e_acsl_end_loop9; + } + } + __gen_e_acsl_i ++; + } + e_acsl_end_loop9: ; + __e_acsl_assert(__gen_e_acsl_forall_7,(char *)"Assertion", + (char *)"main", + (char *)"\\forall integer i; 0 <= i < 10 ==> \\valid(&buf[i])", + 30); + __e_acsl_delete_block((void *)(buf)); + } + } + } __retres = 0; + __e_acsl_memory_clean(); return __retres; } 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 558fad0101c..6cd4639620c 100644 --- a/src/plugins/e-acsl/tests/gmp/oracle/gen_quantif2.c +++ b/src/plugins/e-acsl/tests/gmp/oracle/gen_quantif2.c @@ -3,6 +3,7 @@ int main(void) { int __retres; + __e_acsl_memory_init((int *)0,(char ***)0,(size_t)8); /*@ assert ∀ ℤ x; 0 ≤ x ≤ 1 ⇒ x ≡ 0 ∨ x ≡ 1; */ { { @@ -596,7 +597,71 @@ int main(void) __gmpz_clear(__gen_e_acsl_x_7); } } + { + int buf[10]; + __e_acsl_store_block((void *)(buf),(size_t)40); + /*@ assert ∀ ℤ i; 0 ≤ i < 10 ⇒ \valid(&buf[i]); */ + { + { + int __gen_e_acsl_forall_7; + __e_acsl_mpz_t __gen_e_acsl_i; + __gen_e_acsl_forall_7 = 1; + __gmpz_init(__gen_e_acsl_i); + { + __e_acsl_mpz_t __gen_e_acsl__40; + __gmpz_init_set_si(__gen_e_acsl__40,0L); + __gmpz_set(__gen_e_acsl_i, + (__e_acsl_mpz_struct const *)(__gen_e_acsl__40)); + __gmpz_clear(__gen_e_acsl__40); + } + while (1) { + { + __e_acsl_mpz_t __gen_e_acsl__41; + int __gen_e_acsl_lt_7; + __gmpz_init_set_si(__gen_e_acsl__41,10L); + __gen_e_acsl_lt_7 = __gmpz_cmp((__e_acsl_mpz_struct const *)(__gen_e_acsl_i), + (__e_acsl_mpz_struct const *)(__gen_e_acsl__41)); + if (__gen_e_acsl_lt_7 < 0) ; else break; + __gmpz_clear(__gen_e_acsl__41); + } + { + long __gen_e_acsl_i_2; + int __gen_e_acsl_valid; + __gen_e_acsl_i_2 = __gmpz_get_si((__e_acsl_mpz_struct const *)(__gen_e_acsl_i)); + __gen_e_acsl_valid = __e_acsl_valid((void *)(& buf[__gen_e_acsl_i_2]), + sizeof(int)); + if (__gen_e_acsl_valid) ; + else { + __gen_e_acsl_forall_7 = 0; + goto e_acsl_end_loop9; + } + } + { + __e_acsl_mpz_t __gen_e_acsl__42; + __e_acsl_mpz_t __gen_e_acsl_add_15; + __gmpz_init_set_si(__gen_e_acsl__42,1L); + __gmpz_init(__gen_e_acsl_add_15); + __gmpz_add(__gen_e_acsl_add_15, + (__e_acsl_mpz_struct const *)(__gen_e_acsl_i), + (__e_acsl_mpz_struct const *)(__gen_e_acsl__42)); + __gmpz_set(__gen_e_acsl_i, + (__e_acsl_mpz_struct const *)(__gen_e_acsl_add_15)); + __gmpz_clear(__gen_e_acsl__42); + __gmpz_clear(__gen_e_acsl_add_15); + } + } + e_acsl_end_loop9: ; + __e_acsl_assert(__gen_e_acsl_forall_7,(char *)"Assertion", + (char *)"main", + (char *)"\\forall integer i; 0 <= i < 10 ==> \\valid(&buf[i])", + 30); + __gmpz_clear(__gen_e_acsl_i); + __e_acsl_delete_block((void *)(buf)); + } + } + } __retres = 0; + __e_acsl_memory_clean(); return __retres; } diff --git a/src/plugins/e-acsl/tests/gmp/oracle/quantif.0.res.oracle b/src/plugins/e-acsl/tests/gmp/oracle/quantif.0.res.oracle index ee86d9b6561..4995ae47205 100644 --- a/src/plugins/e-acsl/tests/gmp/oracle/quantif.0.res.oracle +++ b/src/plugins/e-acsl/tests/gmp/oracle/quantif.0.res.oracle @@ -14,6 +14,7 @@ FRAMAC_SHARE/libc/stdlib.h:277:[kernel] warning: No code nor implicit assigns cl __e_acsl_init ∈ [--..--] __e_acsl_internal_heap ∈ [--..--] __e_acsl_heap_allocation_size ∈ [--..--] +[value] using specification for function __e_acsl_memory_init tests/gmp/quantif.i:9:[value] warning: assertion got status unknown. tests/gmp/quantif.i:9:[value] entering loop for the first time [value] using specification for function __e_acsl_assert @@ -31,4 +32,10 @@ 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 tests/gmp/quantif.i:26:[value] entering loop for the first time +[value] using specification for function __e_acsl_store_block +tests/gmp/quantif.i:30:[value] warning: assertion got status unknown. +tests/gmp/quantif.i:30:[value] entering loop for the first time +[value] using specification for function __e_acsl_valid +[value] using specification for function __e_acsl_delete_block +[value] using specification for function __e_acsl_memory_clean [value] done for function main 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 5621b649209..8fa4c96f4f3 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 @@ -14,6 +14,7 @@ FRAMAC_SHARE/libc/stdlib.h:277:[kernel] warning: No code nor implicit assigns cl __e_acsl_init ∈ [--..--] __e_acsl_internal_heap ∈ [--..--] __e_acsl_heap_allocation_size ∈ [--..--] +[value] using specification for function __e_acsl_memory_init 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 @@ -41,4 +42,11 @@ tests/gmp/quantif.i:25:[value] entering loop for the first time tests/gmp/quantif.i:26:[value] entering loop for the first time [value] using specification for function __gmpz_tdiv_q [value] using specification for function __gmpz_mul +[value] using specification for function __e_acsl_store_block +tests/gmp/quantif.i:30:[value] warning: assertion got status unknown. +tests/gmp/quantif.i:30:[value] entering loop for the first time +[value] using specification for function __gmpz_get_si +[value] using specification for function __e_acsl_valid +[value] using specification for function __e_acsl_delete_block +[value] using specification for function __e_acsl_memory_clean [value] done for function main diff --git a/src/plugins/e-acsl/tests/gmp/quantif.i b/src/plugins/e-acsl/tests/gmp/quantif.i index 81531e338c2..c6e7b2d842e 100644 --- a/src/plugins/e-acsl/tests/gmp/quantif.i +++ b/src/plugins/e-acsl/tests/gmp/quantif.i @@ -25,5 +25,10 @@ int main(void) { /*@ assert \forall int x; 0 <= x < 10 ==> x % 2 == 0 ==> \exists integer y; 0 <= y <= x/2 && x == 2 * y; */ + { // Gitlab issue #42 + int buf[10]; + /*@ assert \forall integer i; 0 <= i < 10 ==> \valid(buf+i); */ + } + return 0; } diff --git a/src/plugins/e-acsl/typing.ml b/src/plugins/e-acsl/typing.ml index 4c7a0424dc2..3ad11c0c70e 100644 --- a/src/plugins/e-acsl/typing.ml +++ b/src/plugins/e-acsl/typing.ml @@ -178,7 +178,9 @@ let ty_of_interv ?ctx i = let ukind = Cil.intKindForValue u is_pos in (* kind corresponding to the interval *) if Cil.intTypeIncluded lkind ukind then ukind else lkind - | _, _ -> Kernel.fatal ~current:true "ival: %a" Ival.pretty i + | None, None -> raise Cil.Not_representable (* GMP *) + | None, Some _ | Some _, None -> + Kernel.fatal ~current:true "ival: %a" Ival.pretty i in (* convert the kind to [IInt] whenever smaller. *) let kind = if Cil.intTypeIncluded itv_kind IInt then IInt else itv_kind in @@ -553,8 +555,8 @@ let rec type_predicate p = | _ -> assert false in let i2 = Interval.infer t2 in - (* add one to [i2], since we increment the loop counter one more - time before going outside the loop. *) + (* add one to [i2], since we increment the loop counter one more + time before going outside the loop. *) let i2 = match r2 with | Rlt -> i2 | Rle -> Ival.add_singleton_int Integer.one i2 @@ -579,6 +581,13 @@ let rec type_predicate p = GMP variable when --e-acsl-gmp-only *) ignore (type_term ~use_gmp_opt:false ~ctx t1); ignore (type_term ~use_gmp_opt:false ~ctx t2); + (* if we must generate GMP code, degrade the interval in order to + guarantee that [x] will be a GMP when typing the goal *) + let i = match ctx with + | C_type _ -> i + | Gmp -> Ival.inject_range None None (* [ -\infty; +\infty ] *) + | Other -> assert false + in Interval.Env.add x i) guards; (type_predicate goal).ty @@ -589,7 +598,7 @@ let rec type_predicate p = | Pvalid(_, t) | Pvalid_read(_, t) | Pvalid_function t -> - ignore (type_term ~use_gmp_opt:true ~ctx:Other t); + ignore (type_term ~use_gmp_opt:false ~ctx:Other t); c_int | Pforall _ -> Error.not_yet "unguarded \\forall quantification" diff --git a/src/plugins/e-acsl/typing.mli b/src/plugins/e-acsl/typing.mli index 2cfeff48d33..1c79574742f 100644 --- a/src/plugins/e-acsl/typing.mli +++ b/src/plugins/e-acsl/typing.mli @@ -56,6 +56,8 @@ type integer_ty = private | C_type of ikind | Other (** Any non-integral type *) +val pretty: Format.formatter -> integer_ty -> unit + (** {3 Smart constructors} *) val gmp: integer_ty -- GitLab