From ee58e76705fbb8d9fde4acd531f930fa3c3119c3 Mon Sep 17 00:00:00 2001
From: Arvid Jakobsson <arvid.jakobsson@gmail.com>
Date: Wed, 16 Jul 2014 14:20:15 +0200
Subject: [PATCH] fix bug #1381, adds argc and argv to memory model when
 present

also change gcc_test.sh so that one can pass arguments to program
under test.
---
 src/plugins/e-acsl/gcc_test.sh                |  16 +-
 .../share/e-acsl/memory_model/e_acsl_mmodel.c |  14 +
 .../share/e-acsl/memory_model/e_acsl_mmodel.h |   5 +
 .../e-acsl/tests/e-acsl-runtime/mainargs.i    |  24 ++
 .../e-acsl-runtime/oracle/gen_mainargs.c      | 248 +++++++++++
 .../e-acsl-runtime/oracle/gen_mainargs2.c     | 402 ++++++++++++++++++
 .../oracle/mainargs.1.err.oracle              |   0
 .../oracle/mainargs.1.res.oracle              |  74 ++++
 .../e-acsl-runtime/oracle/mainargs.err.oracle |   0
 .../e-acsl-runtime/oracle/mainargs.res.oracle |  49 +++
 src/plugins/e-acsl/visit.ml                   |  42 +-
 11 files changed, 860 insertions(+), 14 deletions(-)
 create mode 100644 src/plugins/e-acsl/tests/e-acsl-runtime/mainargs.i
 create mode 100644 src/plugins/e-acsl/tests/e-acsl-runtime/oracle/gen_mainargs.c
 create mode 100644 src/plugins/e-acsl/tests/e-acsl-runtime/oracle/gen_mainargs2.c
 create mode 100644 src/plugins/e-acsl/tests/e-acsl-runtime/oracle/mainargs.1.err.oracle
 create mode 100644 src/plugins/e-acsl/tests/e-acsl-runtime/oracle/mainargs.1.res.oracle
 create mode 100644 src/plugins/e-acsl/tests/e-acsl-runtime/oracle/mainargs.err.oracle
 create mode 100644 src/plugins/e-acsl/tests/e-acsl-runtime/oracle/mainargs.res.oracle

diff --git a/src/plugins/e-acsl/gcc_test.sh b/src/plugins/e-acsl/gcc_test.sh
index c8cfdada045..20dc759894c 100755
--- a/src/plugins/e-acsl/gcc_test.sh
+++ b/src/plugins/e-acsl/gcc_test.sh
@@ -1,8 +1,16 @@
 #!/bin/sh
-gcc -std=c99 -Wall -Wno-long-long -Wno-attributes -Wno-unused-but-set-variable -fno-builtin $2 -o ./tests/e-acsl-runtime/result/gen_$1.out ./share/e-acsl/e_acsl.c ./share/e-acsl/memory_model/e_acsl_bittree.c ./share/e-acsl/memory_model/e_acsl_mmodel.c ./tests/e-acsl-runtime/result/gen_$1.c -lgmp && ./tests/e-acsl-runtime/result/gen_$1.out
+IN=$1
+if [ $# -gt 1 ]; then
+    shift;
+    BUILTIN=$1
+    shift;
+    ARGS=$@
+fi
 
-gcc -std=c99 -Wall -Wno-long-long -Wno-attributes -Wno-unused-but-set-variable -fno-builtin $2 -o ./tests/e-acsl-runtime/result/gen_$1.out ./share/e-acsl/e_acsl.c ./share/e-acsl/memory_model/e_acsl_list.c ./share/e-acsl/memory_model/e_acsl_mmodel.c ./tests/e-acsl-runtime/result/gen_$1.c -lgmp && ./tests/e-acsl-runtime/result/gen_$1.out
+gcc -std=c99 -Wall -Wno-long-long -Wno-attributes -Wno-unused-but-set-variable -fno-builtin $BUILTIN -o ./tests/e-acsl-runtime/result/gen_$IN.out ./share/e-acsl/e_acsl.c ./share/e-acsl/memory_model/e_acsl_bittree.c ./share/e-acsl/memory_model/e_acsl_mmodel.c ./tests/e-acsl-runtime/result/gen_$IN.c -lgmp && ./tests/e-acsl-runtime/result/gen_$IN.out $ARGS
 
-gcc -std=c99 -Wall -Wno-long-long -Wno-attributes -Wno-unused-but-set-variable -fno-builtin $2 -o ./tests/e-acsl-runtime/result/gen_$1.out ./share/e-acsl/e_acsl.c ./share/e-acsl/memory_model/e_acsl_splay_tree.c ./share/e-acsl/memory_model/e_acsl_mmodel.c ./tests/e-acsl-runtime/result/gen_$1.c -lgmp && ./tests/e-acsl-runtime/result/gen_$1.out
+gcc -std=c99 -Wall -Wno-long-long -Wno-attributes -Wno-unused-but-set-variable -fno-builtin $BUILTIN -o ./tests/e-acsl-runtime/result/gen_$IN.out ./share/e-acsl/e_acsl.c ./share/e-acsl/memory_model/e_acsl_list.c ./share/e-acsl/memory_model/e_acsl_mmodel.c ./tests/e-acsl-runtime/result/gen_$IN.c -lgmp && ./tests/e-acsl-runtime/result/gen_$IN.out $ARGS
 
-gcc -std=c99 -Wall -Wno-long-long -Wno-attributes -Wno-unused-but-set-variable -fno-builtin $2 -o ./tests/e-acsl-runtime/result/gen_$1.out ./share/e-acsl/e_acsl.c ./share/e-acsl/memory_model/e_acsl_tree.c ./share/e-acsl/memory_model/e_acsl_mmodel.c ./tests/e-acsl-runtime/result/gen_$1.c -lgmp && ./tests/e-acsl-runtime/result/gen_$1.out
+gcc -std=c99 -Wall -Wno-long-long -Wno-attributes -Wno-unused-but-set-variable -fno-builtin $BUILTIN -o ./tests/e-acsl-runtime/result/gen_$IN.out ./share/e-acsl/e_acsl.c ./share/e-acsl/memory_model/e_acsl_splay_tree.c ./share/e-acsl/memory_model/e_acsl_mmodel.c ./tests/e-acsl-runtime/result/gen_$IN.c -lgmp && ./tests/e-acsl-runtime/result/gen_$IN.out $ARGS
+
+gcc -std=c99 -Wall -Wno-long-long -Wno-attributes -Wno-unused-but-set-variable -fno-builtin $BUILTIN -o ./tests/e-acsl-runtime/result/gen_$IN.out ./share/e-acsl/e_acsl.c ./share/e-acsl/memory_model/e_acsl_tree.c ./share/e-acsl/memory_model/e_acsl_mmodel.c ./tests/e-acsl-runtime/result/gen_$IN.c -lgmp && ./tests/e-acsl-runtime/result/gen_$IN.out $ARGS
diff --git a/src/plugins/e-acsl/share/e-acsl/memory_model/e_acsl_mmodel.c b/src/plugins/e-acsl/share/e-acsl/memory_model/e_acsl_mmodel.c
index 8db9c737e84..cb1d9e85836 100644
--- a/src/plugins/e-acsl/share/e-acsl/memory_model/e_acsl_mmodel.c
+++ b/src/plugins/e-acsl/share/e-acsl/memory_model/e_acsl_mmodel.c
@@ -77,6 +77,20 @@ size_t needed_bytes (size_t size) {
   return (size % 8) == 0 ? (size/8) : (size/8 + 1);
 }
 
+
+/* adds argc / argv to the memory model */
+void __init_args(int argc, char **argv) {
+  int i;
+
+  __store_block(argv, (argc+1)*sizeof(char*));
+  __full_init(argv);
+
+  for (i = 0; i < argc; i++) {
+    __store_block(argv[i], strlen(argv[i])+1);
+    __full_init(argv[i]);
+  }
+}
+
 /* store the block of size bytes starting at ptr */
 void* __store_block(void* ptr, size_t size) {
   struct _block * tmp;
diff --git a/src/plugins/e-acsl/share/e-acsl/memory_model/e_acsl_mmodel.h b/src/plugins/e-acsl/share/e-acsl/memory_model/e_acsl_mmodel.h
index 7454e06c2c1..2480dbc0ad5 100644
--- a/src/plugins/e-acsl/share/e-acsl/memory_model/e_acsl_mmodel.h
+++ b/src/plugins/e-acsl/share/e-acsl/memory_model/e_acsl_mmodel.h
@@ -53,6 +53,11 @@ void * __calloc(size_t nbr_elt, size_t size_elt)
 
 /* From outside the library, the following functions have no side effect */
 
+/* put argc/argv in memory model */
+/*@ assigns \nothing; */
+void __init_args(int argc_ref, char **argv_ref)
+	__attribute__((FC_BUILTIN));
+
 /* store the block of size bytes starting at ptr */
 /*@ assigns \result \from *(((char*)ptr)+(0..size-1)); */
 void * __store_block(void * ptr, size_t size)
diff --git a/src/plugins/e-acsl/tests/e-acsl-runtime/mainargs.i b/src/plugins/e-acsl/tests/e-acsl-runtime/mainargs.i
new file mode 100644
index 00000000000..a08234b3a93
--- /dev/null
+++ b/src/plugins/e-acsl/tests/e-acsl-runtime/mainargs.i
@@ -0,0 +1,24 @@
+/* run.config
+   COMMENT: the contents of argv should be valid
+   EXECNOW: LOG gen_mainargs.c BIN gen_mainargs.out @frama-c@ -machdep x86_64 -e-acsl-share ./share/e-acsl ./tests/e-acsl-runtime/mainargs.i -e-acsl -then-on e-acsl -print -ocode ./tests/e-acsl-runtime/result/gen_mainargs.c > /dev/null && ./gcc_test.sh mainargs "" bar baz
+   EXECNOW: LOG gen_mainargs2.c BIN gen_mainargs2.out @frama-c@ -machdep x86_64 -e-acsl-share ./share/e-acsl ./tests/e-acsl-runtime/mainargs.i -e-acsl-gmp-only -e-acsl -then-on e-acsl -print -ocode ./tests/e-acsl-runtime/result/gen_mainargs2.c > /dev/null && ./gcc_test.sh mainargs2 "" bar baz
+*/
+
+#include <string.h>
+
+int main(int argc, char **argv) {
+  int i;
+
+  /*@ assert \valid(&argc) ; */
+  /*@ assert \valid(&argv) ; */
+  /*@ assert \forall int k; 0 <= k && k < argc ==> \valid(argv + k) ; */
+  /*@ assert \block_length(argv) == (argc+1)*sizeof(char*) ; */
+
+  /*@ assert argv[argc] == \null ; */
+  /*@ assert ! \valid(argv[argc]) ; */
+  for (i = 0; i < argc; i++) {
+    int len = strlen(argv[i]);
+    /*@ assert \valid(argv[i]) ; */
+    /*@ assert \forall int k; 0 <= k && k <= len ==> \valid(&argv[i][k]) ; */
+  }
+}
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
new file mode 100644
index 00000000000..8e31ea4ce12
--- /dev/null
+++ b/src/plugins/e-acsl/tests/e-acsl-runtime/oracle/gen_mainargs.c
@@ -0,0 +1,248 @@
+/* Generated by Frama-C */
+struct __anonstruct___mpz_struct_1 {
+   int _mp_alloc ;
+   int _mp_size ;
+   unsigned long *_mp_d ;
+};
+typedef struct __anonstruct___mpz_struct_1 __mpz_struct;
+typedef __mpz_struct ( __attribute__((__FC_BUILTIN__)) mpz_t)[1];
+typedef unsigned int size_t;
+/*@ requires predicate ≢ 0;
+    assigns \nothing; */
+extern  __attribute__((__FC_BUILTIN__)) void e_acsl_assert(int predicate,
+                                                           char *kind,
+                                                           char *fct,
+                                                           char *pred_txt,
+                                                           int line);
+
+/*@
+model __mpz_struct { ℤ n };
+*/
+int random_counter __attribute__((__unused__));
+unsigned long const rand_max = (unsigned long)32767;
+/*@ ghost extern int __fc_heap_status; */
+
+/*@
+axiomatic
+  dynamic_allocation {
+  predicate is_allocable{L}(size_t n) 
+    reads __fc_heap_status;
+  
+  }
+ */
+/*@ ghost extern int __e_acsl_init; */
+
+/*@ assigns \nothing; */
+extern  __attribute__((__FC_BUILTIN__)) void __init_args(int argc_ref,
+                                                         char **argv_ref);
+
+/*@ assigns \result;
+    assigns \result \from *((char *)ptr+(0 .. size-1)); */
+extern  __attribute__((__FC_BUILTIN__)) void *__store_block(void *ptr,
+                                                            size_t size);
+
+/*@ assigns \nothing; */
+extern  __attribute__((__FC_BUILTIN__)) void __delete_block(void *ptr);
+
+/*@ ensures \result ≡ 0 ∨ \result ≡ 1;
+    ensures \result ≡ 1 ⇒ \valid((char *)\old(ptr)+(0 .. \old(size)-1));
+    assigns \result;
+    assigns \result \from *((char *)ptr+(0 .. size-1));
+ */
+extern  __attribute__((__FC_BUILTIN__)) int __valid(void *ptr, size_t size);
+
+/*@ ensures \result ≡ 0 ∨ \result ≡ 1;
+    ensures
+      \result ≡ 1 ⇒ \valid_read((char *)\old(ptr)+(0 .. \old(size)-1));
+    assigns \result;
+    assigns \result \from *((char *)ptr+(0 .. size-1));
+ */
+extern  __attribute__((__FC_BUILTIN__)) int __valid_read(void *ptr,
+                                                         size_t size);
+
+/*@ ensures \result ≡ \block_length(\old(ptr));
+    assigns \result;
+    assigns \result \from ptr;
+ */
+extern  __attribute__((__FC_BUILTIN__)) size_t __block_length(void *ptr);
+
+/*@ ensures \result ≡ 0 ∨ \result ≡ 1;
+    ensures
+      \result ≡ 1 ⇒ \initialized((char *)\old(ptr)+(0 .. \old(size)-1));
+    assigns \result;
+    assigns \result \from *((char *)ptr+(0 .. size-1));
+ */
+extern  __attribute__((__FC_BUILTIN__)) int __initialized(void *ptr,
+                                                          size_t size);
+
+/*@ ghost extern int __e_acsl_internal_heap; */
+
+/*@ assigns __e_acsl_internal_heap;
+    assigns __e_acsl_internal_heap \from __e_acsl_internal_heap;
+ */
+extern  __attribute__((__FC_BUILTIN__)) void __e_acsl_memory_clean(void);
+
+/*@ ghost extern size_t __memory_size; */
+
+/*@
+predicate diffSize{L1, L2}(ℤ i) =
+  \at(__memory_size,L1)-\at(__memory_size,L2) ≡ i;
+ */
+/*@ assigns \result, *(x_0+(0 ..));
+    assigns \result \from *(x_0+(0 ..));
+    assigns *(x_0+(0 ..)) \from *(x_0+(0 ..));
+ */
+extern int ( /* missing proto */ strlen)(char *x_0);
+
+int main(int argc, char **argv)
+{
+  int __retres;
+  int i;
+  __init_args(argc,argv);
+  /*@ assert \valid(&argc); */
+  {
+    int __e_acsl_valid;
+    __store_block((void *)(& argc),4U);
+    __store_block((void *)(& argv),8U);
+    __e_acsl_valid = __valid((void *)(& argc),(size_t)sizeof(int));
+    e_acsl_assert(__e_acsl_valid,(char *)"Assertion",(char *)"main",
+                  (char *)"\\valid(&argc)",12);
+  }
+  /*@ assert \valid(&argv); */
+  {
+    int __e_acsl_valid_2;
+    __e_acsl_valid_2 = __valid((void *)(& argv),(size_t)sizeof(char **));
+    e_acsl_assert(__e_acsl_valid_2,(char *)"Assertion",(char *)"main",
+                  (char *)"\\valid(&argv)",13);
+  }
+  /*@ assert ∀ int k; 0 ≤ k ∧ k < argc ⇒ \valid(argv+k); */
+  {
+    int __e_acsl_forall;
+    int __e_acsl_k;
+    __e_acsl_forall = 1;
+    __e_acsl_k = 0;
+    while (1) {
+      if (__e_acsl_k < argc) ; else break;
+      {
+        int __e_acsl_valid_3;
+        __e_acsl_valid_3 = __valid((void *)(argv + __e_acsl_k),
+                                   (size_t)sizeof(char *));
+        if (__e_acsl_valid_3) ;
+        else {
+          __e_acsl_forall = 0;
+          goto e_acsl_end_loop1;
+        }
+      }
+      __e_acsl_k ++;
+    }
+    e_acsl_end_loop1: ;
+    e_acsl_assert(__e_acsl_forall,(char *)"Assertion",(char *)"main",
+                  (char *)"\\forall int k; 0 <= k && k < argc ==> \\valid(argv+k)",
+                  14);
+  }
+  /*@ assert \block_length(argv) ≡ (argc+1)*sizeof(char *); */
+  {
+    unsigned long __e_acsl_block_length;
+    __e_acsl_block_length = (unsigned long)__block_length((void *)argv);
+    e_acsl_assert(__e_acsl_block_length == (unsigned long)(((long)argc + (long)1) * 8L),
+                  (char *)"Assertion",(char *)"main",
+                  (char *)"\\block_length(argv) == (argc+1)*sizeof(char *)",
+                  15);
+  }
+  /*@ assert *(argv+argc) ≡ \null; */
+  {
+    int __e_acsl_valid_read;
+    __e_acsl_valid_read = __valid_read((void *)(argv + argc),
+                                       (size_t)sizeof(char *));
+    e_acsl_assert(__e_acsl_valid_read,(char *)"RTE",(char *)"main",
+                  (char *)"mem_access: \\valid_read(argv+argc)",17);
+    e_acsl_assert(*(argv + argc) == (void *)0,(char *)"Assertion",
+                  (char *)"main",(char *)"*(argv+argc) == \\null",17);
+  }
+  /*@ assert ¬\valid(*(argv+argc)); */
+  {
+    int __e_acsl_initialized;
+    int __e_acsl_and;
+    __e_acsl_initialized = __initialized((void *)(argv + argc),
+                                         (size_t)sizeof(char *));
+    if (__e_acsl_initialized) {
+      int __e_acsl_valid_read_2;
+      int __e_acsl_valid_4;
+      __e_acsl_valid_read_2 = __valid_read((void *)(argv + argc),
+                                           (size_t)sizeof(char *));
+      e_acsl_assert(__e_acsl_valid_read_2,(char *)"RTE",(char *)"main",
+                    (char *)"mem_access: \\valid_read(argv+argc)",18);
+      __e_acsl_valid_4 = __valid((void *)*(argv + argc),(size_t)sizeof(char));
+      __e_acsl_and = __e_acsl_valid_4;
+    }
+    else __e_acsl_and = 0;
+    e_acsl_assert(! __e_acsl_and,(char *)"Assertion",(char *)"main",
+                  (char *)"!\\valid(*(argv+argc))",18);
+  }
+  i = 0;
+  while (i < argc) {
+    {
+      int len;
+      len = strlen(*(argv + i));
+      /*@ assert \valid(*(argv+i)); */
+      {
+        int __e_acsl_initialized_2;
+        int __e_acsl_and_2;
+        __e_acsl_initialized_2 = __initialized((void *)(argv + i),
+                                               (size_t)sizeof(char *));
+        if (__e_acsl_initialized_2) {
+          int __e_acsl_valid_read_3;
+          int __e_acsl_valid_5;
+          __e_acsl_valid_read_3 = __valid_read((void *)(argv + i),
+                                               (size_t)sizeof(char *));
+          e_acsl_assert(__e_acsl_valid_read_3,(char *)"RTE",(char *)"main",
+                        (char *)"mem_access: \\valid_read(argv+i)",21);
+          __e_acsl_valid_5 = __valid((void *)*(argv + i),
+                                     (size_t)sizeof(char));
+          __e_acsl_and_2 = __e_acsl_valid_5;
+        }
+        else __e_acsl_and_2 = 0;
+        e_acsl_assert(__e_acsl_and_2,(char *)"Assertion",(char *)"main",
+                      (char *)"\\valid(*(argv+i))",21);
+      }
+      /*@ assert ∀ int k; 0 ≤ k ∧ k ≤ len ⇒ \valid(*(argv+i)+k); */
+      {
+        int __e_acsl_forall_2;
+        long __e_acsl_k_2;
+        __e_acsl_forall_2 = 1;
+        __e_acsl_k_2 = (long)0;
+        while (1) {
+          if (__e_acsl_k_2 <= (long)len) ; else break;
+          {
+            int __e_acsl_valid_read_4;
+            int __e_acsl_valid_6;
+            __e_acsl_valid_read_4 = __valid_read((void *)(argv + i),
+                                                 (size_t)sizeof(char *));
+            e_acsl_assert(__e_acsl_valid_read_4,(char *)"RTE",(char *)"main",
+                          (char *)"mem_access: \\valid_read(argv+i)",22);
+            __e_acsl_valid_6 = __valid((void *)(*(argv + i) + __e_acsl_k_2),
+                                       (size_t)sizeof(char));
+            if (__e_acsl_valid_6) ;
+            else {
+              __e_acsl_forall_2 = 0;
+              goto e_acsl_end_loop2;
+            }
+          }
+          __e_acsl_k_2 ++;
+        }
+        e_acsl_end_loop2: ;
+        e_acsl_assert(__e_acsl_forall_2,(char *)"Assertion",(char *)"main",
+                      (char *)"\\forall int k; 0 <= k && k <= len ==> \\valid(*(argv+i)+k)",
+                      22);
+      }
+    }
+    i ++;
+  }
+  __retres = 0;
+  __delete_block((void *)(& argc));
+  __delete_block((void *)(& argv));
+  __e_acsl_memory_clean();
+  return __retres;
+}
+
+
diff --git a/src/plugins/e-acsl/tests/e-acsl-runtime/oracle/gen_mainargs2.c b/src/plugins/e-acsl/tests/e-acsl-runtime/oracle/gen_mainargs2.c
new file mode 100644
index 00000000000..00f3f226a99
--- /dev/null
+++ b/src/plugins/e-acsl/tests/e-acsl-runtime/oracle/gen_mainargs2.c
@@ -0,0 +1,402 @@
+/* Generated by Frama-C */
+struct __anonstruct___mpz_struct_1 {
+   int _mp_alloc ;
+   int _mp_size ;
+   unsigned long *_mp_d ;
+};
+typedef struct __anonstruct___mpz_struct_1 __mpz_struct;
+typedef __mpz_struct ( __attribute__((__FC_BUILTIN__)) mpz_t)[1];
+typedef unsigned int size_t;
+/*@ requires predicate ≢ 0;
+    assigns \nothing; */
+extern  __attribute__((__FC_BUILTIN__)) void e_acsl_assert(int predicate,
+                                                           char *kind,
+                                                           char *fct,
+                                                           char *pred_txt,
+                                                           int line);
+
+/*@
+model __mpz_struct { ℤ n };
+*/
+int random_counter __attribute__((__unused__));
+unsigned long const rand_max = (unsigned long)32767;
+/*@ ghost extern int __fc_heap_status; */
+
+/*@
+axiomatic
+  dynamic_allocation {
+  predicate is_allocable{L}(size_t n) 
+    reads __fc_heap_status;
+  
+  }
+ */
+/*@ ghost extern int __e_acsl_init; */
+
+/*@ requires ¬\initialized(z);
+    ensures \valid(\old(z));
+    assigns *z;
+    assigns *z \from __e_acsl_init;
+    allocates \old(z);
+ */
+extern  __attribute__((__FC_BUILTIN__)) void __gmpz_init(__mpz_struct * /*[1]*/ z);
+
+/*@ 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(z_orig);
+    requires \valid(z);
+    assigns *z;
+    assigns *z \from *z_orig;
+ */
+extern  __attribute__((__FC_BUILTIN__)) void __gmpz_set(__mpz_struct * /*[1]*/ z,
+                                                        __mpz_struct const * /*[1]*/ z_orig);
+
+/*@ requires \valid(x);
+    assigns *x;
+    assigns *x \from *x; */
+extern  __attribute__((__FC_BUILTIN__)) void __gmpz_clear(__mpz_struct * /*[1]*/ x);
+
+/*@ requires \valid(z1);
+    requires \valid(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);
+
+/*@ requires \valid(z1);
+    requires \valid(z2);
+    requires \valid(z3);
+    assigns *z1;
+    assigns *z1 \from *z2, *z3;
+ */
+extern  __attribute__((__FC_BUILTIN__)) void __gmpz_add(__mpz_struct * /*[1]*/ z1,
+                                                        __mpz_struct const * /*[1]*/ z2,
+                                                        __mpz_struct const * /*[1]*/ z3);
+
+/*@ requires \valid(z1);
+    requires \valid(z2);
+    requires \valid(z3);
+    assigns *z1;
+    assigns *z1 \from *z2, *z3;
+ */
+extern  __attribute__((__FC_BUILTIN__)) void __gmpz_mul(__mpz_struct * /*[1]*/ z1,
+                                                        __mpz_struct const * /*[1]*/ z2,
+                                                        __mpz_struct const * /*[1]*/ z3);
+
+/*@ requires \valid(z);
+    assigns \result;
+    assigns \result \from *z; */
+extern  __attribute__((__FC_BUILTIN__)) unsigned long __gmpz_get_ui(__mpz_struct const * /*[1]*/ z);
+
+/*@ assigns \nothing; */
+extern  __attribute__((__FC_BUILTIN__)) void __init_args(int argc_ref,
+                                                         char **argv_ref);
+
+/*@ assigns \result;
+    assigns \result \from *((char *)ptr+(0 .. size-1)); */
+extern  __attribute__((__FC_BUILTIN__)) void *__store_block(void *ptr,
+                                                            size_t size);
+
+/*@ assigns \nothing; */
+extern  __attribute__((__FC_BUILTIN__)) void __delete_block(void *ptr);
+
+/*@ ensures \result ≡ 0 ∨ \result ≡ 1;
+    ensures \result ≡ 1 ⇒ \valid((char *)\old(ptr)+(0 .. \old(size)-1));
+    assigns \result;
+    assigns \result \from *((char *)ptr+(0 .. size-1));
+ */
+extern  __attribute__((__FC_BUILTIN__)) int __valid(void *ptr, size_t size);
+
+/*@ ensures \result ≡ 0 ∨ \result ≡ 1;
+    ensures
+      \result ≡ 1 ⇒ \valid_read((char *)\old(ptr)+(0 .. \old(size)-1));
+    assigns \result;
+    assigns \result \from *((char *)ptr+(0 .. size-1));
+ */
+extern  __attribute__((__FC_BUILTIN__)) int __valid_read(void *ptr,
+                                                         size_t size);
+
+/*@ ensures \result ≡ \block_length(\old(ptr));
+    assigns \result;
+    assigns \result \from ptr;
+ */
+extern  __attribute__((__FC_BUILTIN__)) size_t __block_length(void *ptr);
+
+/*@ ensures \result ≡ 0 ∨ \result ≡ 1;
+    ensures
+      \result ≡ 1 ⇒ \initialized((char *)\old(ptr)+(0 .. \old(size)-1));
+    assigns \result;
+    assigns \result \from *((char *)ptr+(0 .. size-1));
+ */
+extern  __attribute__((__FC_BUILTIN__)) int __initialized(void *ptr,
+                                                          size_t size);
+
+/*@ ghost extern int __e_acsl_internal_heap; */
+
+/*@ assigns __e_acsl_internal_heap;
+    assigns __e_acsl_internal_heap \from __e_acsl_internal_heap;
+ */
+extern  __attribute__((__FC_BUILTIN__)) void __e_acsl_memory_clean(void);
+
+/*@ ghost extern size_t __memory_size; */
+
+/*@
+predicate diffSize{L1, L2}(ℤ i) =
+  \at(__memory_size,L1)-\at(__memory_size,L2) ≡ i;
+ */
+/*@ assigns \result, *(x_0+(0 ..));
+    assigns \result \from *(x_0+(0 ..));
+    assigns *(x_0+(0 ..)) \from *(x_0+(0 ..));
+ */
+extern int ( /* missing proto */ strlen)(char *x_0);
+
+int main(int argc, char **argv)
+{
+  int __retres;
+  int i;
+  __init_args(argc,argv);
+  /*@ assert \valid(&argc); */
+  {
+    int __e_acsl_valid;
+    __store_block((void *)(& argc),4U);
+    __store_block((void *)(& argv),8U);
+    __e_acsl_valid = __valid((void *)(& argc),(size_t)sizeof(int));
+    e_acsl_assert(__e_acsl_valid,(char *)"Assertion",(char *)"main",
+                  (char *)"\\valid(&argc)",12);
+  }
+  /*@ assert \valid(&argv); */
+  {
+    int __e_acsl_valid_2;
+    __e_acsl_valid_2 = __valid((void *)(& argv),(size_t)sizeof(char **));
+    e_acsl_assert(__e_acsl_valid_2,(char *)"Assertion",(char *)"main",
+                  (char *)"\\valid(&argv)",13);
+  }
+  /*@ assert ∀ int k; 0 ≤ k ∧ k < argc ⇒ \valid(argv+k); */
+  {
+    int __e_acsl_forall;
+    mpz_t __e_acsl_k;
+    __e_acsl_forall = 1;
+    __gmpz_init(__e_acsl_k);
+    {
+      mpz_t __e_acsl;
+      __gmpz_init_set_si(__e_acsl,(long)0);
+      __gmpz_set(__e_acsl_k,(__mpz_struct const *)(__e_acsl));
+      __gmpz_clear(__e_acsl);
+    }
+    while (1) {
+      {
+        mpz_t __e_acsl_argc;
+        int __e_acsl_lt;
+        __gmpz_init_set_si(__e_acsl_argc,(long)argc);
+        __e_acsl_lt = __gmpz_cmp((__mpz_struct const *)(__e_acsl_k),
+                                 (__mpz_struct const *)(__e_acsl_argc));
+        if (__e_acsl_lt < 0) ; else break;
+        __gmpz_clear(__e_acsl_argc);
+      }
+      {
+        unsigned long __e_acsl_k_2;
+        int __e_acsl_valid_3;
+        __e_acsl_k_2 = __gmpz_get_ui((__mpz_struct const *)(__e_acsl_k));
+        __e_acsl_valid_3 = __valid((void *)(argv + __e_acsl_k_2),
+                                   (size_t)sizeof(char *));
+        if (__e_acsl_valid_3) ;
+        else {
+          __e_acsl_forall = 0;
+          goto e_acsl_end_loop1;
+        }
+      }
+      {
+        mpz_t __e_acsl_2;
+        mpz_t __e_acsl_add;
+        __gmpz_init_set_si(__e_acsl_2,1L);
+        __gmpz_init(__e_acsl_add);
+        __gmpz_add(__e_acsl_add,(__mpz_struct const *)(__e_acsl_k),
+                   (__mpz_struct const *)(__e_acsl_2));
+        __gmpz_set(__e_acsl_k,(__mpz_struct const *)(__e_acsl_add));
+        __gmpz_clear(__e_acsl_2);
+        __gmpz_clear(__e_acsl_add);
+      }
+    }
+    e_acsl_end_loop1: ;
+    e_acsl_assert(__e_acsl_forall,(char *)"Assertion",(char *)"main",
+                  (char *)"\\forall int k; 0 <= k && k < argc ==> \\valid(argv+k)",
+                  14);
+    __gmpz_clear(__e_acsl_k);
+  }
+  /*@ 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_argc_2;
+    mpz_t __e_acsl_3;
+    mpz_t __e_acsl_add_2;
+    mpz_t __e_acsl_sizeof;
+    mpz_t __e_acsl_mul;
+    int __e_acsl_eq;
+    __e_acsl_block_length = (unsigned long)__block_length((void *)argv);
+    __gmpz_init_set_ui(__e_acsl_block_length_2,__e_acsl_block_length);
+    __gmpz_init_set_si(__e_acsl_argc_2,(long)argc);
+    __gmpz_init_set_si(__e_acsl_3,(long)1);
+    __gmpz_init(__e_acsl_add_2);
+    __gmpz_add(__e_acsl_add_2,(__mpz_struct const *)(__e_acsl_argc_2),
+               (__mpz_struct const *)(__e_acsl_3));
+    __gmpz_init_set_si(__e_acsl_sizeof,8L);
+    __gmpz_init(__e_acsl_mul);
+    __gmpz_mul(__e_acsl_mul,(__mpz_struct const *)(__e_acsl_add_2),
+               (__mpz_struct const *)(__e_acsl_sizeof));
+    __e_acsl_eq = __gmpz_cmp((__mpz_struct const *)(__e_acsl_block_length_2),
+                             (__mpz_struct const *)(__e_acsl_mul));
+    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_argc_2);
+    __gmpz_clear(__e_acsl_3);
+    __gmpz_clear(__e_acsl_add_2);
+    __gmpz_clear(__e_acsl_sizeof);
+    __gmpz_clear(__e_acsl_mul);
+  }
+  /*@ assert *(argv+argc) ≡ \null; */
+  {
+    int __e_acsl_valid_read;
+    __e_acsl_valid_read = __valid_read((void *)(argv + (long)argc),
+                                       (size_t)sizeof(char *));
+    e_acsl_assert(__e_acsl_valid_read,(char *)"RTE",(char *)"main",
+                  (char *)"mem_access: \\valid_read(argv+(long)argc)",17);
+    e_acsl_assert(*(argv + (long)argc) == (void *)0,(char *)"Assertion",
+                  (char *)"main",(char *)"*(argv+argc) == \\null",17);
+  }
+  /*@ assert ¬\valid(*(argv+argc)); */
+  {
+    int __e_acsl_initialized;
+    int __e_acsl_and;
+    __e_acsl_initialized = __initialized((void *)(argv + (long)argc),
+                                         (size_t)sizeof(char *));
+    if (__e_acsl_initialized) {
+      int __e_acsl_valid_read_2;
+      int __e_acsl_valid_4;
+      __e_acsl_valid_read_2 = __valid_read((void *)(argv + (long)argc),
+                                           (size_t)sizeof(char *));
+      e_acsl_assert(__e_acsl_valid_read_2,(char *)"RTE",(char *)"main",
+                    (char *)"mem_access: \\valid_read(argv+(long)argc)",18);
+      __e_acsl_valid_4 = __valid((void *)*(argv + (long)argc),
+                                 (size_t)sizeof(char));
+      __e_acsl_and = __e_acsl_valid_4;
+    }
+    else __e_acsl_and = 0;
+    e_acsl_assert(! __e_acsl_and,(char *)"Assertion",(char *)"main",
+                  (char *)"!\\valid(*(argv+argc))",18);
+  }
+  i = 0;
+  while (i < argc) {
+    {
+      int len;
+      len = strlen(*(argv + i));
+      /*@ assert \valid(*(argv+i)); */
+      {
+        int __e_acsl_initialized_2;
+        int __e_acsl_and_2;
+        __e_acsl_initialized_2 = __initialized((void *)(argv + (long)i),
+                                               (size_t)sizeof(char *));
+        if (__e_acsl_initialized_2) {
+          int __e_acsl_valid_read_3;
+          int __e_acsl_valid_5;
+          __e_acsl_valid_read_3 = __valid_read((void *)(argv + (long)i),
+                                               (size_t)sizeof(char *));
+          e_acsl_assert(__e_acsl_valid_read_3,(char *)"RTE",(char *)"main",
+                        (char *)"mem_access: \\valid_read(argv+(long)i)",21);
+          __e_acsl_valid_5 = __valid((void *)*(argv + (long)i),
+                                     (size_t)sizeof(char));
+          __e_acsl_and_2 = __e_acsl_valid_5;
+        }
+        else __e_acsl_and_2 = 0;
+        e_acsl_assert(__e_acsl_and_2,(char *)"Assertion",(char *)"main",
+                      (char *)"\\valid(*(argv+i))",21);
+      }
+      /*@ assert ∀ int k; 0 ≤ k ∧ k ≤ len ⇒ \valid(*(argv+i)+k); */
+      {
+        int __e_acsl_forall_2;
+        mpz_t __e_acsl_k_3;
+        __e_acsl_forall_2 = 1;
+        __gmpz_init(__e_acsl_k_3);
+        {
+          mpz_t __e_acsl_4;
+          __gmpz_init_set_si(__e_acsl_4,(long)0);
+          __gmpz_set(__e_acsl_k_3,(__mpz_struct const *)(__e_acsl_4));
+          __gmpz_clear(__e_acsl_4);
+        }
+        while (1) {
+          {
+            mpz_t __e_acsl_len;
+            int __e_acsl_le;
+            __gmpz_init_set_si(__e_acsl_len,(long)len);
+            __e_acsl_le = __gmpz_cmp((__mpz_struct const *)(__e_acsl_k_3),
+                                     (__mpz_struct const *)(__e_acsl_len));
+            if (__e_acsl_le <= 0) ; else break;
+            __gmpz_clear(__e_acsl_len);
+          }
+          {
+            unsigned long __e_acsl_k_4;
+            int __e_acsl_valid_read_4;
+            int __e_acsl_valid_6;
+            __e_acsl_k_4 = __gmpz_get_ui((__mpz_struct const *)(__e_acsl_k_3));
+            __e_acsl_valid_read_4 = __valid_read((void *)(argv + (long)i),
+                                                 (size_t)sizeof(char *));
+            e_acsl_assert(__e_acsl_valid_read_4,(char *)"RTE",(char *)"main",
+                          (char *)"mem_access: \\valid_read(argv+(long)i)",
+                          22);
+            __e_acsl_valid_6 = __valid((void *)(*(argv + (long)i) + __e_acsl_k_4),
+                                       (size_t)sizeof(char));
+            if (__e_acsl_valid_6) ;
+            else {
+              __e_acsl_forall_2 = 0;
+              goto e_acsl_end_loop2;
+            }
+          }
+          {
+            mpz_t __e_acsl_5;
+            mpz_t __e_acsl_add_3;
+            __gmpz_init_set_si(__e_acsl_5,1L);
+            __gmpz_init(__e_acsl_add_3);
+            __gmpz_add(__e_acsl_add_3,(__mpz_struct const *)(__e_acsl_k_3),
+                       (__mpz_struct const *)(__e_acsl_5));
+            __gmpz_set(__e_acsl_k_3,(__mpz_struct const *)(__e_acsl_add_3));
+            __gmpz_clear(__e_acsl_5);
+            __gmpz_clear(__e_acsl_add_3);
+          }
+        }
+        e_acsl_end_loop2: ;
+        e_acsl_assert(__e_acsl_forall_2,(char *)"Assertion",(char *)"main",
+                      (char *)"\\forall int k; 0 <= k && k <= len ==> \\valid(*(argv+i)+k)",
+                      22);
+        __gmpz_clear(__e_acsl_k_3);
+      }
+    }
+    i ++;
+  }
+  __retres = 0;
+  __delete_block((void *)(& argc));
+  __delete_block((void *)(& argv));
+  __e_acsl_memory_clean();
+  return __retres;
+}
+
+
diff --git a/src/plugins/e-acsl/tests/e-acsl-runtime/oracle/mainargs.1.err.oracle b/src/plugins/e-acsl/tests/e-acsl-runtime/oracle/mainargs.1.err.oracle
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/src/plugins/e-acsl/tests/e-acsl-runtime/oracle/mainargs.1.res.oracle b/src/plugins/e-acsl/tests/e-acsl-runtime/oracle/mainargs.1.res.oracle
new file mode 100644
index 00000000000..10628751ac5
--- /dev/null
+++ b/src/plugins/e-acsl/tests/e-acsl-runtime/oracle/mainargs.1.res.oracle
@@ -0,0 +1,74 @@
+[kernel] preprocessing with "gcc -C -E -I. -IFRAMAC_SHARE/e-acsl  -DE_ACSL_MACHDEP=x86_32 -IFRAMAC_SHARE/libc FRAMAC_SHARE/e-acsl/e_acsl.h"
+[kernel] preprocessing with "gcc -C -E -I. -IFRAMAC_SHARE/e-acsl  -DE_ACSL_MACHDEP=x86_32 -IFRAMAC_SHARE/libc FRAMAC_SHARE/e-acsl/e_acsl_gmp_types.h"
+[kernel] preprocessing with "gcc -C -E -I. -IFRAMAC_SHARE/e-acsl  -DE_ACSL_MACHDEP=x86_32 -IFRAMAC_SHARE/libc FRAMAC_SHARE/e-acsl/e_acsl_gmp.h"
+[kernel] preprocessing with "gcc -C -E -I. -IFRAMAC_SHARE/e-acsl  -DE_ACSL_MACHDEP=x86_32 -IFRAMAC_SHARE/libc FRAMAC_SHARE/e-acsl/memory_model/e_acsl_mmodel_api.h"
+[kernel] preprocessing with "gcc -C -E -I. -IFRAMAC_SHARE/e-acsl  -DE_ACSL_MACHDEP=x86_32 -IFRAMAC_SHARE/libc FRAMAC_SHARE/e-acsl/memory_model/e_acsl_bittree.h"
+[kernel] preprocessing with "gcc -C -E -I. -IFRAMAC_SHARE/e-acsl  -DE_ACSL_MACHDEP=x86_32 -IFRAMAC_SHARE/libc FRAMAC_SHARE/e-acsl/memory_model/e_acsl_mmodel.h"
+tests/e-acsl-runtime/mainargs.i:20:[kernel] warning: Calling undeclared function strlen. Old style K&R code?
+[e-acsl] beginning translation.
+tests/e-acsl-runtime/mainargs.i:20:[kernel] warning: Neither code nor specification for function strlen, generating default assigns from the prototype
+[e-acsl] translation done in project "e-acsl".
+[value] Analyzing a complete application starting at main
+[value] Computing initial state
+[value] Initial state computed
+[value] Values of globals at initialization
+  random_counter ∈ {0}
+  rand_max ∈ {32767}
+  __fc_heap_status ∈ [--..--]
+  __e_acsl_init ∈ [--..--]
+  __e_acsl_internal_heap ∈ [--..--]
+  __memory_size ∈ [--..--]
+[value] using specification for function __init_args
+tests/e-acsl-runtime/mainargs.i:12:[value] Assertion got status valid.
+[value] using specification for function __store_block
+[value] using specification for function __valid
+[value] using specification for function e_acsl_assert
+FRAMAC_SHARE/e-acsl/e_acsl.h:34:[value] Function e_acsl_assert: precondition got status unknown.
+tests/e-acsl-runtime/mainargs.i:13:[value] Assertion got status valid.
+tests/e-acsl-runtime/mainargs.i:14:[value] Assertion got status unknown.
+[value] using specification for function __gmpz_init
+FRAMAC_SHARE/e-acsl/e_acsl_gmp.h:39:[value] Function __gmpz_init: precondition got status valid.
+[value] using specification for function __gmpz_init_set_si
+FRAMAC_SHARE/e-acsl/e_acsl_gmp.h:64:[value] Function __gmpz_init_set_si: precondition got status valid.
+[value] using specification for function __gmpz_set
+FRAMAC_SHARE/e-acsl/e_acsl_gmp.h:94:[value] Function __gmpz_set: precondition got status valid.
+FRAMAC_SHARE/e-acsl/e_acsl_gmp.h:95:[value] Function __gmpz_set: precondition got status valid.
+[value] using specification for function __gmpz_clear
+FRAMAC_SHARE/e-acsl/e_acsl_gmp.h:117:[value] Function __gmpz_clear: precondition got status valid.
+tests/e-acsl-runtime/mainargs.i:14:[value] entering loop for the first time
+[value] using specification for function __gmpz_cmp
+FRAMAC_SHARE/e-acsl/e_acsl_gmp.h:127:[value] Function __gmpz_cmp: precondition got status valid.
+FRAMAC_SHARE/e-acsl/e_acsl_gmp.h:128:[value] Function __gmpz_cmp: precondition got status valid.
+[value] using specification for function __gmpz_get_ui
+FRAMAC_SHARE/e-acsl/e_acsl_gmp.h:198:[value] Function __gmpz_get_ui: precondition got status valid.
+[value] using specification for function __gmpz_add
+FRAMAC_SHARE/e-acsl/e_acsl_gmp.h:143:[value] Function __gmpz_add: precondition got status valid.
+FRAMAC_SHARE/e-acsl/e_acsl_gmp.h:144:[value] Function __gmpz_add: precondition got status valid.
+FRAMAC_SHARE/e-acsl/e_acsl_gmp.h:145:[value] Function __gmpz_add: precondition got status valid.
+tests/e-acsl-runtime/mainargs.i:15:[value] Assertion got status unknown.
+[value] using specification for function __block_length
+[value] using specification for function __gmpz_init_set_ui
+FRAMAC_SHARE/e-acsl/e_acsl_gmp.h:55:[value] Function __gmpz_init_set_ui: precondition got status valid.
+[value] using specification for function __gmpz_mul
+FRAMAC_SHARE/e-acsl/e_acsl_gmp.h:157:[value] Function __gmpz_mul: precondition got status valid.
+FRAMAC_SHARE/e-acsl/e_acsl_gmp.h:158:[value] Function __gmpz_mul: precondition got status valid.
+FRAMAC_SHARE/e-acsl/e_acsl_gmp.h:159:[value] Function __gmpz_mul: precondition got status valid.
+tests/e-acsl-runtime/mainargs.i:17:[value] Assertion got status unknown.
+[value] using specification for function __valid_read
+tests/e-acsl-runtime/mainargs.i:17:[kernel] warning: out of bounds read. assert \valid_read(argv+(long)argc);
+tests/e-acsl-runtime/mainargs.i:18:[value] Assertion got status unknown.
+[value] using specification for function __initialized
+tests/e-acsl-runtime/mainargs.i:18:[kernel] warning: out of bounds read. assert \valid_read(argv+(long)argc);
+tests/e-acsl-runtime/mainargs.i:19:[value] entering loop for the first time
+tests/e-acsl-runtime/mainargs.i:20:[kernel] warning: out of bounds read. assert \valid_read(argv+i);
+[value] using specification for function strlen
+tests/e-acsl-runtime/mainargs.i:21:[value] Assertion got status unknown.
+tests/e-acsl-runtime/mainargs.i:21:[kernel] warning: out of bounds read. assert \valid_read(argv+(long)i);
+tests/e-acsl-runtime/mainargs.i:22:[value] Assertion got status unknown.
+tests/e-acsl-runtime/mainargs.i:22:[value] entering loop for the first time
+tests/e-acsl-runtime/mainargs.i:22:[kernel] warning: out of bounds read. assert \valid_read(argv+(long)i);
+tests/e-acsl-runtime/mainargs.i:19:[kernel] warning: signed overflow. assert i+1 ≤ 2147483647;
+[value] using specification for function __delete_block
+[value] using specification for function __e_acsl_memory_clean
+[value] done for function main
+[value] ====== VALUES COMPUTED ======
diff --git a/src/plugins/e-acsl/tests/e-acsl-runtime/oracle/mainargs.err.oracle b/src/plugins/e-acsl/tests/e-acsl-runtime/oracle/mainargs.err.oracle
new file mode 100644
index 00000000000..e69de29bb2d
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
new file mode 100644
index 00000000000..0919a446346
--- /dev/null
+++ b/src/plugins/e-acsl/tests/e-acsl-runtime/oracle/mainargs.res.oracle
@@ -0,0 +1,49 @@
+[kernel] preprocessing with "gcc -C -E -I. -IFRAMAC_SHARE/e-acsl  -DE_ACSL_MACHDEP=x86_32 -IFRAMAC_SHARE/libc FRAMAC_SHARE/e-acsl/e_acsl.h"
+[kernel] preprocessing with "gcc -C -E -I. -IFRAMAC_SHARE/e-acsl  -DE_ACSL_MACHDEP=x86_32 -IFRAMAC_SHARE/libc FRAMAC_SHARE/e-acsl/e_acsl_gmp_types.h"
+[kernel] preprocessing with "gcc -C -E -I. -IFRAMAC_SHARE/e-acsl  -DE_ACSL_MACHDEP=x86_32 -IFRAMAC_SHARE/libc FRAMAC_SHARE/e-acsl/e_acsl_gmp.h"
+[kernel] preprocessing with "gcc -C -E -I. -IFRAMAC_SHARE/e-acsl  -DE_ACSL_MACHDEP=x86_32 -IFRAMAC_SHARE/libc FRAMAC_SHARE/e-acsl/memory_model/e_acsl_mmodel_api.h"
+[kernel] preprocessing with "gcc -C -E -I. -IFRAMAC_SHARE/e-acsl  -DE_ACSL_MACHDEP=x86_32 -IFRAMAC_SHARE/libc FRAMAC_SHARE/e-acsl/memory_model/e_acsl_bittree.h"
+[kernel] preprocessing with "gcc -C -E -I. -IFRAMAC_SHARE/e-acsl  -DE_ACSL_MACHDEP=x86_32 -IFRAMAC_SHARE/libc FRAMAC_SHARE/e-acsl/memory_model/e_acsl_mmodel.h"
+tests/e-acsl-runtime/mainargs.i:20:[kernel] warning: Calling undeclared function strlen. Old style K&R code?
+[e-acsl] beginning translation.
+tests/e-acsl-runtime/mainargs.i:20:[kernel] warning: Neither code nor specification for function strlen, generating default assigns from the prototype
+[e-acsl] translation done in project "e-acsl".
+[value] Analyzing a complete application starting at main
+[value] Computing initial state
+[value] Initial state computed
+[value] Values of globals at initialization
+  random_counter ∈ {0}
+  rand_max ∈ {32767}
+  __fc_heap_status ∈ [--..--]
+  __e_acsl_init ∈ [--..--]
+  __e_acsl_internal_heap ∈ [--..--]
+  __memory_size ∈ [--..--]
+[value] using specification for function __init_args
+tests/e-acsl-runtime/mainargs.i:12:[value] Assertion got status valid.
+[value] using specification for function __store_block
+[value] using specification for function __valid
+[value] using specification for function e_acsl_assert
+FRAMAC_SHARE/e-acsl/e_acsl.h:34:[value] Function e_acsl_assert: precondition got status unknown.
+tests/e-acsl-runtime/mainargs.i:13:[value] Assertion got status valid.
+tests/e-acsl-runtime/mainargs.i:14:[value] Assertion got status unknown.
+tests/e-acsl-runtime/mainargs.i:14:[value] entering loop for the first time
+tests/e-acsl-runtime/mainargs.i:15:[value] Assertion got status unknown.
+[value] using specification for function __block_length
+tests/e-acsl-runtime/mainargs.i:17:[value] Assertion got status unknown.
+[value] using specification for function __valid_read
+tests/e-acsl-runtime/mainargs.i:17:[kernel] warning: out of bounds read. assert \valid_read(argv+argc);
+tests/e-acsl-runtime/mainargs.i:18:[value] Assertion got status unknown.
+[value] using specification for function __initialized
+tests/e-acsl-runtime/mainargs.i:18:[kernel] warning: out of bounds read. assert \valid_read(argv+argc);
+tests/e-acsl-runtime/mainargs.i:19:[value] entering loop for the first time
+tests/e-acsl-runtime/mainargs.i:20:[kernel] warning: out of bounds read. assert \valid_read(argv+i);
+[value] using specification for function strlen
+tests/e-acsl-runtime/mainargs.i:21:[value] Assertion got status unknown.
+tests/e-acsl-runtime/mainargs.i:21:[kernel] warning: out of bounds read. assert \valid_read(argv+i);
+tests/e-acsl-runtime/mainargs.i:22:[value] Assertion got status unknown.
+tests/e-acsl-runtime/mainargs.i:22:[value] entering loop for the first time
+tests/e-acsl-runtime/mainargs.i:22:[kernel] warning: out of bounds read. assert \valid_read(argv+i);
+[value] using specification for function __delete_block
+[value] using specification for function __e_acsl_memory_clean
+[value] done for function main
+[value] ====== VALUES COMPUTED ======
diff --git a/src/plugins/e-acsl/visit.ml b/src/plugins/e-acsl/visit.ml
index 5af377d2bf8..850e9faf10f 100644
--- a/src/plugins/e-acsl/visit.ml
+++ b/src/plugins/e-acsl/visit.ml
@@ -196,18 +196,40 @@ class e_acsl_visitor prj generate = object (self)
 		      [ cil_fct; GFun(main, Location.unknown) ]
 		  in
 		  f.globals <- new_globals
-		| None -> 
+		| None ->
 		  Kernel.warning "@[no entry point specified:@ \
 you must call function `%s' and `__e_acsl_memory_clean by yourself.@]" 
-		    fname;
-		  f.globals <- f.globals @ [ cil_fct ]
-	    in
-	    Project.on prj build_initializer ()
-	end;
-	(* reset copied states at the end to be observationally equivalent to a
-	   standard visitor. *)
-	if generate then Project.clear ~selection ~project:prj ();
-	f)
+      fname;
+    f.globals <- f.globals @ [ cil_fct ]
+     in
+     Project.on prj build_initializer ()
+ end;
+
+ (* init memory store, and then add program arguments if there
+    are any. must be called before global variables are
+    initialized. *)
+ if Pre_analysis.use_model () then begin
+   match main_fct with
+   | Some main ->
+     let charPtrPtrType = TPtr(Cil.charPtrType,[]) in
+     let loc = Location.unknown in
+     (* this might not be valid in an embedded environment,
+        where int/char**  arguments is not necessarily valid *)
+     let stmts_pre = match main.sformals with
+       | { vtype = t1 }::{ vtype = t2 }::_ when
+           t1 = Cil.intType && t2 = charPtrPtrType ->
+         let args = (List.map Cil.evar main.sformals) in
+         [(Misc.mk_call loc "__init_args" args)]
+       | _ -> []
+     in
+     main.sbody.bstmts <- stmts_pre @ main.sbody.bstmts;
+   | None -> ()
+ end;
+
+ (* reset copied states at the end to be observationally equivalent to a
+    standard visitor. *)
+ if generate then Project.clear ~selection ~project:prj ();
+ f)
 
   method !vglob_aux = function
   | GVarDecl(_, vi, _) | GVar(vi, _, _) | GFun({ svar = vi }, _) 
-- 
GitLab