From cb0d67a84bd73b571df59a009ef9a81f0eb39dfd Mon Sep 17 00:00:00 2001
From: Julien Signoles <julien.signoles@cea.fr>
Date: Thu, 28 May 2015 14:54:06 +0200
Subject: [PATCH] [typing] fix typing of \block_length and \offset

---
 src/plugins/e-acsl/doc/Changelog              |  1 +
 .../e-acsl-runtime/oracle/gen_mainargs.c      | 45 ++++++++++++++++++-
 src/plugins/e-acsl/translate.ml               |  2 +-
 src/plugins/e-acsl/typing.ml                  | 26 +++++++----
 src/plugins/e-acsl/typing.mli                 |  2 +-
 5 files changed, 64 insertions(+), 12 deletions(-)

diff --git a/src/plugins/e-acsl/doc/Changelog b/src/plugins/e-acsl/doc/Changelog
index a8ccb4ffa76..5eefc9d5eaa 100644
--- a/src/plugins/e-acsl/doc/Changelog
+++ b/src/plugins/e-acsl/doc/Changelog
@@ -15,6 +15,7 @@
 #   E-ACSL: the Whole E-ACSL plug-in
 ###############################################################################
 
+-* E-ACSL       [2015/05/28] Fix types of \block_length and \offset.
 -  E-ACSL       [2015/05/27] Search .h in the E-ACSL memory model by
 	        default (easier to use declarations like __memory_size).
 -  E-ACSL       [2015/05/27] Compatibility with new Frama-C Sodium option
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 2dffc64ca52..a4eacb8e664 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
@@ -32,6 +32,39 @@ axiomatic dynamic_allocation {
  */
 /*@ ghost extern int __e_acsl_init; */
 
+/*@ requires ¬\initialized(z);
+    ensures \valid(\old(z));
+    ensures \initialized(\old(z));
+    assigns *z;
+    assigns *z \from n;
+    allocates \old(z);
+ */
+extern  __attribute__((__FC_BUILTIN__)) void __gmpz_init_set_ui(__mpz_struct * /*[1]*/ z,
+                                                                unsigned long n);
+
+/*@ requires ¬\initialized(z);
+    ensures \valid(\old(z));
+    ensures \initialized(\old(z));
+    assigns *z;
+    assigns *z \from n;
+    allocates \old(z);
+ */
+extern  __attribute__((__FC_BUILTIN__)) void __gmpz_init_set_si(__mpz_struct * /*[1]*/ z,
+                                                                long n);
+
+/*@ requires \valid(x);
+    assigns *x;
+    assigns *x \from *x; */
+extern  __attribute__((__FC_BUILTIN__)) void __gmpz_clear(__mpz_struct * /*[1]*/ x);
+
+/*@ requires \valid_read(z1);
+    requires \valid_read(z2);
+    assigns \result;
+    assigns \result \from *z1, *z2;
+ */
+extern  __attribute__((__FC_BUILTIN__)) int __gmpz_cmp(__mpz_struct const * /*[1]*/ z1,
+                                                       __mpz_struct const * /*[1]*/ z2);
+
 /*@ assigns \nothing; */
 extern  __attribute__((__FC_BUILTIN__)) void __init_args(int argc_ref,
                                                          char **argv_ref);
@@ -404,11 +437,19 @@ int main(int argc, char **argv)
   /*@ assert \block_length(argv) ≡ (argc+1)*sizeof(char *); */
   {
     unsigned long __e_acsl_block_length;
+    mpz_t __e_acsl_block_length_2;
+    mpz_t __e_acsl;
+    int __e_acsl_eq;
     __e_acsl_block_length = __block_length((void *)argv);
-    e_acsl_assert(__e_acsl_block_length == (unsigned long)(((long)argc + (long)1) * 8L),
-                  (char *)"Assertion",(char *)"main",
+    __gmpz_init_set_ui(__e_acsl_block_length_2,__e_acsl_block_length);
+    __gmpz_init_set_si(__e_acsl,((long)argc + (long)1) * 8L);
+    __e_acsl_eq = __gmpz_cmp((__mpz_struct const *)(__e_acsl_block_length_2),
+                             (__mpz_struct const *)(__e_acsl));
+    e_acsl_assert(__e_acsl_eq == 0,(char *)"Assertion",(char *)"main",
                   (char *)"\\block_length(argv) == (argc+1)*sizeof(char *)",
                   15);
+    __gmpz_clear(__e_acsl_block_length_2);
+    __gmpz_clear(__e_acsl);
   }
   /*@ assert *(argv+argc) ≡ \null; */
   {
diff --git a/src/plugins/e-acsl/translate.ml b/src/plugins/e-acsl/translate.ml
index 824eb210ff2..b177a968fcd 100644
--- a/src/plugins/e-acsl/translate.ml
+++ b/src/plugins/e-acsl/translate.ml
@@ -84,7 +84,7 @@ let name_of_mpz_arith_bop = function
 let constant_to_exp ~loc = function
   | Integer(n, repr) ->
     (try
-       let kind = Typing.typ_of_integer n (Integer.ge n Integer.zero) in
+       let kind = Typing.ikind_of_integer n (Integer.ge n Integer.zero) in
        if Typing.is_representable n kind then 
          Cil.kinteger64 ~loc ~kind ?repr n, false
        else 
diff --git a/src/plugins/e-acsl/typing.ml b/src/plugins/e-acsl/typing.ml
index 89ae8344e8f..36a1af9f2ec 100644
--- a/src/plugins/e-acsl/typing.ml
+++ b/src/plugins/e-acsl/typing.ml
@@ -57,7 +57,7 @@ let pretty_eacsl_typ fmt = function
   | Z -> Format.fprintf fmt "Z"
   | No_integral lty -> Format.fprintf fmt "%a" Printer.pp_logic_type lty
 
-let typ_of_integer i unsigned = 
+let ikind_of_integer i unsigned = 
   (* int whenever possible to prevent superfluous casts in the generated code *)
   if Cil.fitsInInt IInt i then IInt else Cil.intKindForValue i unsigned
 
@@ -65,8 +65,8 @@ let typ_of_eacsl_typ = function
   | Interv(l, u) -> 
     let is_pos = Z.ge l Z.zero in
     (try 
-       let ty_l = TInt(typ_of_integer l is_pos, []) in
-       let ty_u = TInt(typ_of_integer u is_pos, []) in
+       let ty_l = TInt(ikind_of_integer l is_pos, []) in
+       let ty_u = TInt(ikind_of_integer u is_pos, []) in
        Cil.arithmeticConversion ty_l ty_u
      with Cil.Not_representable -> 
        Mpz.t ())
@@ -322,12 +322,22 @@ let rec type_term t =
       dup (join ty2) ty3
     | Tat(t, _)
     | Tbase_addr(_, t) -> dup type_term t
-    | Toffset(_, t)
-    | Tblock_length(_, t) -> 
+    | Toffset(_, t) ->
       ignore (type_term t);
-      (* TODO: to be improved by computing the length of the type of the
-	 pointer *)
-      dup eacsl_typ_of_typ Cil.theMachine.Cil.typeOfSizeOf
+      let n = Z.div (Bit_utils.max_bit_address ()) (Z.of_int 8) in
+      let ty =
+        try TInt(ikind_of_integer n true, [])
+        with Cil.Not_representable -> Mpz.t ()
+      in
+      dup eacsl_typ_of_typ ty
+    | Tblock_length(_, t) ->
+      ignore (type_term t);
+      let n = Z.div (Bit_utils.max_bit_size ()) (Z.of_int 8) in
+      let ty =
+        try TInt(ikind_of_integer n true, [])
+        with Cil.Not_representable -> Mpz.t ()
+      in
+      dup eacsl_typ_of_typ ty
     | Tnull -> dup int_to_interv 0
     | TLogic_coerce(_, t) -> dup type_term t
     | TCoerce(t, ty) -> 
diff --git a/src/plugins/e-acsl/typing.mli b/src/plugins/e-acsl/typing.mli
index f2cbdab0616..71cd5d84e6b 100644
--- a/src/plugins/e-acsl/typing.mli
+++ b/src/plugins/e-acsl/typing.mli
@@ -26,7 +26,7 @@ open Cil_types
 (** {2 Typing} *)
 (******************************************************************************)
 
-val typ_of_integer: Integer.t -> bool -> ikind
+val ikind_of_integer: Integer.t -> bool -> ikind
 (** Compute the best type of a bigint. The boolean must be [true] for unsigned
     and [false] for signed.
     @raise Cil.Not_representable if the integer does not fit in any C type. *)
-- 
GitLab