diff --git a/src/plugins/e-acsl/doc/userman/examples/modified_main.c b/src/plugins/e-acsl/doc/userman/examples/modified_main.c
new file mode 100644
index 0000000000000000000000000000000000000000..c990f33187a8d89bc4b32e2d880c4f89be28e182
--- /dev/null
+++ b/src/plugins/e-acsl/doc/userman/examples/modified_main.c
@@ -0,0 +1,10 @@
+extern void e_acsl_global_init(void);
+extern void __clean(void);
+extern void f(void);
+
+int main(void) {
+  e_acsl_global_init();
+  f();
+  __clean();
+  return 0;
+}
diff --git a/src/plugins/e-acsl/doc/userman/examples/my_assert.c b/src/plugins/e-acsl/doc/userman/examples/my_assert.c
new file mode 100644
index 0000000000000000000000000000000000000000..4c124e0b1866d7674d034e5017d3fdb8f9caa6c8
--- /dev/null
+++ b/src/plugins/e-acsl/doc/userman/examples/my_assert.c
@@ -0,0 +1,12 @@
+#include "stdio.h"
+
+void e_acsl_assert(int predicate, 
+		   char *kind, 
+		   char *fct, 
+		   char *pred_txt, 
+		   int line) 
+{
+  printf("%s at line %d in function %s is %s.\n\
+The verified predicate was: `%s'.\n",
+	 kind, line, fct, predicate ? "valid" : "invalid", pred_txt);
+}
diff --git a/src/plugins/e-acsl/doc/userman/examples/valid_no_main.c b/src/plugins/e-acsl/doc/userman/examples/valid_no_main.c
new file mode 100644
index 0000000000000000000000000000000000000000..da6dd0f055bc877a83f5479fd00d6e0a7e874674
--- /dev/null
+++ b/src/plugins/e-acsl/doc/userman/examples/valid_no_main.c
@@ -0,0 +1,13 @@
+#include "stdlib.h"
+
+extern void *malloc(size_t);
+extern void free(void*);
+
+int f(void) {
+  int *x;
+  x = (int*)malloc(sizeof(int));
+  /*@ assert \valid(x); */
+  free(x);
+  /*@ assert freed: \valid(x); */
+  return 0;
+}
diff --git a/src/plugins/e-acsl/doc/userman/limitations.tex b/src/plugins/e-acsl/doc/userman/limitations.tex
index bdc38a33c342ce287865a4a6369c82cfcd00519b..f839e590b08033a7b38569c6203e246ab35f6384 100644
--- a/src/plugins/e-acsl/doc/userman/limitations.tex
+++ b/src/plugins/e-acsl/doc/userman/limitations.tex
@@ -22,9 +22,69 @@ of commercial supports\footnote{Contact us or read
 \end{itemize}
 
 \section{Incomplete Programs}
+
+Section~\ref{sec:incomplete} explains how the \eacsl plug-in is able to handle
+incomplete programs, which are either programs without main, or programs
+containing functions without bodies.
+
+However, if such programs contain memory-related annotations, the generated code
+may be incorrect. That is made explicit by a warning displayed when the \eacsl
+plug-in is running (see examples of Sections~\ref{sec:no-main} and
+\ref{sec:no-code}).
+
+\subsection{Program without Main}
 \index{Program!Without main}
+\label{sec:limits:no-main}
+
+The generation is incorrect for every program without main containing a
+memory-related annotations, except if the option
+\optionuse{-}{e-acsl-full-mmodel} is provided.
+
+Consider the following example.
+
+\listingname{valid\_no\_main.c}
+\cinput{examples/valid_no_main.c}
+
+You can generate the instrumented program as follows.
+\begin{shell}
+\$ frama-c -e-acsl-full-mmodel -machdep x86_64 -e-acsl valid_no_main.c \
+          -then-on e-acsl -print -ocode monitored_valid_no_main.i
+<skip preprocessing commands>
+[e-acsl] beginning translation.
+<skip warnings about annotations from the Frama-C libc 
+      which cannot be translated>
+[kernel] warning: no entry point specified:
+                  you must call function `e_acsl_global_init' and `__clean' by yourself.
+[e-acsl] translation done in project "e-acsl".
+\end{shell}
+
+The last warning states an important point: if this program is linked against
+another file containing a \texttt{main} function, then this main function must
+be modified to insert a call to the function
+\texttt{e\_acsl\_global\_init}\codeidx{e\_acsl\_global\_init} at 
+the very beginning and a call to the function
+\texttt{\_\_clean}\codeidx{\_\_clean} at the very end like in the following
+example.
+
+\listingname{modified\_main.c}
+\cinput{examples/modified_main.c}
+
+Then just compile and run it as explained in Section~\ref{sec:memory}.
+
+\begin{shell}
+\$ DIR=`frama-c -print-share-path`/e-acsl
+\$ MDIR=\$DIR/memory_model
+\$ gcc -o valid_no_main \$DIR/e_acsl.c \$MDIR/e_acsl_bittree.c \
+      \$MDIR/e_acsl_mmodel.c monitored_valid_no_main.i modified_main.c
+\$ ./valid_no_main
+Assertion failed at line 11 in function f.
+The failing predicate is:
+freed: \valid(x).
+\end{shell}
+
+\subsection{Function without Code}
+\label{sec:limits:no-code}
 \index{Function!Without code}
-\label{sec:limits:incomplete}
 
 \section{Recursive Function}
 \index{Function!Recursive}
diff --git a/src/plugins/e-acsl/doc/userman/main.pdf b/src/plugins/e-acsl/doc/userman/main.pdf
index 140f0229b2b2ffb4d6f764b2892462e76c9a7de1..2e7c0e5973cad57c03ed424a9244c69e52e5ef65 100644
Binary files a/src/plugins/e-acsl/doc/userman/main.pdf and b/src/plugins/e-acsl/doc/userman/main.pdf differ
diff --git a/src/plugins/e-acsl/doc/userman/provides.tex b/src/plugins/e-acsl/doc/userman/provides.tex
index 8c04fe99a92b14e8a5bad010675ea4750b2f8673..d25c27fcbe94371be601af90c297fc5bcb6c39f9 100644
--- a/src/plugins/e-acsl/doc/userman/provides.tex
+++ b/src/plugins/e-acsl/doc/userman/provides.tex
@@ -343,6 +343,11 @@ We can now execute it as usual.
 
 Since the assertion is valid, there is no output in this case.
 
+The option \optiondef{-}{e-acsl-gmp-only} (unset by default) may be set to
+always generate \gmp integers, even when it is not required. If it is set, the
+generated program must be linked against \gmp as soon as there is an integer or
+any integral \C type in an annotation.
+
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
 \subsection{Memory-related Annotations}
@@ -378,7 +383,8 @@ must be generated from \texttt{monitored\_valid.i} as follows:
 \begin{shell}
 \$ DIR=`frama-c -print-share-path`/e-acsl
 \$ MDIR=\$DIR/memory_model
-\$ gcc -o valid \$DIR/e_acsl.c \$MDIR/e_acsl_bittree.c \$MDIR/e_acsl_mmodel.c monitored_valid.i
+\$ gcc -o valid \$DIR/e_acsl.c \$MDIR/e_acsl_bittree.c \$MDIR/e_acsl_mmodel.c \
+       monitored_valid.i
 \end{shell}
 
 Now we can execute the generate binary which fails at runtime since the second
@@ -417,6 +423,11 @@ The failing predicate is:
 mem_access: \valid_read(x).
 \end{shell}
 
+The option \optiondef{-}{e-acsl-full-mmodel} (unset by default) may be set to
+always instrumente the code for handline potential memory-related annotations,
+even when it is not required. If it is set, the generated program must be always
+linked against the memory library.
+
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
 \subsection{Execution Behavior Environment}
@@ -463,6 +474,7 @@ instrumented code.
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
 \subsection{Program without Main}
+\label{sec:no-main}
 \index{Program!Without main}
 
 The \eacsl plug-in may work even if there is no \texttt{main} function.
@@ -487,7 +499,7 @@ warning.
 
 This warning indicates that the instrumentation would be incorrect if the
 program contains memory-related annotations (see
-Section~\ref{sec:limits:incomplete}). That is not the case here, so you can
+Section~\ref{sec:limits:no-main}). That is not the case here, so you can
 safely ignore it. Now, it is possible to compile the generated code with a \C
 compiler in a standard way, and even to link it against additional files like
 the following one. In this particular case, we also need to link against \gmp as
@@ -530,7 +542,7 @@ generating default assigns from the prototype
 
 Like in the previous Section, this warning indicates that the instrumentation
 would be incorrect if the program contains memory-related annotations (see
-Section~\ref{sec:limits:incomplete}). That is still not the case here, so you
+Section~\ref{sec:limits:no-code}). That is still not the case here, so you
 can safely ignore it. Now, it is possible to compile the generated code with a
 \C compiler in a standard way, and even to link it against additional files that
 provided an implementation for the missing functions like the following one. In
diff --git a/src/plugins/e-acsl/options.ml b/src/plugins/e-acsl/options.ml
index 116b536b441780b80d15891aba42a3e9a1876866..e7e4af5cb0069e97f5d4887ef4917f3011977e22 100644
--- a/src/plugins/e-acsl/options.ml
+++ b/src/plugins/e-acsl/options.ml
@@ -73,14 +73,14 @@ module Gmp_only =
   False
     (struct
       let option_name = "-e-acsl-gmp-only"
-      let help = ""
+      let help = "always use GMP integers instead of C integral types"
      end)
 
 module Full_mmodel =
   False
     (struct
       let option_name = "-e-acsl-full-mmodel"
-      let help = ""
+      let help = "maximal memory-related instrumentation"
      end)
 
 let () = Plugin.set_group help
diff --git a/src/plugins/e-acsl/pre_analysis.ml b/src/plugins/e-acsl/pre_analysis.ml
index e3ec7b0847c3a8f6a49f46f3308419143677dd94..529771ac51896e4d27bd7361ff36219f9f8cf430 100644
--- a/src/plugins/e-acsl/pre_analysis.ml
+++ b/src/plugins/e-acsl/pre_analysis.ml
@@ -663,8 +663,10 @@ and must_model_exp ?kf ?stmt e = match e.enode with
   | AlignOfE _ -> assert false
 
 let must_model_vi ?kf ?stmt vi =
-  Options.Full_mmodel.get ()
-  || Error.generic_handle (must_model_vi ?kf ?stmt) false vi
+  not (Cil.isFunctionType vi.vtype || (vi.vghost && vi.vstorage = Extern))
+  &&
+    (Options.Full_mmodel.get ()
+     || Error.generic_handle (must_model_vi ?kf ?stmt) false vi)
 
 let must_model_lval ?kf ?stmt lv = 
   Options.Full_mmodel.get ()
@@ -674,7 +676,7 @@ let old_must_model_vi bhv ?kf ?stmt vi =
   Options.Full_mmodel.get ()
   || must_model_vi ?kf ?stmt (Cil.get_original_varinfo bhv vi)
 
-let use_model () = not (Env.is_empty ())
+let use_model () = not (Env.is_empty ()) || Options.Full_mmodel.get ()
 
 (*
 Local Variables:
diff --git a/src/plugins/e-acsl/visit.ml b/src/plugins/e-acsl/visit.ml
index ec969c8d87a7af09f6f522a393c881c2f57f76d3..5b32e4fc6b80a32dd471f8bc2ff502617de3aef1 100644
--- a/src/plugins/e-acsl/visit.ml
+++ b/src/plugins/e-acsl/visit.ml
@@ -226,7 +226,7 @@ class e_acsl_visitor prj generate = object (self)
 		  let new_globals =
 		    List.fold_right
 		      (fun g acc -> match g with
-		      | GFun({ svar = vi }, _) 
+		      | GFun({ svar = vi }, _)
 			  when Varinfo.equal vi main.svar -> 
 			acc
 		      | _ -> g :: acc)
@@ -235,8 +235,8 @@ class e_acsl_visitor prj generate = object (self)
 		  in
 		  f.globals <- new_globals
 		| None -> 
-		  Kernel.warning "no entry point specified:@ \
-you must call function `%s' by yourself" 
+		  Kernel.warning "@[no entry point specified:@ \
+you must call function `%s' and `__clean' by yourself.@]" 
 		    fname;
 		  f.globals <- f.globals @ [ cil_fct ]
 	    in