diff --git a/.gitignore b/.gitignore
index b458e734ce8fc11f52dd8058aeef29319dba8dfc..509b46e7ac947299b35a7ef11dcaf12597820e1d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -34,6 +34,7 @@ autom4te.cache
 /config.log
 /config.status
 /frama-c-*.tar.gz
+/distributed
 /.log.autoconf
 /.Makefile.user
 /ocamlgraph/
@@ -193,7 +194,6 @@ Makefile.plugin.generated
 /src/libraries/utils/json.ml
 /src/kernel_internals/runtime/toplevel_boot.ml
 /src/kernel_internals/runtime/fc_config.ml
-/src/kernel_internals/runtime/frama_c_config.ml
 /src/kernel_internals/parsing/logic_lexer.ml
 /src/kernel_internals/parsing/logic_parser.ml
 /src/kernel_internals/parsing/logic_parser.mli
@@ -210,6 +210,7 @@ Makefile.plugin.generated
 /src/plugins/gui/GSourceView2.ml
 /src/plugins/gui/GSourceView2.mli
 /src/plugins/gui/gtk_compat.ml
+/src/plugins/markdown-report/META
 
 # generated tar.gz files
 
diff --git a/bin/build-src-distrib.sh b/bin/build-src-distrib.sh
index 1bfb095e9c7ede6d469630aa0896568f7c4e48cd..003db5f0f80ba222d5681d98f80449198de48830 100755
--- a/bin/build-src-distrib.sh
+++ b/bin/build-src-distrib.sh
@@ -2,6 +2,14 @@
 
 set -u
 
+# Search "BEGIN SCRIPT" to skip functions
+
+# Set it to "no" in order to really execute the commands.
+# Otherwise, they are only printed.
+DEBUG=no
+
+# Set variable VERBOSE_MAKE_DOC to see all latex messages during manuals build
+
 # Executing this script requires bash 4.0 or higher
 # (special use of the 'case' construct)
 if test `echo $BASH_VERSION | sed "s/\([0-9]\).*/\1/" ` -lt 4; then
@@ -15,9 +23,531 @@ if ! command -v git-lfs >/dev/null 2>/dev/null; then
     exit 99
 fi
 
-# Set it to "no" in order to really execute the commands.
-# Otherwise, they are only printed.
-DEBUG=no
+# rgrep needs to be installed
+if ! command -v rgrep --version >/dev/null 2>/dev/null; then
+    echo "rgrep is required"
+    exit 99
+fi
+
+function run {
+    cmd=$1
+    echo "$cmd"
+    if test "$DEBUG" == "no"; then
+        sh -c "$cmd" || { echo "Aborting step ${STEP}."; exit "${STEP}"; }
+    fi
+}
+
+function step {
+    STEP=$1
+    echo
+    echo "Step $1: $2"
+}
+
+# find_repository_DIRECTORY_BRANCH path url
+# - path: path to the directory
+# - url: URL of the repository
+# Checks:
+# - master branch
+# Sets:
+# DIRECTORY: path to the directory
+function find_repository_DIRECTORY_BRANCH {
+    name=$1
+    url=$2
+    if test \! -d $name/.git ; then
+        echo "### WARNING: $name/.git directory not found; do you want to clone it? (y/n)"
+        read CHOICE
+        case "${CHOICE}" in
+            "Y"|"y")
+                run "git clone $url $name"
+                ;;
+            *)
+                echo "The $url repository must be linked at $name (clone or symbolic link)"
+                exit 1
+                ;&
+        esac
+    fi
+    DIRECTORY=$name
+    BRANCH=`git --git-dir=$name/.git rev-parse --abbrev-ref HEAD`
+    if [ "$BRANCH" != "master" ]; then
+        echo "### WARNING: $name repository is on branch $BRANCH"
+        proceed_anyway "Reset the branch to 'master', then run the script again."
+    fi
+}
+
+# proceed_anyway message
+# - message: text to display if we have to stop
+# Ask if the user wants to continue and display the message if not (then exit)
+function proceed_anyway {
+    message=$1
+    echo "Proceed anyway? [y/N]"
+    read CHOICE
+    case "${CHOICE}" in
+        "Y"|"y")
+            ;;
+        *)
+            echo "$message"
+            exit 1
+    esac
+}
+
+function look_for_uncommited_changes {
+    run "git update-index --refresh"
+    if ! git diff-index HEAD --; then
+        echo ""
+        echo "### WARNING: uncommitted git changes will be discarded when creating archive!"
+        proceed_anyway "Stash or commit local changes, then run the script again."
+    fi
+}
+
+function look_for_frama_c_dev {
+    rgrep -i "frama-c+dev" src &> /dev/null
+    if [ "$?" == "0" ]; then
+        echo "### WARNING: Remaining frama-c+dev occurrences in 'src'"
+        proceed_anyway "Update API, then run the script again"
+    fi
+}
+
+function assert_build_dir {
+    if test \! -d "$BUILD_DIR" ; then
+        echo "ERROR: $BUILD_DIR does not exist, possibly removed by another step"
+        exit 1
+    fi
+}
+
+function assert_out_dir {
+    if test \! -d "$OUT_DIR" ; then
+        echo "ERROR: $OUT_DIR does not exist, possibly removed by another step"
+        exit 1
+    fi
+}
+
+# diff_validation repository file
+# - repository: target repository
+# - file: target file
+# Ask for user validation before staging changes in [file] on the [repository].
+# Stops the script if the user refuses the changes
+function diff_validation {
+    repo=$1
+    file=$2
+    run "git -C $repo diff $file"
+    echo
+    echo "Is the above diff correct for $file? [y/N]"
+    read CHOICE
+    case "${CHOICE}" in
+        "Y"|"y")
+            ;;
+        *)
+            echo "Something went wrong, you may want to clean $repo"
+            exit 1
+    esac
+    run "git -C $repo add $file"
+}
+
+# Manuals choice
+
+function get_MANUAL_NAME {
+    case "$1" in
+        "user") MANUAL_NAME="Frama-C user manual" ;;
+        "plugin-dev") MANUAL_NAME="Frama-C plug-in development guide" ;;
+        "api") MANUAL_NAME="Frama-C API bundle" ;;
+        "acsl-1") MANUAL_NAME="ACSL manual" ;;
+        "acsl-impl") MANUAL_NAME="ACSL implementation" ;;
+        "aorai") MANUAL_NAME="Aorai manual" ;;
+        "e-acsl-1") MANUAL_NAME="E-ACSL reference" ;;
+        "e-acsl-impl") MANUAL_NAME="E-ACSL implementation" ;;
+        "e-acsl-man") MANUAL_NAME="E-ACSL manual" ;;
+        "eva") MANUAL_NAME="EVA manual" ;;
+        "metrics") MANUAL_NAME="Metrics manual" ;;
+        "rte") MANUAL_NAME="RTE manual" ;;
+        "wp") MANUAL_NAME="WP manual" ;;
+        *) MANUAL_NAME="Not a manual identifier: $1" ;;
+    esac
+}
+
+function check_manual {
+    value=$1
+    if [[ ! " ${AVAILABLE_MANUALS[@]} " =~ " ${value} " ]]; then
+        echo "### ERROR: in $INCLUDED_MANUALS_CONFIG: $value is not a valid manual identifier"
+        exit 1
+    fi
+}
+
+function show_generated_manuals {
+    echo
+    echo "The following manuals will be included."
+    for i in ${INCLUDED_MANUALS[@]}; do
+        get_MANUAL_NAME $i
+        echo "- $MANUAL_NAME"
+    done
+    echo
+}
+
+function create_manuals_config {
+    echo -n > $INCLUDED_MANUALS_CONFIG
+    for i in ${AVAILABLE_MANUALS[@]}; do
+        get_MANUAL_NAME $i
+        echo "Include $MANUAL_NAME? [y/N]"
+        read CHOICE
+        case "${CHOICE}" in
+            "Y"|"y")
+                echo $i >> $INCLUDED_MANUALS_CONFIG ;;
+            *) ;;
+        esac
+    done
+}
+
+function check_manual_path_MUST_ADD {
+    MUST_ADD="no"
+    for i in ${INCLUDED_MANUALS[@]}; do
+        if [[ $1 == "$i"* ]]; then
+            MUST_ADD="yes"
+        fi
+    done
+}
+
+# WIKI generation
+
+function fill_wiki {
+    PAGE_NAME=Frama-C-${FRAMAC_VERSION_AND_CODENAME}.md
+    WIKI_PAGE=$WIKI_DIR/$PAGE_NAME
+    run "mkdir -p $WIKI_DIR/manuals"
+    run "sed -i -e '/<!-- LAST RELEASE -->/a \
+- [${FRAMAC_VERSION} (${FRAMAC_VERSION_CODENAME})](Frama-C-${FRAMAC_VERSION_AND_CODENAME})' $WIKI_DIR/Home.md"
+    if test "$FINAL_RELEASE" = "yes"; then
+        release_type="FINAL"
+    else
+        release_type="BETA"
+    fi
+    run "sed -i -e '/<!-- LAST ${release_type} RELEASE -->/a \
+- [${FRAMAC_VERSION} (${FRAMAC_VERSION_CODENAME})](Frama-C-${FRAMAC_VERSION_AND_CODENAME})' $WIKI_DIR/_sidebar.md"
+    echo "# Frama-C release ${FRAMAC_VERSION} (${FRAMAC_VERSION_CODENAME})" > $WIKI_PAGE
+    echo "## Sources" >> $WIKI_PAGE
+    run "cp $OUT_DIR/$TARGZ_FILENAME $WIKI_DIR/downloads"
+    run "git -C $WIKI_DIR add downloads/$TARGZ_FILENAME"
+    echo " - [$TARGZ_FILENAME](downloads/$TARGZ_FILENAME)" >> $WIKI_PAGE
+    echo "" >> $WIKI_PAGE
+    echo "## Manuals" >> $WIKI_PAGE
+    for fpath in $OUT_DIR/manuals/* ; do
+        f=$(basename $fpath)
+        check_manual_path_MUST_ADD $f
+        if [[ $MUST_ADD == "yes" ]]; then
+            f_no_ext=${f%.*}
+            f_no_pdf_ext="${f%.pdf}"
+            echo "- [${f_no_pdf_ext%-${FRAMAC_VERSION_AND_CODENAME}}](manuals/$f)" >> $WIKI_PAGE
+            run "cp $fpath $WIKI_DIR/manuals/"
+            run "git -C $WIKI_DIR add manuals/$f"
+        fi
+    done
+    echo "" >> $WIKI_PAGE
+    echo "## Main changes" >> $WIKI_PAGE
+    sed 's/\(\#.*\)/##\1/' $CHANGES >> $WIKI_PAGE
+    run "git -C $WIKI_DIR add $PAGE_NAME"
+    diff_validation $WIKI_DIR "Home.md"
+    diff_validation $WIKI_DIR "_sidebar.md"
+}
+
+# WEBSITE pages generation
+
+function add_install_page {
+    INSTALL_WEBPAGE=html/installations/$FRAMAC_VERSION_CODENAME_LOWER.md
+    INSTALL_WEBPAGE_PATH=$WEBSITE_DIR/$INSTALL_WEBPAGE
+    echo "---" > $INSTALL_WEBPAGE_PATH
+    echo "layout: doc_page" >> $INSTALL_WEBPAGE_PATH
+    echo "title: Installation instructions for $FRAMAC_VERSION_CODENAME" >> $INSTALL_WEBPAGE_PATH
+    echo "---" >> $INSTALL_WEBPAGE_PATH
+    echo >> $INSTALL_WEBPAGE_PATH
+    cat ./INSTALL.md >> $INSTALL_WEBPAGE_PATH
+
+    run "git -C $WEBSITE_DIR add $INSTALL_WEBPAGE"
+}
+
+function add_event_page {
+    EVENT_WEBPAGE=_events/framac-$FRAMAC_VERSION.md
+    EVENT_WEBPAGE_PATH=$WEBSITE_DIR/$EVENT_WEBPAGE
+
+    if [ "$VERSION_MINOR" != 0 ]; then
+        PREVIOUS=$VERSION_MAJOR
+    else
+        PREVIOUS=$(( $VERSION_MAJOR-1 ))
+    fi
+    PREVIOUS_NAME=$(git show $PREVIOUS.0:VERSION_CODENAME)
+
+    TEXTUAL_VERSION="Frama-C $FRAMAC_VERSION ($FRAMAC_VERSION_CODENAME)"
+    TEXTUAL_PREVIOUS="Frama-C $PREVIOUS ($PREVIOUS_NAME)"
+
+    echo "---" > $EVENT_WEBPAGE_PATH
+    echo "layout: default" >> $EVENT_WEBPAGE_PATH
+    echo "date: $(date +\"%d-%m-%Y\")" >> $EVENT_WEBPAGE_PATH
+    echo "event: $TEXTUAL_VERSION" >> $EVENT_WEBPAGE_PATH
+    echo -n "title: " >> $EVENT_WEBPAGE_PATH
+    if [ "$FINAL_RELEASE" = "no" ]; then
+        echo -n "Beta release " >> $EVENT_WEBPAGE_PATH
+    else
+        echo -n "Release " >> $EVENT_WEBPAGE_PATH
+    fi
+    echo "of $TEXTUAL_VERSION" >> $EVENT_WEBPAGE_PATH
+    VERSION_PAGE="/fc-versions/$FRAMAC_VERSION_CODENAME_LOWER.html"
+    echo "link: $VERSION_PAGE" >> $EVENT_WEBPAGE_PATH
+    echo "---" >> $EVENT_WEBPAGE_PATH
+    echo >> $EVENT_WEBPAGE_PATH
+    echo "$TEXTUAL_VERSION is out. Download it [here]($VERSION_PAGE)." >> $EVENT_WEBPAGE_PATH
+    echo >> $EVENT_WEBPAGE_PATH
+    echo "Main changes with respect to $TEXTUAL_PREVIOUS include:" >> $EVENT_WEBPAGE_PATH
+    echo >> $EVENT_WEBPAGE_PATH
+    sed 's/\(\#.*\)/###\1/' $CHANGES >> $EVENT_WEBPAGE_PATH
+
+    run "git -C $WEBSITE_DIR add $EVENT_WEBPAGE"
+}
+
+function add_version_page {
+    VERSION_WEBPAGE="_fc-versions/$FRAMAC_VERSION_CODENAME_LOWER.md"
+    VERSION_WEBPAGE_PATH=$WEBSITE_DIR/$VERSION_WEBPAGE
+    ACSL_VERSION=$(ls $OUT_DIR/manuals | sed -n 's/^acsl-1.\([0-9][0-9]\).pdf/\1/p')
+    echo "---" > $VERSION_WEBPAGE_PATH
+    echo "layout: version" >> $VERSION_WEBPAGE_PATH
+    echo "number: $VERSION_MAJOR" >> $VERSION_WEBPAGE_PATH
+    echo "name: $FRAMAC_VERSION_CODENAME" >> $VERSION_WEBPAGE_PATH
+    if [ "$FINAL_RELEASE" = "no" ]; then
+        echo "beta: true" >> $VERSION_WEBPAGE_PATH
+    else
+        echo "acsl: $ACSL_VERSION" >> $VERSION_WEBPAGE_PATH
+    fi
+    echo "releases:" >> $VERSION_WEBPAGE_PATH
+    echo "  - number: $VERSION_MINOR" >> $VERSION_WEBPAGE_PATH
+    echo "    categories:" >> $VERSION_WEBPAGE_PATH
+    echo "    - name: Frama-C v$FRAMAC_VERSION $FRAMAC_VERSION_CODENAME" >> $VERSION_WEBPAGE_PATH
+    echo "      files:" >> $VERSION_WEBPAGE_PATH
+    echo "      - name: Source distribution" >> $VERSION_WEBPAGE_PATH
+    echo "        link: /download/$TARGZ_FILENAME" >> $VERSION_WEBPAGE_PATH
+    echo "        help: Compilation instructions" >> $VERSION_WEBPAGE_PATH
+    echo "        help_link: /html/installations/$FRAMAC_VERSION_CODENAME_LOWER.html" >> $VERSION_WEBPAGE_PATH
+    check_manual_path_MUST_ADD "user"
+    if [[ $MUST_ADD == "yes" ]]; then
+        echo "      - name: User manual" >> $VERSION_WEBPAGE_PATH
+        echo "        link: /download/user-manual-$FRAMAC_VERSION_AND_CODENAME.pdf" >> $VERSION_WEBPAGE_PATH
+    fi
+    check_manual_path_MUST_ADD "plugin-dev"
+    if [[ $MUST_ADD == "yes" ]]; then
+        echo "      - name: Plug-in development guide" >> $VERSION_WEBPAGE_PATH
+        echo "        link: /download/plugin-development-guide-$FRAMAC_VERSION_AND_CODENAME.pdf" >> $VERSION_WEBPAGE_PATH
+        echo "        help: Hello plug-in tutorial archive" >> $VERSION_WEBPAGE_PATH
+        echo "        help_link: /download/hello-$FRAMAC_VERSION_AND_CODENAME.tar.gz" >> $VERSION_WEBPAGE_PATH
+    fi
+    check_manual_path_MUST_ADD "api"
+    if [[ $MUST_ADD == "yes" ]]; then
+        echo "      - name: API Documentation" >> $VERSION_WEBPAGE_PATH
+        echo "        link: /download/frama-c-$FRAMAC_VERSION_AND_CODENAME-api.tar.gz" >> $VERSION_WEBPAGE_PATH
+    fi
+    check_manual_path_MUST_ADD "acsl-impl"
+    if [[ $MUST_ADD == "yes" ]]; then
+        echo "      - name: ACSL 1.$ACSL_VERSION ($FRAMAC_VERSION_CODENAME implementation)" >> $VERSION_WEBPAGE_PATH
+        echo "        link: /download/acsl-implementation-$FRAMAC_VERSION_AND_CODENAME.pdf" >> $VERSION_WEBPAGE_PATH
+    fi
+    echo "    - name: Plug-in Manuals" >> $VERSION_WEBPAGE_PATH
+    echo "      sort: true" >> $VERSION_WEBPAGE_PATH
+    echo "      files:" >> $VERSION_WEBPAGE_PATH
+    check_manual_path_MUST_ADD "aorai"
+    if [[ $MUST_ADD == "yes" ]]; then
+        echo "      - name: Aoraï manual" >> $VERSION_WEBPAGE_PATH
+        echo "        link: /download/aorai-manual-$FRAMAC_VERSION_AND_CODENAME.pdf" >> $VERSION_WEBPAGE_PATH
+        echo "        help: Aoraï example" >> $VERSION_WEBPAGE_PATH
+        echo "        help_link: /download/aorai-example-$FRAMAC_VERSION_AND_CODENAME.tgz" >> $VERSION_WEBPAGE_PATH
+    fi
+    check_manual_path_MUST_ADD "metrics"
+    if [[ $MUST_ADD == "yes" ]]; then
+        echo "      - name: Metrics manual" >> $VERSION_WEBPAGE_PATH
+        echo "        link: /download/metrics-manual-$FRAMAC_VERSION_AND_CODENAME.pdf" >> $VERSION_WEBPAGE_PATH
+    fi
+    check_manual_path_MUST_ADD "rte"
+    if [[ $MUST_ADD == "yes" ]]; then
+        echo "      - name: Rte manual" >> $VERSION_WEBPAGE_PATH
+        echo "        link: /download/rte-manual-$FRAMAC_VERSION_AND_CODENAME.pdf" >> $VERSION_WEBPAGE_PATH
+    fi
+    check_manual_path_MUST_ADD "eva"
+    if [[ $MUST_ADD == "yes" ]]; then
+        echo "      - name: Eva manual" >> $VERSION_WEBPAGE_PATH
+        echo "        link: /download/eva-manual-$FRAMAC_VERSION_AND_CODENAME.pdf" >> $VERSION_WEBPAGE_PATH
+    fi
+    check_manual_path_MUST_ADD "wp"
+    if [[ $MUST_ADD == "yes" ]]; then
+        echo "      - name: WP manual" >> $VERSION_WEBPAGE_PATH
+        echo "        link: /download/wp-manual-$FRAMAC_VERSION_AND_CODENAME.pdf" >> $VERSION_WEBPAGE_PATH
+    fi
+    check_manual_path_MUST_ADD "e-acsl-man"
+    if [[ $MUST_ADD == "yes" ]]; then
+        echo "      - name: E-ACSL manual" >> $VERSION_WEBPAGE_PATH
+        echo "        link: /download/e-acsl/e-acsl-manual-$FRAMAC_VERSION_AND_CODENAME.pdf" >> $VERSION_WEBPAGE_PATH
+    fi
+    echo "---" >> $VERSION_WEBPAGE_PATH
+
+    run "git -C $WEBSITE_DIR add $VERSION_WEBPAGE"
+}
+
+function add_downloads {
+    DOWNLOAD_DIR="$WEBSITE_DIR/download"
+    DOWNLOAD_PATH="download"
+    for fpath in $OUT_DIR/manuals/* ; do
+        f=$(basename $fpath)
+        f_no_ext=${f%.*}
+
+        check_manual_path_MUST_ADD $f
+        if [[ $MUST_ADD == "yes" ]]; then
+            if [[ $f_no_ext =~ ^e-acsl.*$ ]]; then
+                BASE="e-acsl/$f"
+            else
+                BASE="$f"
+            fi
+
+            if   [[ $f_no_ext =~ ^(e-)?acsl-[0-9].[0-9][0-9]$ ]]; then
+                REPL=$(echo $BASE | sed -e "s/-[0-9].[0-9][0-9]//")
+            elif [[ $f_no_ext =~ ^e-acsl-* ]]; then
+                REPL=$(echo $BASE | sed -e "s/-$FRAMAC_VERSION_AND_CODENAME//")
+            else
+                REPL=$(echo $BASE | sed -e "s/\(.*\)-$FRAMAC_VERSION_AND_CODENAME/frama-c-\1/")
+            fi
+
+            run "cp $fpath $DOWNLOAD_DIR/$BASE"
+            run "git -C $WEBSITE_DIR add $DOWNLOAD_PATH/$BASE"
+
+            # we change generic files ONLY for FINAL release
+            if test "$FINAL_RELEASE" = "yes"; then
+                run "cp $fpath $DOWNLOAD_DIR/$REPL"
+                run "git -C $WEBSITE_DIR add $DOWNLOAD_PATH/$REPL"
+            fi
+        fi
+    done
+
+    # Particular case for the value analysis manual:
+    EVA_FILE="$OUT_DIR/manuals/eva-manual-$FRAMAC_VERSION_AND_CODENAME.pdf"
+    VALUE_PATH="$DOWNLOAD_DIR/frama-c-value-analysis.pdf"
+    VALUE_GIT_PATH="$DOWNLOAD_PATH/frama-c-value-analysis.pdf"
+    # we change generic files ONLY for FINAL release
+    if test "$FINAL_RELEASE" = "yes"; then
+        run "cp $EVA_FILE $VALUE_PATH"
+        run "git -C $WEBSITE_DIR add $VALUE_GIT_PATH"
+    fi
+
+    # Examples:
+    HELLO="hello-$FRAMAC_VERSION_AND_CODENAME.tar.gz"
+    check_manual_path_MUST_ADD "plugin-dev"
+    if [[ $MUST_ADD == "yes" ]]; then
+        run "cp $OUT_DIR/$HELLO $DOWNLOAD_DIR"
+        run "git -C $WEBSITE_DIR add $DOWNLOAD_PATH/$HELLO"
+        # we change generic files ONLY for FINAL release
+        if test "$FINAL_RELEASE" = "yes"; then
+            run "cp $OUT_DIR/$HELLO $DOWNLOAD_DIR"
+            run "git -C $WEBSITE_DIR add $DOWNLOAD_PATH/hello.tar.gz"
+        fi
+    fi
+
+    # Source distribution:
+    run "cp $OUT_DIR/$TARGZ_FILENAME $DOWNLOAD_DIR"
+    run "git -C $WEBSITE_DIR add $DOWNLOAD_PATH/$TARGZ_FILENAME"
+
+    # API
+    run "cp $OUT_DIR/frama-c-api.tar.gz $DOWNLOAD_DIR/frama-c-api-$FRAMAC_VERSION_AND_CODENAME.tar.gz"
+    run "git -C $WEBSITE_DIR add $DOWNLOAD_PATH/frama-c-api-$FRAMAC_VERSION_AND_CODENAME.tar.gz"
+}
+
+function fill_website {
+    add_install_page
+    add_event_page
+    add_version_page
+    add_downloads
+}
+
+# Commit changes
+
+function create_website_branch {
+    if test "$FINAL_RELEASE" = "yes"; then
+        BRANCH_NAME="release/stable-$FRAMAC_VERSION-$FRAMAC_VERSION_CODENAME_LOWER"
+    else
+        BRANCH_NAME="release/beta-$FRAMAC_VERSION-$FRAMAC_VERSION_CODENAME_LOWER"
+    fi
+    # Chech whether release/<release> exists on the website
+    git -C $WEBSITE_DIR show-ref --verify --quiet refs/heads/$BRANCH_NAME
+    if [[ "$?" == "0" ]]; then
+        echo "### Warning: branch $BRANCH_NAME already exists in $WEBSITE_DIR"
+        echo "The script will ERASE this branch"
+        proceed_anyway "Rename or erase the branch, then run the script again."
+        run "git -C $WEBSITE_DIR branch -D $BRANCH_NAME"
+    fi
+
+    # Set release/<release> and displays changes to be committed
+    run "git -C $WEBSITE_DIR checkout --quiet -b $BRANCH_NAME"
+    run "git -C $WEBSITE_DIR status"
+
+    echo "Commit locally the previous changes on $WEBSITE_DIR:$BRANCH_NAME? [y/N]"
+    read CHOICE
+    case "${CHOICE}" in
+        "Y"|"y")
+            ;;
+        *)
+            echo "Abort website branch creation, reset to master."
+            run "git -C $WEBSITE_DIR checkout master"
+            exit 1
+    esac
+    run "git -C $WEBSITE_DIR commit -m \"Prepare pages for the release of Frama-C $FRAMAC_VERSION\""
+}
+
+function commit_wiki {
+    run "git -C $WIKI_DIR status"
+
+    echo "Commit locally the previous changes on $WIKI_DIR? [y/N]"
+    read CHOICE
+    case "${CHOICE}" in
+        "Y"|"y")
+            ;;
+        *)
+            echo "Abort wiki update."
+            exit 1
+    esac
+    run "git -C $WIKI_DIR commit -m \"Prepare pages for the release of Frama-C $FRAMAC_VERSION\""
+}
+
+
+function propagate_changes {
+    create_website_branch
+    commit_wiki
+}
+
+function last_step_validation {
+    # if test "$FRAMAC_VERSION" != "$FRAMAC_TAG"; then
+    #     echo "To go further, the last commit must be tagged with the right version"
+    #     exit 1
+    # fi
+    echo "
+    This step will:
+
+      - ask for a validation of the changes to website
+      - create a NEW branch on for the website
+
+      - ask for a validation of the changes to wiki
+      - commit changes to the wiki MASTER branch
+
+    If you want to perform some additional checks it is probably time to stop.
+
+    Generated files are available in: $OUT_DIR.
+    "
+    echo -n "If you are ready to continue, type exactly \"RELEASE\": "
+    read CHOICE
+    case "${CHOICE}" in
+        "RELEASE")
+            ;;
+        *)
+            echo "Aborting"
+            exit 1
+    esac
+}
+
+
+# BEGIN SCRIPT
+GITLAB_FRAMA_C_PUBLIC="git@git.frama-c.com:pub"
+GITLAB_WIKI="$GITLAB_FRAMA_C_PUBLIC/frama-c.wiki.git"
+GITLAB_WEBSITE="$GITLAB_FRAMA_C_PUBLIC/pub.frama-c.com.git"
+GITLAB_ACSL="git@github.com:acsl-language/acsl.git"
+GITLAB_FRAMA_C_PRIVATE="git@git.frama-c.com:frama-c/frama-c.git"
+
 if test \! -e .git ; then
     echo "ERROR: .git directory not found"
     echo "This script must be run at the root of a Frama-C repository"
@@ -30,9 +560,11 @@ if test \! -f VERSION ; then
     echo "This script must be run at the root of a Frama-C repository"
     exit 1
 fi
+
 FRAMAC_VERSION=$(cat VERSION)
 FRAMAC_TAG=$(git describe --tag)
 FRAMAC_VERSION_CODENAME=$(cat VERSION_CODENAME)
+FRAMAC_VERSION_CODENAME_LOWER=$(echo "$FRAMAC_VERSION_CODENAME" | tr '[:upper:]' '[:lower:]')
 FRAMAC_VERSION_AND_CODENAME="${FRAMAC_VERSION}-${FRAMAC_VERSION_CODENAME}"
 TARGZ_FILENAME=frama-c-${FRAMAC_VERSION_AND_CODENAME}.tar.gz
 
@@ -41,144 +573,129 @@ VERSION_MAJOR=$(cat VERSION | sed -e s/\\\([0-9]*\\\).[0-9]*.*/\\1/)
 VERSION_MINOR=$(cat VERSION | sed -e s/[0-9]*.\\\([0-9]*\\\).*/\\1/)
 
 if test -n "$VERSION_MODIFIER"; then FINAL_RELEASE=no; else FINAL_RELEASE=yes; fi
+if [ "$VERSION_MODIFIER" == "+dev" ]; then
+    echo "### WARNING: The VERSION is a development version"
+    proceed_anyway "Update VERSION and run the script again"
+fi
 
 if test "$FRAMAC_VERSION" != "$FRAMAC_TAG"; then
-    echo "WARNING: The current commit is not tagged with the current version:"
+    echo "### WARNING: The current commit is not tagged with the current version:"
     echo "Frama-C Version: $FRAMAC_VERSION"
     echo "Frama-C Tag    : $FRAMAC_TAG"
 fi
 
-run () {
-    cmd=$1
-    echo "$cmd"
-    if test "$DEBUG" == "no"; then
-        sh -c "$cmd" || { echo "Aborting step ${STEP}."; exit "${STEP}"; }
-    fi
-}
+# Find specific repositories
 
-# GITLAB_DIR=./pub-frama-c
-# GITLAB_GIT="git@git.frama-c.com:pub/frama-c.git"
-
-# if test ! -d $GITLAB_DIR/.git; then
-#     echo "WARNING: $GITLAB_DIR/.git directory not found; do you want to clone it? (y/n)"
-#     read CHOICE
-#     case "${CHOICE}" in
-#         "Y"|"y")
-#             run "git clone $GITLAB_GIT $GITLAB_DIR"
-#             ;;
-#         *)
-#             echo "gitlab's public Frama-C project must be linked at $GITLAB_DIR \
-    #                  (clone or symbolic link)"
-#             exit 1
-#             ;&
-#     esac
-# fi
-# GITLAB_BRANCH=$(git --git-dir=$GITLAB_DIR/.git rev-parse --abbrev-ref HEAD)
-# if test "$FRAMAC_BRANCH" != "$GITLAB_BRANCH"; then
-#     echo "WARNING: switching pub-frama-c to current branch $FRAMAC_BRANCH"
-#     run "git -C $GITLAB_DIR checkout -b $FRAMAC_BRANCH"
-# fi
-
-GITLAB_WIKI_GIT="git@git.frama-c.com:pub/frama-c.wiki"
-GITLAB_WIKI=./frama-c.wiki
-if test ! -d $GITLAB_WIKI/.git; then
-    echo "WARNING: $GITLAB_WIKI/.git directory not found; do you want to clone it? (y/n)"
-    read CHOICE
-    case "${CHOICE}" in
-        "Y"|"y")
-            run "git clone $GITLAB_WIKI_GIT"
-            ;;
-        *)
-            echo "pub/frama-c wiki must be linked at $GITLAB_WIKI \
-                 (clone or symbolic link)"
-            exit 1
-            ;&
-    esac
-fi
-GITLAB_WIKI_BRANCH=$(git --git-dir=$GITLAB_WIKI/.git rev-parse --abbrev-ref HEAD)
+find_repository_DIRECTORY_BRANCH "./frama-c.wiki" $GITLAB_WIKI
+WIKI_DIR=$DIRECTORY
+WIKI_BRANCH=$BRANCH
 
-if test "$GITLAB_WIKI_BRANCH" != "master"; then
-    echo "WARNING: pub/frama-c's wiki is not on the master branch";
-fi
+find_repository_DIRECTORY_BRANCH "./website" $GITLAB_WEBSITE
+WEBSITE_DIR=$DIRECTORY
+WEBSITE_BRANCH=$BRANCH
 
-ACSL_GIT="git@gitlab.com:acsl-language/acsl.git"
-ACSL_DIR="./doc/acsl"
-if test \! -d $ACSL_DIR/.git ; then
-    echo "WARNING: $ACSL_DIR/.git directory not found; do you want to clone it? (y/n)"
+find_repository_DIRECTORY_BRANCH "./doc/acsl" $GITLAB_ACSL
+ACSL_DIR=$DIRECTORY
+
+CHANGES="./main_changes.md"
+if test \! -f $CHANGES ; then
+    echo "### WARNING: The $CHANGES file is missing"
+    echo "Do you want to create an empty one? [y/N]"
     read CHOICE
     case "${CHOICE}" in
         "Y"|"y")
-            pushd "./doc"
-            run "git clone $ACSL_GIT"
-            popd
-            ;;
+            touch $CHANGES;;
         *)
-            echo "The Github ACSL repository must be linked at $ACSL_DIR (clone or symbolic link)"
+            echo "Create a changes file and run the script again"
             exit 1
-            ;&
     esac
 fi
 
+AVAILABLE_MANUALS=("user" "api" "plugin-dev" "acsl-1" "acsl-impl" "aorai" "e-acsl-1" "e-acsl-man" "e-acsl-impl" "eva" "metrics" "rte" "wp")
+INCLUDED_MANUALS_CONFIG="./included_manuals"
+INCLUDED_MANUALS=()
 
-
-MANUALS_DIR="./doc/manuals"
-
-# push on frama-c.com only for final releases
-WEBSITE_GIT="git@git.frama-c.com:pub/pub.frama-c.com.git"
 if test "$FINAL_RELEASE" = "yes"; then
-    WEBSITE_DIR="./website"
-    if test \! -d $WEBSITE_DIR/.git ; then
-        echo "ERROR: $WEBSITE_DIR/.git directory not found; do you want to clone it? (y/n)"
+    # In final release mode, all manuals must be distributed
+    for i in ${AVAILABLE_MANUALS[@]}; do
+        INCLUDED_MANUALS+=($i)
+    done
+else
+    if test \! -f $INCLUDED_MANUALS_CONFIG ; then
+        echo "### WARNING: The $INCLUDED_MANUALS_CONFIG file is missing"
+        echo "Do you want to create one? [y/N]"
         read CHOICE
         case "${CHOICE}" in
             "Y"|"y")
-                run "git clone $WEBSITE_GIT website"
+                create_manuals_config
+                for i in $(cat $INCLUDED_MANUALS_CONFIG); do
+                    check_manual $i
+                    INCLUDED_MANUALS+=($i)
+                done
                 ;;
             *)
-                echo "The Github Website repository must be linked at $WEBSITE_DIR (clone or symbolic link)"
-                exit 1
-                ;&
+                echo "NO manuals will be included"
+                ;;
         esac
+    else
+        for i in $(cat $INCLUDED_MANUALS_CONFIG); do
+            check_manual $i
+            INCLUDED_MANUALS+=($i)
+        done
     fi
-    WEBSITE_BRANCH=`git --git-dir=$WEBSITE_DIR/.git rev-parse --abbrev-ref HEAD`
-fi # FINAL_RELEASE == yes
+fi
+
+MANUALS_DIR="./doc/manuals"
+
+FILTER=""
+if [ -z ${VERBOSE_MAKE_DOC+x} ]; then
+    if command -v texfot --version >/dev/null 2>/dev/null; then
+        FILTER="texfot --ignore '(Warning|Overfull|Underfull|Version)'"
+    fi
+fi
 
 BUILD_DIR_ROOT="/tmp/release"
 BUILD_DIR="$BUILD_DIR_ROOT/frama-c"
 
-echo "Frama-C Version         : $FRAMAC_VERSION"
-echo "Frama-C Branch          : $FRAMAC_BRANCH"
-echo "Final release           : $FINAL_RELEASE"
-# echo "pub/frama-c dir         : $GITLAB_DIR"
-# echo "pub/frama-c branch      : $GITLAB_BRANCH"
-echo "pub/frama-c wiki        : $GITLAB_WIKI"
-echo "Manuals Dir             : $MANUALS_DIR"
-if test "$FINAL_RELEASE" = "yes"; then
-    echo "Website Dir             : $WEBSITE_DIR"
-    echo "Website Branch          : $WEBSITE_BRANCH"
-else
-    echo "Intermediate release: website not updated"
-fi
-echo "Build Dir      : $BUILD_DIR"
+OUT_DIR="./distributed"
 
-DOWNLOAD_DIR="download"
+echo "############################# Frama-C Info ##############################"
+echo ""
+echo "Frama-C Version      : $FRAMAC_VERSION"
+echo "Final release        : $FINAL_RELEASE"
+echo "Frama-C Branch       : $FRAMAC_BRANCH"
+echo "Frama-C Wiki Dir     : $WIKI_DIR"
+echo "Website Dir          : $WEBSITE_DIR"
+echo "Changes file         : $CHANGES"
+echo "Build Dir            : $BUILD_DIR"
+echo "Output Dir           : $OUT_DIR"
+echo ""
+echo "############################# Manuals      ##############################"
+echo ""
+echo "Manuals Dir          : $MANUALS_DIR"
+echo "ACSL Dir             : $ACSL_DIR"
+show_generated_manuals
 
-step () {
-    STEP=$1
-    echo
-    echo "Step $1: $2"
-}
+echo "#########################################################################"
 
 export LC_CTYPE=en_US.UTF-8
 
-echo -n "Steps are:
+echo -n "
+Steps are:
+
   N) previous information is wrong, STOP the script
-  0) compile PDF manuals (will ERASE $MANUALS_DIR!)
-  1) reset local copy of target repositories
+  0) ERASE $OUT_DIR
+  1) compile PDF manuals (will ERASE $MANUALS_DIR!)
   2) build the source distribution
   3) build API bundle
   4) build documentation companions
-  5) copy and stage locally the distributed manuals
+  5) clean $BUILD_DIR
+  6) prepare wiki (will RESET HARD $WIKI_DIR:$WIKI_BRANCH)
+  7) prepare website (will RESET HARD $WEBSITE_DIR:$WEBSITE_BRANCH)
+  8) check generated distribution
+  9) generate opam file
+  10) commit changes
+
 Start at which step? (default is N, which cancels everything)
 - If this is the first time running this script, start at 0
 - Otherwise, start at the latest step before failure
@@ -191,36 +708,24 @@ case "${STEP}" in
         exit 0;
         ;&
     0)
-        step 0 "COMPILING PDF MANUALS"
-        run "rm -rf $MANUALS_DIR"
-        run "mkdir -p $MANUALS_DIR"
-        run "doc/build-manuals.sh"
+        step 0 "PREPARE DISTRIBUTION DIRECTORY"
+        run "rm -rf $OUT_DIR"
+        run "mkdir -p $OUT_DIR"
         ;&
+
     1)
-        # run "git -C $GITLAB_DIR reset --hard"
-        run "git -C $GITLAB_WIKI reset --hard"
-        if test "$FINAL_RELEASE" = "yes"; then
-            run "git -C $WEBSITE_DIR reset --hard"
-        fi
+        step 1 "COMPILING PDF MANUALS"
+        run "rm -rf $MANUALS_DIR"
+        run "mkdir -p $MANUALS_DIR"
+        run "$FILTER doc/build-manuals.sh"
+        run "rm -rf $OUT_DIR/manuals"
+        run "mkdir -p $OUT_DIR/manuals"
+        run "cp $MANUALS_DIR/* $OUT_DIR/manuals"
         ;&
     2)
         step 2 "BUILDING THE SOURCE DISTRIBUTION"
-        # WARNING! MUST RUN git update-index BEFORE git diff-index!
-        # See: https://stackoverflow.com/questions/36367190/git-diff-files-output-changes-after-git-status
-        run "git update-index --refresh"
-        if ! git diff-index HEAD --; then
-            echo ""
-            echo "### WARNING: uncommitted git changes will be discarded when creating archive!"
-            echo "Proceed anyway? [y/N]"
-            read CHOICE
-            case "${CHOICE}" in
-                "Y"|"y")
-                ;;
-                *)
-                    echo "Stash or commit local changes, then run the script again."
-                    exit 1
-            esac
-        fi
+        look_for_uncommited_changes
+        look_for_frama_c_dev
         run "mkdir -p $BUILD_DIR_ROOT"
         run "rm -rf $BUILD_DIR"
         run "git worktree add -f --detach $BUILD_DIR $FRAMAC_BRANCH"
@@ -229,112 +734,63 @@ case "${STEP}" in
         run "cd $BUILD_DIR; make -j OPEN_SOURCE=yes src-distrib"
         # sanity check: markdown-report must be distributed
         run "tar tf $BUILD_DIR/$TARGZ_FILENAME | grep -q src/plugins/markdown-report"
-        # populate release assets in wiki
-        run "mkdir -p $GITLAB_WIKI/downloads"
-        run "cp $BUILD_DIR/$TARGZ_FILENAME $GITLAB_WIKI/downloads/"
-        if test "$FINAL_RELEASE" = "yes"; then
-            SPEC_FILE="$DOWNLOAD_DIR/$TARGZ_FILENAME"
-            run "rm -f $WEBSITE_DIR/$SPEC_FILE"
-            run "cp $BUILD_DIR/$TARGZ_FILENAME $WEBSITE_DIR/$SPEC_FILE"
-            run "git -C $WEBSITE_DIR add $SPEC_FILE"
-        fi
+        run "cp $BUILD_DIR/$TARGZ_FILENAME $OUT_DIR"
         ;&
     3)
-        #note: this step may fail if step 4 was performed,
-        #      because it will erase BUILD_DIR
         step 3 "BUILDING THE API BUNDLE"
-        if test \! -d "$BUILD_DIR" ; then
-            echo "ERROR: $BUILD_DIR does not exist, possibly removed by another step"
-            exit 1
-        fi
+        assert_build_dir
         run "cd $BUILD_DIR; make -j doc-distrib"
-        if test "$FINAL_RELEASE" = "yes"; then
-            SPEC_FILE="$DOWNLOAD_DIR/frama-c-${FRAMAC_VERSION_AND_CODENAME}-api.tar.gz"
-            run "rm -f $WEBSITE_DIR/$SPEC_FILE"
-            run "cp $BUILD_DIR/frama-c-api.tar.gz $WEBSITE_DIR/$SPEC_FILE"
-            run "git -C $WEBSITE_DIR add $SPEC_FILE"
-        fi
+        run "cp $BUILD_DIR/frama-c-api.tar.gz $OUT_DIR"
         ;&
     4)
         step 4 "BUILDING THE DOCUMENTATION COMPANIONS"
-        if test \! -d "$BUILD_DIR" ; then
-            echo "ERROR: $BUILD_DIR does not exist, possibly removed by another step"
-            exit 1
-        fi
+        assert_build_dir
         run "cd $BUILD_DIR; make -j doc-companions"
-        if test "$FINAL_RELEASE" = "yes"; then
-            SPEC_FILE="$DOWNLOAD_DIR/hello-${FRAMAC_VERSION_AND_CODENAME}.tar.gz"
-            RELE_FILE="$DOWNLOAD_DIR/hello.tar.gz"
-            run "rm -f $WEBSITE_DIR/$SPEC_FILE $WEBSITE_DIR/$RELE_FILE"
-            run "cp $BUILD_DIR/hello-${FRAMAC_VERSION_AND_CODENAME}.tar.gz $WEBSITE_DIR/$SPEC_FILE"
-            run "git -C $WEBSITE_DIR add $SPEC_FILE"
-            run "ln -s hello-${FRAMAC_VERSION_AND_CODENAME}.tar.gz $WEBSITE_DIR/$RELE_FILE";
-            run "git -C $WEBSITE_DIR add $RELE_FILE"
-            run "rm -rf $BUILD_DIR"
-            run "git worktree prune"
-        fi
+        run "cp $BUILD_DIR/hello-${FRAMAC_VERSION_AND_CODENAME}.tar.gz $OUT_DIR"
         ;&
     5)
-        step 5 "COPYING AND STAGING THE DISTRIBUTED MANUALS"
-        PAGE_NAME=Frama-C-${FRAMAC_VERSION_AND_CODENAME}.md
-        WIKI_PAGE=$GITLAB_WIKI/$PAGE_NAME
-        run "mkdir -p $GITLAB_WIKI/manuals"
-        run "sed -i -e '/<!-- LAST RELEASE -->/a \
-- [${FRAMAC_VERSION} (${FRAMAC_VERSION_CODENAME})](Frama-C-${FRAMAC_VERSION_AND_CODENAME})' $GITLAB_WIKI/Home.md"
-        if test "$FINAL_RELEASE" = "yes"; then
-            release_type="FINAL"
-        else
-            release_type="BETA"
-        fi
-        run "sed -i -e '/<!-- LAST ${release_type} RELEASE -->/a \
-- [${FRAMAC_VERSION} (${FRAMAC_VERSION_CODENAME})](Frama-C-${FRAMAC_VERSION_AND_CODENAME})' $GITLAB_WIKI/_sidebar.md"
-        echo "# Frama-C release ${FRAMAC_VERSION} (${FRAMAC_VERSION_CODENAME})" > $WIKI_PAGE
-        echo "## Sources" >> $WIKI_PAGE
-        echo " - [$TARGZ_FILENAME](downloads/$TARGZ_FILENAME)" >> $WIKI_PAGE
-        echo "" >> $WIKI_PAGE
-        echo "## Manuals" >> $WIKI_PAGE
-        for fpath in $MANUALS_DIR/*; do
-            f=$(basename $fpath)
-            f_no_ext=${f%.*}
-            # E-ACSL-related files are stored in subdirectory e-acsl
-            if [[ $f_no_ext =~ ^e-acsl.*$ ]]; then
-                destdir="$WEBSITE_DIR/$DOWNLOAD_DIR/e-acsl"
-            else
-                destdir="$WEBSITE_DIR/$DOWNLOAD_DIR"
-            fi
-            if [[ -L $fpath ]]; then
-                # symbolic links are copied to the website and prepended with 'frama-c-'
-                # (except for acsl.pdf, which is copied as is)
-                if [[ $f_no_ext =~ ^(e-)?acsl$ ]]; then
-                    ln="$f"
-                else
-                    ln="frama-c-$f"
-                fi
-                run "rm -f $destdir/$ln"
-                run "cp -P $fpath $destdir/$ln"
-                run "git -C $destdir add $ln"
-            else
-                # non-symbolic links are copied as-is to the website, and also to
-                # the Gitlab wiki, where they are also added as links
-                f_no_pdf_ext="${f%.pdf}"
-                echo "- [${f_no_pdf_ext%-${FRAMAC_VERSION_AND_CODENAME}}](manuals/$f)" >> $WIKI_PAGE
-                run "cp $fpath $GITLAB_WIKI/manuals/"
-                run "git -C $GITLAB_WIKI add manuals/$f"
-                run "cp $fpath $destdir/$f"
-                run "git -C $destdir add $f"
-            fi
-        done
-
-        INSTALL_WEBPAGE=html/installations/$(echo "$FRAMAC_VERSION_CODENAME" | tr '[:upper:]' '[:lower:]').md
-        INSTALL_WEBPAGE_PATH=$WEBSITE_DIR/$INSTALL_WEBPAGE
-        echo "----" > $INSTALL_WEBPAGE_PATH
-        echo "layout: doc_page" >> $INSTALL_WEBPAGE_PATH
-        echo "title: Installation instructions for $FRAMAC_VERSION_CODENAME" >> $INSTALL_WEBPAGE_PATH
-        echo "----" >> $INSTALL_WEBPAGE_PATH
-        cat ./INSTALL.md >> $INSTALL_WEBPAGE_PATH
-        run "git -C $WEBSITE_DIR add $INSTALL_WEBPAGE"
-
-        run "git -C $GITLAB_WIKI add $PAGE_NAME"
+        step 5 "CLEAN $BUILD_DIR"
+        run "rm -rf $BUILD_DIR"
+        run "git worktree prune"
+        ;&
+    6)
+        step 6 "PREPARE WIKI"
+        assert_out_dir
+        run "git -C $WIKI_DIR reset --hard"
+        fill_wiki
+        ;&
+    7)
+        step 7 "PREPARE WEBSITE"
+        assert_out_dir
+        run "git -C $WEBSITE_DIR reset --hard"
+        fill_website
+        ;&
+    8)
+        step 8 "CHECK GENERATED DISTRIBUTION"
+        assert_out_dir
+        TEST_DIR="$BUILD_DIR_ROOT/frama-c-$FRAMAC_VERSION-$FRAMAC_VERSION_CODENAME"
+        run "mkdir -p $BUILD_DIR_ROOT"
+        run "rm -rf $TEST_DIR"
+        run "cp $OUT_DIR/$TARGZ_FILENAME $BUILD_DIR_ROOT"
+        run "cd $BUILD_DIR_ROOT ; tar xzf $TARGZ_FILENAME"
+        run "./doc/release/checktar.sh $TEST_DIR"
+        run "cd $TEST_DIR ; ./configure && make -j && make tests PTESTS_OPTS=\"-error-code\""
+        run "rm -rf $TEST_DIR"
+        ;&
+    9)
+        step 9 "GENERATE OPAM FILE"
+        assert_out_dir
+        run "cp opam/opam $OUT_DIR/opam"
+        echo >> "$OUT_DIR/opam"
+        echo "url {" >> "$OUT_DIR/opam"
+        echo "  src: \"https://git.frama-c.com/pub/frama-c/-/wikis/downloads/$TARGZ_FILENAME\"" >> "$OUT_DIR/opam"
+        echo "  checksum: \"md5=$(md5sum $OUT_DIR/$TARGZ_FILENAME | cut -d" " -f1)\"" >> "$OUT_DIR/opam"
+        echo "}" >> "$OUT_DIR/opam"
+        ;&
+    10)
+        step 10 "COMMIT CHANGES"
+        last_step_validation
+        propagate_changes
         ;;
     *)
         echo "Bad entry: ${STEP}"
diff --git a/devel_tools/docker/frama-c.22.0/Dockerfile b/devel_tools/docker/frama-c.22.0/Dockerfile
new file mode 100644
index 0000000000000000000000000000000000000000..d1e25df7a9d7df30b4b0cba10fccfc169a3dec7f
--- /dev/null
+++ b/devel_tools/docker/frama-c.22.0/Dockerfile
@@ -0,0 +1,66 @@
+FROM debian:buster as base
+
+# Install non-OCaml dependencies + opam
+RUN apt-get update && apt-get install -y \
+    cvc4 \
+    opam \
+    z3 \
+    && rm -rf /var/lib/apt/lists/*
+
+RUN opam init --disable-sandboxing --compiler=ocaml-base-compiler.4.08.1 -y
+
+# "RUN eval $(opam env)" does not work, so we manually set its variables
+ENV OPAM_SWITCH_PREFIX "/root/.opam/ocaml-base-compiler.4.08.1"
+ENV CAML_LD_LIBRARY_PATH "/root/.opam/ocaml-base-compiler.4.08.1/lib/stublibs:/root/.opam/ocaml-base-compiler.4.08.1/lib/ocaml/stublibs:/root/.opam/ocaml-base-compiler.4.08.1/lib/ocaml"
+ENV OCAML_TOPLEVEL_PATH "/root/.opam/ocaml-base-compiler.4.08.1/lib/toplevel"
+ENV MANPATH "$MANPATH:/root/.opam/ocaml-base-compiler.4.08.1/man"
+ENV PATH "/root/.opam/ocaml-base-compiler.4.08.1/bin:$PATH"
+
+RUN opam update -y && opam install depext -y
+
+# Install packages from reference configuration
+# Note: Python and time packages are only required for tests, but if so,
+# they need to be present before running './configure'
+RUN apt-get update && opam update -y && opam depext --install -y --verbose \
+    alt-ergo.2.2.0 \
+    apron.v0.9.12 \
+    conf-graphviz.0.1 \
+    mlgmpidl.1.2.12 \
+    ocamlfind.1.8.1 \
+    ocamlgraph.1.8.8 \
+    ppx_deriving_yojson.3.5.2 \
+    why3.1.3.3 \
+    yojson.1.7.0 \
+    zarith.1.9.1 \
+    zmq.5.1.3 \
+    conf-python-3.1.0.0 \
+    conf-time.1 \
+    && rm -rf /var/lib/apt/lists/*
+
+RUN why3 config --detect
+
+# with_source: keep Frama-C sources
+ARG with_source=no
+
+RUN cd /root && \
+    wget http://frama-c.com/download/frama-c-22.0-Titanium.tar.gz && \
+    tar xvf frama-c-*.tar.gz && \
+    (cd frama-c-* && \
+        ./configure --disable-gui && \
+        make -j && \
+        make install \
+    ) && \
+    rm -f frama-c-*.tar.gz && \
+    ([ "${with_source}" != "no" ] || rm -rf frama-c-*)
+
+# with_test: run Frama-C tests; requires "with_source=yes"
+ARG with_test=no
+
+# run general tests, then test that WP can see external provers
+RUN if [ "${with_test}" != "no" ]; then \
+        cd /root/frama-c-* && \
+        make tests PTESTS_OPTS=-error-code && \
+        (cd src/plugins/wp/tests/ && \
+         frama-c -wp wp_gallery/binary-multiplication-without-overflow.c \
+         -wp-prover alt-ergo,cvc4); \
+    fi
diff --git a/devel_tools/docker/frama-c.custom/Dockerfile b/devel_tools/docker/frama-c.custom/Dockerfile
index 0d93e4f5b41b8b06faa056db6d05c0cc5351d613..4eb330c4d69c7dfb1134868b877f2d761193a77c 100644
--- a/devel_tools/docker/frama-c.custom/Dockerfile
+++ b/devel_tools/docker/frama-c.custom/Dockerfile
@@ -2,7 +2,6 @@ FROM debian:sid as base
 
 # Install non-OCaml dependencies + opam
 RUN apt-get update && apt-get install -y \
-    cvc4 \
     opam \
     z3 \
     && rm -rf /var/lib/apt/lists/*
@@ -37,6 +36,11 @@ RUN apt-get update && opam update -y && opam depext --install -y --verbose \
     conf-time.1 \
     && rm -rf /var/lib/apt/lists/*
 
+# Note: Debian's CVC is too recent for Why3, so we do not install the Debian
+# package; instead, we download its binary and add it to a directory in PATH.
+RUN wget https://github.com/CVC4/CVC4/releases/download/1.7/cvc4-1.7-x86_64-linux-opt -O /usr/local/bin/cvc4
+RUN chmod a+x /usr/local/bin/cvc4
+
 RUN why3 config --detect
 
 # with_source: keep Frama-C sources
@@ -59,7 +63,7 @@ ARG with_test=no
 # run general tests, then test that WP can see external provers
 RUN if [ "${with_test}" != "no" ]; then \
         cd /root/frama-c && \
-        make tests && \
+        make tests PTESTS_OPTS=-error-code && \
         (cd src/plugins/wp/tests/ && \
          frama-c -wp wp_gallery/binary-multiplication-without-overflow.c \
          -wp-prover alt-ergo,cvc4); \
diff --git a/devel_tools/docker/frama-c.dev/Dockerfile b/devel_tools/docker/frama-c.dev/Dockerfile
index ff51e8094c952ebdf3254a7b0ece8d5b37843218..bdd95a3d5de09857476f68b4fd01def1cdc6b9a2 100644
--- a/devel_tools/docker/frama-c.dev/Dockerfile
+++ b/devel_tools/docker/frama-c.dev/Dockerfile
@@ -2,7 +2,6 @@ FROM debian:sid as base
 
 # Install non-OCaml dependencies + opam
 RUN apt-get update && apt-get install -y \
-    cvc4 \
     opam \
     z3 \
     && rm -rf /var/lib/apt/lists/*
@@ -37,6 +36,11 @@ RUN apt-get update && opam update -y && opam depext --install -y --verbose \
     conf-time.1 \
     && rm -rf /var/lib/apt/lists/*
 
+# Note: Debian's CVC is too recent for Why3, so we do not install the Debian
+# package; instead, we download its binary and add it to a directory in PATH.
+RUN wget https://github.com/CVC4/CVC4/releases/download/1.7/cvc4-1.7-x86_64-linux-opt -O /usr/local/bin/cvc4
+RUN chmod a+x /usr/local/bin/cvc4
+
 RUN why3 config --detect
 
 # with_source: keep Frama-C sources
@@ -49,7 +53,7 @@ RUN cd /root && \
         make -j && \
         make install \
     ) && \
-    [ "${with_source}" != "no" ] || rm -rf frama-c
+    ([ "${with_source}" != "no" ] || rm -rf frama-c)
 
 # with_test: run Frama-C tests; requires "with_source=yes"
 ARG with_test=no
@@ -57,7 +61,7 @@ ARG with_test=no
 # run general tests, then test that WP can see external provers
 RUN if [ "${with_test}" != "no" ]; then \
         cd /root/frama-c && \
-        make tests && \
+        make tests PTESTS_OPTS=-error-code && \
         (cd src/plugins/wp/tests/ && \
          frama-c -wp wp_gallery/binary-multiplication-without-overflow.c \
          -wp-prover alt-ergo,cvc4); \
diff --git a/devel_tools/git-hooks/pre-commit b/devel_tools/git-hooks/pre-commit
index d444779a23156ab969227415792b622e0c9766a1..fec935b5fc0ca5d771f4b43bbd2a137789f76287 100755
--- a/devel_tools/git-hooks/pre-commit
+++ b/devel_tools/git-hooks/pre-commit
@@ -17,6 +17,6 @@ else
 fi
 
 MANUAL_ML_FILES=\
-$(git diff-index --name-only $against | \
+$(git diff-index --name-only --diff-filter d $against | \
     grep -e '^src/.*\.mli\?$' | tr '\n' ' ') \
 make ${MAKELEVEL} lint
diff --git a/doc/build-manuals.sh b/doc/build-manuals.sh
index 725ae1c670b36d9f33b091d199cb851cfd55c332..353f2a43d2922800c2c49054163491b92f712242 100755
--- a/doc/build-manuals.sh
+++ b/doc/build-manuals.sh
@@ -39,14 +39,20 @@ fi
 build () {
 
     echo "##### Building $1"
-    make -C $(dirname $1) $(basename $1) || \
-         (echo "######### $1 failed" ; exit 1)
-    echo "##### $1 done"
+    set +e
+    make -C $(dirname $1) $(basename $1)
+    ret=$?
+    if [ $ret -eq 0 ]; then
+        echo "##### $1 done"
+    else
+        echo "######### $1 failed"
+        exit 1
+    fi
     # extract extension, add suffix, re-append extension
     MANUAL=${2%.*}-$3.${2##*.}
     cp -f $1 manuals/$MANUAL
     echo "##### $MANUAL copied"
-    ln -srf manuals/$MANUAL manuals/$2
+    
 }
 
 EACSL_DOC=../src/plugins/e-acsl/doc
diff --git a/doc/release/branch.tex b/doc/release/branch.tex
index 5ee6c9b56ce577b22486f3ea5b426fbb0366e0c0..ca2cb8d1c8e44672d4243488ab1b6d6a2cb23e8c 100644
--- a/doc/release/branch.tex
+++ b/doc/release/branch.tex
@@ -21,6 +21,9 @@ $\rightarrow$ Repository $\rightarrow$ Protected Branches.
 
 \section{Creating the branch}
 
+Note that you must be member of the GitLab groups "frama-c", "dev" and have
+access to each plugin of continuous integration.
+
 Create the branch \texttt{stable/release}, where \texttt{release} is the
 element name, using the \texttt{frama-ci} tool:
 \begin{enumerate}
@@ -64,7 +67,7 @@ the issues should be tagged with the current release, or with the next one.
 
 Create headers in the Changelog(s). This is to avoid some merge conflicts,
 but also so that merge requests add information in the proper part of
-the Changelog.   
+the Changelog.
 
 \begin{itemize}
 \item Add the following in the Changelog, in \texttt{stable/element}
@@ -86,7 +89,7 @@ This should go directly below
 
 From now on, Changelog items corresponding to MR merged into \texttt{master}
 must be placed between these two banners. This should minimize conflicts when
-merging back \texttt{stable/element} into \texttt{master}
+merging back \texttt{stable/element} into \texttt{master}.
 
 \todo{Do the same thing in the manuals that contain a Changelog?}
 
diff --git a/doc/release/build.tex b/doc/release/build.tex
index 7d2cfc524726c384cdf7279618022a4ed25b2298..e3c9386b25c4516fd10187fffbc1b047d526c18a 100644
--- a/doc/release/build.tex
+++ b/doc/release/build.tex
@@ -7,9 +7,11 @@ The procedure for creating the source distribution.
 \begin{itemize}
 \item All tools needed to compile Frama-C (that you should have anyways)
 \item \texttt{bash} v4.0 or higher
+\item \texttt{rgrep}
 \item \texttt{git-lfs}
 \item GNU \texttt{parallel}
 \item a \TeX distribution
+\item (recommended) \texttt{texfot}
 \end{itemize}
 
 \section{Final checks}
@@ -33,7 +35,7 @@ The procedure for creating the source distribution.
     opam packages, including alt-ergo, why3, coq, etc.
     Use \verb+bin/check-reference-configuration.sh+ to help check if the
     configuration is ok. You can also try running
-    \verb+ptests.opt -config qualif src/plugins/wp/tests+.
+    \verb+make wp-qualif+.
   \end{itemize}
 \item Check the contents of \texttt{README.md} \todo{Should always be up to date}
 \item Check the contents of \texttt{Changelog}
@@ -235,16 +237,60 @@ website git.
 
 \expertise{release manager} Use the script
 \texttt{build-src-distrib.sh} for this purpose (\texttt{bash version
-  4} required) after cloning the following repositories
+  4} required).
+
+The script will search for the following repositories:
+
+\begin{itemize}
+  \item \texttt{./doc/acsl} (\texttt{git@github.com:acsl-language/acsl.git})
+  \item \texttt{./frama-c.wiki} (\texttt{git@git.frama-c.com:pub/frama-c.wiki.git})
+  \item \texttt{./website} (\texttt{git@git.frama-c.com:pub/pub.frama-c.com.git})
+\end{itemize}
+
+If they are not available, they can be cloned by the script.
+
+The following steps will be performed by the script:
+
 \begin{itemize}
-\item \texttt{pub-frama-c} (\texttt{git@git.frama-c.com:pub/frama-c}),
-\item \texttt{frama-c.wiki} (\texttt{git@git.frama-c.com:pub/frama-c.wiki}), and
-\item \texttt{website} (\texttt{git@git.frama-c.com:frama-c/website})
+  \item compile manuals
+  \item build source distribution
+  \item build the API bundle
+  \item build the documentation companions
+  \item update locally the wiki pages
+  \item create a new branch for the website
+  \item run some sanity checks on the source distribution
+  \item generate the \texttt{opam} file
 \end{itemize}
-in the root directory of Frama-C. The last one is only needed when creating a
-final release. Release candidates are pushed as a branch \texttt{stable/<codename>}
-and added to the \texttt{pub/frama-c} wiki.
-For \texttt{website}, a new branch should be created over \texttt{online}.
+
+In order to create "ready to deploy" wiki and website pages, a file \texttt{main\_changes.md}
+must be provided. The expected format is:
+
+\begin{lstlisting}
+# Kernel
+
+- item
+- ...
+
+# <Plugin-Name> (Prefer alphabetic order)
+
+- item
+- ...
+
+# ...
+
+\end{lstlisting}
+
+The performed sanity checks are:
+
+\begin{itemize}
+  \item verification that no non-free files are distributed,
+  \item verification that no non-free plugins are distributed,
+  \item no \texttt{/home/user} path can be found in the distribution,
+  \item the source code can be compiled and tests succeed.
+\end{itemize}
+
+Note that there are some interactive steps in the script, that ask for user
+approval before going further.
 
 Finally, ensure that locale \verb+en_US.UTF-8+ is available on your system,
 as it is used by the script to ensure a proper encoding of the generated files.
@@ -254,17 +300,21 @@ Now, run the script:
 ./bin/build-src-distrib.sh
 \end{shell}
 
+The generated files are available in the \texttt{./distributed} repository.
+After testing more extensively the distribution, the following actions should
+be performed:
+
+\begin{itemize}
+  \item push stable branch on the public repository
+  \item push stable tag on the public repository
+  \item push the local Frama-C wiki branch to the public repository
+  \item push the generated website branch
+\end{itemize}
+
 \section{Testing the Distribution}
 
 Please check that the distribution (sources and API) is OK:
 \begin{enumerate}
-\item Inspect the contents of the \texttt{tar.gz}:
-  \begin{enumerate}
-  \item Extract it to a new directory.
-  \item run \texttt{<path-to-frama-c-git-clone>/doc/release/checktar.sh}
-    (CWD must be where the tar was extracted). Fix issues and/or update
-    the script if needed.
-  \end{enumerate}
 \item check for possible path/environment leaks in the \texttt{tar.gz}:
   grep for the path where your Frama-C git directory is, e.g.
   \texttt{/home/user/git/frama-c}. It should appear nowhere in the archive.
@@ -272,8 +322,8 @@ Please check that the distribution (sources and API) is OK:
   (or check e.g. \texttt{./configure --prefix=\$PWD/build \&\& make -j \&\& make install});
 \item test the installed binaries (especially the GUI). (On Linux, OCI tests
   everything but the GUI);
-\item redo the two steps above on Windows/WSL \expertise{André/Allan}, macOS
-  \expertise{André/Loïc/Thibaud};
+\item redo the two steps above on Windows/WSL \expertise{André}\expertise{Allan},
+  macOS \expertise{André}\expertise{Loïc}\\\expertise{Thibaud};
   \begin{itemize}
   \item For instance, you can compile and test as follows:
   \item \verb+./configure --prefix="$PWD/build"+
diff --git a/doc/release/checktar.sh b/doc/release/checktar.sh
index db08047a27a1cea62a982859f3260d682f296463..66a852c693bcc02af7e3a92ea51fd9bbdef5c5e1 100755
--- a/doc/release/checktar.sh
+++ b/doc/release/checktar.sh
@@ -1,15 +1,43 @@
-#!/bin/bash -eu
+#!/usr/bin/env bash
 
-echo "To check: "
+if [[ "$1" == "" ]]; then
+    DIR="."
+else
+    DIR=${1%/}
+fi
 
-find . -name '*NE_PAS_LIVRER*'
-find . -name '*nonfree*' -o -name '*non_free*' -o -name '*non-free*'
+ERROR_CODE=0
+
+RESULT=$(find $DIR -name '*NE_PAS_LIVRER*')
+if [[ "$RESULT" != "" ]]; then
+    echo "### ERROR: The following files should not be distributed:"
+    echo $RESULT
+    ERROR_CODE=1
+fi
+
+RESULT=$(find $DIR -name '*nonfree*' -o -name '*non_free*' -o -name '*non-free*')
+if [[ "$RESULT" != "" ]]; then
+    echo "### ERROR: The following files should not be distributed:"
+    echo $RESULT
+    ERROR_CODE=1
+fi
 
 PLUGINS=( genassigns mthread volatile acsl-importer caveat-importer cfp security pathcrawler a3export )
 
 for A in ${PLUGINS[@]}
 do
-    if [ -e src/plugins/$A ]; then
-        echo "!!! Error: trying to release $A"
+    if [ -e $DIR/src/plugins/$A ]; then
+        echo "### ERROR: Trying to release plugin: $A"
+        ERROR_CODE=1
     fi
 done
+
+RESULT=$(rgrep $HOME $DIR)
+
+if [[ "$RESULT" != "" ]]; then
+    echo "### ERROR: Found some $HOME occurrences in the distribution"
+    echo $RESULT
+    ERROR_CODE=1
+fi
+
+exit $ERROR_CODE
diff --git a/doc/release/website.tex b/doc/release/website.tex
index b10cda813a798083bb2264a7e72001f29493b445..6e6b79dc3aec6550a8aebbb00c3a994bc2333011 100644
--- a/doc/release/website.tex
+++ b/doc/release/website.tex
@@ -1,4 +1,4 @@
-\chapter{The Website Stage}
+\chapter{The Web Stage}
 
 Where all our efforts goes on the web.  There are two very different
 tasks for \FramaC to go online.  Authoring the web site pages is the
@@ -8,131 +8,75 @@ be the release manager.
 
 \section{Requirements}
 
-You need the following applications:
-\begin{itemize}
-\item \texttt{pandoc}>=2.0; if your distribution has an older
-  version, you can find installation instructions at
-  \url{https://github.com/jgm/pandoc/blob/master/INSTALL.md}
-\item \texttt{tidy}
-\item \texttt{linkchecker}
-\end{itemize}
-
-\section{Authoring the Pages}
-
-The website sources are in \texttt{src}. Go to this directory.
-
-\subsection{Editing Web Pages}
+The website \texttt{README.md} provides a quick guide to locally setup
+the website.
 
-You should consult and/or improve the \texttt{README} for style
-instructions, and edit \texttt{*.prehtml} files.
+\section{Generate website}
 
-Compile the web pages with:
-\begin{shell}[gobble=2]
-  \$ make local
-\end{shell}
+Before pushing the branch to the website, it can be deployed locally but
+this is not absolutely necessary.
 
-This way, you get a snapshot of the web-site in \texttt{src},
-without any downloadable resources. You can start browsing at
-\texttt{index.html}. Note that the new news and download pages still
-need to be manually updated.
+Push the branch generated by the release script on the website repository.
 
-\subsection{Adding News}
-The news are defined in the \texttt{news.def} page. All the news
-are published in the \textsf{RSS} of \FramaC. Only the first news are
-published on the home page of the web site. The limit is marked with:
-\begin{shell}
-  <#def end-of-html-news></#def>
-\end{shell}
+You can have a look at the generated pages on \texttt{pub.frama-c.com}.
+Note however that the download links won't work as they are available only
+once the branch is merged (\texttt{download} links are handled by Git-LFS).
 
-Move it upward in order to keep only few interesting news on the
-\FramaC home page.
+Check the following pages:
 
-\section{Adding the new Release}
-
-From the build stage, the files to distributed are available in the
-\texttt{website} repository and already ready to commit (look at
-\texttt{git status}). The release manager should update the web pages
-of the \emph{download} and \emph{support} sections to make the new
-release and documentation available.
-
-The current (\emph{awkward}) procedure is as follows:
-\begin{enumerate}
-\item In case a new release of ACSL is done together with Frama-C's release;
-  \begin{itemize}
-  \item copy the ACSL manual using the ``numeric'' version
-    (\texttt{www/download/acsl\_x.y.pdf}) and add it via \texttt{git add}
-    (\texttt{git lfs} should automatically handle it, since it's a .pdf);
-  \item check that \texttt{www/download/acsl.pdf} was updated by the build script;
-%  \item update \texttt{src/download.def} (can't find where???);
-  \item update \texttt{src/acsl.prehtml}: add a new entry for the new version of ACSL
- \end{itemize}
-\item Copy the file \texttt{INSTALL.md} from Frama-C to
-  \texttt{INSTALL-NAME.md} where \texttt{NAME} is the version name of the
-  distribution.
-\item Update the \texttt{Makefile} in \texttt{src}:
+\begin{itemize}
+  \item \texttt{index.html} must display:
   \begin{itemize}
-  \item Add to variable \texttt{PAGES} the new files to export (at least
-    install-<version>.html, following the pattern already present). This will
-    create a target that will generate it from the previous .md file.
-  \item Add the previous latest version to the \texttt{DOWNLOAD\_PAGES}
-    variable for adding a specific downloading page related to that
-    previous release.
+    \item the new event,
+    \item a link to the (beta) release at the bottom.
   \end{itemize}
-\item Update also some macros of \texttt{download.def} file:
-  \begin{enumerate}
-  \item Add an entry after the \texttt{selector-previous-versions} macro.
-  \item Update macros \texttt{latest-No-Version}, \texttt{previous-version} and
-    \texttt{previous-No-Version}.
-  \item Move the definition of \texttt{download-last-version} macro
-  to a new macro \texttt{download\_NAME}, where \texttt{NAME}
-  is the version name added to \texttt{DOWNLOAD\_PAGES} variable of the
-  \texttt{Makefile}.
-  \item Update the definition of \texttt{download-last-version} macro.
-  \item Add a new \texttt{selector-download\_NAME} macro.
-  \item Add a link back to that downloading page into the \texttt{selector-download\_PREVIOUS\_NAME} macro.
-  \item Check the occurrences of references to the previous release
-  resources, and update them. A good practice is to \texttt{grep}
-  \texttt{*.prehtml} \texttt{*.def} against the name of the release.
-  You should at least update the links to reference documentation from the
-  \texttt{support.prehtml} page.
-  \end{enumerate}
-\item Build the web site:
-  \begin{shell}[gobble=4]
-    \$ make local
-    \$ make distrib
-  \end{shell}
-  You get a snapshot of the repository in the \texttt{www} directory.
-  Before going there, check for compliance with \textsf{W3C} and link
-  consistency by running:
-  \begin{shell}
-    \$ make check_link
-  \end{shell}
-  Run it and check the result, fixing broken links if necessary.
-  Go to \texttt{../www}, then open \texttt{index.html} and test the website
-  carefully, especially:
+  \item \texttt{/fc-versions/<version\_name>.html}:
   \begin{itemize}
-  \item the new Downloads page;
-  \item the previous Downloads page;
-  \item Compilation instructions;
-  \item Changelog (check parsing, for all plug-ins).
+    \item check Changelog link,
+    \item check manual links (reminder: the links are dead at this moment), it must contain \texttt{NN.N-Version}
+    \item check ACSL version.
   \end{itemize}
+  \item \texttt{/html/changelog.html\#Version-NN.N}
+  \item \texttt{/html/installations/titanium.html}
+  \item \texttt{/html/acsl.html}: check ACSL versions list
+  \item \texttt{rss.xml}: check last event
+\end{itemize}
 
-\item Commit the web site:
-  \begin{shell}
-    \$ cd ..
-    \$ # manually check that only wanted new files are present
-    \$ git add .
-    \$ git checkout -b \$RELEASE
-    \$ git commit -m "updating distrib website"
-  \end{shell}
-\end{enumerate}
+On GitLab, the following files must appear as \textbf{new} in \texttt{download}.
+Note that for beta versions, if you have not included all manuals, not all of
+them will appear:
 
-\section{Publishing}
+\begin{itemize}
+  \item \texttt{acsl-X.XX.pdf}
+  \item \texttt{acsl-implementation-NN.N-CODENAME.pdf}
+  \item \texttt{plugin-development-guide-NN.N-CODENAME.pdf}
+  \item \texttt{user-manual-NN.N-CODENAME.pdf}
+  \item \texttt{<plugin>-manual-NN.N-CODENAME.pdf}\\
+        for Aorai, EVA, Metrics, RTE and WP
+  \item \texttt{e-acsl/e-acsl-X.XX.pdf}
+  \item \texttt{e-acsl/e-acsl-implementation-NN.N-CODENAME.pdf}
+  \item \texttt{e-acsl/e-acsl-manual-NN.N-CODENAME.pdf}
+  \item \texttt{aorai-example-NN.N-CODENAME.tgz}
+  \item \texttt{frama-c-NN.N-CODENAME.tar.gz}
+  \item \texttt{frama-c-api-NN.N-CODENAME.tar.gz}
+  \item \texttt{hello-NN.N-CODENAME.tar.gz}
+\end{itemize}
 
-You have to create a merge request on the website repository that will be published when Florent
-accepts it on the online branch.
+For final release \textbf{ONLY}, the following files must appear as \textbf{modified} in \texttt{download}:
 
-\textbf{Note:} the following steps are done only after the release is live on the website.
+\begin{itemize}
+  \item \texttt{acsl.pdf}
+  \item \texttt{frama-c-acsl-implementation.pdf}
+  \item \texttt{frama-c-plugin-development-guide.pdf}
+  \item \texttt{frama-c-user-manual.pdf}
+  \item \texttt{frama-c-<plugin>-manual.pdf}\\
+        for Aorai, EVA, Metrics, RTE, \textbf{Value Analysis} and WP
+  \item \texttt{e-acsl/e-acsl.pdf}
+  \item \texttt{e-acsl/e-acsl-implementation.pdf}
+  \item \texttt{e-acsl/e-acsl-manual.pdf}
+  \item \texttt{frama-c-aorai-example.tgz}
+  \item \texttt{hello.tar.gz}
+\end{itemize}
 
 \section{Announcements}
 
@@ -152,20 +96,10 @@ You'll need a GitHub account to create a pull request on the official opam repos
 \item Clone \texttt{opam-repository}: \texttt{git clone git@github.com:ocaml/opam-repository.git}
 \item Make sure you are on \texttt{master} and your branch is up-to-date
 \item Create a new directory: \\
-  \texttt{packages/frama-c/frama-c.<version>} \\
-\item Copy the file \texttt{opam/opam} from the release
- to the opam repository clone in: \\
+  \texttt{packages/frama-c/frama-c.<version>}
+\item Copy the file \texttt{./distributed/opam} to the opam repository clone in: \\
  \texttt{packages/frama-c/frama-c.<version>/opam}
-\item Compute the MD5sum of the .tar.gz file and update the \texttt{opam} file
-with the following entry:
-\begin{verbatim}
-url {
-  src: "https://frama-c.com/download/frama-c-<version>-<version-name>.tar.gz"
-  checksum: "md5=<xxxxxx>"
-}
-\end{verbatim}
-You can provide \verb|sha256| and/or \verb|sha512| checksums as well if
-you wish.
+\item You can provide \verb|sha256| and/or \verb|sha512| checksums at the end of this file if ou wish.
 \item (optional) Check locally that everything is fine:
 \begin{verbatim}
 opam switch create local <some-ocaml-compiler-version>
@@ -203,6 +137,16 @@ commit to it.
 ({\em Non-beta only}) After pushing the tag to Gitlab, go to the Releases page
 and create a release for the tag.
 
+You should also push the wiki changes. Note that all files listed as \textbf{new}
+in the website section should appear in the wiki but:
+
+\begin{itemize}
+  \item \texttt{frama-c-api-NN.N-CODENAME.tar.gz}
+  \item \texttt{hello-NN.N-CODENAME.tar.gz}
+\end{itemize}
+
+and E-ACSL files are not in a sub-folder \texttt{e-acsl} on the wiki.
+
 \section{Updating the BTS}
 
 \expertise{Usually Julien performs this step. Soon to be obsoleted.}
@@ -218,11 +162,6 @@ already done).
 Finally have a look at each still opened task in order to see what should be
 resolved in the next release.
 
-%% \section{Update the Wiki}
-
-%% Update references of the Wiki, especially pointers to manuals of this page:
-%% \url{http://bts.frama-c.com/dokuwiki/doku.php?id=mantis:frama-c:publications}
-
 \section{Other repositories to update}
 
 Check if other Frama-C (and related) repositories need to be updated:
@@ -240,6 +179,48 @@ Just update the \texttt{VERSION} file in \texttt{master}, by adding
 \texttt{"+dev"}. Do not add any newline at the end of the
 \texttt{VERSION} file.
 
+\section{Docker image preparation}
+
+\textbf{Note:} you need access to the \texttt{framac} Docker Hub account to be able to upload the image.
+
+Make sure:
+\begin{itemize}
+  \item \texttt{devel\_tools/docker/frama-c.dev/Dockerfile}
+  \item \texttt{devel\_tools/docker/frama-c.custom/Dockerfile}
+\end{itemize}
+are up-to-date; to do so, you can do the following:
+
+\begin{lstlisting}
+cd devel_tools/docker/frama-c.custom
+<edit Dockerfile to change the base image, from debian:sid (unstable) to the
+ latest stable release>
+<copy release .tar.gz to this directory, extract and rename the directory
+ `frama-c`>
+docker build . -t fc-with-test --build-arg=with_source=yes\
+  --build-arg=with_test=yes
+\end{lstlisting}
+
+This should copy the contents of \texttt{frama-c} into the Docker image and try
+to compile Frama-C with it, then run the tests.
+
+If the local tests do not work, check that the OCaml version and package
+dependencies are all up-to-date. Remember that there are several differences
+between Debian unstable (`sid`) and stable, which may require changes to the
+\texttt{Dockerfile}.
+
+If the local tests work, then re-run Docker \textit{without} the source/tests,
+to make the image leaner:
+
+\begin{lstlisting}
+docker build . -t framac/frama-c:<VERSION>
+\end{lstlisting}
+
+Replacing \texttt{<VERSION>} with the release number, e.g. \texttt{23.0}.
+
+After building the image, upload it with \texttt{docker push framac/frama-c:<VERSION>}.
+You will need to have setup your \texttt{framac} Docker Hub account for this to work.
+
+
 %%% Local Variables:
 %%% mode: latex
 %%% TeX-master: "release"
diff --git a/headers/header_spec.txt b/headers/header_spec.txt
index d52363f4281bd136fe28d7872fbaf083cd1f9b7c..18b91267bf15ef43f86ba5fe2c7b046b07162595 100644
--- a/headers/header_spec.txt
+++ b/headers/header_spec.txt
@@ -914,9 +914,10 @@ src/plugins/loop_analysis/region_analysis_stmt.mli: CEA_LGPL_OR_PROPRIETARY
 src/plugins/loop_analysis/register.ml: CEA_LGPL_OR_PROPRIETARY
 src/plugins/loop_analysis/slevel_analysis.ml: CEA_LGPL_OR_PROPRIETARY
 src/plugins/markdown-report/configure.ac: CEA_LGPL
-src/plugins/markdown-report/eva_coverage.ml: CEA_LGPL
-src/plugins/markdown-report/eva_coverage.mli: CEA_LGPL
+src/plugins/markdown-report/eva_info.ml: CEA_LGPL
+src/plugins/markdown-report/eva_info.mli: CEA_LGPL
 src/plugins/markdown-report/Makefile.in: CEA_LGPL
+src/plugins/markdown-report/META.in: .ignore
 src/plugins/markdown-report/md_gen.ml: CEA_LGPL
 src/plugins/markdown-report/md_gen.mli: CEA_LGPL
 src/plugins/markdown-report/mdr_params.ml: CEA_LGPL
@@ -1691,7 +1692,6 @@ src/plugins/wp/doc/coqdoc/typed_generated.tex: .ignore
 src/plugins/wp/doc/coqdoc/wpcoq.tex: .ignore
 src/plugins/wp/doc/manual/.gitignore: .ignore
 src/plugins/wp/doc/manual/Makefile: .ignore
-src/plugins/wp/doc/manual/cealistlogo.jpg: .ignore
 src/plugins/wp/doc/manual/mem.pdf: .ignore
 src/plugins/wp/doc/manual/size_base.pdf: .ignore
 src/plugins/wp/doc/manual/size_compl.pdf: .ignore
diff --git a/ivette/api/generated/kernel/ast/index.ts b/ivette/api/generated/kernel/ast/index.ts
index 83fe1a4fe381959d597e6ca6ac36a19cf56d2a29..dc1398e2ab95606276eb5ab92a4475f1ffbe3299 100644
--- a/ivette/api/generated/kernel/ast/index.ts
+++ b/ivette/api/generated/kernel/ast/index.ts
@@ -280,6 +280,16 @@ export interface functionsData {
   name: string;
   /** Signature */
   signature: string;
+  /** Is the function the main entry point */
+  main?: boolean;
+  /** Is the function defined? */
+  defined?: boolean;
+  /** Is the function from the Frama-C stdlib? */
+  stdlib?: boolean;
+  /** Is the function a Frama-C builtin? */
+  builtin?: boolean;
+  /** Has the function been analyzed by Eva */
+  eva_analyzed?: boolean;
 }
 
 /** Loose decoder for `functionsData` */
@@ -289,6 +299,11 @@ export const jFunctionsData: Json.Loose<functionsData> =
            '#functions expected'),
     name: Json.jFail(Json.jString,'String expected'),
     signature: Json.jFail(Json.jString,'String expected'),
+    main: Json.jBoolean,
+    defined: Json.jBoolean,
+    stdlib: Json.jBoolean,
+    builtin: Json.jBoolean,
+    eva_analyzed: Json.jBoolean,
   });
 
 /** Safe decoder for `functionsData` */
@@ -298,10 +313,17 @@ export const jFunctionsDataSafe: Json.Safe<functionsData> =
 /** Natural order for `functionsData` */
 export const byFunctionsData: Compare.Order<functionsData> =
   Compare.byFields
-    <{ key: Json.key<'#functions'>, name: string, signature: string }>({
+    <{ key: Json.key<'#functions'>, name: string, signature: string,
+       main?: boolean, defined?: boolean, stdlib?: boolean,
+       builtin?: boolean, eva_analyzed?: boolean }>({
     key: Compare.string,
     name: Compare.alpha,
     signature: Compare.string,
+    main: Compare.defined(Compare.boolean),
+    defined: Compare.defined(Compare.boolean),
+    stdlib: Compare.defined(Compare.boolean),
+    builtin: Compare.defined(Compare.boolean),
+    eva_analyzed: Compare.defined(Compare.boolean),
   });
 
 /** Signal for array [`functions`](#functions)  */
diff --git a/ivette/api/generated/plugins/eva/general/index.ts b/ivette/api/generated/plugins/eva/general/index.ts
index 008df7649b0abefc37880b90d6e771a8e6d49cc8..d16a45ad200fe7939ed2b1f81461ec0d78dce8e8 100644
--- a/ivette/api/generated/plugins/eva/general/index.ts
+++ b/ivette/api/generated/plugins/eva/general/index.ts
@@ -24,6 +24,15 @@ import { jMarkerSafe } from 'frama-c/api/kernel/ast';
 //@ts-ignore
 import { marker } from 'frama-c/api/kernel/ast';
 
+const isComputed_internal: Server.GetRequest<null,boolean> = {
+  kind: Server.RqKind.GET,
+  name:   'plugins.eva.general.isComputed',
+  input:  Json.jNull,
+  output: Json.jBoolean,
+};
+/** True if the Eva analysis has been done */
+export const isComputed: Server.GetRequest<null,boolean>= isComputed_internal;
+
 const getCallers_internal: Server.GetRequest<
   Json.key<'#fct'>,
   [ Json.key<'#fct'>, Json.key<'#stmt'> ][]
diff --git a/ivette/src/dome/src/renderer/frame/sidebars.tsx b/ivette/src/dome/src/renderer/frame/sidebars.tsx
index 27fea8e0cc749bcda882d8e1176c8ea7358cded9..94d66b95e639b4ae1d2ceb14e34b3676e3093b64 100644
--- a/ivette/src/dome/src/renderer/frame/sidebars.tsx
+++ b/ivette/src/dome/src/renderer/frame/sidebars.tsx
@@ -99,6 +99,8 @@ export interface SectionProps {
   disabled?: boolean;
   /** Badge summary (only visible when folded). */
   summary?: Badge;
+  /** Right-click callback. */
+  onContextMenu?: () => void;
   /** Section contents. */
   children?: React.ReactNode;
 }
@@ -132,7 +134,8 @@ export function Section(props: SectionProps) {
     <div className="dome-xSideBarSection">
       <div
         className="dome-xSideBarSection-title dome-color-frame"
-        title={props.label}
+        title={props.title}
+        onContextMenu={props.onContextMenu}
       >
         <Label label={props.label} />
         {!visible && makeBadge(props.summary)}
@@ -168,6 +171,10 @@ export interface ItemProps {
   onSelection?: () => void;
   /** Right-click callback. */
   onContextMenu?: () => void;
+  /** Additional class. */
+  className?: string;
+  /** Additional styles. */
+  style?: React.CSSProperties;
   /** Other item elements. */
   children?: React.ReactNode;
 }
@@ -176,16 +183,35 @@ export interface ItemProps {
 export function Item(props: ItemProps) {
   const { selected = false, disabled = false, enabled = true } = props;
   const isDisabled = disabled || !enabled;
-  const onClick = isDisabled ? undefined : props.onSelection;
+  const ref = React.useRef<HTMLDivElement>(null);
+  const [clicked, setClicked] = React.useState(false);
+  const onSelection = isDisabled ? undefined : props.onSelection;
+  const onClick =
+    onSelection ? () => { setClicked(true); onSelection(); } : undefined;
   const onContextMenu = isDisabled ? undefined : props.onContextMenu;
   const className = classes(
     'dome-xSideBarItem',
     selected ? 'dome-active' : 'dome-inactive',
     isDisabled && 'dome-disabled',
+    props.className,
   );
+
+  React.useLayoutEffect(() => {
+    if (!clicked && selected) {
+      ref?.current?.scrollIntoView({
+        behavior: 'auto',
+        block: 'center',
+      });
+    }
+    if (!selected && clicked)
+      setClicked(false);
+  }, [clicked, selected]);
+
   return (
     <div
+      ref={ref}
       className={className}
+      style={props.style}
       title={props.title}
       onContextMenu={onContextMenu}
       onClick={onClick}
diff --git a/ivette/src/dome/src/renderer/frame/style.css b/ivette/src/dome/src/renderer/frame/style.css
index 5ec0dd8eba070447366ccea4defb7cf1b1577ac5..9cdc1f5d44786efe4f31587d3c8cd593fe7ae051 100644
--- a/ivette/src/dome/src/renderer/frame/style.css
+++ b/ivette/src/dome/src/renderer/frame/style.css
@@ -130,7 +130,7 @@
     padding-left: 3px ;
     padding-right: 2px ;
     display: flex ;
-    flew-flow: row nowrap ;
+    flex-flow: row nowrap ;
     align-items: center ;
 }
 
@@ -174,6 +174,7 @@
     display: flex ;
     flex-flow: row nowrap ;
     align-items: center ;
+    scroll-margin-top: 30px;
 }
 
 .dome-window-active .dome-xSideBarItem.dome-active {
diff --git a/ivette/src/renderer/Globals.tsx b/ivette/src/renderer/Globals.tsx
index 4b153c03dde17807d64943188e5a4667c6a0e063..27d21bc47181ee8f530e98abf2c209324240992b 100644
--- a/ivette/src/renderer/Globals.tsx
+++ b/ivette/src/renderer/Globals.tsx
@@ -5,9 +5,13 @@
 import React from 'react';
 import { Section, Item } from 'dome/frame/sidebars';
 import type { Hint } from 'dome/frame/toolbars';
+import { classes } from 'dome/misc/utils';
 import * as States from 'frama-c/states';
+import { useFlipSettings } from 'dome';
 import { alpha } from 'dome/data/compare';
 import { functions, functionsData } from 'frama-c/api/kernel/ast';
+import { isComputed } from 'frama-c/api/plugins/eva/general';
+import * as Dome from 'dome';
 
 // --------------------------------------------------------------------------
 // --- Global Search Hints
@@ -37,6 +41,39 @@ export function useHints(): [GlobalHint[], (pattern: string) => void] {
   return [hints, onSearch];
 }
 
+// --------------------------------------------------------------------------
+// --- Function Item
+// --------------------------------------------------------------------------
+
+interface FctItemProps {
+  fct: functionsData;
+  current: string | undefined;
+  onSelection: (name: string) => void;
+}
+
+function FctItem(props: FctItemProps) {
+  const { name, signature, main, stdlib, builtin, defined } = props.fct;
+  const className = classes(
+    main && 'globals-main',
+    (stdlib || builtin) && 'globals-stdlib',
+  );
+  const attributes = classes(
+    main && '(main)',
+    !stdlib && !builtin && !defined && '(ext)',
+  );
+  return (
+    <Item
+      className={className}
+      label={name}
+      title={signature}
+      selected={name === props.current}
+      onSelection={() => props.onSelection(name)}
+    >
+      {attributes && <span className="globals-attr">{attributes}</span>}
+    </Item>
+  );
+}
+
 // --------------------------------------------------------------------------
 // --- Globals Section(s)
 // --------------------------------------------------------------------------
@@ -48,25 +85,98 @@ export default () => {
   const fcts = States.useSyncArray(functions).getArray().sort(
     (f, g) => alpha(f.name, g.name),
   );
+  const [stdlib, flipStdlib] =
+    useFlipSettings('ivette.globals.stdlib', false);
+  const [builtin, flipBuiltin] =
+    useFlipSettings('ivette.globals.builtin', false);
+  const [undef, flipUndef] =
+    useFlipSettings('ivette.globals.undef', true);
+  const [selected, flipSelected] =
+    useFlipSettings('ivette.globals.selected', false);
+  const [evaOnly, flipEvaOnly] =
+    useFlipSettings('ivette.globals.evaonly', false);
+  const multipleSelection = selection?.multiple;
+  const multipleSelectionActive = multipleSelection?.allSelections.length > 0;
+  const evaComputed = States.useRequest(isComputed, null);
 
-  // Items
-  const current: undefined | string = selection?.current?.function;
-  const makeFctItem = (fct: functionsData) => {
-    const kf = fct.name;
-    return (
-      <Item
-        key={kf}
-        label={kf}
-        title={fct.signature}
-        selected={kf === current}
-        onSelection={() => updateSelection({ location: { function: kf } })}
-      />
+  function isSelected(fct: functionsData) {
+    return multipleSelection?.allSelections.some(
+      (l) => fct.name === l?.function
     );
-  };
+  }
+
+  // Currently selected function.
+  const current: undefined | string = selection?.current?.function;
+
+  function showFunction(fct: functionsData) {
+    const visible =
+      (stdlib || !fct.stdlib)
+      && (builtin || !fct.builtin)
+      && (undef || fct.defined)
+      && (!evaOnly || !evaComputed || (fct.eva_analyzed === true))
+      && (!selected || !multipleSelectionActive || isSelected(fct));
+    return visible || (current && fct.name === current);
+  }
+
+  function onSelection(name: string) {
+    updateSelection({ location: { function: name } });
+  }
+
+  async function onContextMenu() {
+    const items: Dome.PopupMenuItem[] = [
+      {
+        label: 'Show Frama-C builtins',
+        checked: builtin,
+        onClick: flipBuiltin,
+      },
+      {
+        label: 'Show stdlib functions',
+        checked: stdlib,
+        onClick: flipStdlib,
+      },
+      {
+        label: 'Show undefined functions',
+        checked: undef,
+        onClick: flipUndef,
+      },
+      'separator',
+      {
+        label: 'Selected only',
+        enabled: multipleSelectionActive,
+        checked: selected,
+        onClick: flipSelected,
+      },
+      {
+        label: 'Analyzed by Eva only',
+        enabled: evaComputed,
+        checked: evaOnly,
+        onClick: flipEvaOnly,
+      },
+    ];
+    Dome.popupMenu(items);
+  }
+
+  // Filtered
 
+  const filtered = fcts.filter(showFunction);
+  const nTotal = fcts.length;
+  const nFilter = filtered.length;
+  const title = `Functions ${nFilter} / ${nTotal}`;
   return (
-    <Section label="Functions" defaultUnfold>
-      {fcts.map(makeFctItem)}
+    <Section
+      label="Functions"
+      title={title}
+      onContextMenu={onContextMenu}
+      defaultUnfold
+    >
+      {filtered.map((fct) => (
+        <FctItem
+          key={fct.name}
+          fct={fct}
+          current={current}
+          onSelection={onSelection}
+        />
+      ))}
     </Section>
   );
 
diff --git a/ivette/src/renderer/style.css b/ivette/src/renderer/style.css
index caad586871615e6cbd24ba8bca61a8075d9d188c..8c93bec94b766a926815cd03c0f9895f3cf4b02a 100644
--- a/ivette/src/renderer/style.css
+++ b/ivette/src/renderer/style.css
@@ -41,4 +41,18 @@
     background: #DDD
 }
 
+.globals-main label {
+    text-decoration: underline;
+}
+
+.globals-stdlib label {
+    font-style: italic;
+}
+
+.globals-attr {
+    font-size: smaller;
+    font-weight: lighter;
+    color: #aaa;
+}
+
 /* -------------------------------------------------------------------------- */
diff --git a/opam/opam b/opam/opam
index 859e70202be557be065bb940943269bc8d9d7c01..a102e260f1917bf705f3806fcdaad692a90754f1 100644
--- a/opam/opam
+++ b/opam/opam
@@ -63,7 +63,7 @@ authors: [
   "Boris Yakobowski"
 ]
 homepage: "http://frama-c.com/"
-license: "GNU Lesser General Public License version 2.1"
+license: "LGPL-2.1-only"
 dev-repo: "git+https://git.frama-c.com/pub/frama-c.git"
 doc: "http://frama-c.com/download/user-manual-22.0-Titanium.pdf"
 bug-reports: "https://git.frama-c.com/pub/frama-c/issues"
diff --git a/share/analysis-scripts/analysis.mk b/share/analysis-scripts/analysis.mk
index a1319e9756817f674bcc22cb0d64debcc23810d2..07bcf42f649be6868296faa913b8aaa052716515 100644
--- a/share/analysis-scripts/analysis.mk
+++ b/share/analysis-scripts/analysis.mk
@@ -96,9 +96,13 @@ endif
 # --- Utilities ---
 
 define display_command =
-  $(info )
-  $(info $(shell tput setaf 4)Command: $(1)$(shell tput sgr0))
-  $(info )
+  @{
+    echo '';
+    [ -t 1 ] && tput setaf 4;
+    echo "Command: $(strip $(1))";
+    [ -t 1 ] && tput sgr0;
+    echo '';
+  }
 endef
 
 empty :=
diff --git a/src/kernel_internals/runtime/special_hooks.ml b/src/kernel_internals/runtime/special_hooks.ml
index 9161ca6e6d622b3f901ecd4ae23d9b41142ad11c..de0cf6026b6f7437e8b5e584c80fd4ce908f75db 100644
--- a/src/kernel_internals/runtime/special_hooks.ml
+++ b/src/kernel_internals/runtime/special_hooks.ml
@@ -221,6 +221,15 @@ let run_list_all_plugin_options () =
   else Cmdline.nop
 let () = Cmdline.run_after_exiting_stage run_list_all_plugin_options
 
+(* Write JSON files to disk if required *)
+let flush_json_files () =
+  let written = Json.flush_cache () in
+  List.iter (fun fp ->
+      Kernel.feedback "Wrote: %a" Filepath.Normalized.pretty fp)
+    written
+
+let () = Cmdline.at_normal_exit (fun () -> flush_json_files ())
+
 (*
 Local Variables:
 compile-command: "make -C ../../.."
diff --git a/src/kernel_services/ast_data/kernel_function.ml b/src/kernel_services/ast_data/kernel_function.ml
index e428ec472cf0d420869f8a080b9d7e5dfa3a87e1..9d77d6ecb2d8a66cf7f851d2e658901dd79c14a6 100644
--- a/src/kernel_services/ast_data/kernel_function.ml
+++ b/src/kernel_services/ast_data/kernel_function.ml
@@ -578,12 +578,11 @@ let is_return_stmt kf stmt =
     false
 
 let is_entry_point kf =
-  let main, _ = Globals.entry_point () in
-  equal kf main
+  try equal kf (fst (Globals.entry_point ()))
+  with Globals.No_such_entry_point _ -> false
 
 let is_main kf =
-  let name = get_name kf in
-  Datatype.String.equal name "main"
+  String.equal (get_name kf) "main"
 
 let returns_void kf =
   let result_type,_,_,_ = Cil.splitFunctionType (get_type kf) in
diff --git a/src/kernel_services/plugin_entry_points/dynamic.ml b/src/kernel_services/plugin_entry_points/dynamic.ml
index 8d52b20163f8efcb9f77d1deb3fe64a445a5d7e4..e28fc9157b68b3aeb01de7eb6f68de3dc6d0eed5 100644
--- a/src/kernel_services/plugin_entry_points/dynamic.ml
+++ b/src/kernel_services/plugin_entry_points/dynamic.ml
@@ -132,6 +132,8 @@ let once pkg =
   if Hashtbl.mem packages pkg then false
   else ( Hashtbl.add packages pkg () ; true )
 
+let is_loaded pkg = Hashtbl.mem packages pkg
+
 exception ArchiveError of string
 
 let load_archive pkg base file =
diff --git a/src/kernel_services/plugin_entry_points/dynamic.mli b/src/kernel_services/plugin_entry_points/dynamic.mli
index cf663dc88ff45bfbb3b31aee709d84a8727869c3..ee97d92aed01c85ea6ad5c4185877eeac5c00917 100644
--- a/src/kernel_services/plugin_entry_points/dynamic.mli
+++ b/src/kernel_services/plugin_entry_points/dynamic.mli
@@ -149,9 +149,14 @@ end
 (** {2 Dynamically Loaded Modules} *)
 (* ************************************************************************* *)
 
-val load_module: string -> unit
+(** loads a list of Findlib packages
+    @since Frama-C+dev
+*)
+val load_packages: string list -> unit
+
 (** Load the module specification. See -load-module option.
     @modify Magnesium-20151001 new API. *)
+val load_module: string -> unit
 
 (** Sets the load path for modules in FRAMAC_PLUGIN, prepending it with [path].
     Does not load any plugins.
@@ -159,6 +164,11 @@ val load_module: string -> unit
     @since Phosphorus-20170501-beta1. *)
 val set_module_load_path : string list -> unit
 
+(** [is_loaded package] returns [true] iff [package] has already been loaded.
+    @since Frama-C+dev
+*)
+val is_loaded: string -> bool
+
 (**/**)
 val load_plugin_path: unit -> unit
 (** Load all plugins in the path set with [set_module_load_path].
diff --git a/src/libraries/utils/json.mli b/src/libraries/utils/json.mli
index f374ebf853bda2feb075aa70ca7fc4a1b70922d7..80ffaf64513064f8ffcb5b9c9ae1d41f6343f2da 100644
--- a/src/libraries/utils/json.mli
+++ b/src/libraries/utils/json.mli
@@ -125,3 +125,67 @@ val field : string -> t -> t
     [Null] is considered an empty object.
     @raise Not_found if the field is absent from the object.
     @raise Invalid_argument if the object is not an [Assoc] or [Null] object. *)
+
+(** The functions below read and write to JSON files asynchronously; they are
+    intended to be called at different times during execution.
+    To avoid reopening, re-reading and rewriting the same file several times,
+    they instead operate as following:
+    - Read the file on first use, and store it in memory;
+    - Perform merge operations using the in-memory representations;
+    - Flush the final form to disk before quitting Frama-C.
+      The latter is done via function [json_flush_cache] below, which is setup
+      to run with an [at_exit] trigger.
+
+    Note: no other functions should modify the contents of [path]; any
+    modifications will be overwritten when the cache is flushed.
+
+    @since Frama-C+dev
+*)
+
+(** Exception raised by the functions below when incompatible types are
+    merged. *)
+exception CannotMerge of string
+
+(**
+   [merge_object path json_obj] recursively merges the object [json_obj] into the
+   JSON file [path]. If [path] does not exist, it is created.
+   Merge consists in combining values with the same key, e.g. if [path]
+   already contains an object {"kernel": {"options": ["a"]}}, and
+   [json_obj] is {"kernel": {"options": ["b"]}}, the result will be
+   {"kernel": {"options": ["a", "b"]}}. Cannot merge heterogeneous
+   objects, i.e. in the previous example, if "options" were associated
+   with a string in [path], trying to merge an array into it would
+   raise [JsonCannotMerge].
+   The merged object is updated in the memory cache.
+
+   @raise [CannotMerge] if the objects have conflicting types for
+   the same keys, or if the root JSON element is not an object.
+   @since Frama-C+dev
+*)
+val merge_object : Filepath.Normalized.t -> Yojson.Basic.t -> unit
+
+(**
+   [merge_list path json_array] merges the array [json_array] into the
+   JSON file [path]. See [merge_object] for more details.
+   Unlike objects, arrays are merged by simply concatenating their list
+   of elements.
+
+   @raise [CannotMerge] if the root JSON element is not an array.
+   @since Frama-C+dev
+*)
+val merge_array : Filepath.Normalized.t -> Yojson.Basic.t -> unit
+
+(**
+   [from_file path] opens [path] and stores its JSON object in
+   a memory cache, to be used by the other related functions.
+   @since Frama-C+dev
+*)
+val from_file: Filepath.Normalized.t -> Yojson.Basic.t
+
+(**
+   Flushes the JSON objects in the cache. Returns the names of the written
+   files.
+
+   @since Frama-C+dev
+*)
+val flush_cache : unit -> Filepath.Normalized.t list
diff --git a/src/libraries/utils/json.mll b/src/libraries/utils/json.mll
index f17c82ac25de8d3bc772b2ea4eb1141432190980..7368c65f3e4763bb9481816f3db45f43fd992596 100644
--- a/src/libraries/utils/json.mll
+++ b/src/libraries/utils/json.mll
@@ -296,4 +296,94 @@ let of_list xs = `List xs
 let of_array xs = `List (Array.to_list xs)
 let of_fields m = `Assoc m
 
+
+(* JSON file cache and merging *)
+
+exception CannotMerge of string
+
+(* Table of filepaths to JSON arrays, to be written at the end of a run *)
+let json_tbl = Hashtbl.create 3
+
+let rec merge_assoc_lists la lb =
+  let cmp = fun (k1, _) (k2, _) -> String.compare k1 k2 in
+  let rec aux acc l1 l2 =
+    match l1, l2 with
+    | [], [] -> acc
+    | [], l | l, [] -> List.rev_append l acc
+    | e1 :: r1, e2 :: r2 ->
+      let c = cmp e1 e2 in
+      if c < 0 then aux (e1 :: acc) r1 l2
+      else if c > 0 then aux (e2 :: acc) l1 r2
+      else (* c = 0 *)
+        let (k1, v1) = e1 in
+        let (_, v2) = e2 in
+        match v1, v2 with
+        | `Assoc a1, `Assoc a2 ->
+          let v = `Assoc (merge_assoc_lists a1 a2) in
+          aux ((k1, v) :: acc) r1 r2
+        | `List l1, `List l2 ->
+          let v = `List (l1 @ l2) in
+          aux ((k1, v) :: acc) r1 r2
+        | o1, o2 ->
+          let pp = Yojson.Basic.pretty_to_string in
+          raise (CannotMerge
+                   ("cannot merge heterogeneous objects '"
+                    ^ pp o1 ^ "' and '" ^ pp o2 ^ "'"))
+  in
+  let r = aux [] (List.sort cmp la) (List.sort cmp lb) in
+  List.rev r
+
+let merge_object path json_root_obj =
+  let open Yojson.Basic.Util in
+  let existing_root_obj =
+    try
+      match Hashtbl.find json_tbl path with
+      | `Assoc _ as root -> root
+      | _ -> raise (CannotMerge "JSON root element should be an object")
+    with Not_found ->
+      `Assoc []
+  in
+  let existing_assoc = existing_root_obj |> to_assoc in
+  let new_assoc = json_root_obj |> to_assoc in
+  let merged = merge_assoc_lists existing_assoc new_assoc in
+  let merged_obj = `Assoc merged in
+  Hashtbl.replace json_tbl path merged_obj
+
+let merge_array path json_root_array =
+  let open Yojson.Basic.Util in
+  let existing_root_array =
+    try
+      match Hashtbl.find json_tbl path with
+      | `List _ as root -> root
+      | _ -> raise (CannotMerge "JSON root element should be an array")
+    with Not_found ->
+      `List []
+  in
+  let existing_list = existing_root_array |> to_list in
+  let new_list = json_root_array |> to_list in
+  let merged_list = `List (existing_list @ new_list) in
+  Hashtbl.replace json_tbl path merged_list
+
+let flush_cache () =
+  let written =
+    Hashtbl.fold (fun (path : Filepath.Normalized.t) json acc ->
+        let oc = open_out (path:>string) in
+        Yojson.Basic.pretty_to_channel oc json;
+        output_char oc '\n'; (* ensure JSON file terminates with a newline *)
+        path :: acc
+      ) json_tbl []
+  in
+  Hashtbl.clear json_tbl;
+  List.rev written
+
+let json_cache = Hashtbl.create 3
+
+let from_file (path : Filepath.Normalized.t) =
+  try
+    Hashtbl.find json_cache path
+  with Not_found ->
+    let json = Yojson.Basic.from_file (path:>string) in
+    Hashtbl.replace json_cache path json;
+    json
+
 }
diff --git a/src/plugins/e-acsl/contrib/libdlmalloc/dlmalloc.c b/src/plugins/e-acsl/contrib/libdlmalloc/dlmalloc.c
index be59fec25029ee982890a09a45d3aa4c268d56a4..1e7d5016f843628504740cf187156ff9d0cf120d 100644
--- a/src/plugins/e-acsl/contrib/libdlmalloc/dlmalloc.c
+++ b/src/plugins/e-acsl/contrib/libdlmalloc/dlmalloc.c
@@ -797,7 +797,17 @@ struct mallinfo {
   Try to persuade compilers to inline. The most critical functions for
   inlining are defined as macros, so these aren't used for them.
 */
-
+// MinGW defines `FORCEINLINE` as `__forceinline`, and defines `__forceinline`
+// with an "extern" storage class. Since the macro `FORCEINLINE` is used here
+// on `static` function, a compilation error occurs because `static` and
+// `extern` cannot be used at the same time.
+// This implementation "problem" is known to the MinGW team but is explicitely
+// marked as "won't fix": https://sourceforge.net/p/mingw-w64/bugs/269/
+// So the workaround here is to `undef FORCEINLINE` if the file is being
+// compiled by MinGW.
+#ifdef __MINGW32__ // defined for 32 bits and 64 bits MinGW
+#undef FORCEINLINE
+#endif
 #ifndef FORCEINLINE
   #if defined(__GNUC__)
 #define FORCEINLINE __inline __attribute__ ((always_inline))
diff --git a/src/plugins/e-acsl/doc/Changelog b/src/plugins/e-acsl/doc/Changelog
index 5a7d4b618dba3400398d2be044936114698e65bd..c988d92e0c9f25a6faf85cfe8ab5724c1e4ef286 100644
--- a/src/plugins/e-acsl/doc/Changelog
+++ b/src/plugins/e-acsl/doc/Changelog
@@ -25,6 +25,7 @@
 Plugin E-ACSL <next-release>
 ############################
 
+-  E-ACSL       [2020-12-09] Add RTL support for Windows.
 -  E-ACSL       [2020-11-17] Update e-acsl-gcc.sh so that the library dlmalloc
                 can be compiled and used from sources.
 
diff --git a/src/plugins/e-acsl/headers/header_spec.txt b/src/plugins/e-acsl/headers/header_spec.txt
index cf2b2a13c0e9dec43354173a1758d67cf4a4132d..b7f88f446f513c056e4509f5ddc8b1a51215af0a 100644
--- a/src/plugins/e-acsl/headers/header_spec.txt
+++ b/src/plugins/e-acsl/headers/header_spec.txt
@@ -21,6 +21,7 @@ share/e-acsl/instrumentation_model/e_acsl_temporal_timestamp.h: CEA_LGPL_OR_PROP
 share/e-acsl/internals/e_acsl_alias.h: CEA_LGPL_OR_PROPRIETARY.E_ACSL
 share/e-acsl/internals/e_acsl_bits.c: CEA_LGPL_OR_PROPRIETARY.E_ACSL
 share/e-acsl/internals/e_acsl_bits.h: CEA_LGPL_OR_PROPRIETARY.E_ACSL
+share/e-acsl/internals/e_acsl_config.h: CEA_LGPL_OR_PROPRIETARY.E_ACSL
 share/e-acsl/internals/e_acsl_debug.c: CEA_LGPL_OR_PROPRIETARY.E_ACSL
 share/e-acsl/internals/e_acsl_debug.h: CEA_LGPL_OR_PROPRIETARY.E_ACSL
 share/e-acsl/internals/e_acsl_malloc.c: CEA_LGPL_OR_PROPRIETARY.E_ACSL
diff --git a/src/plugins/e-acsl/man/e-acsl-gcc.sh.1 b/src/plugins/e-acsl/man/e-acsl-gcc.sh.1
index e3bc300bdb9cfecd266095c95aa89fecf275b056..884dfb189ef701e5fe8a7ebe7d234fa76d4abe90 100644
--- a/src/plugins/e-acsl/man/e-acsl-gcc.sh.1
+++ b/src/plugins/e-acsl/man/e-acsl-gcc.sh.1
@@ -123,6 +123,13 @@ alternatives that include internal runtime error checking.
 always use GMP integers instead of C integral types.
 By default the GMP integers are used on as-needed basis.
 .TP
+.B --mbits=\fI<BITS>
+architecture to compile to. Valid arguments are \fI16\fP, \fI32\fP or \fI64\fP.
+Default to the architecture of the current environment.
+This option is used to select the \fBmachdep\fP when calling \fBFrama-C\fP, and
+to pass the corresponding \fB-m16\fP, \fB-m32\fP or \fB-m64\fP flag to the
+compiler.
+.TP
 .B -l, --ld-flags=\fI<FLAGS>
 pass the specified flags to the linker.
 .TP
diff --git a/src/plugins/e-acsl/scripts/e-acsl-gcc.comp b/src/plugins/e-acsl/scripts/e-acsl-gcc.comp
index 2195d4cca8d9f0cd09df9a5d0a57093c7ceff68b..ba42f3854cab950f8e08416fd90a90132e6bd20d 100644
--- a/src/plugins/e-acsl/scripts/e-acsl-gcc.comp
+++ b/src/plugins/e-acsl/scripts/e-acsl-gcc.comp
@@ -36,7 +36,7 @@ _eacsl_gcc() {
     --no-trace
     --ocode= --oexec= --oexec-e-acsl=
     --ld-flags= --cpp-flags= --extra-cpp-args=
-    --frama-c-extra= --frama-c= --gcc= --ar= --ranlib=
+    --frama-c-extra= --frama-c= --gcc= --ar= --ranlib= --mbits=
     --e-acsl-share= --memory-model= --e-acsl-extra=
     --compile --compile-only --print-mmodels --frama-c-only --instrumented-only
     --gmp --full-mtracking --rte= --rte-select= --no-int-overflow
diff --git a/src/plugins/e-acsl/scripts/e-acsl-gcc.sh b/src/plugins/e-acsl/scripts/e-acsl-gcc.sh
index 044bd8fab58bd62175ed6405651c14984df607fa..f446a9f3c49a22f19c6641f64c89bd545703e2f5 100755
--- a/src/plugins/e-acsl/scripts/e-acsl-gcc.sh
+++ b/src/plugins/e-acsl/scripts/e-acsl-gcc.sh
@@ -276,7 +276,7 @@ LONGOPTIONS="help,compile,compile-only,debug:,ocode:,oexec:,verbose:,
   temporal,weak-validity,stack-size:,heap-size:,rt-verbose,free-valid-address,
   external-assert:,validate-format-strings,no-trace,libc-replacements,
   with-dlmalloc:,dlmalloc-from-sources,dlmalloc-compile-only,
-  dlmalloc-compile-flags:,odlmalloc:,ar:,ranlib:"
+  dlmalloc-compile-flags:,odlmalloc:,ar:,ranlib:,mbits:"
 SHORTOPTIONS="h,c,C,d:,D,o:,O:,v:,f,E:,L,M,l:,e:,g,q,s:,F:,m:,I:,G:,X,a:,T,k,V"
 # Prefix for an error message due to wrong arguments
 ERROR="ERROR parsing arguments:"
@@ -286,6 +286,7 @@ OPTION_CFLAGS=                           # Compiler flags
 OPTION_CPPFLAGS=                         # Preprocessor flags
 OPTION_LDFLAGS=                          # Linker flags
 OPTION_FRAMAC="frama-c"                  # Frama-C executable name
+OPTION_MBITS=                            # Which architecture to compile to
 OPTION_CC="gcc"                          # GCC executable name
 OPTION_AR="ar"                           # AR executable name
 OPTION_RANLIB="ranlib"                   # RANLIB executable name
@@ -684,6 +685,12 @@ do
       OPTION_OUTPUT_DLMALLOC="$1"
       shift;
     ;;
+    # Architecture selection
+    --mbits)
+      shift;
+      OPTION_MBITS="$1"
+      shift;
+    ;;
   esac
 done
 shift;
@@ -732,7 +739,11 @@ fi
 # Architecture-dependent flags. Since by default Frama-C uses 32-bit
 # architecture we need to make sure that same architecture is used for
 # instrumentation and for compilation.
-MACHDEPFLAGS="`getconf LONG_BIT`"
+if [ -n "$OPTION_MBITS" ]; then
+  MACHDEPFLAGS="$OPTION_MBITS"
+else
+  MACHDEPFLAGS="`getconf LONG_BIT`"
+fi
 # Check if getconf gives out the value accepted by Frama-C/GCC
 echo "$MACHDEPFLAGS" | grep '16\|32\|64' 2>&1 >/dev/null \
   || error "$MACHDEPFLAGS-bit architecture not supported"
@@ -846,6 +857,7 @@ if [ "$OPTION_DLMALLOC_FROM_SOURCES" = "1" -o \
   fi
 
   DLMALLOC_FLAGS="\
+    $GCCMACHDEP \
     -DHAVE_MORECORE=0 \
     -DHAVE_MMAP=1  \
     -DNO_MALLINFO=1 \
diff --git a/src/plugins/e-acsl/share/e-acsl/e_acsl_rtl.c b/src/plugins/e-acsl/share/e-acsl/e_acsl_rtl.c
index 7e74611ac5ee19b82530640f0ffa594151660c7b..4317ace0b93bc35b60ff88efe31380acb44035b1 100644
--- a/src/plugins/e-acsl/share/e-acsl/e_acsl_rtl.c
+++ b/src/plugins/e-acsl/share/e-acsl/e_acsl_rtl.c
@@ -25,6 +25,14 @@
 # define _DEFAULT_SOURCE 1
 #endif
 
+/* On Windows, setup minimum version to Windows 8 (or Server 2012) to be able to
+   use some specific API functions.
+   Check directly for windows instead of using E_ACSL_OS_IS_WINDOWS so that it
+   can be done without including anything. */
+#if defined(WIN32) || defined(_WIN32) || defined(__WIN32)
+# define _WIN32_WINNT 0x0602
+#endif
+
 // Internals
 #include "internals/e_acsl_bits.c"
 #include "internals/e_acsl_debug.c"
diff --git a/src/plugins/e-acsl/share/e-acsl/internals/e_acsl_config.h b/src/plugins/e-acsl/share/e-acsl/internals/e_acsl_config.h
new file mode 100644
index 0000000000000000000000000000000000000000..7ab971cc8b2ea03672415c85629ed54d3c755b94
--- /dev/null
+++ b/src/plugins/e-acsl/share/e-acsl/internals/e_acsl_config.h
@@ -0,0 +1,66 @@
+/**************************************************************************/
+/*                                                                        */
+/*  This file is part of the Frama-C's E-ACSL plug-in.                    */
+/*                                                                        */
+/*  Copyright (C) 2012-2020                                               */
+/*    CEA (Commissariat à l'énergie atomique et aux énergies              */
+/*         alternatives)                                                  */
+/*                                                                        */
+/*  you can redistribute it and/or modify it under the terms of the GNU   */
+/*  Lesser General Public License as published by the Free Software       */
+/*  Foundation, version 2.1.                                              */
+/*                                                                        */
+/*  It is distributed in the hope that it will be useful,                 */
+/*  but WITHOUT ANY WARRANTY; without even the implied warranty of        */
+/*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         */
+/*  GNU Lesser General Public License for more details.                   */
+/*                                                                        */
+/*  See the GNU Lesser General Public License version 2.1                 */
+/*  for more details (enclosed in the file licenses/LGPLv2.1).            */
+/*                                                                        */
+/**************************************************************************/
+
+/*! ***********************************************************************
+ * \file
+ * \brief Internal defines for E-ACSL set according to the current environment.
+ *
+ * Instead of using complicated logic with predefined macros in the RTL, the
+ * logic should be done in this file and an E-ACSL specific define set to record
+ * the result of the logic.
+ */
+
+#ifndef E_ACSL_CONFIG_H
+#define E_ACSL_CONFIG_H
+
+// OS detection
+//  - Assign values to specific OSes
+#define E_ACSL_OS_LINUX_VALUE 1
+#define E_ACSL_OS_WINDOWS_VALUE 2
+#define E_ACSL_OS_OTHER_VALUE 999
+//  - Declare defines to test for a specific OS
+/*!
+ * \brief True if the target OS is linux, false otherwise
+ */
+#define E_ACSL_OS_IS_LINUX E_ACSL_OS == E_ACSL_OS_LINUX_VALUE
+/*!
+ * \brief True if the target OS is windows, false otherwise
+ */
+#define E_ACSL_OS_IS_WINDOWS E_ACSL_OS == E_ACSL_OS_WINDOWS_VALUE
+/*!
+ * \brief True if the target OS is unknown, false otherwise
+ */
+#define E_ACSL_OS_IS_OTHER E_ACSL_OS == E_ACSL_OS_OTHER_VALUE
+//  - Check current OS
+#ifdef __linux__
+// Linux compilation
+# define E_ACSL_OS E_ACSL_OS_LINUX_VALUE
+#elif defined(WIN32) || defined(_WIN32) || defined(__WIN32)
+// Windows compilation
+# define E_ACSL_OS E_ACSL_OS_WINDOWS_VALUE
+#else
+// Other
+# define E_ACSL_OS E_ACSL_OS_OTHER_VALUE
+# error "Unsupported OS for E-ACSL RTL"
+#endif
+
+#endif // E_ACSL_CONFIG_H
diff --git a/src/plugins/e-acsl/share/e-acsl/internals/e_acsl_debug.c b/src/plugins/e-acsl/share/e-acsl/internals/e_acsl_debug.c
index 0c42873864c1d7b89465dcc26403ac252afb3de3..3389f05f78e8d93125ba3759ce1baf45771047d4 100644
--- a/src/plugins/e-acsl/share/e-acsl/internals/e_acsl_debug.c
+++ b/src/plugins/e-acsl/share/e-acsl/internals/e_acsl_debug.c
@@ -24,6 +24,7 @@
 #include <fcntl.h>
 
 #include "../observation_model/internals/e_acsl_omodel_debug.h"
+#include "e_acsl_config.h"
 #include "e_acsl_private_assert.h"
 #include "e_acsl_rtl_io.h"
 
@@ -45,8 +46,13 @@ void initialize_report_file(int *argc, char ***argv) {
   if (!strcmp(dlog_name, "-") || !strcmp(dlog_name, "1")) {
     dlog_fd = 2;
   } else {
-    dlog_fd = open(dlog_name, O_WRONLY | O_CREAT | O_TRUNC  |O_NONBLOCK
+#if E_ACSL_OS_IS_LINUX
+    dlog_fd = open(dlog_name, O_WRONLY | O_CREAT | O_TRUNC | O_NONBLOCK
       | O_NOCTTY, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
+#elif E_ACSL_OS_IS_WINDOWS
+    dlog_fd = _open(dlog_name, _O_WRONLY | _O_CREAT | _O_TRUNC,
+      _S_IREAD | _S_IWRITE);
+#endif
   }
   if (dlog_fd == -1)
     private_abort("Cannot open file descriptor for %s\n", dlog_name);
diff --git a/src/plugins/e-acsl/share/e-acsl/internals/e_acsl_private_assert.c b/src/plugins/e-acsl/share/e-acsl/internals/e_acsl_private_assert.c
index 94516feab171db3523c2e71ce28f0fefd575cfb6..b5133be6fdc26828abba82fa819ce520af351ac9 100644
--- a/src/plugins/e-acsl/share/e-acsl/internals/e_acsl_private_assert.c
+++ b/src/plugins/e-acsl/share/e-acsl/internals/e_acsl_private_assert.c
@@ -20,16 +20,12 @@
 /*                                                                        */
 /**************************************************************************/
 
-/* Get default definitions and macros e.g., PATH_MAX */
-// #ifndef _DEFAULT_SOURCE
-// # define _DEFAULT_SOURCE 1
-// #endif
-
 #include <limits.h>
 #include <signal.h>
 #include <stdarg.h>
 #include <stddef.h>
 
+#include "e_acsl_config.h"
 #include "e_acsl_rtl_io.h"
 #include "e_acsl_trace.h"
 
@@ -54,14 +50,18 @@ void raise_abort(const char *file, int line) {
 
 void private_abort_fail(const char * file, int line, char *fmt, ...) {
   va_list va;
+#if E_ACSL_OS_IS_LINUX
   sigset_t defer_abrt;
   sigemptyset(&defer_abrt);
   sigaddset(&defer_abrt,SIGABRT);
   sigprocmask(SIG_BLOCK,&defer_abrt,NULL);
+#endif // E_ACSL_OS_IS_LINUX
   va_start(va,fmt);
   rtl_veprintf(fmt, va);
   va_end(va);
+#if E_ACSL_OS_IS_LINUX
   sigprocmask(SIG_UNBLOCK,&defer_abrt,NULL);
+#endif // E_ACSL_OS_IS_LINUX
   raise_abort(file, line);
 }
 
diff --git a/src/plugins/e-acsl/share/e-acsl/internals/e_acsl_shexec.c b/src/plugins/e-acsl/share/e-acsl/internals/e_acsl_shexec.c
index e13e8dfdaa1972564d400fdb2d673294841a18cf..77f1b91237ebb27d9c8d6610089f6c2e190fd6fa 100644
--- a/src/plugins/e-acsl/share/e-acsl/internals/e_acsl_shexec.c
+++ b/src/plugins/e-acsl/share/e-acsl/internals/e_acsl_shexec.c
@@ -25,6 +25,11 @@
  * \brief Implementation for running shell commands
 ***************************************************************************/
 
+#include "e_acsl_config.h"
+
+// Only available on linux
+#if E_ACSL_OS_IS_LINUX
+
 #include <errno.h>
 #include <stddef.h>
 #include <sys/types.h>
@@ -201,3 +206,5 @@ ipr_t* shexec (char **data, const char *sin) {
   /* Run the command returning a pointer to `ipr_t` */
   return __shexec(ipr);
 }
+
+#endif // E_ACSL_OS_IS_LINUX
diff --git a/src/plugins/e-acsl/share/e-acsl/internals/e_acsl_shexec.h b/src/plugins/e-acsl/share/e-acsl/internals/e_acsl_shexec.h
index 16cb2d9a1d3a0161bc39ca0159d03962d07a8a00..754cabb418656fbde4bbfc1cb8a6bd9dbc85780b 100644
--- a/src/plugins/e-acsl/share/e-acsl/internals/e_acsl_shexec.h
+++ b/src/plugins/e-acsl/share/e-acsl/internals/e_acsl_shexec.h
@@ -28,6 +28,11 @@
 #ifndef E_ACSL_SHEXEC_H
 #define E_ACSL_SHEXEC_H
 
+#include "e_acsl_config.h"
+
+// Only available on linux
+#if E_ACSL_OS_IS_LINUX
+
 #include <sys/types.h>
 
 /*! \class ipr_t
@@ -68,4 +73,6 @@ typedef struct {
  *  `free_ipr` function. */
 ipr_t* shexec (char **data, const char *sin);
 
+#endif // E_ACSL_OS_IS_LINUX
+
 #endif // E_ACSL_SHEXEC_H
diff --git a/src/plugins/e-acsl/share/e-acsl/internals/e_acsl_trace.c b/src/plugins/e-acsl/share/e-acsl/internals/e_acsl_trace.c
index 892f53f5c204ed69fda30a7f89bd4452384825b3..64336e758bd4f23af52d118a5a8854be7985bed3 100644
--- a/src/plugins/e-acsl/share/e-acsl/internals/e_acsl_trace.c
+++ b/src/plugins/e-acsl/share/e-acsl/internals/e_acsl_trace.c
@@ -28,6 +28,7 @@
 #include <limits.h>
 #include <stddef.h>
 
+#include "e_acsl_config.h"
 #include "e_acsl_malloc.h"
 #include "e_acsl_rtl_io.h"
 #include "e_acsl_rtl_string.h"
@@ -35,6 +36,7 @@
 
 #include "e_acsl_trace.h"
 
+#if E_ACSL_OS_IS_LINUX
 extern void  *__libc_stack_end;
 
 struct frame_layout {
@@ -69,9 +71,10 @@ static int native_backtrace (void **array, int size) {
   }
   return cnt;
 }
+#endif
 
 void trace() {
-# ifdef __linux__
+# if E_ACSL_OS_IS_LINUX
 
   int size = 24;
   void **bb = private_malloc(sizeof(void*)*size);
@@ -107,5 +110,5 @@ void trace() {
     counter++;
   }
   STDOUT("/***************************************/\n");
-# endif /* __linux__ */
+# endif /* E_ACSL_OS_IS_LINUX */
 }
diff --git a/src/plugins/e-acsl/share/e-acsl/observation_model/bittree_model/e_acsl_bittree.c b/src/plugins/e-acsl/share/e-acsl/observation_model/bittree_model/e_acsl_bittree.c
index a605bbdb95f10e6f31fb443915653495c2e7ae4a..e0dcc56094698aaf8d1c0df34008a8b6d4ee2ee6 100644
--- a/src/plugins/e-acsl/share/e-acsl/observation_model/bittree_model/e_acsl_bittree.c
+++ b/src/plugins/e-acsl/share/e-acsl/observation_model/bittree_model/e_acsl_bittree.c
@@ -25,12 +25,24 @@
  * \brief Patricia Trie API Implementation
 ***************************************************************************/
 
+#include "../../internals/e_acsl_config.h"
 #include "../../internals/e_acsl_malloc.h"
 #include "../../internals/e_acsl_private_assert.h"
 
 #include "e_acsl_bittree.h"
 
+#if E_ACSL_OS_IS_LINUX
 #define WORDBITS __WORDSIZE
+#elif E_ACSL_OS_IS_WINDOWS
+// On windows, __WORDSIZE is not available
+# ifdef _WIN64
+#   define WORDBITS 64
+# else
+#   define WORDBITS 32
+# endif
+#else
+# error "Unsupported OS"
+#endif
 
 static size_t mask(size_t, size_t);
 
diff --git a/src/plugins/e-acsl/share/e-acsl/observation_model/bittree_model/e_acsl_bittree_observation_model.c b/src/plugins/e-acsl/share/e-acsl/observation_model/bittree_model/e_acsl_bittree_observation_model.c
index e729c281313b6d416e029212f012a2cc90f31695..1f6296b66387b1971aa988af762766526fe9e681 100644
--- a/src/plugins/e-acsl/share/e-acsl/observation_model/bittree_model/e_acsl_bittree_observation_model.c
+++ b/src/plugins/e-acsl/share/e-acsl/observation_model/bittree_model/e_acsl_bittree_observation_model.c
@@ -587,11 +587,13 @@ void eacsl_memory_init(int *argc_ref, char ***argv_ref, size_t ptr_size) {
   int i;
   for (i = 0; i < get_safe_locations_count(); i++) {
     memory_location * loc = get_safe_location(i);
-    void *addr = (void*)loc->address;
-    uintptr_t len = loc->length;
-    eacsl_store_block(addr, len);
-    if (loc->is_initialized)
-      eacsl_initialize(addr, len);
+    if (loc->is_on_static) {
+      void *addr = (void*)loc->address;
+      uintptr_t len = loc->length;
+      eacsl_store_block(addr, len);
+      if (loc->is_initialized)
+        eacsl_initialize(addr, len);
+    }
   }
   init_infinity_values();
 }
diff --git a/src/plugins/e-acsl/share/e-acsl/observation_model/internals/e_acsl_safe_locations.c b/src/plugins/e-acsl/share/e-acsl/observation_model/internals/e_acsl_safe_locations.c
index 86d1ad4e0a63e4cc6c1b927e520a7f6877e2c4cd..9c2e61b587126620383f4c16337b7a457d4a3f58 100644
--- a/src/plugins/e-acsl/share/e-acsl/observation_model/internals/e_acsl_safe_locations.c
+++ b/src/plugins/e-acsl/share/e-acsl/observation_model/internals/e_acsl_safe_locations.c
@@ -23,6 +23,7 @@
 #include <stdio.h>
 #include <errno.h>
 
+#include "../../internals/e_acsl_config.h"
 #include "e_acsl_safe_locations.h"
 
 /* An array storing safe locations up to `safe_location_counter` position.
@@ -31,18 +32,20 @@
 static memory_location safe_locations [16];
 static int safe_location_counter = 0;
 
-#define add_safe_location(_addr,_len,_init) { \
+#define add_safe_location(_addr,_len,_init,_on_static) do { \
   safe_locations[safe_location_counter].address = _addr; \
   safe_locations[safe_location_counter].length = _len; \
+  safe_locations[safe_location_counter].is_initialized = _init; \
+  safe_locations[safe_location_counter].is_on_static = _on_static; \
   safe_location_counter++; \
-}
+} while (0)
 
 void collect_safe_locations() {
   /* Tracking of errno and standard streams */
-  add_safe_location((uintptr_t)&errno, sizeof(int), "errno");
-  add_safe_location((uintptr_t)stdout, sizeof(FILE), "stdout");
-  add_safe_location((uintptr_t)stderr, sizeof(FILE), "stderr");
-  add_safe_location((uintptr_t)stdin, sizeof(FILE), "stdin");
+  add_safe_location((uintptr_t)&errno, sizeof(int), 1, E_ACSL_OS_IS_LINUX);
+  add_safe_location((uintptr_t)stdout, sizeof(FILE), 1, E_ACSL_OS_IS_LINUX);
+  add_safe_location((uintptr_t)stderr, sizeof(FILE), 1, E_ACSL_OS_IS_LINUX);
+  add_safe_location((uintptr_t)stdin, sizeof(FILE), 1, E_ACSL_OS_IS_LINUX);
 }
 
 size_t get_safe_locations_count() {
diff --git a/src/plugins/e-acsl/share/e-acsl/observation_model/internals/e_acsl_safe_locations.h b/src/plugins/e-acsl/share/e-acsl/observation_model/internals/e_acsl_safe_locations.h
index fa24ba37f875a71bbdf3d110be9d8054f47d5741..1b34dab3f464665b0b03c0ba6ac6e7a79960aada 100644
--- a/src/plugins/e-acsl/share/e-acsl/observation_model/internals/e_acsl_safe_locations.h
+++ b/src/plugins/e-acsl/share/e-acsl/observation_model/internals/e_acsl_safe_locations.h
@@ -34,11 +34,17 @@
 #include <stdint.h>
 #include <stddef.h>
 
-/* Simple representation of a safe location */
+/*! Simple representation of a safe location */
 struct memory_location {
-  uintptr_t address; /* Address */
-  uintptr_t length; /* Byte-length */
-  int is_initialized; /* Notion of initialization */
+  /*! Address */
+  uintptr_t address;
+  /*! Byte-length */
+  uintptr_t length;
+  /*! Notion of initialization */
+  int is_initialized;
+  /*! True if the address is on static memory, false if it is on dynamic
+      memory */
+  int is_on_static;
 };
 typedef struct memory_location memory_location;
 
diff --git a/src/plugins/e-acsl/share/e-acsl/observation_model/segment_model/e_acsl_segment_observation_model.c b/src/plugins/e-acsl/share/e-acsl/observation_model/segment_model/e_acsl_segment_observation_model.c
index 87e369e22b43f37edb1567fb21ffe9f4f204a764..5dfcd7efd90c29821dfd16f131c1531c90a8b7b3 100644
--- a/src/plugins/e-acsl/share/e-acsl/observation_model/segment_model/e_acsl_segment_observation_model.c
+++ b/src/plugins/e-acsl/share/e-acsl/observation_model/segment_model/e_acsl_segment_observation_model.c
@@ -215,8 +215,8 @@ void mspaces_init() {
     describe_run();
     eacsl_make_memory_spaces(64*MB, get_heap_size());
     /* Allocate and log shadow memory layout of the execution.
-       Case of the heap, globals and tls. */
-    init_shadow_layout_heap_global_tls();
+       Case of the segments available before main. */
+    init_shadow_layout_pre_main();
     already_run = 1;
   }
 }
@@ -235,8 +235,9 @@ void eacsl_memory_init(int *argc_ref, char *** argv_ref, size_t ptr_size) {
     initialize_report_file(argc_ref, argv_ref);
     /* Lift stack limit to account for extra stack memory overhead.  */
     increase_stack_limit(get_stack_size()*2);
-    /* Allocate and log shadow memory layout of the execution. Case of stack. */
-    init_shadow_layout_stack(argc_ref, argv_ref);
+    /* Allocate and log shadow memory layout of the execution. Case of the
+       segments available after main. */
+    init_shadow_layout_main(argc_ref, argv_ref);
     //DEBUG_PRINT_LAYOUT;
     /* Make sure the layout holds */
     DVALIDATE_SHADOW_LAYOUT;
@@ -250,12 +251,14 @@ void eacsl_memory_init(int *argc_ref, char *** argv_ref, size_t ptr_size) {
     collect_safe_locations();
     int i;
     for (i = 0; i < get_safe_locations_count(); i++) {
-    memory_location * loc = get_safe_location(i);
-      void *addr = (void*)loc->address;
-      uintptr_t len = loc->length;
-      shadow_alloca(addr, len);
-      if (loc->is_initialized)
-        eacsl_initialize(addr, len);
+      memory_location * loc = get_safe_location(i);
+      if (loc->is_on_static) {
+        void *addr = (void*)loc->address;
+        uintptr_t len = loc->length;
+        shadow_alloca(addr, len);
+        if (loc->is_initialized)
+          eacsl_initialize(addr, len);
+      }
     }
     init_infinity_values();
     already_run = 1;
diff --git a/src/plugins/e-acsl/share/e-acsl/observation_model/segment_model/e_acsl_segment_omodel_debug.c b/src/plugins/e-acsl/share/e-acsl/observation_model/segment_model/e_acsl_segment_omodel_debug.c
index 9be75d5bb9e087c6eda750aed9e13e53c3fc02cd..d6be5cd96e4abbc8a2202e9fa44ad4b7b1139b0d 100644
--- a/src/plugins/e-acsl/share/e-acsl/observation_model/segment_model/e_acsl_segment_omodel_debug.c
+++ b/src/plugins/e-acsl/share/e-acsl/observation_model/segment_model/e_acsl_segment_omodel_debug.c
@@ -20,6 +20,7 @@
 /*                                                                        */
 /**************************************************************************/
 
+#include "../../internals/e_acsl_bits.h"
 #include "../../internals/e_acsl_rtl_io.h"
 #include "e_acsl_segment_tracking.h"
 #include "e_acsl_shadow_layout.h"
diff --git a/src/plugins/e-acsl/share/e-acsl/observation_model/segment_model/e_acsl_segment_tracking.c b/src/plugins/e-acsl/share/e-acsl/observation_model/segment_model/e_acsl_segment_tracking.c
index 852f1447084e3b2569b4c28eb681abfe3f7bb06b..6e3011ce48c98c4637fcc3259b094df2c0cd8188 100644
--- a/src/plugins/e-acsl/share/e-acsl/observation_model/segment_model/e_acsl_segment_tracking.c
+++ b/src/plugins/e-acsl/share/e-acsl/observation_model/segment_model/e_acsl_segment_tracking.c
@@ -345,14 +345,6 @@ void shadow_freea(void *ptr) {
 
 /* Static querying {{{ */
 
-/*! \brief Checking whether a globally allocated memory block containing an
- * address _addr has read-only access. Note, this is light checking that
- * relies on the fact that a single block cannot contain read/write and
- * read-only parts, that is to check whether the block has read-only access it
- * is sufficient to check any of its bytes. */
-#define global_readonly(_addr) \
-  checkbit(READONLY_BIT, (*(char*)PRIMARY_GLOBAL_SHADOW(addr)))
-
 int static_allocated(uintptr_t addr, long size, uintptr_t base_ptr) {
   unsigned char *prim_shadow = (unsigned char*)PRIMARY_SHADOW(addr);
   /* Unless the address belongs to tracked allocation 0 is returned */
@@ -557,7 +549,7 @@ static void set_heap_segment(void *ptr, size_t size, size_t alloc_size,
   private_assert(mem_spaces.heap_end > max_addr,
     "Exceeded heap allocation limit of %luMB\n", E_ACSL_HEAP_SIZE);
 
-  DVALIDATE_MEMORY_INIT;
+  DVALIDATE_MEMORY_PRE_MAIN_INIT;
   /* Ensure the shadowed block in on the tracked heap portion */
   DVALIDATE_IS_ON_HEAP(((uintptr_t)ptr) - HEAP_SEGMENT, size);
   DVALIDATE_ALIGNMENT(ptr); /* Make sure alignment is right */
@@ -664,7 +656,7 @@ void *shadow_copy(const void *ptr, size_t size, int init) {
  * \param function - name of the de-allocation function (e.g., `free` or `cfree`)
 */
 static void unset_heap_segment(void *ptr, int init, const char *function) {
-  DVALIDATE_MEMORY_INIT;
+  DVALIDATE_MEMORY_PRE_MAIN_INIT;
   DVALIDATE_FREEABLE(((uintptr_t)ptr));
   /* Base address of shadow block */
   uintptr_t *base_shadow = (uintptr_t*)HEAP_SHADOW(ptr);
@@ -1134,10 +1126,23 @@ void print_shadow_layout() {
   print_memory_partition(&mem_layout.heap);
   DLOG(">>> STACK --------------------\n");
   print_memory_partition(&mem_layout.stack);
+#if E_ACSL_OS_IS_LINUX
   DLOG(">>> GLOBAL -------------------\n");
   print_memory_partition(&mem_layout.global);
   DLOG(">>> TLS ----------------------\n");
   print_memory_partition(&mem_layout.tls);
+#elif E_ACSL_OS_IS_WINDOWS
+  DLOG(">>> TEXT ---------------------\n");
+  print_memory_partition(&mem_layout.text);
+  DLOG(">>> BSS ----------------------\n");
+  print_memory_partition(&mem_layout.bss);
+  DLOG(">>> DATA --------------------\n");
+  print_memory_partition(&mem_layout.data);
+  DLOG(">>> IDATA --------------------\n");
+  print_memory_partition(&mem_layout.idata);
+  DLOG(">>> RDATA --------------------\n");
+  print_memory_partition(&mem_layout.rdata);
+#endif
   DLOG(">>> --------------------------\n");
 }
 
@@ -1147,10 +1152,23 @@ const char* which_segment(uintptr_t addr) {
     loc = "stack";
   else if (IS_ON_HEAP(addr))
     loc = "heap";
+#if E_ACSL_OS_IS_LINUX
   else if (IS_ON_GLOBAL(addr))
     loc = "global";
   else if (IS_ON_TLS(addr))
     loc = "TLS";
+#elif E_ACSL_OS_IS_WINDOWS
+  else if (IS_ON_TEXT(addr))
+    loc = "text";
+  else if (IS_ON_BSS(addr))
+    loc = "bss";
+  else if (IS_ON_DATA(addr))
+    loc = "data";
+  else if (IS_ON_IDATA(addr))
+    loc = "idata";
+  else if (IS_ON_RDATA(addr))
+    loc = "rdata";
+#endif
   else
     loc = "untracked";
   return loc;
diff --git a/src/plugins/e-acsl/share/e-acsl/observation_model/segment_model/e_acsl_segment_tracking.h b/src/plugins/e-acsl/share/e-acsl/observation_model/segment_model/e_acsl_segment_tracking.h
index 4379e1cda6f1baa4d0783ba51654a0a788245248..0baf6b56c0f0942270575031dadcf9756bc79db5 100644
--- a/src/plugins/e-acsl/share/e-acsl/observation_model/segment_model/e_acsl_segment_tracking.h
+++ b/src/plugins/e-acsl/share/e-acsl/observation_model/segment_model/e_acsl_segment_tracking.h
@@ -114,8 +114,18 @@
   DVASSERT(((uintptr_t)_addr) % HEAP_SEGMENT == 0,  \
       "Heap base address %a is unaligned", _addr)
 
+#define DVALIDATE_MEMORY_PRE_MAIN_INIT \
+  DVASSERT(mem_layout.is_initialized_pre_main != 0, \
+           "Un-initialized pre-main shadow layout", NULL)
+
+#define DVALIDATE_MEMORY_MAIN_INIT \
+  DVASSERT(mem_layout.is_initialized_main != 0, \
+           "Un-initialized main shadow layout", NULL)
+
 #define DVALIDATE_MEMORY_INIT \
-  DVASSERT(mem_layout.is_initialized != 0, "Un-initialized shadow layout", NULL)
+  DVASSERT(mem_layout.is_initialized_pre_main != 0 && \
+           mem_layout.is_initialized_main != 0, \
+           "Un-initialized shadow layout", NULL)
 
 /* Debug function making sure that the order of program segments is as expected
  * and that the program and the shadow segments used do not overlap. */
@@ -137,12 +147,24 @@ void validate_shadow_layout();
 /* Assert that [_addr, _addr+_size] are within stack segment */
 #define DVALIDATE_IS_ON_STACK(_addr, _size) \
   DVALIDATE_IS_ON(_addr, _size, STACK)
+#if E_ACSL_OS_IS_LINUX
 /* Assert that [_addr, _addr+_size] are within global segment */
-#define DVALIDATE_IS_ON_GLOBAL(_addr, _size) \
+# define DVALIDATE_IS_ON_GLOBAL(_addr, _size) \
   DVALIDATE_IS_ON(_addr, _size, GLOBAL)
 /* Assert that [_addr, _addr+_size] are within TLS segment */
-#define DVALIDATE_IS_ON_TLS(_addr, _size) \
+# define DVALIDATE_IS_ON_TLS(_addr, _size) \
   DVALIDATE_IS_ON(_addr, _size, TLS)
+#elif E_ACSL_OS_IS_WINDOWS
+/* Assert that [_addr, _addr+_size] are within text segment */
+# define DVALIDATE_IS_ON_TEXT(_addr, _size) \
+  DVALIDATE_IS_ON(_addr, _size, TEXT)
+/* Assert that [_addr, _addr+_size] are within bss segment */
+# define DVALIDATE_IS_ON_BSS(_addr, _size) \
+  DVALIDATE_IS_ON(_addr, _size, BSS)
+/* Assert that [_addr, _addr+_size] are within idata segment */
+# define DVALIDATE_IS_ON_IDATA(_addr, _size) \
+  DVALIDATE_IS_ON(_addr, _size, IDATA)
+#endif
 /* Assert that [_addr, _addr+_size] are within stack, global or TLS segments */
 #define DVALIDATE_IS_ON_STATIC(_addr, _size) \
   DVALIDATE_IS_ON(_addr, _size, STATIC)
@@ -222,6 +244,8 @@ void validate_shadow_layout();
 
 #else
 /*! \cond exclude from doxygen */
+#  define DVALIDATE_MEMORY_PRE_MAIN_INIT
+#  define DVALIDATE_MEMORY_MAIN_INIT
 #  define DVALIDATE_MEMORY_INIT
 #  define DVALIDATE_SHADOW_LAYOUT
 #  define DVALIDATE_HEAP_ACCESS
@@ -231,8 +255,14 @@ void validate_shadow_layout();
 #  define DVALIDATE_IS_ON
 #  define DVALIDATE_IS_ON_HEAP
 #  define DVALIDATE_IS_ON_STACK
+#  if E_ACSL_OS_IS_LINUX
 #  define DVALIDATE_IS_ON_GLOBAL
 #  define DVALIDATE_IS_ON_TLS
+#  elif E_ACSL_OS_IS_WINDOWS
+#    define DVALIDATE_IS_ON_TEXT
+#    define DVALIDATE_IS_ON_BSS
+#    define DVALIDATE_IS_ON_IDATA
+#  endif
 #  define DVALIDATE_IS_ON_STATIC
 #  define DVALIDATE_FREEABLE
 #  define DVALIDATE_STATIC_FREE
@@ -309,6 +339,14 @@ void shadow_freea(void *ptr);
 
 /* Static querying {{{ */
 
+/*! \brief Checking whether a globally allocated memory block containing an
+ * address _addr has read-only access. Note, this is light checking that
+ * relies on the fact that a single block cannot contain read/write and
+ * read-only parts, that is to check whether the block has read-only access it
+ * is sufficient to check any of its bytes. */
+#define global_readonly(_addr) \
+  checkbit(READONLY_BIT, (*(char*)PRIMARY_GLOBAL_SHADOW(_addr)))
+
 /*! \brief Return a non-zero value if a memory region of length `size`
  * starting at address `addr` belongs to a tracked stack, tls or
  * global memory block and 0 otherwise.
diff --git a/src/plugins/e-acsl/share/e-acsl/observation_model/segment_model/e_acsl_shadow_layout.c b/src/plugins/e-acsl/share/e-acsl/observation_model/segment_model/e_acsl_shadow_layout.c
index e070180edfc3d7f90a539120704675f210a28a6c..5ddb496007a2074e7581ad6089aca7c4fda0ce56 100644
--- a/src/plugins/e-acsl/share/e-acsl/observation_model/segment_model/e_acsl_shadow_layout.c
+++ b/src/plugins/e-acsl/share/e-acsl/observation_model/segment_model/e_acsl_shadow_layout.c
@@ -20,7 +20,6 @@
 /*                                                                        */
 /**************************************************************************/
 
-#include <sys/resource.h>
 #include <errno.h>
 #include <stddef.h>
 
@@ -29,8 +28,23 @@
 
 #include "e_acsl_shadow_layout.h"
 
+#if E_ACSL_OS_IS_LINUX
+
+#include <sys/resource.h>
+
 /** Program stack information {{{ */
 
+/* Symbols exported by the linker script */
+
+/*!\brief The first address past the end of the text segment. */
+extern char etext;
+/*!\brief The first address past the end of the initialized data segment. */
+extern char edata;
+/*!\brief The first address past the end of the uninitialized data segment. */
+extern char end;
+/*!\brief The first address of a program. */
+extern char __executable_start;
+
 size_t increase_stack_limit(const size_t size) {
   rlim_t stacksz = (rlim_t)size;
   struct rlimit rl;
@@ -59,7 +73,15 @@ size_t get_stack_size() {
   return rlim.rlim_cur;
 }
 
-uintptr_t get_stack_start(int *argc_ref,  char *** argv_ref) {
+
+extern char ** environ;
+
+/*! \brief Return the greatest (known) address on a program's stack.
+ * This function presently determines the address using the address of the
+ * last string in `environ`. That is, it assumes that argc and argv are
+ * stored below environ, which holds for GCC or Clang and Glibc but is not
+ * necessarily true for some other compilers/libraries. */
+static uintptr_t get_stack_start(int *argc_ref,  char *** argv_ref) {
   char **env = environ;
   while (env[1])
     env++;
@@ -72,74 +94,72 @@ uintptr_t get_stack_start(int *argc_ref,  char *** argv_ref) {
    * ::argv_alloca. */
   uintptr_t stack_end = addr + ULONG_BITS;
   uintptr_t stack_start = stack_end - get_stack_size();
-  return stack_start;
-}
-/* }}} */
 
-/** Program heap information {{{ */
-uintptr_t get_heap_start() {
-  return mem_spaces.heap_start;
-}
-
-size_t get_heap_size() {
-  return PGM_HEAP_SIZE;
-}
+  // Check that the assumption that argc and argv are stored below environ in
+  // the stack holds
+  DVASSERT(stack_start <= (uintptr_t)argc_ref
+           && (uintptr_t)argc_ref <= stack_end,
+           "Assumption that argc is stored below environ is not verified.\n\
+           \tStack: [%a - %a]\n\t&argc: %a",
+           stack_start, stack_end, argc_ref);
+  DVASSERT(stack_start <= (uintptr_t)argv_ref
+           && (uintptr_t)argv_ref <= stack_end,
+           "Assumption that argv is stored below environ is not verified.\n\
+           \tStack: [%a - %a]\n\t&argc: %a",
+           stack_start, stack_end, argc_ref);
 
-size_t get_heap_init_size() {
-  return get_heap_size()/8;
+  return stack_start;
 }
+/* }}} */
 
-uintptr_t get_global_start() {
+/** Program global information {{{ */
+/*! \brief Return the start address of a segment holding globals (generally
+ * BSS and Data segments). */
+static uintptr_t get_global_start() {
   return (uintptr_t)&__executable_start;
 }
 
-size_t get_global_size() {
+/*! \brief Return byte-size of global segment */
+static size_t get_global_size() {
   return ((uintptr_t)&end - get_global_start());
 }
 /** }}} */
 
-/** Shadow Layout {{{ */
+/** Thread-local storage information {{{ */
 
-void set_application_segment(memory_segment *seg, uintptr_t start,
-    size_t size, const char *name, mspace msp) {
-  seg->name = name;
-  seg->start = start;
-  seg->size = size;
-  seg->end = seg->start + seg->size;
-  seg->mspace = msp;
-  seg->parent = NULL;
-  seg->shadow_ratio = 0;
-  seg->shadow_offset = 0;
-}
+/*! Thread-local storage (TLS) keeps track of copies of per-thread variables.
+ * Even though at the present stage, E-ACSL's RTL is not thread-safe, some
+ * of the variables (for instance ::errno) are allocated there. In X86, TLS
+ * is typically located somewhere below the program's stack but above mmap
+ * areas. TLS is typically separated into two sections: .tdata and .tbss.
+ * Similar to globals using .data and .bss, .tdata keeps track of initialized
+ * thread-local variables, while .tbss holds uninitialized ones.
+ *
+ * Start and end addresses of TLS are obtained by taking addresses of
+ * initialized and uninitialized variables in TLS (::id_tdata and ::id_tss)
+ * and adding fixed amount of shadow space around them. Visually it looks
+ * as follows:
+ *
+ *   end TLS address (&id_tdata + TLS_SHADOW_SIZE/2)
+ *   id_tdata address
+ *   ...
+ *   id_tbss address
+ *   start TLS address (&id_bss - TLS_SHADOW_SIZE/2)
+ *
+ * HOWEVER problems can occur if PGM_TLS_SIZE is too big:
+ * see get_tls_start for details.
+ */
 
-void set_shadow_segment(memory_segment *seg, memory_segment *parent,
-    size_t ratio, const char *name) {
-  seg->parent = parent;
-  seg->name = name;
-  seg->shadow_ratio = ratio;
-  seg->size = parent->size/seg->shadow_ratio;
-  seg->mspace = eacsl_create_mspace(seg->size + SHADOW_SEGMENT_PADDING, 0);
-  seg->start = (uintptr_t)eacsl_mspace_malloc(seg->mspace,1);
-  seg->end = seg->start + seg->size;
-  seg->shadow_offset = parent->start - seg->start;
+/*! \brief Return byte-size of the TLS segment */
+inline static size_t get_tls_size() {
+  return PGM_TLS_SIZE;
 }
 
-void init_shadow_layout_stack(int *argc_ref, char ***argv_ref) {
-  memory_partition *pstack = &mem_layout.stack;
-  set_application_segment(&pstack->application, get_stack_start(argc_ref, argv_ref),
-    get_stack_size(), "stack", NULL);
-  /* Changes of the ratio in the following will require changes in get_tls_start */
-  set_shadow_segment(&pstack->primary, &pstack->application, 1, "stack_primary");
-  set_shadow_segment(&pstack->secondary, &pstack->application, 1, "stack_secondary");
-#ifdef E_ACSL_TEMPORAL
-  set_shadow_segment(&pstack->temporal_primary, &pstack->application, 1, "temporal_stack_primary");
-  set_shadow_segment(&pstack->temporal_secondary, &pstack->application, 1, "temporal_stack_secondary");
-#endif
-
-  mem_layout.is_initialized = 1;
-}
+static __thread int id_tdata = 1;
+static __thread int id_tbss;
 
-uintptr_t get_tls_start() {
+/*! \brief Return start address of a program's TLS */
+static uintptr_t get_tls_start() {
   size_t tls_size = get_tls_size();
   uintptr_t data = (uintptr_t)&id_tdata,
             bss = (uintptr_t)&id_tbss;
@@ -173,17 +193,10 @@ uintptr_t get_tls_start() {
   return tls_start_half > max_shadow ? tls_start_half : max_shadow;
 }
 
-void init_shadow_layout_heap_global_tls() {
-  memory_partition *pheap = &mem_layout.heap;
-  set_application_segment(&pheap->application, get_heap_start(),
-    get_heap_size(), "heap", mem_spaces.heap_mspace);
-  set_shadow_segment(&pheap->primary, &pheap->application, 1, "heap_primary");
-  set_shadow_segment(&pheap->secondary, &pheap->application, 8, "heap_secondary");
-#ifdef E_ACSL_TEMPORAL
-  set_shadow_segment(&pheap->temporal_primary, &pheap->application, 1, "temporal_heap_primary");
-  set_shadow_segment(&pheap->temporal_secondary, &pheap->application, 1, "temporal_heap_secondary");
-#endif
+/* }}} */
 
+/** Memory partitions {{{ */
+static void init_shadow_layout_global() {
   memory_partition *pglobal = &mem_layout.global;
   set_application_segment(&pglobal->application, get_global_start(),
     get_global_size(), "global", NULL);
@@ -193,7 +206,9 @@ void init_shadow_layout_heap_global_tls() {
   set_shadow_segment(&pglobal->temporal_primary, &pglobal->application, 1, "temporal_global_primary");
   set_shadow_segment(&pglobal->temporal_secondary, &pglobal->application, 1, "temporal_global_secondary");
 #endif
+}
 
+static void init_shadow_layout_tls() {
   memory_partition *ptls = &mem_layout.tls;
   set_application_segment(&ptls->application, get_tls_start(),
     get_tls_size(), "tls", NULL);
@@ -203,12 +218,260 @@ void init_shadow_layout_heap_global_tls() {
   set_shadow_segment(&ptls->temporal_primary, &ptls->application, 1, "temporal_tls_primary");
   set_shadow_segment(&ptls->temporal_secondary, &ptls->application, 1, "temporal_tls_secondary");
 #endif
+}
+
+static void init_shadow_layout_stack(int *argc_ref, char ***argv_ref) {
+  memory_partition *pstack = &mem_layout.stack;
+  set_application_segment(&pstack->application, get_stack_start(argc_ref, argv_ref),
+    get_stack_size(), "stack", NULL);
+  /* Changes of the ratio in the following will require changes in get_tls_start */
+  set_shadow_segment(&pstack->primary, &pstack->application, 1, "stack_primary");
+  set_shadow_segment(&pstack->secondary, &pstack->application, 1, "stack_secondary");
+#ifdef E_ACSL_TEMPORAL
+  set_shadow_segment(&pstack->temporal_primary, &pstack->application, 1, "temporal_stack_primary");
+  set_shadow_segment(&pstack->temporal_secondary, &pstack->application, 1, "temporal_stack_secondary");
+#endif
+}
+/** }}} */
+#elif E_ACSL_OS_IS_WINDOWS
+
+#include <processthreadsapi.h>
+#include <windows.h>
+#include <dbghelp.h>
+
+
+/** Program segment informations {{{ */
+typedef struct mem_loc_info {
+  uintptr_t start;
+  size_t size;
+} mem_loc_info_t;
+
+static mem_loc_info_t get_section_info(HANDLE hModule, const char * section_name) {
+  // Get the location of the module's IMAGE_NT_HEADERS structure
+  IMAGE_NT_HEADERS *pNtHdr = ImageNtHeader(hModule);
+
+  // Section table immediately follows the IMAGE_NT_HEADERS
+  IMAGE_SECTION_HEADER *pSectionHdr = (IMAGE_SECTION_HEADER *)(pNtHdr + 1);
+
+  const char* imageBase = (const char*)hModule;
+  size_t scnNameSize = sizeof(pSectionHdr->Name);
+  char scnName[scnNameSize + 1];
+  // Enforce nul-termination for scn names that are the whole length of
+  // pSectionHdr->Name[]
+  scnName[scnNameSize] = '\0';
+
+  mem_loc_info_t res = { .start = 0, .size = 0 };
+
+  for (int scn = 0; scn < pNtHdr->FileHeader.NumberOfSections; ++scn, ++pSectionHdr) {
+    // Note: pSectionHdr->Name[] is 8-byte long. If the scn name is 8-byte
+    // long, ->Name[] will not be nul-terminated. For this reason, copy it to a
+    // local buffer that is nul-terminated to be sure we only print the real scn
+    // name, and no extra garbage beyond it.
+    strncpy(scnName, (const char*)pSectionHdr->Name, scnNameSize);
+
+    if (strcmp(scnName, section_name) == 0) {
+      res.start = (uintptr_t)imageBase + pSectionHdr->VirtualAddress;
+      res.size = pSectionHdr->Misc.VirtualSize;
+      break;
+    }
+  }
+
+  return res;
+}
+/** }}} */
+
+/** Program stack information {{{ */
+static mem_loc_info_t get_stack_mem_loc_info() {
+  ULONG_PTR low;
+  ULONG_PTR high;
+  GetCurrentThreadStackLimits(&low, &high);
+  return (mem_loc_info_t) {
+    .start = low,
+    .size = high - low + 1
+  };
+}
+
+size_t increase_stack_limit(const size_t size) {
+  size_t actual_size = get_stack_size();
+  if (actual_size < size) {
+    DLOG("Increasing stack size at runtime is unsupported on Windows.\n\
+      \t   Actual stack size: %lu\n\
+      \tRequested stack size: %lu\n",
+      actual_size, size);
+  }
+  return actual_size;
+}
+
+size_t get_stack_size() {
+  return get_stack_mem_loc_info().size;
+}
+/** }}} */
+
+/** Memory partitions {{{ */
+static void init_shadow_layout_stack(int *argc_ref, char ***argv_ref) {
+  memory_partition *pstack = &mem_layout.stack;
+  mem_loc_info_t stack_loc_info = get_stack_mem_loc_info();
+  set_application_segment(&pstack->application, stack_loc_info.start,
+    stack_loc_info.size, "stack", NULL);
+  set_shadow_segment(&pstack->primary, &pstack->application, 1, "stack_primary");
+  set_shadow_segment(&pstack->secondary, &pstack->application, 1, "stack_secondary");
+#ifdef E_ACSL_TEMPORAL
+  set_shadow_segment(&pstack->temporal_primary, &pstack->application, 1, "temporal_stack_primary");
+  set_shadow_segment(&pstack->temporal_secondary, &pstack->application, 1, "temporal_stack_secondary");
+#endif
+}
+
+static void init_shadow_layout_text(HMODULE module) {
+  // Retrieve mem loc info for the text section
+  mem_loc_info_t text = get_section_info(module, ".text");
+
+  memory_partition *ptext = &mem_layout.text;
+  set_application_segment(&ptext->application, text.start,
+    text.size, "text", NULL);
+  set_shadow_segment(&ptext->primary, &ptext->application, 1, "text_primary");
+  set_shadow_segment(&ptext->secondary, &ptext->application, 1, "text_secondary");
+#ifdef E_ACSL_TEMPORAL
+  set_shadow_segment(&ptext->temporal_primary, &ptext->application, 1, "temporal_text_primary");
+  set_shadow_segment(&ptext->temporal_secondary, &ptext->application, 1, "temporal_text_secondary");
+#endif
+}
+
+static void init_shadow_layout_bss(HMODULE module) {
+  // Retrieve mem loc info for the uninidialized data segment
+  mem_loc_info_t bss = get_section_info(module, ".bss");
+
+  memory_partition *pbss = &mem_layout.bss;
+  set_application_segment(&pbss->application, bss.start, bss.size, "bss", NULL);
+  set_shadow_segment(&pbss->primary, &pbss->application, 1, "bss_primary");
+  set_shadow_segment(&pbss->secondary, &pbss->application, 1, "bss_secondary");
+#ifdef E_ACSL_TEMPORAL
+  set_shadow_segment(&pbss->temporal_primary, &pbss->application, 1, "temporal_bss_primary");
+  set_shadow_segment(&pbss->temporal_secondary, &pbss->application, 1, "temporal_bss_secondary");
+#endif
+}
+
+static void init_shadow_layout_data(HMODULE module) {
+  // Retrieve mem loc info for the initialized data segment
+  mem_loc_info_t data = get_section_info(module, ".data");
+
+  memory_partition *pdata = &mem_layout.data;
+  set_application_segment(&pdata->application, data.start, data.size, "data", NULL);
+  set_shadow_segment(&pdata->primary, &pdata->application, 1, "data_primary");
+  set_shadow_segment(&pdata->secondary, &pdata->application, 1, "data_secondary");
+#ifdef E_ACSL_TEMPORAL
+  set_shadow_segment(&pdata->temporal_primary, &pdata->application, 1, "temporal_data_primary");
+  set_shadow_segment(&pdata->temporal_secondary, &pdata->application, 1, "temporal_data_secondary");
+#endif
+}
+
+static void init_shadow_layout_idata(HMODULE module) {
+  // Retrieve mem loc info for the initialized data segment
+  mem_loc_info_t idata = get_section_info(module, ".idata");
+
+  memory_partition *pidata = &mem_layout.idata;
+  set_application_segment(&pidata->application, idata.start, idata.size, "idata", NULL);
+  set_shadow_segment(&pidata->primary, &pidata->application, 1, "idata_primary");
+  set_shadow_segment(&pidata->secondary, &pidata->application, 1, "idata_secondary");
+#ifdef E_ACSL_TEMPORAL
+  set_shadow_segment(&pidata->temporal_primary, &pidata->application, 1, "temporal_idata_primary");
+  set_shadow_segment(&pidata->temporal_secondary, &pidata->application, 1, "temporal_idata_secondary");
+#endif
+}
+
+static void init_shadow_layout_rdata(HMODULE module) {
+  // Retrieve mem loc info for the initialized data segment
+  mem_loc_info_t rdata = get_section_info(module, ".rdata");
+
+  memory_partition *prdata = &mem_layout.rdata;
+  set_application_segment(&prdata->application, rdata.start, rdata.size, "rdata", NULL);
+  set_shadow_segment(&prdata->primary, &prdata->application, 1, "rdata_primary");
+  set_shadow_segment(&prdata->secondary, &prdata->application, 1, "rdata_secondary");
+#ifdef E_ACSL_TEMPORAL
+  set_shadow_segment(&prdata->temporal_primary, &prdata->application, 1, "temporal_rdata_primary");
+  set_shadow_segment(&prdata->temporal_secondary, &prdata->application, 1, "temporal_rdata_secondary");
+#endif
+}
+/** }}} */
+#endif
+
+/** Program heap information {{{ */
+static uintptr_t get_heap_start() {
+  return mem_spaces.heap_start;
+}
+
+size_t get_heap_size() {
+  return PGM_HEAP_SIZE;
+}
+
+static size_t get_heap_init_size() {
+  return get_heap_size()/8;
+}
+
+static void init_shadow_layout_heap() {
+  memory_partition *pheap = &mem_layout.heap;
+  set_application_segment(&pheap->application, get_heap_start(),
+    get_heap_size(), "heap", mem_spaces.heap_mspace);
+  set_shadow_segment(&pheap->primary, &pheap->application, 1, "heap_primary");
+  set_shadow_segment(&pheap->secondary, &pheap->application, 8, "heap_secondary");
+#ifdef E_ACSL_TEMPORAL
+  set_shadow_segment(&pheap->temporal_primary, &pheap->application, 1, "temporal_heap_primary");
+  set_shadow_segment(&pheap->temporal_secondary, &pheap->application, 1, "temporal_heap_secondary");
+#endif
+}
+/** }}} */
+
+/** Shadow Layout {{{ */
+
+void set_application_segment(memory_segment *seg, uintptr_t start,
+    size_t size, const char *name, mspace msp) {
+  seg->name = name;
+  seg->start = start;
+  seg->size = size;
+  seg->end = seg->start + seg->size;
+  seg->mspace = msp;
+  seg->parent = NULL;
+  seg->shadow_ratio = 0;
+  seg->shadow_offset = 0;
+}
+
+void set_shadow_segment(memory_segment *seg, memory_segment *parent,
+    size_t ratio, const char *name) {
+  seg->parent = parent;
+  seg->name = name;
+  seg->shadow_ratio = ratio;
+  seg->size = parent->size/seg->shadow_ratio;
+  seg->mspace = eacsl_create_mspace(seg->size + SHADOW_SEGMENT_PADDING, 0);
+  seg->start = (uintptr_t)eacsl_mspace_malloc(seg->mspace,1);
+  seg->end = seg->start + seg->size;
+  seg->shadow_offset = parent->start - seg->start;
+}
+
+void init_shadow_layout_pre_main() {
+  init_shadow_layout_heap();
+
+#if E_ACSL_OS_IS_LINUX
+  init_shadow_layout_global();
+  init_shadow_layout_tls();
+#elif E_ACSL_OS_IS_WINDOWS
+  HANDLE module = GetModuleHandle(NULL);
+  init_shadow_layout_text(module);
+  init_shadow_layout_bss(module);
+  init_shadow_layout_data(module);
+  init_shadow_layout_idata(module);
+  init_shadow_layout_rdata(module);
+#endif
+
+  mem_layout.is_initialized_pre_main = 1;
+}
+
+void init_shadow_layout_main(int *argc_ref, char *** argv_ref) {
+  init_shadow_layout_stack(argc_ref, argv_ref);
 
-  mem_layout.is_initialized = 1;
+  mem_layout.is_initialized_main = 1;
 }
 
 void clean_shadow_layout() {
-  if (mem_layout.is_initialized) {
+  if (mem_layout.is_initialized_pre_main && mem_layout.is_initialized_main) {
     int i;
     for (i = 0; i < sizeof(mem_partitions)/sizeof(memory_partition*); i++) {
       if (mem_partitions[i]->primary.mspace)
diff --git a/src/plugins/e-acsl/share/e-acsl/observation_model/segment_model/e_acsl_shadow_layout.h b/src/plugins/e-acsl/share/e-acsl/observation_model/segment_model/e_acsl_shadow_layout.h
index b15415383d498ef48e84b392a5e6323cbbac5912..93dc849c54d3710c0b0a95581551d5b3e9a687ef 100644
--- a/src/plugins/e-acsl/share/e-acsl/observation_model/segment_model/e_acsl_shadow_layout.h
+++ b/src/plugins/e-acsl/share/e-acsl/observation_model/segment_model/e_acsl_shadow_layout.h
@@ -30,6 +30,7 @@
 
 #include <stddef.h>
 #include <stdint.h>
+#include "../../internals/e_acsl_config.h"
 #include "../../internals/e_acsl_malloc.h"
 
 /* Default size of a program's heap tracked via shadow memory */
@@ -42,21 +43,6 @@
 #define E_ACSL_STACK_SIZE 64
 #endif
 
-/* Symbols exported by the linker script */
-
-/*!\brief The first address past the end of the text segment. */
-extern char etext;
-/*!\brief The first address past the end of the initialized data segment. */
-extern char edata;
-/*!\brief The first address past the end of the uninitialized data segment. */
-extern char end;
-/*!\brief The first address of a program. */
-extern char __executable_start;
-
-/* \cond */
-void *sbrk(intptr_t increment);
-char *strerror(int errnum);
-
 /* MAP_ANONYMOUS is a mmap flag indicating that the contents of allocated blocks
  * should be nullified. Set value from <bits/mman-linux.h>, if MAP_ANONYMOUS is
  * undefined */
@@ -95,43 +81,7 @@ char *strerror(int errnum);
 #define SHADOW_SEGMENT_PADDING (512*KB)
 /* }}} */
 
-/** Thread-local storage information {{{ */
-
-/*! Thread-local storage (TLS) keeps track of copies of per-thread variables.
- * Even though at the present stage RTL of E-ACSL is not thread-safe, some
- * of the variables (for instance ::errno) are allocated there. In X86 TLS
- * is typically located somewhere below the program's stack but above mmap
- * areas. TLS is typically separated into two sections: .tdata and .tbss.
- * Similar to globals using .data and .bss, .tdata keeps track of initialized
- * thread-local variables, while .tbss holds uninitialized ones.
- *
- * Start and end addresses of TLS are obtained by taking addresses of
- * initialized and uninitialized variables in TLS (::id_tdata and ::id_tss)
- * and adding fixed amount of shadow space around them. Visually it looks
- * as follows:
- *
- *   end TLS address (&id_tdata + TLS_SHADOW_SIZE/2)
- *   id_tdata address
- *   ...
- *   id_tbss address
- *   start TLS address (&id_bss - TLS_SHADOW_SIZE/2)
- *
- * HOWEVER problems can occur if PGM_TLS_SIZE is too big:
- * see get_tls_start for details.
- */
-
-/*! \brief Return byte-size of the TLS segment */
-inline static size_t get_tls_size() {
-  return PGM_TLS_SIZE;
-}
-
-static __thread int id_tdata = 1;
-static __thread int id_tbss;
-
-/* }}} */
-
 /** Program stack information {{{ */
-extern char ** environ;
 
 /*! \brief Set a new soft stack limit
  *
@@ -149,35 +99,11 @@ size_t increase_stack_limit(const size_t size);
 /*! \brief Return byte-size of a program's stack. The return value is the soft
  * stack limit, i.e., it can be programmatically increased at runtime. */
 size_t get_stack_size();
-
-/*! \brief Return greatest (known) address on a program's stack.
- * This function presently determines the address using the address of the
- * last string in `environ`. That is, it assumes that argc and argv are
- * stored below environ, which holds for GCC/Glibc but is not necessarily
- * true for some other compilers/libraries. */
-uintptr_t get_stack_start(int *argc_ref,  char *** argv_ref);
 /* }}} */
 
 /** Program heap information {{{ */
-/*! \brief Return the start address of a program's heap. */
-uintptr_t get_heap_start();
-
 /*! \brief Return the tracked size of a program's heap. */
 size_t get_heap_size();
-
-/*! \brief Return the size of a secondary shadow region tracking
- * initialization (i.e., init shadow). */
-size_t get_heap_init_size();
-
-/** }}} */
-
-/** Program global information {{{ */
-/*! \brief Return the start address of a segment holding globals (generally
- * BSS and Data segments). */
-uintptr_t get_global_start();
-
-/*! \brief Return byte-size of global segment */
-size_t get_global_size();
 /** }}} */
 
 /** Shadow Layout {{{ */
@@ -257,20 +183,48 @@ typedef struct memory_partition memory_partition;
 struct memory_layout {
   memory_partition heap;
   memory_partition stack;
+#if E_ACSL_OS_IS_LINUX
+  // On linux
+  // The text, bss and data segments are contiguous and regrouped here in a
+  // global memory partition
   memory_partition global;
+  // The TLS is in a specific section and identifiable
   memory_partition tls;
-  int is_initialized;
+#elif E_ACSL_OS_IS_WINDOWS
+  // On windows
+  // The text, bss and data segments are not necessarily contiguous so each one
+  // is in its own memory partition
+  memory_partition text;
+  memory_partition bss;
+  memory_partition data;
+  memory_partition idata;
+  memory_partition rdata;
+  // The TLS is stored on the heap and is indistiguishable from it
+#endif
+  int is_initialized_pre_main;
+  int is_initialized_main;
 };
 
 /*! \brief Full program memory layout. */
-struct memory_layout mem_layout;
+struct memory_layout mem_layout = {
+  .is_initialized_pre_main = 0,
+  .is_initialized_main = 0,
+};
 
 /*! \brief Array of used partitions */
 memory_partition *mem_partitions [] = {
   &mem_layout.heap,
   &mem_layout.stack,
+#if E_ACSL_OS_IS_LINUX
   &mem_layout.global,
-  &mem_layout.tls
+  &mem_layout.tls,
+#elif E_ACSL_OS_IS_WINDOWS
+  &mem_layout.text,
+  &mem_layout.bss,
+  &mem_layout.data,
+  &mem_layout.idata,
+  &mem_layout.rdata,
+#endif
 };
 
 /*! \brief Initialize an application memory segment.
@@ -296,17 +250,18 @@ void set_shadow_segment(memory_segment *seg, memory_segment *parent,
 /*! \brief Initialize memory layout, i.e., determine bounds of program segments,
  * allocate shadow memory spaces and compute offsets. This function populates
  * global struct ::memory_layout holding that information with data.
-   Case of the stack. */
-void init_shadow_layout_stack(int *argc_ref, char ***argv_ref);
-
-/*! \brief Return start address of a program's TLS */
-uintptr_t get_tls_start();
+ *
+ * Case of segments available before main (for instance from a function marked
+ * as `__constructor__`). */
+void init_shadow_layout_pre_main();
 
 /*! \brief Initialize memory layout, i.e., determine bounds of program segments,
  * allocate shadow memory spaces and compute offsets. This function populates
  * global struct ::memory_layout holding that information with data.
-   Case of the heap, globals and tls. */
-void init_shadow_layout_heap_global_tls();
+ *
+ * Case of segments only available once inside of main (for instance the stack
+ * of the program). */
+void init_shadow_layout_main(int *argc_ref, char ***argv_ref);
 
 /*! \brief Deallocate shadow regions used by runtime analysis */
 void clean_shadow_layout();
@@ -333,10 +288,23 @@ void clean_shadow_layout();
 #define heap_secondary_offset   mem_layout.heap.secondary.shadow_offset
 #define stack_primary_offset    mem_layout.stack.primary.shadow_offset
 #define stack_secondary_offset  mem_layout.stack.secondary.shadow_offset
-#define global_primary_offset   mem_layout.global.primary.shadow_offset
-#define global_secondary_offset mem_layout.global.secondary.shadow_offset
-#define tls_primary_offset      mem_layout.tls.primary.shadow_offset
-#define tls_secondary_offset    mem_layout.tls.secondary.shadow_offset
+#if E_ACSL_OS_IS_LINUX
+# define global_primary_offset   mem_layout.global.primary.shadow_offset
+# define global_secondary_offset mem_layout.global.secondary.shadow_offset
+# define tls_primary_offset      mem_layout.tls.primary.shadow_offset
+# define tls_secondary_offset    mem_layout.tls.secondary.shadow_offset
+#elif E_ACSL_OS_IS_WINDOWS
+# define text_primary_offset mem_layout.text.primary.shadow_offset
+# define text_secondary_offset mem_layout.text.secondary.shadow_offset
+# define bss_primary_offset mem_layout.bss.primary.shadow_offset
+# define bss_secondary_offset mem_layout.bss.secondary.shadow_offset
+# define data_primary_offset mem_layout.data.primary.shadow_offset
+# define data_secondary_offset mem_layout.data.secondary.shadow_offset
+# define idata_primary_offset mem_layout.idata.primary.shadow_offset
+# define idata_secondary_offset mem_layout.idata.secondary.shadow_offset
+# define rdata_primary_offset mem_layout.rdata.primary.shadow_offset
+# define rdata_secondary_offset mem_layout.rdata.secondary.shadow_offset
+#endif
 
 /*! \brief Compute a shadow address using displacement offset
  * @param _addr - an application space address
@@ -374,29 +342,97 @@ void clean_shadow_layout();
 #define SECONDARY_STACK_SHADOW(_addr) \
   SHADOW_ACCESS(_addr, stack_secondary_offset)
 
+#if E_ACSL_OS_IS_LINUX
 /*! \brief Convert a global address into its primary shadow counterpart */
-#define PRIMARY_GLOBAL_SHADOW(_addr)  \
+# define PRIMARY_GLOBAL_SHADOW(_addr)  \
   SHADOW_ACCESS(_addr, global_primary_offset)
 
 /*! \brief Convert a global address into its secondary shadow counterpart */
-#define SECONDARY_GLOBAL_SHADOW(_addr) \
+# define SECONDARY_GLOBAL_SHADOW(_addr) \
   SHADOW_ACCESS(_addr, global_secondary_offset)
 
 /*! \brief Convert a TLS address into its primary shadow counterpart */
-#define PRIMARY_TLS_SHADOW(_addr)  \
+# define PRIMARY_TLS_SHADOW(_addr)  \
   SHADOW_ACCESS(_addr, tls_primary_offset)
 
 /*! \brief Convert a TLS address into its secondary shadow counterpart */
-#define SECONDARY_TLS_SHADOW(_addr) \
+# define SECONDARY_TLS_SHADOW(_addr) \
   SHADOW_ACCESS(_addr, tls_secondary_offset)
+#elif E_ACSL_OS_IS_WINDOWS
+/*! \brief Convert a text address into its primary shadow counterpart */
+# define PRIMARY_TEXT_SHADOW(_addr)  \
+  SHADOW_ACCESS(_addr, text_primary_offset)
+
+/*! \brief Convert a text address into its secondary shadow counterpart */
+# define SECONDARY_TEXT_SHADOW(_addr) \
+  SHADOW_ACCESS(_addr, text_secondary_offset)
+
+/*! \brief Convert a bss address into its primary shadow counterpart */
+# define PRIMARY_BSS_SHADOW(_addr)  \
+  SHADOW_ACCESS(_addr, bss_primary_offset)
+
+/*! \brief Convert a bss address into its secondary shadow counterpart */
+# define SECONDARY_BSS_SHADOW(_addr) \
+  SHADOW_ACCESS(_addr, bss_secondary_offset)
+
+/*! \brief Convert an data address into its primary shadow counterpart */
+# define PRIMARY_DATA_SHADOW(_addr)  \
+  SHADOW_ACCESS(_addr, data_primary_offset)
+
+/*! \brief Convert an data address into its secondary shadow counterpart */
+# define SECONDARY_DATA_SHADOW(_addr) \
+  SHADOW_ACCESS(_addr, data_secondary_offset)
+
+/*! \brief Convert an idata address into its primary shadow counterpart */
+# define PRIMARY_IDATA_SHADOW(_addr)  \
+  SHADOW_ACCESS(_addr, idata_primary_offset)
+
+/*! \brief Convert an idata address into its secondary shadow counterpart */
+# define SECONDARY_IDATA_SHADOW(_addr) \
+  SHADOW_ACCESS(_addr, idata_secondary_offset)
+
+/*! \brief Convert an rdata address into its primary shadow counterpart */
+# define PRIMARY_RDATA_SHADOW(_addr)  \
+  SHADOW_ACCESS(_addr, rdata_primary_offset)
+
+/*! \brief Convert an rdata address into its secondary shadow counterpart */
+# define SECONDARY_RDATA_SHADOW(_addr) \
+  SHADOW_ACCESS(_addr, rdata_secondary_offset)
+
+/*! \brief Convert a global address into its primary shadow counterpart */
+# define PRIMARY_GLOBAL_SHADOW(_addr) \
+    (IS_ON_TEXT(_addr) ? PRIMARY_TEXT_SHADOW(_addr) : \
+     IS_ON_BSS(_addr) ? PRIMARY_BSS_SHADOW(_addr) : \
+     IS_ON_DATA(_addr) ? PRIMARY_DATA_SHADOW(_addr) : \
+     IS_ON_IDATA(_addr) ? PRIMARY_IDATA_SHADOW(_addr) : \
+     IS_ON_RDATA(_addr) ? PRIMARY_RDATA_SHADOW(_addr) : (intptr_t)0)
+
+/*! \brief Convert a global address into its secondary shadow counterpart */
+# define SECONDARY_GLOBAL_SHADOW(_addr) \
+    (IS_ON_TEXT(_addr) ? SECONDARY_TEXT_SHADOW(_addr) : \
+     IS_ON_BSS(_addr) ? SECONDARY_BSS_SHADOW(_addr) : \
+     IS_ON_DATA(_addr) ? SECONDARY_DATA_SHADOW(_addr) : \
+     IS_ON_IDATA(_addr) ? SECONDARY_IDATA_SHADOW(_addr) : \
+     IS_ON_RDATA(_addr) ? SECONDARY_RDATA_SHADOW(_addr) : (intptr_t)0)
+#endif
 
 /* \brief Compute a primary or a secondary shadow address (based on the value of
  * parameter `_region`) of an address tracked via an offset-based encoding.
  * For an untracked address `0` is returned. */
-#define SHADOW_REGION_ADDRESS(_addr, _region) \
-  (IS_ON_STACK(_addr) ? _region##_STACK_SHADOW(_addr) : \
-    IS_ON_GLOBAL(_addr) ? _region##_GLOBAL_SHADOW(_addr) : \
-      IS_ON_TLS(_addr) ? _region##_TLS_SHADOW(_addr) : 0)
+#if E_ACSL_OS_IS_LINUX
+# define SHADOW_REGION_ADDRESS(_addr, _region) \
+    (IS_ON_STACK(_addr) ? _region##_STACK_SHADOW(_addr) : \
+     IS_ON_GLOBAL(_addr) ? _region##_GLOBAL_SHADOW(_addr) : \
+     IS_ON_TLS(_addr) ? _region##_TLS_SHADOW(_addr) : (intptr_t)0)
+#elif E_ACSL_OS_IS_WINDOWS
+# define SHADOW_REGION_ADDRESS(_addr, _region) \
+    (IS_ON_STACK(_addr) ? _region##_STACK_SHADOW(_addr) : \
+     IS_ON_TEXT(_addr) ? _region##_TEXT_SHADOW(_addr) : \
+     IS_ON_BSS(_addr) ? _region##_BSS_SHADOW(_addr) : \
+     IS_ON_DATA(_addr) ? _region##_DATA_SHADOW(_addr) : \
+     IS_ON_IDATA(_addr) ? _region##_IDATA_SHADOW(_addr) : \
+     IS_ON_RDATA(_addr) ? _region##_RDATA_SHADOW(_addr) : (intptr_t)0)
+#endif
 
 /*! \brief Primary shadow address of a non-dynamic region */
 #define PRIMARY_SHADOW(_addr) SHADOW_REGION_ADDRESS(_addr, PRIMARY)
@@ -422,22 +458,50 @@ void clean_shadow_layout();
 /*! \brief Evaluate to true if `_addr` is a stack address */
 #define IS_ON_STACK(_addr) IS_ON(_addr, mem_layout.stack.application)
 
+#if E_ACSL_OS_IS_LINUX
 /*! \brief Evaluate to true if `_addr` is a global address */
-#define IS_ON_GLOBAL(_addr) IS_ON(_addr, mem_layout.global.application)
+# define IS_ON_GLOBAL(_addr) IS_ON(_addr, mem_layout.global.application)
 
 /*! \brief Evaluate to true if _addr is a TLS address */
-#define IS_ON_TLS(_addr) IS_ON(_addr, mem_layout.tls.application)
+# define IS_ON_TLS(_addr) IS_ON(_addr, mem_layout.tls.application)
 
 /*! \brief Shortcut for evaluating an address via ::IS_ON_STACK,
  * ::IS_ON_GLOBAL or ::IS_ON_TLS  */
-#define IS_ON_STATIC(_addr) \
-  (IS_ON_STACK(_addr) || IS_ON_GLOBAL(_addr) || IS_ON_TLS(_addr))
+# define IS_ON_STATIC(_addr) \
+    (IS_ON_STACK(_addr) || IS_ON_GLOBAL(_addr) || IS_ON_TLS(_addr))
+#elif E_ACSL_OS_IS_WINDOWS
+/*! \brief Evaluate to true if `_addr` is a text address */
+# define IS_ON_TEXT(_addr) IS_ON(_addr, mem_layout.text.application)
+
+/*! \brief Evaluate to true if `_addr` is a bss address */
+# define IS_ON_BSS(_addr) IS_ON(_addr, mem_layout.bss.application)
+
+/*! \brief Evaluate to true if `_addr` is an idata address */
+# define IS_ON_DATA(_addr) IS_ON(_addr, mem_layout.data.application)
+
+/*! \brief Evaluate to true if `_addr` is an idata address */
+# define IS_ON_IDATA(_addr) IS_ON(_addr, mem_layout.idata.application)
+
+/*! \brief Evaluate to true if `_addr` is an rdata address */
+# define IS_ON_RDATA(_addr) IS_ON(_addr, mem_layout.rdata.application)
+
+/*! \brief Evaluate to true if `_addr` is a global address */
+# define IS_ON_GLOBAL(_addr) \
+    (IS_ON_TEXT(_addr) || IS_ON_BSS(_addr) || IS_ON_DATA(_addr) || \
+     IS_ON_IDATA(_addr) || IS_ON_RDATA(_addr))
+
+/*! \brief Shortcut for evaluating an address via ::IS_ON_STACK,
+ * ::IS_ON_TEXT, :: IS_ON_BSS, ::IS_ON_IDATA, or ::IS_ON_RDATA  */
+# define IS_ON_STATIC(_addr) \
+    (IS_ON_STACK(_addr) || IS_ON_TEXT(_addr) || IS_ON_BSS(_addr) || \
+     IS_ON_DATA(_addr) || IS_ON_IDATA(_addr) || IS_ON_RDATA(_addr))
+#endif
 
 /*! \brief Evaluate to a true value if a given address belongs to tracked
- * allocation (i.e., found within tls, stack, heap or globally) */
+ * allocation (i.e., found within static or dynamic allocation) */
 #define IS_ON_VALID(_addr) \
-  (IS_ON_STACK(_addr) || IS_ON_HEAP(_addr) || \
-   IS_ON_GLOBAL(_addr) || IS_ON_TLS(_addr))
+  (IS_ON_STATIC(_addr) || IS_ON_HEAP(_addr))
+
 /* }}} */
 
 #ifdef E_ACSL_TEMPORAL /* {{{ */
@@ -453,21 +517,79 @@ void clean_shadow_layout();
 #define TEMPORAL_SECONDARY_STACK_SHADOW(_addr) \
   SHADOW_ACCESS(_addr, mem_layout.stack.temporal_secondary.shadow_offset)
 
+#if E_ACSL_OS_IS_LINUX
 /*! \brief Convert a global address into its primary temporal shadow counterpart */
-#define TEMPORAL_PRIMARY_GLOBAL_SHADOW(_addr)  \
-  SHADOW_ACCESS(_addr, mem_layout.global.temporal_primary.shadow_offset)
+# define TEMPORAL_PRIMARY_GLOBAL_SHADOW(_addr)  \
+    SHADOW_ACCESS(_addr, mem_layout.global.temporal_primary.shadow_offset)
 
 /*! \brief Convert a global address into its primary temporal shadow counterpart */
-#define TEMPORAL_SECONDARY_GLOBAL_SHADOW(_addr)  \
-  SHADOW_ACCESS(_addr, mem_layout.global.temporal_secondary.shadow_offset)
+# define TEMPORAL_SECONDARY_GLOBAL_SHADOW(_addr)  \
+    SHADOW_ACCESS(_addr, mem_layout.global.temporal_secondary.shadow_offset)
 
 /*! \brief Convert a TLS address into its primary temporal shadow counterpart */
-#define TEMPORAL_PRIMARY_TLS_SHADOW(_addr)  \
-  SHADOW_ACCESS(_addr, mem_layout.tls.temporal_primary.shadow_offset)
+# define TEMPORAL_PRIMARY_TLS_SHADOW(_addr)  \
+    SHADOW_ACCESS(_addr, mem_layout.tls.temporal_primary.shadow_offset)
 
 /*! \brief Convert a TLS address into its secondary temporal shadow counterpart */
-#define TEMPORAL_SECONDARY_TLS_SHADOW(_addr)  \
-  SHADOW_ACCESS(_addr, mem_layout.tls.temporal_secondary.shadow_offset)
+# define TEMPORAL_SECONDARY_TLS_SHADOW(_addr)  \
+    SHADOW_ACCESS(_addr, mem_layout.tls.temporal_secondary.shadow_offset)
+#elif E_ACSL_OS_IS_WINDOWS
+/*! \brief Convert a text address into its primary temporal shadow counterpart */
+# define TEMPORAL_PRIMARY_TEXT_SHADOW(_addr)  \
+    SHADOW_ACCESS(_addr, mem_layout.text.temporal_primary.shadow_offset)
+
+/*! \brief Convert a text address into its primary temporal shadow counterpart */
+# define TEMPORAL_SECONDARY_TEXT_SHADOW(_addr)  \
+    SHADOW_ACCESS(_addr, mem_layout.text.temporal_secondary.shadow_offset)
+
+/*! \brief Convert a bss address into its primary temporal shadow counterpart */
+# define TEMPORAL_PRIMARY_BSS_SHADOW(_addr)  \
+    SHADOW_ACCESS(_addr, mem_layout.bss.temporal_primary.shadow_offset)
+
+/*! \brief Convert a bss address into its primary temporal shadow counterpart */
+# define TEMPORAL_SECONDARY_BSS_SHADOW(_addr)  \
+    SHADOW_ACCESS(_addr, mem_layout.bss.temporal_secondary.shadow_offset)
+
+/*! \brief Convert an data address into its primary temporal shadow counterpart */
+# define TEMPORAL_PRIMARY_DATA_SHADOW(_addr)  \
+    SHADOW_ACCESS(_addr, mem_layout.data.temporal_primary.shadow_offset)
+
+/*! \brief Convert an data address into its primary temporal shadow counterpart */
+# define TEMPORAL_SECONDARY_DATA_SHADOW(_addr)  \
+    SHADOW_ACCESS(_addr, mem_layout.data.temporal_secondary.shadow_offset)
+
+/*! \brief Convert an idata address into its primary temporal shadow counterpart */
+# define TEMPORAL_PRIMARY_IDATA_SHADOW(_addr)  \
+    SHADOW_ACCESS(_addr, mem_layout.idata.temporal_primary.shadow_offset)
+
+/*! \brief Convert an idata address into its primary temporal shadow counterpart */
+# define TEMPORAL_SECONDARY_IDATA_SHADOW(_addr)  \
+    SHADOW_ACCESS(_addr, mem_layout.idata.temporal_secondary.shadow_offset)
+
+/*! \brief Convert an rdata address into its primary temporal shadow counterpart */
+# define TEMPORAL_PRIMARY_RDATA_SHADOW(_addr)  \
+    SHADOW_ACCESS(_addr, mem_layout.rdata.temporal_primary.shadow_offset)
+
+/*! \brief Convert an rdata address into its primary temporal shadow counterpart */
+# define TEMPORAL_SECONDARY_RDATA_SHADOW(_addr)  \
+    SHADOW_ACCESS(_addr, mem_layout.rdata.temporal_secondary.shadow_offset)
+
+/*! \brief Convert a global address into its primary temporal shadow counterpart */
+# define TEMPORAL_PRIMARY_GLOBAL_SHADOW(_addr) \
+    (IS_ON_TEXT(_addr) ? TEMPORAL_PRIMARY_TEXT_SHADOW(_addr) : \
+     IS_ON_BSS(_addr) ? TEMPORAL_PRIMARY_BSS_SHADOW(_addr) : \
+     IS_ON_DATA(_addr) ? TEMPORAL_PRIMARY_DATA_SHADOW(_addr) : \
+     IS_ON_IDATA(_addr) ? TEMPORAL_PRIMARY_IDATA_SHADOW(_addr) : \
+     IS_ON_RDATA(_addr) ? TEMPORAL_PRIMARY_RDATA_SHADOW(_addr) : (intptr_t)0)
+
+/*! \brief Convert a global address into its primary temporal shadow counterpart */
+# define TEMPORAL_SECONDARY_GLOBAL_SHADOW(_addr) \
+    (IS_ON_TEXT(_addr) ? TEMPORAL_SECONDARY_TEXT_SHADOW(_addr) : \
+     IS_ON_BSS(_addr) ? TEMPORAL_SECONDARY_BSS_SHADOW(_addr) : \
+     IS_ON_DATA(_addr) ? TEMPORAL_SECONDARY_DATA_SHADOW(_addr) : \
+     IS_ON_IDATA(_addr) ? TEMPORAL_SECONDARY_IDATA_SHADOW(_addr) : \
+     IS_ON_RDATA(_addr) ? TEMPORAL_SECONDARY_RDATA_SHADOW(_addr) : (intptr_t)0)
+#endif
 
 /*! \brief Temporal primary shadow address of a non-dynamic region */
 #define TEMPORAL_PRIMARY_STATIC_SHADOW(_addr) \
diff --git a/src/plugins/e-acsl/src/code_generator/at_with_lscope.ml b/src/plugins/e-acsl/src/code_generator/at_with_lscope.ml
index 671ea306b1f641e8cacba62184345c3256d526fd..ea38062b647d72c07d3ef2942cdef132c60e8a6a 100644
--- a/src/plugins/e-acsl/src/code_generator/at_with_lscope.ml
+++ b/src/plugins/e-acsl/src/code_generator/at_with_lscope.ml
@@ -260,7 +260,7 @@ let to_exp ~loc kf env pot label =
              let e_size, _ = term_to_exp kf env t_size in
              let e_size = Cil.constFold false e_size in
              let malloc_stmt =
-               Smart_stmt.lib_call ~loc
+               Smart_stmt.call ~loc
                  ~result:(Cil.var vi)
                  "malloc"
                  [ e_size ]
@@ -273,7 +273,7 @@ let to_exp ~loc kf env pot label =
            | Typing.(Rational | Real | Nan) ->
              Error.not_yet "quantification over non-integer type"
          in
-         let free_stmt = Smart_stmt.lib_call ~loc "free" [e] in
+         let free_stmt = Smart_stmt.call ~loc "free" [e] in
          (* The list of stmts returned by the current closure are inserted
             LOCALLY to the block where the new var is FIRST used, whatever scope
             is indicated to [Env.new_var].
diff --git a/src/plugins/e-acsl/src/code_generator/env.ml b/src/plugins/e-acsl/src/code_generator/env.ml
index 595dc566e1e836413c056e3c2c462ff3fedcf11a..cf56b61500be166e282712a7a2e2adda699481bf 100644
--- a/src/plugins/e-acsl/src/code_generator/env.ml
+++ b/src/plugins/e-acsl/src/code_generator/env.ml
@@ -135,6 +135,20 @@ let generate_rte env =
   let local_env, _ = top env in
   local_env.rte
 
+let with_rte ~f env rte_value =
+  let old_rte_value = generate_rte env in
+  let env = rte env rte_value in
+  let env = f env in
+  let env = rte env old_rte_value in
+  env
+
+let with_rte_and_result ~f env rte_value =
+  let old_rte_value = generate_rte env in
+  let env = rte env rte_value in
+  let other, env = f env in
+  let env = rte env old_rte_value in
+  other, env
+
 (* ************************************************************************** *)
 
 (* eta-expansion required for typing generalisation *)
@@ -201,9 +215,9 @@ let do_new_var ~loc ?(scope=Varname.Block) ?(name="") env kf t ty mk_stmts =
         env_stack = local_env :: tl_env }
     | Varname.Block ->
       let local_env =
-        { block_info = new_block;
-          mp_tbl = extend_tbl local_env.mp_tbl;
-          rte = false (* must be already checked by mk_stmts *) }
+        { local_env with
+          block_info = new_block;
+          mp_tbl = extend_tbl local_env.mp_tbl }
       in
       { env with
         cpt = n;
@@ -213,8 +227,7 @@ let do_new_var ~loc ?(scope=Varname.Block) ?(name="") env kf t ty mk_stmts =
     let new_global_vars = (v, lscope) :: env.new_global_vars in
     let local_env =
       { local_env with
-        block_info = new_block;
-        rte = false (* must be already checked by mk_stmts *) }
+        block_info = new_block }
     in
     { env with
       new_global_vars = new_global_vars;
diff --git a/src/plugins/e-acsl/src/code_generator/env.mli b/src/plugins/e-acsl/src/code_generator/env.mli
index 3a5aebf2f5d4f1a0ea67af77099032535365f8e7..cb6633546cfaaa5527c2be9d5d7ce56e470c59f9 100644
--- a/src/plugins/e-acsl/src/code_generator/env.mli
+++ b/src/plugins/e-acsl/src/code_generator/env.mli
@@ -165,7 +165,26 @@ val pop_loop: t -> predicate list * t
 (* ************************************************************************** *)
 
 val rte: t -> bool -> t
+(** [rte env x] sets RTE generation to x for the given environment *)
+
 val generate_rte: t -> bool
+(** Returns the current value of RTE generation for the given environment *)
+
+val with_rte: f:(t -> t) -> t -> bool -> t
+(** [with_rte ~f env x] executes the given closure with RTE generation set to x,
+    and reset RTE generation to its original value afterwards.
+    This function does not handle exceptions at all. The user must handle them
+    either directly in the [f] closure or around the call to the function. *)
+
+val with_rte_and_result: f:(t -> 'a * t) -> t -> bool -> 'a * t
+(** [with_rte_and_result ~f env x] executes the given closure with RTE
+    generation set to x, and reset RTE generation to its original value
+    afterwards. [f] is a closure that takes an environment an returns a pair
+    where the first member is an arbitrary value and the second member is the
+    environment. The function will return the first member of the returned pair
+    of the closure along with the updated environment.
+    This function does not handle exceptions at all. The user must handle them
+    either directly in the [f] closure or around the call to the function. *)
 
 (* ************************************************************************** *)
 (** {2 Context for error handling} *)
diff --git a/src/plugins/e-acsl/src/code_generator/gmp.ml b/src/plugins/e-acsl/src/code_generator/gmp.ml
index 8a2b5385f1cb1830a92ff5272cb14bd0cd3d7c69..cfc504740298f8517998be505a7512b21b9e50a4 100644
--- a/src/plugins/e-acsl/src/code_generator/gmp.ml
+++ b/src/plugins/e-acsl/src/code_generator/gmp.ml
@@ -33,7 +33,7 @@ let apply_on_var ~loc funname e =
     else if Gmp_types.Q.is_t ty then "__gmpq_"
     else assert false
   in
-  Smart_stmt.lib_call ~loc (prefix ^ funname) [ e ]
+  Smart_stmt.rtl_call ~loc ~prefix funname [ e ]
 
 let init ~loc e = apply_on_var "init" ~loc e
 let clear ~loc e = apply_on_var "clear" ~loc e
@@ -90,7 +90,7 @@ let generic_affect ~loc fname lv ev e =
   let ty = Cil.typeOf ev in
   if Gmp_types.Z.is_t ty || Gmp_types.Q.is_t ty then begin
     let suf, args = get_set_suffix_and_arg ty e in
-    Smart_stmt.lib_call ~loc (fname ^ suf) (ev :: args)
+    Smart_stmt.rtl_call ~loc ~prefix:"" (fname ^ suf) (ev :: args)
   end else
     Smart_stmt.assigns ~loc:e.eloc ~result:lv e
 
@@ -111,7 +111,8 @@ let init_set ~loc lv ev e =
      | Lval elv ->
        assert (Gmp_types.Z.is_t (Cil.typeOf ev));
        let call =
-         Smart_stmt.lib_call ~loc
+         Smart_stmt.rtl_call ~loc
+           ~prefix:""
            "__gmpz_import"
            [ ev;
              Cil.one ~loc;
diff --git a/src/plugins/e-acsl/src/code_generator/memory_translate.ml b/src/plugins/e-acsl/src/code_generator/memory_translate.ml
index be6fbc2bc7a5d9b7025d7896c52e0abe2b89d2d6..524df6755b2c5334a2db69a67b89e771eda1e1c3 100644
--- a/src/plugins/e-acsl/src/code_generator/memory_translate.ml
+++ b/src/plugins/e-acsl/src/code_generator/memory_translate.ml
@@ -115,7 +115,10 @@ let rec eliminate_ranges_from_index_of_toffset ~loc toffset quantifiers =
 let call ~loc kf name ctx env t =
   assert (name = "base_addr" || name = "block_length"
           || name = "offset" || name ="freeable");
-  let e, env = !term_to_exp_ref kf (Env.rte env true) t in
+  let e, env =
+    Env.with_rte_and_result env true
+      ~f:(fun env -> !term_to_exp_ref kf env t)
+  in
   Env.rtl_call_to_new_var
     ~loc
     ~name
@@ -156,8 +159,9 @@ let gmp_to_sizet ~loc kf env size p =
       sizet
       (fun vi _ ->
          [ Smart_stmt.runtime_check Smart_stmt.RTE kf guard p;
-           Smart_stmt.lib_call ~loc
+           Smart_stmt.rtl_call ~loc
              ~result:(Cil.var vi)
+             ~prefix:""
              "__gmpz_get_ui"
              [ size ] ])
   in
@@ -194,7 +198,10 @@ let range_to_ptr_and_size ~loc kf env ptr r p =
       (Ctype typ_charptr)
   in
   Typing.type_term ~use_gmp_opt:false ~ctx:Typing.nan ptr;
-  let ptr, env = !term_to_exp_ref kf (Env.rte env true) ptr in
+  let ptr, env =
+    Env.with_rte_and_result env true
+      ~f:(fun env -> !term_to_exp_ref kf env ptr)
+  in
   (* size *)
   let size_term =
     (* Since [s] and [n1] have been typed through [ptr],
@@ -252,7 +259,10 @@ let range_to_ptr_and_size ~loc kf env ptr r p =
    expression in bytes and [env] is the current environment.
    [p] is the predicate under test. *)
 let term_to_ptr_and_size ~loc kf env t =
-  let e, env = !term_to_exp_ref kf (Env.rte env true) t in
+  let e, env =
+    Env.with_rte_and_result env true
+      ~f:(fun env -> !term_to_exp_ref kf env t)
+  in
   let ty = Misc.cty t.term_type in
   let sizeof = Smart_exp.ptr_sizeof ~loc ty in
   e, sizeof, env
diff --git a/src/plugins/e-acsl/src/code_generator/rational.ml b/src/plugins/e-acsl/src/code_generator/rational.ml
index 2f4417b0191213b6730879074147a5f66f68fe43..0af7f3b0697137395bd885f1e88f797bc4943209 100644
--- a/src/plugins/e-acsl/src/code_generator/rational.ml
+++ b/src/plugins/e-acsl/src/code_generator/rational.ml
@@ -148,8 +148,9 @@ let add_cast ~loc ?name e env kf ty =
         None
         Cil.doubleType
         (fun v _ ->
-           [ Smart_stmt.lib_call ~loc
+           [ Smart_stmt.rtl_call ~loc
                ~result:(Cil.var v)
+               ~prefix:""
                "__gmpq_get_d"
                [ e ] ])
     in
@@ -197,7 +198,11 @@ let cmp ~loc bop e1 e2 env kf t_opt =
       ~name
       Cil.intType
       (fun v _ ->
-         [ Smart_stmt.lib_call ~loc ~result:(Cil.var v) fname [ e1; e2 ] ])
+         [ Smart_stmt.rtl_call ~loc
+             ~result:(Cil.var v)
+             ~prefix:""
+             fname
+             [ e1; e2 ] ])
   in
   Cil.new_exp ~loc (BinOp(bop, e, Cil.zero ~loc, Cil.intType)), env
 
@@ -226,7 +231,10 @@ let binop ~loc bop e1 e2 env kf t_opt =
      [e2] *)
   let e1, env = create ~loc e1 env kf None in
   let e2, env = create ~loc e2 env kf None in
-  let mk_stmts _ e = [ Smart_stmt.lib_call ~loc name [ e; e1; e2 ] ] in
+  let mk_stmts _ e = [ Smart_stmt.rtl_call ~loc
+                         ~prefix:""
+                         name
+                         [ e; e1; e2 ] ] in
   let name = Misc.name_of_binop bop in
   let _, e, env = new_var_and_init ~loc ~name env kf t_opt mk_stmts in
   e, env
diff --git a/src/plugins/e-acsl/src/code_generator/smart_stmt.ml b/src/plugins/e-acsl/src/code_generator/smart_stmt.ml
index 984188546901494f65d6ab58fc6a88919f95dc49..2c3497df87388788c01f9b46c4b751bb24bc240f 100644
--- a/src/plugins/e-acsl/src/code_generator/smart_stmt.ml
+++ b/src/plugins/e-acsl/src/code_generator/smart_stmt.ml
@@ -30,7 +30,7 @@ let stmt sk = Cil.mkStmt ~valid_sid:true sk
 let instr i = stmt (Instr i)
 let block_stmt blk = stmt (Block blk)
 let block_from_stmts stmts = block_stmt (Cil.mkBlock stmts)
-let call ~loc ?result e args = instr (Call(result, e, args, loc))
+let call_instr ~loc ?result e args = instr (Call(result, e, args, loc))
 
 let assigns ~loc ~result e = instr (Set(result, e, loc))
 
@@ -68,13 +68,7 @@ let block stmt b = match b.bstmts with
 (* E-ACSL specific code *)
 (* ********************************************************************** *)
 
-let lib_call ~loc ?result fname args =
-  let vi =
-    try Rtl.Symbols.find_vi fname
-    with Rtl.Symbols.Unregistered _ as exn ->
-    try Builtins.find fname
-    with Not_found -> raise exn
-  in
+let do_call ~loc ?result vi args =
   let f = Cil.evar ~loc vi in
   vi.vreferenced <- true;
   let make_args ~variadic args param_ty =
@@ -95,7 +89,7 @@ let lib_call ~loc ?result fname args =
         Options.fatal
           "Mismatch between the number of expressions given and the number \
            of arguments in the signature when calling function '%s'"
-          fname
+          vi.vname
     in
     List.rev (make_rev_args [] args param_ty)
   in
@@ -104,10 +98,27 @@ let lib_call ~loc ?result fname args =
     | TFun(_, None, _, _) -> []
     | _ -> assert false
   in
-  call ~loc ?result f args
+  call_instr ~loc ?result f args
+
+let call ~loc ?result fname args =
+  let kf =
+    try Globals.Functions.find_by_name fname
+    with Not_found ->
+      Options.fatal "Unable to find function '%s'" fname
+  in
+  let vi = Globals.Functions.get_vi kf in
+  do_call ~loc ?result vi args
 
-let rtl_call ~loc ?result fname args =
-  lib_call ~loc ?result (Functions.RTL.mk_api_name fname) args
+let rtl_call ~loc ?result ?(prefix=Functions.RTL.api_prefix) fname args =
+  let fname = prefix ^ fname in
+  let vi =
+    try Rtl.Symbols.find_vi fname
+    with Rtl.Symbols.Unregistered _ as exn ->
+    try Builtins.find fname
+    with Not_found ->
+      raise exn
+  in
+  do_call ~loc ?result vi args
 
 (* ************************************************************************** *)
 (** {2 Handling the E-ACSL's C-libraries, part II} *)
diff --git a/src/plugins/e-acsl/src/code_generator/smart_stmt.mli b/src/plugins/e-acsl/src/code_generator/smart_stmt.mli
index 3aebb9f4cc27419db8d9337096af57fb2d3cebb6..abd797824e97d0e018a076089db1919abbab50cc 100644
--- a/src/plugins/e-acsl/src/code_generator/smart_stmt.mli
+++ b/src/plugins/e-acsl/src/code_generator/smart_stmt.mli
@@ -56,15 +56,22 @@ val break: loc:location -> stmt
 (* E-ACSL specific code: build calls to its RTL API *)
 (* ********************************************************************** *)
 
-val lib_call: loc:location -> ?result:lval -> string -> exp list -> stmt
+val call: loc:location -> ?result:lval -> string -> exp list -> stmt
+(** Construct a call to a function with the given name.
+    @raise Not_found if the given string does not represent a function in the
+    AST, for instance if the function does not exist. *)
+
+val rtl_call:
+  loc:location -> ?result:lval -> ?prefix:string -> string -> exp list -> stmt
 (** Construct a call to a library function with the given name.
+
+    [prefix] defaults to the E-ACSL RTL API prefix and can be explicitely
+    provided to call functions without this prefix.
+
     @raise Rtl.Symbols.Unregistered if the given string does not represent
     such a function or if library functions were never registered (only possible
     when using E-ACSL through its API). *)
 
-val rtl_call: loc:location -> ?result:lval -> string -> exp list -> stmt
-(** Special version of [lib_call] for E-ACSL's RTL functions. *)
-
 val store_stmt: ?str_size:exp -> varinfo -> stmt
 (** Construct a call to [__e_acsl_store_block] that observes the allocation of
     the given varinfo. See [share/e-acsl/e_acsl.h] for details about this
diff --git a/src/plugins/e-acsl/src/code_generator/temporal.ml b/src/plugins/e-acsl/src/code_generator/temporal.ml
index d0f6ced85f13d7305efda530e904f39ae1dd8cfc..f56c6d4837ff97b473c525cca032457295cdb14c 100644
--- a/src/plugins/e-acsl/src/code_generator/temporal.ml
+++ b/src/plugins/e-acsl/src/code_generator/temporal.ml
@@ -75,13 +75,13 @@ module Mk: sig
 end = struct
 
   let store_reference ~loc flow lhs rhs =
+    let prefix = RTL.temporal_prefix in
     let fname = match flow with
       | Direct -> "store_nblock"
       | Indirect -> "store_nreferent"
       | Copy -> Options.fatal "Copy flow type in store_reference"
     in
-    let fname = RTL.mk_temporal_name fname in
-    Smart_stmt.lib_call ~loc fname [ Cil.mkAddrOf ~loc lhs; rhs ]
+    Smart_stmt.rtl_call ~loc ~prefix fname [ Cil.mkAddrOf ~loc lhs; rhs ]
 
   let save_param ~loc flow lhs pos =
     let infix = match flow with
@@ -89,17 +89,19 @@ end = struct
       | Indirect -> "nreferent"
       | Copy -> "copy"
     in
+    let prefix = RTL.temporal_prefix in
     let fname = "save_" ^ infix ^ "_parameter" in
-    let fname = RTL.mk_temporal_name fname in
-    Smart_stmt.lib_call ~loc fname [ lhs ; Cil.integer ~loc pos ]
+    Smart_stmt.rtl_call ~loc ~prefix fname [ lhs ; Cil.integer ~loc pos ]
 
   let pull_param ~loc vi pos =
+    let prefix = RTL.temporal_prefix in
+    let fname = "pull_parameter" in
     let exp = Cil.mkAddrOfVi vi in
-    let fname = RTL.mk_temporal_name "pull_parameter" in
     let sz = Cil.kinteger ~loc IULong (Cil.bytesSizeOf vi.vtype) in
-    Smart_stmt.lib_call ~loc fname [ exp ; Cil.integer ~loc pos ; sz ]
+    Smart_stmt.rtl_call ~loc ~prefix fname [ exp ; Cil.integer ~loc pos ; sz ]
 
   let handle_return_referent ~save ~loc lhs =
+    let prefix = RTL.temporal_prefix in
     let fname = match save with
       | true -> "save_return"
       | false -> "pull_return"
@@ -108,15 +110,17 @@ end = struct
     (match (Cil.typeOf lhs) with
      | TPtr _ -> ()
      | _ -> Error.not_yet "Struct in return");
-    Smart_stmt.lib_call ~loc (RTL.mk_temporal_name fname) [ lhs ]
+    Smart_stmt.rtl_call ~loc ~prefix fname [ lhs ]
 
   let reset_return_referent ~loc =
-    Smart_stmt.lib_call ~loc (RTL.mk_temporal_name "reset_return") []
+    let prefix = RTL.temporal_prefix in
+    Smart_stmt.rtl_call ~loc ~prefix "reset_return" []
 
   let temporal_memcpy_struct ~loc lhs rhs =
-    let fname  = RTL.mk_temporal_name "memcpy" in
+    let prefix = RTL.temporal_prefix in
+    let fname  = "memcpy" in
     let size = Cil.sizeOf ~loc (Cil.typeOfLval lhs) in
-    Smart_stmt.lib_call ~loc fname [ Cil.mkAddrOf ~loc lhs; rhs; size ]
+    Smart_stmt.rtl_call ~loc ~prefix fname [ Cil.mkAddrOf ~loc lhs; rhs; size ]
 end
 (* }}} *)
 
@@ -301,12 +305,13 @@ end = struct
      associated with memcpy/memset call *)
   let call_memxxx current_stmt loc args fexp env kf =
     if Libc.is_memcpy fexp || Libc.is_memset fexp then
+      let prefix = RTL.temporal_prefix in
       let name = match fexp.enode with
         | Lval(Var vi, _) -> vi.vname
         | _ -> Options.fatal "[Temporal.call_memxxx] not a left-value"
       in
       let stmt =
-        Smart_stmt.lib_call ~loc (RTL.mk_temporal_name name) args
+        Smart_stmt.rtl_call ~loc ~prefix name args
       in
       Env.add_stmt ~before:current_stmt ~post:false env kf stmt
     else
@@ -320,8 +325,11 @@ end = struct
        it makes sense to make this somewhat-debug-level-call. In production mode
        the implementation of the function should be empty and compiler should
        be able to optimize that code out. *)
-    let name = (RTL.mk_temporal_name "reset_parameters") in
-    let stmt = Smart_stmt.lib_call ~loc name [] in
+    let stmt =
+      let prefix = RTL.temporal_prefix in
+      let name = "reset_parameters" in
+      Smart_stmt.rtl_call ~loc ~prefix name []
+    in
     let env = Env.add_stmt ~before:current_stmt ~post:false env kf stmt in
     let stmt = Mk.reset_return_referent ~loc in
     let env = Env.add_stmt ~before:current_stmt ~post:false env kf stmt in
diff --git a/src/plugins/e-acsl/src/code_generator/translate.ml b/src/plugins/e-acsl/src/code_generator/translate.ml
index 9ad2815d009281c1143843a02d583511f334e229..8d7be521858fa77177cee84e5e5f194ffce896e5 100644
--- a/src/plugins/e-acsl/src/code_generator/translate.ml
+++ b/src/plugins/e-acsl/src/code_generator/translate.ml
@@ -135,7 +135,11 @@ let add_cast ~loc ?name env kf ctx strnum t_opt e =
             None
             new_ty
             (fun v _ ->
-               [ Smart_stmt.lib_call ~loc ~result:(Cil.var v) fname [ e ] ])
+               [ Smart_stmt.rtl_call ~loc
+                   ~result:(Cil.var v)
+                   ~prefix:""
+                   fname
+                   [ e ] ])
         in
         e, env
       else if Gmp_types.Q.is_t ty || strnum = Str_R then
@@ -297,7 +301,7 @@ and context_insensitive_term_to_exp kf env t =
           kf
           ~name:vname
           (Some t)
-          (fun _ ev -> [ Smart_stmt.lib_call ~loc name [ ev; e ] ])
+          (fun _ ev -> [ Smart_stmt.rtl_call ~loc ~prefix:"" name [ ev; e ] ])
       in
       e, env, C_number, ""
     else if Gmp_types.Q.is_t ty then
@@ -326,7 +330,10 @@ and context_insensitive_term_to_exp kf env t =
     let e2, env = term_to_exp kf env t2 in
     if Gmp_types.Z.is_t ty then
       let name = name_of_mpz_arith_bop bop in
-      let mk_stmts _ e = [ Smart_stmt.lib_call ~loc name [ e; e1; e2 ] ] in
+      let mk_stmts _ e = [ Smart_stmt.rtl_call ~loc
+                             ~prefix:""
+                             name
+                             [ e; e1; e2 ] ] in
       let name = Misc.name_of_binop bop in
       let _, e, env =
         Env.new_var_and_mpz_init ~loc ~name env kf (Some t) mk_stmts
@@ -371,7 +378,7 @@ and context_insensitive_term_to_exp kf env t =
             p
         in
         Env.add_assert kf cond p;
-        let instr = Smart_stmt.lib_call ~loc name [ e; e1; e2 ] in
+        let instr = Smart_stmt.rtl_call ~loc ~prefix:"" name [ e; e1; e2 ] in
         [ cond; instr ]
       in
       let name = Misc.name_of_binop bop in
@@ -429,7 +436,7 @@ and context_insensitive_term_to_exp kf env t =
             (fun vi _e ->
                let result = Cil.var vi in
                let fname = "__gmpz_fits_ulong_p" in
-               [ Smart_stmt.lib_call ~loc ~result fname [ e2 ] ])
+               [ Smart_stmt.rtl_call ~loc ~result ~prefix:"" fname [ e2 ] ])
         in
         e, env
       in
@@ -459,7 +466,7 @@ and context_insensitive_term_to_exp kf env t =
         in
         let result = Cil.var vi in
         let name = "__gmpz_get_ui" in
-        let instr = Smart_stmt.lib_call ~loc ~result name [ e2 ] in
+        let instr = Smart_stmt.rtl_call ~loc ~result ~prefix:"" name [ e2 ] in
         [ coerce_guard_cond; instr ]
       in
       let name = e2_name ^ bop_name ^ "_coerced" in
@@ -478,7 +485,10 @@ and context_insensitive_term_to_exp kf env t =
       (* Create the shift instruction *)
       let mk_shift_instr result_e =
         let name = name_of_mpz_arith_bop bop in
-        Smart_stmt.lib_call ~loc name [ result_e; e1; e2_as_bitcnt_e ]
+        Smart_stmt.rtl_call ~loc
+          ~prefix:""
+          name
+          [ result_e; e1; e2_as_bitcnt_e ]
       in
 
       (* Put t in an option to use with comparison_to_exp and
@@ -537,21 +547,28 @@ and context_insensitive_term_to_exp kf env t =
     end
   | TBinOp(LOr, t1, t2) ->
     (* t1 || t2 <==> if t1 then true else t2 *)
-    let e1, env1 = term_to_exp kf (Env.rte env true) t1 in
-    let env' = Env.push env1 in
-    let res2 = term_to_exp kf (Env.push env') t2 in
     let e, env =
-      conditional_to_exp ~name:"or" loc kf (Some t) e1 (Cil.one loc, env') res2
+      Env.with_rte_and_result env true
+        ~f:(fun env ->
+            let e1, env1 = term_to_exp kf env t1 in
+            let env' = Env.push env1 in
+            let res2 = term_to_exp kf (Env.push env') t2 in
+            conditional_to_exp
+              ~name:"or" loc kf (Some t) e1 (Cil.one loc, env') res2
+          )
     in
     e, env, C_number, ""
   | TBinOp(LAnd, t1, t2) ->
     (* t1 && t2 <==> if t1 then t2 else false *)
-    let e1, env1 = term_to_exp kf (Env.rte env true) t1 in
-    let _, env2 as res2 = term_to_exp kf (Env.push env1) t2 in
-    let env3 = Env.push env2 in
     let e, env =
-      conditional_to_exp
-        ~name:"and" loc kf (Some t) e1 res2 (Cil.zero loc, env3)
+      Env.with_rte_and_result env true
+        ~f:(fun env ->
+            let e1, env1 = term_to_exp kf env t1 in
+            let _, env2 as res2 = term_to_exp kf (Env.push env1) t2 in
+            let env3 = Env.push env2 in
+            conditional_to_exp
+              ~name:"and" loc kf (Some t) e1 res2 (Cil.zero loc, env3)
+          )
     in
     e, env, C_number, ""
   | TBinOp((BOr | BXor | BAnd) as bop, t1, t2) ->
@@ -562,7 +579,7 @@ and context_insensitive_term_to_exp kf env t =
     if Gmp_types.Z.is_t ty then
       let mk_stmts _v e =
         let name = name_of_mpz_arith_bop bop in
-        let instr = Smart_stmt.lib_call ~loc name [ e; e1; e2 ] in
+        let instr = Smart_stmt.rtl_call ~loc ~prefix:"" name [ e; e1; e2 ] in
         [ instr ]
       in
       let name = Misc.name_of_binop bop in
@@ -641,7 +658,11 @@ and context_insensitive_term_to_exp kf env t =
           (Some t)
           (Misc.cty (Extlib.the li.l_type))
           (fun vi _ ->
-             [ Smart_stmt.lib_call ~loc ~result:(Cil.var vi) fname args ])
+             [ Smart_stmt.rtl_call ~loc
+                 ~result:(Cil.var vi)
+                 ~prefix:""
+                 fname
+                 args ])
       else
         (* build the arguments and compute the integer_ty of the parameters *)
         let params_ty, args, env =
@@ -671,10 +692,15 @@ and context_insensitive_term_to_exp kf env t =
   | Tlambda _ -> Env.not_yet env "functional"
   | TDataCons _ -> Env.not_yet env "constructor"
   | Tif(t1, t2, t3) ->
-    let e1, env1 = term_to_exp kf (Env.rte env true) t1 in
-    let (_, env2 as res2) = term_to_exp kf (Env.push env1) t2 in
-    let res3 = term_to_exp kf (Env.push env2) t3 in
-    let e, env = conditional_to_exp loc kf (Some t) e1 res2 res3 in
+    let e, env =
+      Env.with_rte_and_result env true
+        ~f:(fun env ->
+            let e1, env1 = term_to_exp kf env t1 in
+            let (_, env2 as res2) = term_to_exp kf (Env.push env1) t2 in
+            let res3 = term_to_exp kf (Env.push env2) t3 in
+            conditional_to_exp loc kf (Some t) e1 res2 res3
+          )
+    in
     e, env, C_number, ""
   | Tat(t, BuiltinLabel Here) ->
     let e, env = term_to_exp kf env t in
@@ -731,21 +757,23 @@ and term_to_exp kf env t =
   let generate_rte = Env.generate_rte env in
   Options.feedback ~dkey ~level:4 "translating term %a (rte? %b)"
     Printer.pp_term t generate_rte;
-  let env = Env.rte env false in
-  let t = match t.term_node with TLogic_coerce(_, t) -> t | _ -> t in
-  let e, env, sty, name = context_insensitive_term_to_exp kf env t in
-  let env = if generate_rte then translate_rte kf env e else env in
-  let cast = Typing.get_cast t in
-  let name = if name = "" then None else Some name in
-  add_cast
-    ~loc:t.term_loc
-    ?name
-    env
-    kf
-    cast
-    sty
-    (Some t)
-    e
+  Env.with_rte_and_result env false
+    ~f:(fun env ->
+        let t = match t.term_node with TLogic_coerce(_, t) -> t | _ -> t in
+        let e, env, sty, name = context_insensitive_term_to_exp kf env t in
+        let env = if generate_rte then translate_rte kf env e else env in
+        let cast = Typing.get_cast t in
+        let name = if name = "" then None else Some name in
+        add_cast
+          ~loc:t.term_loc
+          ?name
+          env
+          kf
+          cast
+          sty
+          (Some t)
+          e
+      )
 
 (* generate the C code equivalent to [t1 bop t2]. *)
 and comparison_to_exp
@@ -783,8 +811,9 @@ and comparison_to_exp
             ~name
             Cil.intType
             (fun v _ ->
-               [ Smart_stmt.lib_call ~loc
+               [ Smart_stmt.rtl_call ~loc
                    ~result:(Cil.var v)
+                   ~prefix:""
                    "__gmpz_cmp"
                    [ e1; e2 ] ])
         in
@@ -890,19 +919,25 @@ and predicate_content_to_exp ?name kf env p =
     comparison_to_exp ~loc kf env ity (relation_to_binop rel) t1 t2 None
   | Pand(p1, p2) ->
     (* p1 && p2 <==> if p1 then p2 else false *)
-    let e1, env1 = predicate_to_exp kf (Env.rte env true) p1 in
-    let _, env2 as res2 =
-      predicate_to_exp kf (Env.push env1) p2 in
-    let env3 = Env.push env2 in
-    let name = match name with None -> "and" | Some n -> n in
-    conditional_to_exp ~name loc kf None e1 res2 (Cil.zero loc, env3)
+    Env.with_rte_and_result env true
+      ~f:(fun env ->
+          let e1, env1 = predicate_to_exp kf env p1 in
+          let _, env2 as res2 =
+            predicate_to_exp kf (Env.push env1) p2 in
+          let env3 = Env.push env2 in
+          let name = match name with None -> "and" | Some n -> n in
+          conditional_to_exp ~name loc kf None e1 res2 (Cil.zero loc, env3)
+        )
   | Por(p1, p2) ->
     (* p1 || p2 <==> if p1 then true else p2 *)
-    let e1, env1 = predicate_to_exp kf (Env.rte env true) p1 in
-    let env' = Env.push env1 in
-    let res2 = predicate_to_exp kf (Env.push env') p2 in
-    let name = match name with None -> "or" | Some n -> n in
-    conditional_to_exp ~name loc kf None e1 (Cil.one loc, env') res2
+    Env.with_rte_and_result env true
+      ~f:(fun env ->
+          let e1, env1 = predicate_to_exp kf env p1 in
+          let env' = Env.push env1 in
+          let res2 = predicate_to_exp kf (Env.push env') p2 in
+          let name = match name with None -> "or" | Some n -> n in
+          conditional_to_exp ~name loc kf None e1 (Cil.one loc, env') res2
+        )
   | Pxor _ -> Env.not_yet env "xor"
   | Pimplies(p1, p2) ->
     (* (p1 ==> p2) <==> !p1 || p2 *)
@@ -924,11 +959,14 @@ and predicate_content_to_exp ?name kf env p =
     let e, env = predicate_to_exp kf env p in
     Cil.new_exp ~loc (UnOp(LNot, e, Cil.intType)), env
   | Pif(t, p2, p3) ->
-    let e1, env1 = term_to_exp kf (Env.rte env true) t in
-    let (_, env2 as res2) =
-      predicate_to_exp kf (Env.push env1) p2 in
-    let res3 = predicate_to_exp kf (Env.push env2) p3 in
-    conditional_to_exp loc kf None e1 res2 res3
+    Env.with_rte_and_result env true
+      ~f:(fun env ->
+          let e1, env1 = term_to_exp kf env t in
+          let (_, env2 as res2) =
+            predicate_to_exp kf (Env.push env1) p2 in
+          let res3 = predicate_to_exp kf (Env.push env2) p3 in
+          conditional_to_exp loc kf None e1 res2 res3
+        )
   | Plet(li, p) ->
     let lvs = Lscope.Lvs_let(li.l_var_info, Misc.term_of_li li) in
     let env = Env.Logic_scope.extend env lvs in
@@ -1035,19 +1073,21 @@ and predicate_content_to_exp ?name kf env p =
 
 and predicate_to_exp ?name kf ?rte env p =
   let rte = match rte with None -> Env.generate_rte env | Some b -> b in
-  let env = Env.rte env false in
-  let e, env = predicate_content_to_exp ?name kf env p in
-  let env = if rte then translate_rte kf env e else env in
-  let cast = Typing.get_cast_of_predicate p in
-  add_cast
-    ~loc:p.pred_loc
-    ?name
-    env
-    kf
-    cast
-    C_number
-    None
-    e
+  Env.with_rte_and_result env false
+    ~f:(fun env ->
+        let e, env = predicate_content_to_exp ?name kf env p in
+        let env = if rte then translate_rte kf env e else env in
+        let cast = Typing.get_cast_of_predicate p in
+        add_cast
+          ~loc:p.pred_loc
+          ?name
+          env
+          kf
+          cast
+          C_number
+          None
+          e
+      )
 
 and generalized_untyped_predicate_to_exp ?name kf ?rte ?must_clear_typing env p =
   (* If [rte] is true, it means we're translating the root predicate of an
@@ -1083,7 +1123,10 @@ and translate_rte_annots:
                 let p = p.tp_statement in
                 let lscope_reset_old = Env.Logic_scope.get_reset env in
                 let env = Env.Logic_scope.set_reset env false in
-                let env = translate_predicate kf (Env.rte env false) p in
+                let env =
+                  Env.with_rte env false
+                    ~f:(fun env -> translate_predicate kf env p)
+                in
                 let env = Env.Logic_scope.set_reset env lscope_reset_old in
                 env)
              env
diff --git a/src/plugins/e-acsl/src/code_generator/translate_annots.ml b/src/plugins/e-acsl/src/code_generator/translate_annots.ml
index a65ac3567b95ad3ee2fc4b871ae4bf8dd681b526..bc7ffca4cf1ce0942b2a0e9070d91a85b6269ea4 100644
--- a/src/plugins/e-acsl/src/code_generator/translate_annots.ml
+++ b/src/plugins/e-acsl/src/code_generator/translate_annots.ml
@@ -70,10 +70,12 @@ let pre_funspec kf kinstr env funspec =
   let env = convert_unsupported_clauses env in
   let loc = Kernel_function.get_location kf in
   let contract = Contract.create ~loc funspec in
-  Contract.translate_preconditions kf kinstr env contract
+  Env.with_rte env true
+    ~f:(fun env -> Contract.translate_preconditions kf kinstr env contract)
 
 let post_funspec kf kinstr env =
-  Contract.translate_postconditions kf kinstr env
+  Env.with_rte env true
+    ~f:(fun env -> Contract.translate_postconditions kf kinstr env)
 
 let pre_code_annotation kf stmt env annot =
   let convert env = match annot.annot_content with
@@ -82,7 +84,8 @@ let pre_code_annotation kf stmt env annot =
         let env = Env.set_annotation_kind env Smart_stmt.Assertion in
         if l <> [] then
           Env.not_yet env "@[assertion applied only on some behaviors@]";
-        Translate.translate_predicate kf env p.tp_statement
+        Env.with_rte env true
+          ~f:(fun env -> Translate.translate_predicate kf env p.tp_statement)
       else
         env
     | AStmtSpec(l, spec) ->
@@ -90,13 +93,18 @@ let pre_code_annotation kf stmt env annot =
         Env.not_yet env "@[statement contract applied only on some behaviors@]";
       let loc = Stmt.loc stmt in
       let contract = Contract.create ~loc spec in
-      Contract.translate_preconditions kf (Kstmt stmt) env contract
+      Env.with_rte env true
+        ~f:(fun env ->
+            Contract.translate_preconditions kf (Kstmt stmt) env contract)
     | AInvariant(l, loop_invariant, p) ->
       if must_translate (Property.ip_of_code_annot_single kf stmt annot) then
         let env = Env.set_annotation_kind env Smart_stmt.Invariant in
         if l <> [] then
           Env.not_yet env "@[invariant applied only on some behaviors@]";
-        let env = Translate.translate_predicate kf env p.tp_statement in
+        let env =
+          Env.with_rte env true
+            ~f:(fun env -> Translate.translate_predicate kf env p.tp_statement)
+        in
         if loop_invariant then
           Env.add_loop_invariant env p.tp_statement
         else env
@@ -127,7 +135,9 @@ let pre_code_annotation kf stmt env annot =
 
 let post_code_annotation kf stmt env annot =
   let convert env = match annot.annot_content with
-    | AStmtSpec(_, _) -> Contract.translate_postconditions kf (Kstmt stmt) env
+    | AStmtSpec(_, _) ->
+      Env.with_rte env true
+        ~f:(fun env -> Contract.translate_postconditions kf (Kstmt stmt) env)
     | AAssert _
     | AInvariant _
     | AVariant _
diff --git a/src/plugins/e-acsl/src/libraries/functions.ml b/src/plugins/e-acsl/src/libraries/functions.ml
index 37cf8f8319f67d966635e0704b8ed32bd6a5f91e..4a82689a9640e376c84f739cf32cf3c0b6844697 100644
--- a/src/plugins/e-acsl/src/libraries/functions.ml
+++ b/src/plugins/e-acsl/src/libraries/functions.ml
@@ -63,14 +63,14 @@ let has_fundef exp = match exp.enode with
 module RTL = struct
 
   (* prefix of all functions/variables from the public E-ACSL API *)
-  let e_acsl_api_prefix = "__e_acsl_"
+  let api_prefix = "__e_acsl_"
 
   (* prefix of temporal analysis functions of the public E-ACSL API *)
-  let e_acsl_temporal_prefix = e_acsl_api_prefix ^ "temporal_"
+  let temporal_prefix = api_prefix ^ "temporal_"
 
   (* prefix of all builtin functions/variables from the public E-ACSL API,
      Builtin functions replace original calls in programs. *)
-  let e_acsl_builtin_prefix =  e_acsl_api_prefix ^ "builtin_"
+  let e_acsl_builtin_prefix =  api_prefix ^ "builtin_"
 
   (* prefix of functions/variables generated by E-ACSL *)
   let e_acsl_gen_prefix = "__gen_e_acsl_"
@@ -78,9 +78,9 @@ module RTL = struct
   (* prefix of literal strings generated by E-ACSL *)
   let e_acsl_lit_string_prefix = e_acsl_gen_prefix ^ "literal_string"
 
-  let mk_api_name fname = e_acsl_api_prefix ^ fname
+  let mk_api_name fname = api_prefix ^ fname
 
-  let mk_temporal_name fname = e_acsl_temporal_prefix ^ fname
+  let mk_temporal_name fname = temporal_prefix ^ fname
 
   let mk_gen_name name = e_acsl_gen_prefix ^ name
 
diff --git a/src/plugins/e-acsl/src/libraries/functions.mli b/src/plugins/e-acsl/src/libraries/functions.mli
index 4963870c28539b1b89d055be1bb0285158b71366..f2d66cb65e8309f057da05db34d3338a3951c3ef 100644
--- a/src/plugins/e-acsl/src/libraries/functions.mli
+++ b/src/plugins/e-acsl/src/libraries/functions.mli
@@ -38,6 +38,12 @@ val instrument: kernel_function -> bool
 (* ************************************************************************** *)
 
 module RTL: sig
+  val api_prefix: string
+  (** Prefix used for the public API of E-ACSL runtime library. *)
+
+  val temporal_prefix:string
+  (** Prefix used for the public API of E-ACSL runtime library dealing with
+      temporal analysis. *)
 
   val mk_api_name: string -> string
   (** Prefix a name (of a variable or a function) with a string that identifies
diff --git a/src/plugins/e-acsl/tests/arith/oracle_ci/at_on-purely-logic-variables.res.oracle b/src/plugins/e-acsl/tests/arith/oracle_ci/at_on-purely-logic-variables.res.oracle
index ceb8eed7a93e5cd46801202607b737a163b9b95f..8df5dd5c3147da4920741cd471afd6512ac092fe 100644
--- a/src/plugins/e-acsl/tests/arith/oracle_ci/at_on-purely-logic-variables.res.oracle
+++ b/src/plugins/e-acsl/tests/arith/oracle_ci/at_on-purely-logic-variables.res.oracle
@@ -52,6 +52,10 @@
   function __e_acsl_assert: precondition got status unknown.
 [eva:alarm] tests/arith/at_on-purely-logic-variables.c:43: Warning: 
   assertion got status unknown.
+[eva:alarm] tests/arith/at_on-purely-logic-variables.c:7: Warning: 
+  function __e_acsl_assert: precondition got status unknown.
+[eva:alarm] tests/arith/at_on-purely-logic-variables.c:7: Warning: 
+  function __e_acsl_assert: precondition got status unknown.
 [eva:alarm] tests/arith/at_on-purely-logic-variables.c:7: Warning: 
   accessing uninitialized left-value.
   assert \initialized(__gen_e_acsl_at + (int)((int)(__gen_e_acsl_n - 1) - 1));
diff --git a/src/plugins/e-acsl/tests/arith/oracle_ci/gen_at_on-purely-logic-variables.c b/src/plugins/e-acsl/tests/arith/oracle_ci/gen_at_on-purely-logic-variables.c
index 205c4799a854078e9477b9ef4546492c0726ef6b..55c43cab27b2077a3433af728a43b978e40bc6cd 100644
--- a/src/plugins/e-acsl/tests/arith/oracle_ci/gen_at_on-purely-logic-variables.c
+++ b/src/plugins/e-acsl/tests/arith/oracle_ci/gen_at_on-purely-logic-variables.c
@@ -610,19 +610,50 @@ void __gen_e_acsl_f(int *t)
   {
     int __gen_e_acsl_m_3;
     __gen_e_acsl_m_3 = 4;
-    *(__gen_e_acsl_at_4 + 0) = *(t + (__gen_e_acsl_m_3 - 4));
+    {
+      int __gen_e_acsl_valid_read_7;
+      __gen_e_acsl_valid_read_7 = __e_acsl_valid_read((void *)(t + (int)(
+                                                               __gen_e_acsl_m_3 - 4L)),
+                                                      sizeof(int),(void *)t,
+                                                      (void *)(& t));
+      __e_acsl_assert(__gen_e_acsl_valid_read_7,"RTE","f",
+                      "mem_access: \\valid_read(t + (int)(__gen_e_acsl_m_3 - 4))",
+                      "tests/arith/at_on-purely-logic-variables.c",8);
+      *(__gen_e_acsl_at_4 + 0) = *(t + (__gen_e_acsl_m_3 - 4));
+    }
   }
   {
     int __gen_e_acsl_m_2;
     __gen_e_acsl_m_2 = 4;
-    *(__gen_e_acsl_at_3 + 0) = *(t + __gen_e_acsl_m_2) == -4;
+    {
+      int __gen_e_acsl_valid_read_5;
+      __gen_e_acsl_valid_read_5 = __e_acsl_valid_read((void *)(t + __gen_e_acsl_m_2),
+                                                      sizeof(int),(void *)t,
+                                                      (void *)(& t));
+      __e_acsl_assert(__gen_e_acsl_valid_read_5,"RTE","f",
+                      "mem_access: \\valid_read(t + __gen_e_acsl_m_2)",
+                      "tests/arith/at_on-purely-logic-variables.c",8);
+      *(__gen_e_acsl_at_3 + 0) = *(t + __gen_e_acsl_m_2) == -4;
+    }
   }
   {
     int __gen_e_acsl_n_3;
     __gen_e_acsl_n_3 = 1 + 1;
     while (1) {
       if (__gen_e_acsl_n_3 <= 3) ; else break;
-      *(__gen_e_acsl_at_2 + ((__gen_e_acsl_n_3 - 1) - 1)) = *(t + (__gen_e_acsl_n_3 - 1)) > 5;
+      {
+        int __gen_e_acsl_valid_read_3;
+        __gen_e_acsl_valid_read_3 = __e_acsl_valid_read((void *)(t + (int)(
+                                                                 __gen_e_acsl_n_3 - 1L)),
+                                                        sizeof(int),
+                                                        (void *)t,
+                                                        (void *)(& t));
+        __e_acsl_assert(__gen_e_acsl_valid_read_3,"RTE","f",
+                        "mem_access: \\valid_read(t + (int)(__gen_e_acsl_n_3 - 1))",
+                        "tests/arith/at_on-purely-logic-variables.c",7);
+        *(__gen_e_acsl_at_2 + ((__gen_e_acsl_n_3 - 1) - 1)) = *(t + (
+                                                                __gen_e_acsl_n_3 - 1)) > 5;
+      }
       __gen_e_acsl_n_3 ++;
     }
   }
@@ -631,7 +662,16 @@ void __gen_e_acsl_f(int *t)
     __gen_e_acsl_n_2 = 1 + 1;
     while (1) {
       if (__gen_e_acsl_n_2 <= 3) ; else break;
-      *(__gen_e_acsl_at + ((__gen_e_acsl_n_2 - 1) - 1)) = *(t + __gen_e_acsl_n_2) == 12;
+      {
+        int __gen_e_acsl_valid_read;
+        __gen_e_acsl_valid_read = __e_acsl_valid_read((void *)(t + __gen_e_acsl_n_2),
+                                                      sizeof(int),(void *)t,
+                                                      (void *)(& t));
+        __e_acsl_assert(__gen_e_acsl_valid_read,"RTE","f",
+                        "mem_access: \\valid_read(t + __gen_e_acsl_n_2)",
+                        "tests/arith/at_on-purely-logic-variables.c",7);
+        *(__gen_e_acsl_at + ((__gen_e_acsl_n_2 - 1) - 1)) = *(t + __gen_e_acsl_n_2) == 12;
+      }
       __gen_e_acsl_n_2 ++;
     }
   }
@@ -640,22 +680,22 @@ void __gen_e_acsl_f(int *t)
     int __gen_e_acsl_forall;
     int __gen_e_acsl_n;
     int __gen_e_acsl_m;
-    int __gen_e_acsl_valid_read_3;
+    int __gen_e_acsl_valid_read_6;
     int __gen_e_acsl_and_2;
     __gen_e_acsl_forall = 1;
     __gen_e_acsl_n = 1 + 1;
     while (1) {
       if (__gen_e_acsl_n <= 3) ; else break;
       {
-        int __gen_e_acsl_valid_read;
+        int __gen_e_acsl_valid_read_2;
         int __gen_e_acsl_and;
-        __gen_e_acsl_valid_read = __e_acsl_valid_read((void *)(__gen_e_acsl_at + (int)(
-                                                               (long)((int)(
-                                                               __gen_e_acsl_n - 1L)) - 1L)),
-                                                      sizeof(int),
-                                                      (void *)__gen_e_acsl_at,
-                                                      (void *)(& __gen_e_acsl_at));
-        __e_acsl_assert(__gen_e_acsl_valid_read,"RTE","f",
+        __gen_e_acsl_valid_read_2 = __e_acsl_valid_read((void *)(__gen_e_acsl_at + (int)(
+                                                                 (long)((int)(
+                                                                 __gen_e_acsl_n - 1L)) - 1L)),
+                                                        sizeof(int),
+                                                        (void *)__gen_e_acsl_at,
+                                                        (void *)(& __gen_e_acsl_at));
+        __e_acsl_assert(__gen_e_acsl_valid_read_2,"RTE","f",
                         "mem_access:\n  \\valid_read(__gen_e_acsl_at + (int)((int)(__gen_e_acsl_n - 1) - 1))",
                         "tests/arith/at_on-purely-logic-variables.c",7);
         /*@ assert
@@ -664,14 +704,14 @@ void __gen_e_acsl_f(int *t)
                            (int)((int)(__gen_e_acsl_n - 1) - 1));
         */
         if (*(__gen_e_acsl_at + ((__gen_e_acsl_n - 1) - 1))) {
-          int __gen_e_acsl_valid_read_2;
-          __gen_e_acsl_valid_read_2 = __e_acsl_valid_read((void *)(__gen_e_acsl_at_2 + (int)(
+          int __gen_e_acsl_valid_read_4;
+          __gen_e_acsl_valid_read_4 = __e_acsl_valid_read((void *)(__gen_e_acsl_at_2 + (int)(
                                                                    (long)((int)(
                                                                    __gen_e_acsl_n - 1L)) - 1L)),
                                                           sizeof(int),
                                                           (void *)__gen_e_acsl_at_2,
                                                           (void *)(& __gen_e_acsl_at_2));
-          __e_acsl_assert(__gen_e_acsl_valid_read_2,"RTE","f",
+          __e_acsl_assert(__gen_e_acsl_valid_read_4,"RTE","f",
                           "mem_access:\n  \\valid_read(__gen_e_acsl_at_2 + (int)((int)(__gen_e_acsl_n - 1) - 1))",
                           "tests/arith/at_on-purely-logic-variables.c",7);
           /*@ assert
@@ -695,20 +735,20 @@ void __gen_e_acsl_f(int *t)
                     "\\forall integer n;\n  1 < n <= 3 ==> \\old(*(t + n) == 12) && \\old(*(t + (n - 1)) > 5)",
                     "tests/arith/at_on-purely-logic-variables.c",6);
     __gen_e_acsl_m = 4;
-    __gen_e_acsl_valid_read_3 = __e_acsl_valid_read((void *)(__gen_e_acsl_at_3 + 0),
+    __gen_e_acsl_valid_read_6 = __e_acsl_valid_read((void *)(__gen_e_acsl_at_3 + 0),
                                                     sizeof(int),
                                                     (void *)__gen_e_acsl_at_3,
                                                     (void *)(& __gen_e_acsl_at_3));
-    __e_acsl_assert(__gen_e_acsl_valid_read_3,"RTE","f",
+    __e_acsl_assert(__gen_e_acsl_valid_read_6,"RTE","f",
                     "mem_access: \\valid_read(__gen_e_acsl_at_3 + 0)",
                     "tests/arith/at_on-purely-logic-variables.c",8);
     if (*(__gen_e_acsl_at_3 + 0)) {
-      int __gen_e_acsl_valid_read_4;
-      __gen_e_acsl_valid_read_4 = __e_acsl_valid_read((void *)(__gen_e_acsl_at_4 + 0),
+      int __gen_e_acsl_valid_read_8;
+      __gen_e_acsl_valid_read_8 = __e_acsl_valid_read((void *)(__gen_e_acsl_at_4 + 0),
                                                       sizeof(int),
                                                       (void *)__gen_e_acsl_at_4,
                                                       (void *)(& __gen_e_acsl_at_4));
-      __e_acsl_assert(__gen_e_acsl_valid_read_4,"RTE","f",
+      __e_acsl_assert(__gen_e_acsl_valid_read_8,"RTE","f",
                       "mem_access: \\valid_read(__gen_e_acsl_at_4 + 0)",
                       "tests/arith/at_on-purely-logic-variables.c",8);
       __gen_e_acsl_and_2 = *(__gen_e_acsl_at_4 + 0) == 9;
diff --git a/src/plugins/e-acsl/tests/constructs/oracle_ci/gen_rte.c b/src/plugins/e-acsl/tests/constructs/oracle_ci/gen_rte.c
new file mode 100644
index 0000000000000000000000000000000000000000..f12c75292b7cb7ccfb227dfe8b6f74734708cfa4
--- /dev/null
+++ b/src/plugins/e-acsl/tests/constructs/oracle_ci/gen_rte.c
@@ -0,0 +1,168 @@
+/* Generated by Frama-C */
+#include "stddef.h"
+#include "stdio.h"
+extern int __e_acsl_sound_verdict;
+
+/*@ requires 1 % a ≡ 1;
+    ensures 1 % \old(b) ≡ 1;
+    
+    behavior bhvr:
+      assumes 1 % c ≡ 1;
+      requires 1 % d ≡ 1;
+      requires 1 % f ≡ 1 ∨ 1 % g ≡ 1;
+      requires 1 % h ≡ 1 ∧ 1 % i ≡ 1;
+      requires \let var = 1; var % j ≡ 1;
+      requires ∀ ℤ var; 0 ≤ var < k ⇒ var % k ≡ var;
+      requires ∃ ℤ var; 0 ≤ var < l ∧ var % l ≡ var;
+      ensures 1 % \old(e) ≡ 1;
+ */
+void __gen_e_acsl_test(int a, int b, int c, int d, int e, int f, int g,
+                       int h, int i, int j, int k, int l);
+
+void test(int a, int b, int c, int d, int e, int f, int g, int h, int i,
+          int j, int k, int l)
+{
+  return;
+}
+
+int main(void)
+{
+  int __retres;
+  __gen_e_acsl_test(2,3,4,5,6,7,8,9,10,11,12,13);
+  __retres = 0;
+  return __retres;
+}
+
+/*@ requires 1 % a ≡ 1;
+    ensures 1 % \old(b) ≡ 1;
+    
+    behavior bhvr:
+      assumes 1 % c ≡ 1;
+      requires 1 % d ≡ 1;
+      requires 1 % f ≡ 1 ∨ 1 % g ≡ 1;
+      requires 1 % h ≡ 1 ∧ 1 % i ≡ 1;
+      requires \let var = 1; var % j ≡ 1;
+      requires ∀ ℤ var; 0 ≤ var < k ⇒ var % k ≡ var;
+      requires ∃ ℤ var; 0 ≤ var < l ∧ var % l ≡ var;
+      ensures 1 % \old(e) ≡ 1;
+ */
+void __gen_e_acsl_test(int a, int b, int c, int d, int e, int f, int g,
+                       int h, int i, int j, int k, int l)
+{
+  int __gen_e_acsl_at_2;
+  int __gen_e_acsl_at;
+  __e_acsl_contract_t *__gen_e_acsl_contract;
+  {
+    int __gen_e_acsl_assumes_value;
+    __gen_e_acsl_contract = __e_acsl_contract_init((size_t)1);
+    __e_acsl_assert(c != 0,"RTE","test","division_by_zero: c != 0",
+                    "tests/constructs/rte.i",11);
+    __e_acsl_contract_set_behavior_assumes(__gen_e_acsl_contract,(size_t)0,
+                                           1 % c == 1);
+    __e_acsl_assert(a != 0,"RTE","test","division_by_zero: a != 0",
+                    "tests/constructs/rte.i",7);
+    __e_acsl_assert(1 % a == 1,"Precondition","test","1 % a == 1",
+                    "tests/constructs/rte.i",7);
+    __gen_e_acsl_assumes_value = __e_acsl_contract_get_behavior_assumes
+    ((__e_acsl_contract_t const *)__gen_e_acsl_contract,(size_t)0);
+    if (__gen_e_acsl_assumes_value) {
+      int __gen_e_acsl_or;
+      int __gen_e_acsl_and;
+      int __gen_e_acsl_var;
+      int __gen_e_acsl_forall;
+      int __gen_e_acsl_var_2;
+      int __gen_e_acsl_exists;
+      int __gen_e_acsl_var_3;
+      __e_acsl_assert(d != 0,"RTE","test","division_by_zero: d != 0",
+                      "tests/constructs/rte.i",12);
+      __e_acsl_assert(f != 0,"RTE","test","division_by_zero: f != 0",
+                      "tests/constructs/rte.i",13);
+      if (1 % f == 1) __gen_e_acsl_or = 1;
+      else {
+        __e_acsl_assert(g != 0,"RTE","test","division_by_zero: g != 0",
+                        "tests/constructs/rte.i",13);
+        __gen_e_acsl_or = 1 % g == 1;
+      }
+      __e_acsl_assert(h != 0,"RTE","test","division_by_zero: h != 0",
+                      "tests/constructs/rte.i",14);
+      if (1 % h == 1) {
+        __e_acsl_assert(i != 0,"RTE","test","division_by_zero: i != 0",
+                        "tests/constructs/rte.i",14);
+        __gen_e_acsl_and = 1 % i == 1;
+      }
+      else __gen_e_acsl_and = 0;
+      __gen_e_acsl_var = 1;
+      __e_acsl_assert(j != 0,"RTE","test","division_by_zero: j != 0",
+                      "tests/constructs/rte.i",15);
+      __gen_e_acsl_forall = 1;
+      __gen_e_acsl_var_2 = 0;
+      while (1) {
+        if (__gen_e_acsl_var_2 < k) ; else break;
+        __e_acsl_assert(k != 0,"RTE","test","division_by_zero: k != 0",
+                        "tests/constructs/rte.i",16);
+        if (__gen_e_acsl_var_2 % k == __gen_e_acsl_var_2) ;
+        else {
+          __gen_e_acsl_forall = 0;
+          goto e_acsl_end_loop1;
+        }
+        __gen_e_acsl_var_2 ++;
+      }
+      e_acsl_end_loop1: ;
+      __gen_e_acsl_exists = 0;
+      __gen_e_acsl_var_3 = 0;
+      while (1) {
+        if (__gen_e_acsl_var_3 < l) ; else break;
+        __e_acsl_assert(l != 0,"RTE","test","division_by_zero: l != 0",
+                        "tests/constructs/rte.i",17);
+        if (! (__gen_e_acsl_var_3 % l == __gen_e_acsl_var_3)) ;
+        else {
+          __gen_e_acsl_exists = 1;
+          goto e_acsl_end_loop2;
+        }
+        __gen_e_acsl_var_3 ++;
+      }
+      e_acsl_end_loop2: ;
+      __e_acsl_assert(__gen_e_acsl_exists,"Precondition","test",
+                      "bhvr: \\exists integer var; 0 <= var < l && var % l == var",
+                      "tests/constructs/rte.i",17);
+      __e_acsl_assert(__gen_e_acsl_forall,"Precondition","test",
+                      "bhvr: \\forall integer var; 0 <= var < k ==> var % k == var",
+                      "tests/constructs/rte.i",16);
+      __e_acsl_assert(__gen_e_acsl_var % j == 1,"Precondition","test",
+                      "bhvr: \\let var = 1; var % j == 1",
+                      "tests/constructs/rte.i",15);
+      __e_acsl_assert(__gen_e_acsl_and,"Precondition","test",
+                      "bhvr: 1 % h == 1 && 1 % i == 1",
+                      "tests/constructs/rte.i",14);
+      __e_acsl_assert(__gen_e_acsl_or,"Precondition","test",
+                      "bhvr: 1 % f == 1 || 1 % g == 1",
+                      "tests/constructs/rte.i",13);
+      __e_acsl_assert(1 % d == 1,"Precondition","test","bhvr: 1 % d == 1",
+                      "tests/constructs/rte.i",12);
+    }
+  }
+  __gen_e_acsl_at_2 = e;
+  __gen_e_acsl_at = b;
+  test(a,b,c,d,e,f,g,h,i,j,k,l);
+  {
+    int __gen_e_acsl_assumes_value_2;
+    __e_acsl_assert(__gen_e_acsl_at != 0,"RTE","test",
+                    "division_by_zero: __gen_e_acsl_at != 0",
+                    "tests/constructs/rte.i",8);
+    __e_acsl_assert(1 % __gen_e_acsl_at == 1,"Postcondition","test",
+                    "1 % \\old(b) == 1","tests/constructs/rte.i",8);
+    __gen_e_acsl_assumes_value_2 = __e_acsl_contract_get_behavior_assumes
+    ((__e_acsl_contract_t const *)__gen_e_acsl_contract,(size_t)0);
+    if (__gen_e_acsl_assumes_value_2) {
+      __e_acsl_assert(__gen_e_acsl_at_2 != 0,"RTE","test",
+                      "division_by_zero: __gen_e_acsl_at_2 != 0",
+                      "tests/constructs/rte.i",18);
+      __e_acsl_assert(1 % __gen_e_acsl_at_2 == 1,"Postcondition","test",
+                      "bhvr: 1 % \\old(e) == 1","tests/constructs/rte.i",18);
+    }
+    __e_acsl_contract_clean(__gen_e_acsl_contract);
+    return;
+  }
+}
+
+
diff --git a/src/plugins/e-acsl/tests/constructs/oracle_ci/rte.res.oracle b/src/plugins/e-acsl/tests/constructs/oracle_ci/rte.res.oracle
new file mode 100644
index 0000000000000000000000000000000000000000..59a91431c62c3df5798cb861bd233db93ff56dd4
--- /dev/null
+++ b/src/plugins/e-acsl/tests/constructs/oracle_ci/rte.res.oracle
@@ -0,0 +1,13 @@
+[e-acsl] beginning translation.
+[e-acsl] translation done in project "e-acsl".
+[eva:alarm] tests/constructs/rte.i:24: Warning: 
+  function __gen_e_acsl_test, behavior bhvr: precondition \let var = 1;
+                                                            var % j ≡ 1 got status unknown.
+[eva:alarm] tests/constructs/rte.i:24: Warning: 
+  function __gen_e_acsl_test, behavior bhvr: precondition ∀ ℤ var;
+                                                            0 ≤ var < k ⇒
+                                                            var % k ≡ var got status unknown.
+[eva:alarm] tests/constructs/rte.i:24: Warning: 
+  function __gen_e_acsl_test, behavior bhvr: precondition ∃ ℤ var;
+                                                            0 ≤ var < l ∧
+                                                            var % l ≡ var got status unknown.
diff --git a/src/plugins/e-acsl/tests/constructs/oracle_dev/rte.e-acsl.err.log b/src/plugins/e-acsl/tests/constructs/oracle_dev/rte.e-acsl.err.log
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/src/plugins/e-acsl/tests/constructs/rte.i b/src/plugins/e-acsl/tests/constructs/rte.i
new file mode 100644
index 0000000000000000000000000000000000000000..f80f978c8f7e5b359989b0639da72935e11e9c07
--- /dev/null
+++ b/src/plugins/e-acsl/tests/constructs/rte.i
@@ -0,0 +1,26 @@
+/* run.config_ci, run.config_dev
+ * COMMENT: Check that the RTE checks are generated for every part of a
+ * behavior, and are generated at the right place.
+ */
+
+/*@
+  requires 1 % a == 1;
+  ensures 1 % b == 1;
+
+  behavior bhvr:
+    assumes 1 % c == 1;
+    requires 1 % d == 1;
+    requires (1 % f == 1) || (1 % g == 1);
+    requires (1 % h == 1) && (1 % i == 1);
+    requires \let var = 1; var % j == 1;
+    requires \forall integer var; 0 <= var < k ==> var % k == var;
+    requires \exists integer var; 0 <= var < l && var % l == var;
+    ensures 1 % e == 1;
+*/
+void test(int a, int b, int c, int d, int e, int f, int g, int h, int i, int j, int k, int l) {
+}
+
+int main(void) {
+  test(2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13);
+  return 0;
+}
diff --git a/src/plugins/e-acsl/tests/special/oracle_ci/gen_e-acsl-functions.c b/src/plugins/e-acsl/tests/special/oracle_ci/gen_e-acsl-functions.c
index f317d0df3bcefc001519a56a8c2a001604f0a30e..eb68292992dbc87694f7f832d25339504f5db263 100644
--- a/src/plugins/e-acsl/tests/special/oracle_ci/gen_e-acsl-functions.c
+++ b/src/plugins/e-acsl/tests/special/oracle_ci/gen_e-acsl-functions.c
@@ -77,18 +77,24 @@ int __gen_e_acsl_f(int *p)
   int __retres;
   {
     int __gen_e_acsl_initialized;
+    int __gen_e_acsl_valid_read;
     __e_acsl_store_block((void *)(& p),(size_t)8);
     __gen_e_acsl_initialized = __e_acsl_initialized((void *)p,sizeof(int));
     __e_acsl_assert(__gen_e_acsl_initialized,"Precondition","f",
                     "\\initialized(p)","tests/special/e-acsl-functions.c",7);
+    __gen_e_acsl_valid_read = __e_acsl_valid_read((void *)p,sizeof(int),
+                                                  (void *)p,(void *)(& p));
+    __e_acsl_assert(__gen_e_acsl_valid_read,"RTE","f",
+                    "mem_access: \\valid_read(p)",
+                    "tests/special/e-acsl-functions.c",8);
     __e_acsl_assert(*p == 0,"Precondition","f","*p == 0",
                     "tests/special/e-acsl-functions.c",8);
   }
   {
-    int __gen_e_acsl_valid_read;
-    __gen_e_acsl_valid_read = __e_acsl_valid_read((void *)p,sizeof(int),
-                                                  (void *)p,(void *)(& p));
-    __e_acsl_assert(__gen_e_acsl_valid_read,"RTE","f",
+    int __gen_e_acsl_valid_read_2;
+    __gen_e_acsl_valid_read_2 = __e_acsl_valid_read((void *)p,sizeof(int),
+                                                    (void *)p,(void *)(& p));
+    __e_acsl_assert(__gen_e_acsl_valid_read_2,"RTE","f",
                     "mem_access: \\valid_read(p)",
                     "tests/special/e-acsl-functions.c",9);
     __gen_e_acsl_at = *p;
diff --git a/src/plugins/e-acsl/tests/special/oracle_ci/gen_e-acsl-valid.c b/src/plugins/e-acsl/tests/special/oracle_ci/gen_e-acsl-valid.c
index 890e84bc928baf7442348bff76b96f4437330ebc..e611ff7fd1b7dfe6a16264968bca289f03bafaeb 100644
--- a/src/plugins/e-acsl/tests/special/oracle_ci/gen_e-acsl-valid.c
+++ b/src/plugins/e-acsl/tests/special/oracle_ci/gen_e-acsl-valid.c
@@ -106,19 +106,37 @@ void __gen_e_acsl_f(int *x, int *y)
   int *__gen_e_acsl_at;
   __e_acsl_contract_t *__gen_e_acsl_contract;
   {
+    int __gen_e_acsl_valid_read;
+    int __gen_e_acsl_valid_read_2;
     int __gen_e_acsl_valid;
+    int __gen_e_acsl_valid_read_3;
     int __gen_e_acsl_active_bhvrs;
     __e_acsl_store_block((void *)(& y),(size_t)8);
     __e_acsl_store_block((void *)(& x),(size_t)8);
     __gen_e_acsl_contract = __e_acsl_contract_init((size_t)2);
+    __gen_e_acsl_valid_read = __e_acsl_valid_read((void *)x,sizeof(int),
+                                                  (void *)x,(void *)(& x));
+    __e_acsl_assert(__gen_e_acsl_valid_read,"RTE","f",
+                    "mem_access: \\valid_read(x)",
+                    "tests/special/e-acsl-valid.c",15);
     __e_acsl_contract_set_behavior_assumes(__gen_e_acsl_contract,(size_t)0,
                                            *x == 1);
+    __gen_e_acsl_valid_read_2 = __e_acsl_valid_read((void *)x,sizeof(int),
+                                                    (void *)x,(void *)(& x));
+    __e_acsl_assert(__gen_e_acsl_valid_read_2,"RTE","f",
+                    "mem_access: \\valid_read(x)",
+                    "tests/special/e-acsl-valid.c",19);
     __e_acsl_contract_set_behavior_assumes(__gen_e_acsl_contract,(size_t)1,
                                            *x == 0);
     __gen_e_acsl_valid = __e_acsl_valid((void *)y,sizeof(int),(void *)y,
                                         (void *)(& y));
     __e_acsl_assert(__gen_e_acsl_valid,"Precondition","f","\\valid(y)",
                     "tests/special/e-acsl-valid.c",10);
+    __gen_e_acsl_valid_read_3 = __e_acsl_valid_read((void *)x,sizeof(int),
+                                                    (void *)x,(void *)(& x));
+    __e_acsl_assert(__gen_e_acsl_valid_read_3,"RTE","f",
+                    "mem_access: \\valid_read(x)",
+                    "tests/special/e-acsl-valid.c",11);
     __e_acsl_assert(*x >= 0,"Precondition","f","*x >= 0",
                     "tests/special/e-acsl-valid.c",11);
     __gen_e_acsl_active_bhvrs = __e_acsl_contract_partial_count_all_behaviors
@@ -135,10 +153,10 @@ void __gen_e_acsl_f(int *x, int *y)
   __gen_e_acsl_at_4 = x;
   __gen_e_acsl_at_3 = x;
   {
-    int __gen_e_acsl_valid_read;
-    __gen_e_acsl_valid_read = __e_acsl_valid_read((void *)x,sizeof(int),
-                                                  (void *)x,(void *)(& x));
-    __e_acsl_assert(__gen_e_acsl_valid_read,"RTE","f",
+    int __gen_e_acsl_valid_read_4;
+    __gen_e_acsl_valid_read_4 = __e_acsl_valid_read((void *)x,sizeof(int),
+                                                    (void *)x,(void *)(& x));
+    __e_acsl_assert(__gen_e_acsl_valid_read_4,"RTE","f",
                     "mem_access: \\valid_read(x)",
                     "tests/special/e-acsl-valid.c",12);
     __gen_e_acsl_at_2 = (long)*x;
@@ -146,13 +164,13 @@ void __gen_e_acsl_f(int *x, int *y)
   __gen_e_acsl_at = x;
   f(x,y);
   {
-    int __gen_e_acsl_valid_read_2;
+    int __gen_e_acsl_valid_read_5;
     int __gen_e_acsl_assumes_value;
-    __gen_e_acsl_valid_read_2 = __e_acsl_valid_read((void *)__gen_e_acsl_at,
+    __gen_e_acsl_valid_read_5 = __e_acsl_valid_read((void *)__gen_e_acsl_at,
                                                     sizeof(int),
                                                     (void *)__gen_e_acsl_at,
                                                     (void *)(& __gen_e_acsl_at));
-    __e_acsl_assert(__gen_e_acsl_valid_read_2,"RTE","f",
+    __e_acsl_assert(__gen_e_acsl_valid_read_5,"RTE","f",
                     "mem_access: \\valid_read(__gen_e_acsl_at)",
                     "tests/special/e-acsl-valid.c",12);
     __e_acsl_assert((long)*__gen_e_acsl_at == __gen_e_acsl_at_2 + 1L,
@@ -161,12 +179,12 @@ void __gen_e_acsl_f(int *x, int *y)
     __gen_e_acsl_assumes_value = __e_acsl_contract_get_behavior_assumes
     ((__e_acsl_contract_t const *)__gen_e_acsl_contract,(size_t)0);
     if (__gen_e_acsl_assumes_value) {
-      int __gen_e_acsl_valid_read_3;
-      __gen_e_acsl_valid_read_3 = __e_acsl_valid_read((void *)__gen_e_acsl_at_3,
+      int __gen_e_acsl_valid_read_6;
+      __gen_e_acsl_valid_read_6 = __e_acsl_valid_read((void *)__gen_e_acsl_at_3,
                                                       sizeof(int),
                                                       (void *)__gen_e_acsl_at_3,
                                                       (void *)(& __gen_e_acsl_at_3));
-      __e_acsl_assert(__gen_e_acsl_valid_read_3,"RTE","f",
+      __e_acsl_assert(__gen_e_acsl_valid_read_6,"RTE","f",
                       "mem_access: \\valid_read(__gen_e_acsl_at_3)",
                       "tests/special/e-acsl-valid.c",17);
       __e_acsl_assert(*__gen_e_acsl_at_3 < 0,"Postcondition","f",
@@ -175,12 +193,12 @@ void __gen_e_acsl_f(int *x, int *y)
     __gen_e_acsl_assumes_value = __e_acsl_contract_get_behavior_assumes
     ((__e_acsl_contract_t const *)__gen_e_acsl_contract,(size_t)1);
     if (__gen_e_acsl_assumes_value) {
-      int __gen_e_acsl_valid_read_4;
-      __gen_e_acsl_valid_read_4 = __e_acsl_valid_read((void *)__gen_e_acsl_at_4,
+      int __gen_e_acsl_valid_read_7;
+      __gen_e_acsl_valid_read_7 = __e_acsl_valid_read((void *)__gen_e_acsl_at_4,
                                                       sizeof(int),
                                                       (void *)__gen_e_acsl_at_4,
                                                       (void *)(& __gen_e_acsl_at_4));
-      __e_acsl_assert(__gen_e_acsl_valid_read_4,"RTE","f",
+      __e_acsl_assert(__gen_e_acsl_valid_read_7,"RTE","f",
                       "mem_access: \\valid_read(__gen_e_acsl_at_4)",
                       "tests/special/e-acsl-valid.c",20);
       __e_acsl_assert(*__gen_e_acsl_at_4 == 1,"Postcondition","f",
diff --git a/src/plugins/markdown-report/.gitignore b/src/plugins/markdown-report/.gitignore
index 6c2faaa71d31861e38605eb6bebc51dec9a0e3da..08329726023435c95a4fdd89252eb0c3a5b27651 100644
--- a/src/plugins/markdown-report/.gitignore
+++ b/src/plugins/markdown-report/.gitignore
@@ -1,5 +1,4 @@
 *.cm*
-META.*
 *.o
 top/
 *.check_mli_exists
diff --git a/src/plugins/markdown-report/META.in b/src/plugins/markdown-report/META.in
new file mode 100644
index 0000000000000000000000000000000000000000..28043759d7571d4c856d12af47d511f662f0a1ef
--- /dev/null
+++ b/src/plugins/markdown-report/META.in
@@ -0,0 +1,12 @@
+description = "Frama-C Markdown_report plug-in"
+version = "@VERSION@"
+requires = "frama-c.kernel ppx_deriving ppx_deriving_yojson yojson"
+archive(byte) = "top/Markdown_report.cmo"
+archive(native) = "top/Markdown_report.cmx"
+plugin(native) = "top/Markdown_report.cmxs"
+plugin(byte) = "top/Markdown_report.cmo"
+package "eva_info" (
+  requires = "frama-c-markdown_report frama-c-eva"
+  plugin(native) = "top/eva_info.cmxs"
+  plugin(byte) = "top/eva_info.cmo"
+)
diff --git a/src/plugins/markdown-report/Makefile.in b/src/plugins/markdown-report/Makefile.in
index 1adec8aa487ab7e020bccff40c7594fa694ffed3..08dec2b3520bd3c3cc80e203121373bce8dce2e5 100644
--- a/src/plugins/markdown-report/Makefile.in
+++ b/src/plugins/markdown-report/Makefile.in
@@ -32,17 +32,38 @@ endif
 PLUGIN_DIR ?=.
 PLUGIN_ENABLE:=@ENABLE_MDR@
 PLUGIN_NAME:=Markdown_report
+PLUGIN_HAS_META:=yes
 PLUGIN_GENERATED:=$(PLUGIN_DIR)/Markdown_report.mli
 PLUGIN_CMO:=\
-  sarif mdr_params parse_remarks \
-  eva_coverage md_gen sarif_gen mdr_register
+  sarif mdr_params parse_remarks md_gen sarif_gen mdr_register
 PLUGIN_DISTRIBUTED:=$(PLUGIN_ENABLE)
 PLUGIN_REQUIRES:=ppx_deriving ppx_deriving_yojson yojson
-PLUGIN_DISTRIB_EXTERNAL:= Makefile.in configure.ac configure share/acsl.xml
+PLUGIN_DISTRIB_EXTERNAL:=\
+ Makefile.in configure.ac configure share/acsl.xml META.in \
+ eva_info.ml eva_info.mli
+PLUGIN_DEPFLAGS:= $(PLUGIN_DIR)/eva_info.mli $(PLUGIN_DIR)/eva_info.ml
 PLUGIN_TESTS_DIRS:= md sarif
 
 include $(FRAMAC_SHARE)/Makefile.dynamic
 
+ifneq (@ENABLE_MDR@,no)
+ifneq ($(ENABLE_EVA), no)
+byte:: $(PLUGIN_LIB_DIR)/top/eva_info.cmo $(PLUGIN_LIB_DIR)/top/eva_info.cmi
+opt:: $(PLUGIN_LIB_DIR)/top/eva_info.cmxs $(PLUGIN_LIB_DIR)/top/eva_info.cmi
+install::
+	$(MKDIR) $(PLUGIN_INSTALL_DIR)/top
+	$(CP) $(PLUGIN_LIB_DIR)/top/eva_info.cm* $(PLUGIN_INSTALL_DIR)/top
+
+$(PLUGIN_LIB_DIR)/top/eva_info.cm%: $(Markdown_report_DIR)/eva_info.cm%
+	$(MKDIR) $(dir $@)
+	$(CP) $< $@
+
+$(Markdown_report_DIR)/eva_info.cmo: BFLAGS+=-I $(Markdown_report_DIR)
+$(Markdown_report_DIR)/eva_info.cmx: OFLAGS+=-I $(Markdown_report_DIR)
+
+endif
+endif
+
 $(Markdown_report_DIR)/Markdown_report.mli: \
   $(Markdown_report_DIR)/mdr_params.mli \
   $(Markdown_report_DIR)/md_gen.mli \
@@ -54,6 +75,14 @@ $(Markdown_report_DIR)/Markdown_report.mli: \
 	cat $(Markdown_report_DIR)/md_gen.mli >> $@
 	echo "end" >> $@
 
+VERSION:=$(shell $(CAT) $(FRAMAC_SRC)/VERSION)
+
+$(Markdown_report_DIR)/META: $(Markdown_report_DIR)/META.in $(FRAMAC_SRC)/VERSION
+	$(PRINT_MAKING) $@
+	$(RM) $@
+	$(SED) -e 's|@VERSION@|$(VERSION)|' $< > $@
+	$(CHMOD_RO) $@
+
 ifeq ("$(FRAMAC_INTERNAL)","yes")
 CONFIG_STATUS_DIR=$(FRAMAC_SRC)
 else
diff --git a/src/plugins/markdown-report/configure.ac b/src/plugins/markdown-report/configure.ac
index f9fb685d2009e4f62e42b4843106c3feab70c1df..b187dc61bc24ba6f6b6bad4032bce49f0632ea4c 100644
--- a/src/plugins/markdown-report/configure.ac
+++ b/src/plugins/markdown-report/configure.ac
@@ -35,6 +35,8 @@ m4_ifndef([FRAMAC_M4_MACROS],
 
 check_plugin(mdr,PLUGIN_RELATIVE_PATH(plugin_file),[Markdown/SARIF report plug-in],yes)
 
+plugin_use(mdr,eva)
+
 plugin_require_pkg(mdr,ppx_deriving)
 plugin_require_pkg(mdr,ppx_deriving_yojson)
 
diff --git a/src/plugins/markdown-report/eva_coverage.ml b/src/plugins/markdown-report/eva_info.ml
similarity index 92%
rename from src/plugins/markdown-report/eva_coverage.ml
rename to src/plugins/markdown-report/eva_info.ml
index 1308a8b29b8077af7ebb9ea5b4fd685e2b3e5f36..39d95c27e2909af6afb0269a8242a16c972b215c 100644
--- a/src/plugins/markdown-report/eva_coverage.ml
+++ b/src/plugins/markdown-report/eva_info.ml
@@ -68,7 +68,7 @@ let is_analyzed_function vi =
                    vi)
               (Globals.FileIndex.get_functions
                  (Filepath.Normalized.of_string s)))
-         (Mdr_params.Stubs.get())) &&
+         (Markdown_report.Mdr_params.Stubs.get())) &&
   not (List.mem vi.vname
          (String.split_on_char ','
             (Dynamic.Parameter.String.get "-eva-use-spec" ()))) &&
@@ -184,7 +184,9 @@ let nb_fundefs () =
           is_analyzed_function (Kernel_function.get_vi kf)
        then nb + 1 else nb) 0
 
-let md_gen () =
+open Markdown
+
+let coverage_md_gen () =
   let main = Kernel.MainFunction.get () in
   !Db.Value.compute ();
   let vis = new eva_coverage_vis ~from_entry_point:false in
@@ -192,7 +194,7 @@ let md_gen () =
   let summary_whole =
     Markdown.format
       "There are %d function definitions that are not stubbed. They represent \
-       %d statements, of which %d are potentially reachable through EVA, \
+       %d statements, of which %d are potentially reachable through Eva, \
        resulting in a **statement coverage of %.1f%%** with respect to the \
        entire application."
       (nb_fundefs())
@@ -220,11 +222,22 @@ let md_gen () =
     summary @
     Markdown.format
       "These functions contain %d statements, \
-       of which %d are potentially reachable according to EVA, resulting in \
+       of which %d are potentially reachable according to Eva, resulting in \
        a **statement coverage of %.1f%%** with respect to the perimeter set \
        by this entry point."
       stats.total_stmts stats.covered_stmts
       (float_of_int stats.covered_stmts *. 100. /.
        float_of_int stats.total_stmts)
   in
-  Markdown.([ Block [Text summary_whole]; Block [Text summary ]])
+  [ Block [Text summary_whole]; Block [Text summary ]]
+
+let domains_md_gen () =
+  let eva_domains = Eva.Value_parameters.enabled_domains () in
+  let domains = List.filter (fun (name, _) -> name <> "cvalue") eva_domains in
+  let aux (name, descr) = (plain "domain" @ bold name), plain descr in
+  List.map aux domains
+
+let () =
+  Markdown_report.Md_gen.Eva_info.coverage_md_gen := coverage_md_gen;
+  Markdown_report.Md_gen.Eva_info.domains_md_gen := domains_md_gen;
+  Markdown_report.Md_gen.Eva_info.loaded := true
diff --git a/src/plugins/markdown-report/eva_coverage.mli b/src/plugins/markdown-report/eva_info.mli
similarity index 92%
rename from src/plugins/markdown-report/eva_coverage.mli
rename to src/plugins/markdown-report/eva_info.mli
index 68e7b5fb773d1772310d3059178b9d8325e0b481..7ba39b81ae472b3543306e442b123eefc3ee6340 100644
--- a/src/plugins/markdown-report/eva_coverage.mli
+++ b/src/plugins/markdown-report/eva_info.mli
@@ -20,5 +20,5 @@
 (*                                                                        *)
 (**************************************************************************)
 
-(** generates a coverage summary of EVA's run*)
-val md_gen: unit -> Markdown.element list
+(** Only loaded when Eva is loaded. Nothing is exported, rather the module
+    does fill the functions of {!Md_gen.Eva_info}. *)
diff --git a/src/plugins/markdown-report/md_gen.ml b/src/plugins/markdown-report/md_gen.ml
index d751577ab1e2d2fd6e3d761ca26ce6a3b1a5cfd7..2930c0065138c7bf4ddedd0517ba8ccc6cd92849 100644
--- a/src/plugins/markdown-report/md_gen.ml
+++ b/src/plugins/markdown-report/md_gen.ml
@@ -23,6 +23,13 @@
 open Cil_types
 open Markdown
 
+module Eva_info = struct
+  let loaded = ref false
+  let coverage_md_gen: (unit -> elements) ref = Extlib.mk_fun "coverage_md_gen"
+  let domains_md_gen: (unit -> (text * text) list) ref=
+    Extlib.mk_fun "domains_md_gen"
+end
+
 type env =
   { is_draft: bool;
     remarks: Markdown.element list Datatype.String.Map.t; }
@@ -49,21 +56,15 @@ let plural l s =
   | [] | [ _ ] -> s
   | _::_::_ -> s ^ "s"
 
-let get_eva_domains () =
-  let eva_domains = Eva.Value_parameters.enabled_domains () in
-  let domains = List.filter (fun (name, _) -> name <> "cvalue") eva_domains in
-  let aux (name, descr) = (plain "domain" @ bold name), plain descr in
-  List.map aux domains
-
 let section_domains env =
   let anchor = "domains" in
-  let head = H3 (plain "EVA Domains", Some anchor) in
+  let head = H3 (plain "Eva Domains", Some anchor) in
   if env.is_draft then
     head
-    :: Comment "You can give more information about the choice of EVA domains"
+    :: Comment "You can give more information about the choice of Eva domains"
     :: insert_marks env anchor
   else begin
-    let l = get_eva_domains () in
+    let l = !Eva_info.domains_md_gen () in
     head
     :: Block
       (match l with
@@ -76,7 +77,7 @@ let section_domains env =
          [Text
             (plain
                "In addition to the base domain (`cvalue`), additional \
-                domains have been used by EVA");
+                domains have been used by Eva");
           DL l]
       )
     :: insert_remark env anchor
@@ -258,7 +259,7 @@ let gen_context env =
   H1 (plain "Context of the analysis", Some "context")
   :: gen_inputs env
   @ gen_config env
-  @ section_domains env
+  @ (if !Eva_info.loaded then section_domains env else [])
   @ H3 (plain "Stubbed Functions", Some "stubs")
     :: (
       if env.is_draft then
@@ -271,11 +272,11 @@ let gen_context env =
 let gen_coverage env =
   let anchor = "coverage" in
   let header = H1 (plain "Coverage", Some anchor) in
-  let content = Eva_coverage.md_gen () in
+  let content = !Eva_info.coverage_md_gen () in
   let content =
     if env.is_draft then
       content @
-      Comment "You can comment on the coverage obtained by EVA"
+      Comment "You can comment on the coverage obtained by Eva"
       :: insert_marks env anchor
     else
       content @ insert_remark env anchor
@@ -568,7 +569,7 @@ let gen_report ~draft:is_draft () =
   let remarks = mk_remarks is_draft in
   let env = { remarks; is_draft } in
   let context = gen_context env in
-  let coverage = gen_coverage env in
+  let coverage = if !Eva_info.loaded then gen_coverage env else [] in
   let alarms = gen_alarms env in
   let title = Mdr_params.Title.get () in
   let title =
diff --git a/src/plugins/markdown-report/md_gen.mli b/src/plugins/markdown-report/md_gen.mli
index 0a7374f90f792a6338878fe0d96fefd24d81ad81..3083a44b11acce51fddddb0ad1f9b15969d63aff 100644
--- a/src/plugins/markdown-report/md_gen.mli
+++ b/src/plugins/markdown-report/md_gen.mli
@@ -22,3 +22,10 @@
 
 (** generates the report (either final or [draft] according to the flag) *)
 val gen_report: draft:bool -> unit -> unit
+
+(** Filled when Eva is loaded. *)
+module Eva_info: sig
+  val loaded: bool ref
+  val coverage_md_gen: (unit -> Markdown.elements) ref
+  val domains_md_gen: (unit -> (Markdown.text * Markdown.text) list) ref
+end
diff --git a/src/plugins/markdown-report/mdr_register.ml b/src/plugins/markdown-report/mdr_register.ml
index 09080fadc158d0ca0aa3b28ee3cf5298753a5320..800c08408b1aca2b6d2aa93daaffca19532486a6 100644
--- a/src/plugins/markdown-report/mdr_register.ml
+++ b/src/plugins/markdown-report/mdr_register.ml
@@ -20,6 +20,15 @@
 (*                                                                        *)
 (**************************************************************************)
 
+let load_eva_info () =
+  if not !Md_gen.Eva_info.loaded && Dynamic.is_loaded "frama-c-eva"
+  then begin
+    let eva_info = "frama-c-markdown_report.eva_info" in
+    Dynamic.load_packages [eva_info];
+  end
+
+(*  end *)
+
 let main () =
   match Mdr_params.Generate.get () with
   | "none" -> ()
@@ -30,4 +39,6 @@ let main () =
     Mdr_params.fatal "Unexpected value for option %s: %s"
       Mdr_params.Generate.option_name s
 
-let () = Db.Main.extend main
+let () =
+  Cmdline.run_after_extended_stage load_eva_info;
+  Db.Main.extend main
diff --git a/src/plugins/markdown-report/tests/md/oracle/cwe126.0.md b/src/plugins/markdown-report/tests/md/oracle/cwe126.0.md
index 22a6d1e702051cc185f1bce1fb29ba87263f302d..4fddd3e2ba0c3414e25c1cedddfbcd8fd54241d1 100644
--- a/src/plugins/markdown-report/tests/md/oracle/cwe126.0.md
+++ b/src/plugins/markdown-report/tests/md/oracle/cwe126.0.md
@@ -26,7 +26,7 @@ that have been considered during the analysis are the following:
 
 ## Configuration {#options}
 
-### EVA Domains {#domains}
+### Eva Domains {#domains}
 
 Only the base domain (`cvalue`) has been used for the analysis
 
@@ -38,11 +38,11 @@ No stubs have been used for this analysis
 
 # Coverage {#coverage}
 
-There are 6 function definitions that are not stubbed. They represent 50 statements, of which 50 are potentially reachable through EVA, resulting in a **statement coverage of 100.0%** with respect to the entire application.
+There are 6 function definitions that are not stubbed. They represent 50 statements, of which 50 are potentially reachable through Eva, resulting in a **statement coverage of 100.0%** with respect to the entire application.
 
 
 There were potentially 6 functions syntactically reachable from main.
-These functions contain 50 statements, of which 50 are potentially reachable according to EVA, resulting in a **statement coverage of 100.0%** with respect to the perimeter set by this entry point.
+These functions contain 50 statements, of which 50 are potentially reachable according to Eva, resulting in a **statement coverage of 100.0%** with respect to the perimeter set by this entry point.
 
 
 # Warnings {#warnings}
diff --git a/src/plugins/server/kernel_ast.ml b/src/plugins/server/kernel_ast.ml
index 832c1adce2b70ba182a4549234391d18512c4f28..6dd76c134789afb91c5d3db8ef6eb3213da42721 100644
--- a/src/plugins/server/kernel_ast.ml
+++ b/src/plugins/server/kernel_ast.ml
@@ -338,11 +338,13 @@ let () = Request.register ~package
     ~input:(module Kf) ~output:(module Jtext)
     begin fun kf ->
       let libc = Kernel.PrintLibc.get () in
-      if not libc then Kernel.PrintLibc.set true ;
-      let global = Kernel_function.get_global kf in
-      let ast = Jbuffer.to_json Printer.pp_global global in
-      if not libc then Kernel.PrintLibc.set false ;
-      ast
+      try
+        if not libc then Kernel.PrintLibc.set true ;
+        let global = Kernel_function.get_global kf in
+        let ast = Jbuffer.to_json Printer.pp_global global in
+        if not libc then Kernel.PrintLibc.set false ; ast
+      with err ->
+        if not libc then Kernel.PrintLibc.set false ; raise err
     end
 
 module Functions =
@@ -352,7 +354,31 @@ struct
 
   let signature kf =
     let global = Kernel_function.get_global kf in
-    Rich_text.to_string Printer_tag.pretty (PGlobal global)
+    let libc = Kernel.PrintLibc.get () in
+    try
+      if not libc then Kernel.PrintLibc.set true ;
+      let txt = Rich_text.to_string Printer_tag.pretty (PGlobal global) in
+      if not libc then Kernel.PrintLibc.set false ;
+      if Kernel_function.is_entry_point kf then (txt ^ " /* main */") else txt
+    with err ->
+      if not libc then Kernel.PrintLibc.set false ; raise err
+
+  let is_builtin kf =
+    Cil_builtins.is_builtin (Kernel_function.get_vi kf)
+
+  let is_stdlib kf =
+    let vi = Kernel_function.get_vi kf in
+    Cil.hasAttribute "fc_stdlib" vi.vattr ||
+    Cil.hasAttribute "fc_stdlib_generated" vi.vattr
+
+  let is_eva_analyzed kf =
+    if Db.Value.is_computed () then !Db.Value.is_called kf else false
+
+  let iter f =
+    Globals.Functions.iter
+      (fun kf ->
+         let name = Kernel_function.get_name kf in
+         if not (Ast_info.is_frama_c_builtin name) then f kf)
 
   let array : kernel_function States.array =
     begin
@@ -367,11 +393,41 @@ struct
         ~descr:(Md.plain "Signature")
         ~data:(module Data.Jstring)
         ~get:signature ;
+      States.column model
+        ~name:"main"
+        ~descr:(Md.plain "Is the function the main entry point")
+        ~data:(module Data.Jbool)
+        ~default:false
+        ~get:Kernel_function.is_entry_point;
+      States.column model
+        ~name:"defined"
+        ~descr:(Md.plain "Is the function defined?")
+        ~data:(module Data.Jbool)
+        ~default:false
+        ~get:Kernel_function.is_definition;
+      States.column model
+        ~name:"stdlib"
+        ~descr:(Md.plain "Is the function from the Frama-C stdlib?")
+        ~data:(module Data.Jbool)
+        ~default:false
+        ~get:is_stdlib;
+      States.column model
+        ~name:"builtin"
+        ~descr:(Md.plain "Is the function a Frama-C builtin?")
+        ~data:(module Data.Jbool)
+        ~default:false
+        ~get:is_builtin;
+      States.column model
+        ~name:"eva_analyzed"
+        ~descr:(Md.plain "Has the function been analyzed by Eva")
+        ~data:(module Data.Jbool)
+        ~default:false
+        ~get:is_eva_analyzed;
       States.register_array model
         ~package ~key
         ~name:"functions"
         ~descr:(Md.plain "AST Functions")
-        ~iter:Globals.Functions.iter
+        ~iter
         ~add_reload_hook:Ast.add_hook_on_update ;
     end
 
diff --git a/src/plugins/server/states.ml b/src/plugins/server/states.ml
index 5b172c2d4efdfc5e9a25b7839fa276761fb0766b..f9ae51a5b8acb166d074e7b2dc88b1624e90c1b1 100644
--- a/src/plugins/server/states.ml
+++ b/src/plugins/server/states.ml
@@ -92,23 +92,55 @@ let register_state (type a) ~package ~name ~descr
 (* --- Model Signature                                                    --- *)
 (* -------------------------------------------------------------------------- *)
 
-type 'a column = Package.fieldInfo * ('a -> json)
+type 'a column = Package.fieldInfo * ('a -> json option)
 
 type 'a model = 'a column list ref
 
 let model () = ref []
 
+let mkfield (model : 'a model) fd (js : 'a -> json option) =
+  let open Package in
+  let name = fd.fd_name in
+  if List.exists (fun (fd,_) -> fd.fd_name = name) !model then
+    raise (Invalid_argument "Server.States.column: duplicate name") ;
+  model := (fd , js) :: !model
+
 let column (type a b) ~name ~descr
-    ~(data: b Request.output) ~(get : a -> b) (model : a model) =
+    ~(data: b Request.output)
+    ~(get : a -> b)
+    ?(default: b option)
+    (model : a model) =
+  let module D = (val data) in
+  match default with
+  | None ->
+    let fd = Package.{
+        fd_name = name ;
+        fd_type = D.jtype ;
+        fd_descr = descr ;
+      } in
+    mkfield model fd (fun a -> Some (D.to_json (get a)))
+  | Some d ->
+    let fd = Package.{
+        fd_name = name ;
+        fd_type = Joption D.jtype ;
+        fd_descr = descr ;
+      } in
+    mkfield model fd (fun a ->
+        let v = get a in
+        if v = d then None else Some (D.to_json v)
+      )
+
+let option (type a b) ~name ~descr
+    ~(data: b Request.output) ~(get : a -> b option) (model : a model) =
   let module D = (val data) in
-  if List.exists (fun (fd,_) -> fd.Package.fd_name = name) !model then
-    raise (Invalid_argument "Server.States.column: duplicate name") ;
   let fd = Package.{
       fd_name = name ;
-      fd_type = D.jtype ;
+      fd_type = Joption D.jtype ;
       fd_descr = descr ;
     } in
-  model := (fd , fun a -> D.to_json (get a)) :: !model
+  mkfield model fd (fun a -> match get a with
+      | None -> None
+      | Some b -> Some (D.to_json b))
 
 module Kmap = Map.Make(String)
 
@@ -127,7 +159,7 @@ type 'a array = {
   fkey : string ;
   key : 'a -> string ;
   iter : ('a -> unit) -> unit ;
-  getter : (string * ('a -> json)) list ;
+  getter : (string * ('a -> json option)) list ;
   (* [LC+JS]
      The two following fields allow to keep an array in sync
      with the current project and still have a polymorphic data type. *)
@@ -206,8 +238,9 @@ type buffer = {
 
 let add_entry buffer cols fkey key v =
   let fjs = List.fold_left (fun fjs (fd,to_json) ->
-      try (fd , to_json v) :: fjs
-      with Not_found -> fjs
+      match to_json v with
+      | Some js -> (fd , js) :: fjs
+      | None | exception Not_found -> fjs
     ) [] cols in
   let row = (fkey, `String key) :: fjs in
   buffer.updated <- `Assoc row :: buffer.updated ;
@@ -267,7 +300,7 @@ let register_array ~package ~name ~descr ~key
     ?(add_update_hook : 'a callback option)
     ?(add_remove_hook : 'a callback option)
     ?(add_reload_hook : unit callback option)
-    model =
+    (model : 'a model) =
   let open Markdown in
   let href = link ~name () in
   let columns = List.rev !model in
diff --git a/src/plugins/server/states.mli b/src/plugins/server/states.mli
index 3e2c681cb406e8b08cf75a0e218871525f3a9967..a75c6c76c8776b067e39b4544c66198d3424fe89 100644
--- a/src/plugins/server/states.mli
+++ b/src/plugins/server/states.mli
@@ -76,12 +76,23 @@ type 'a model (** Columns array model *)
 val model : unit -> 'a model
 
 (** Populate an array model with a new field.
-    Columns with name `"id"` and `"_index"` are reserved for internal use. *)
+    If a [~default] value is given, the field becomes optional and
+    the field is omitted when equal to the default value (compared with [=]).
+*)
 val column :
   name:string ->
   descr:Markdown.text ->
   data:('b Request.output) ->
   get:('a -> 'b) ->
+  ?default:'b ->
+  'a model -> unit
+
+(** Populate an array model with a new optional field. *)
+val option :
+  name:string ->
+  descr:Markdown.text ->
+  data:('b Request.output) ->
+  get:('a -> 'b option) ->
   'a model -> unit
 
 (** Synchronized array state. *)
diff --git a/src/plugins/server/tests/batch/oracle/ast_services.out.json b/src/plugins/server/tests/batch/oracle/ast_services.out.json
index 865d7d9f0c0c0821b47b4dbfefd7ef66440c82c8..3dc3730f8f4b2707777bde129a6916dcb1f94d84 100644
--- a/src/plugins/server/tests/batch/oracle/ast_services.out.json
+++ b/src/plugins/server/tests/batch/oracle/ast_services.out.json
@@ -3,8 +3,18 @@
     "id": "GET-1",
     "data": {
       "updated": [
-        { "key": "kf#24", "name": "g", "signature": "int g(int y);" },
-        { "key": "kf#20", "name": "f", "signature": "int f(int x);" }
+        {
+          "key": "kf#24",
+          "name": "g",
+          "signature": "int g(int y);",
+          "defined": true
+        },
+        {
+          "key": "kf#20",
+          "name": "f",
+          "signature": "int f(int x);",
+          "defined": true
+        }
       ],
       "removed": [],
       "reload": true,
diff --git a/src/plugins/value/api/general_requests.ml b/src/plugins/value/api/general_requests.ml
index abf821d1d69063f79af1cc14354030b3920ae856..bbb5c95724375e6306e6e47c70497fcd2c28e9f5 100644
--- a/src/plugins/value/api/general_requests.ml
+++ b/src/plugins/value/api/general_requests.ml
@@ -31,6 +31,12 @@ let package =
     ~readme:"eva.md"
     ()
 
+let () = Request.register ~package
+    ~kind:`GET ~name:"isComputed"
+    ~descr:(Markdown.plain "True if the Eva analysis has been done")
+    ~input:(module Data.Junit) ~output:(module Data.Jbool)
+    Db.Value.is_computed
+
 let is_computed kf =
   Db.Value.is_computed () &&
   match kf with
diff --git a/src/plugins/value/engine/subdivided_evaluation.ml b/src/plugins/value/engine/subdivided_evaluation.ml
index 42e1eec994ff1e24401c645959e19246e03eec3c..f8cd150852485631688939f48782d496a9463ce4 100644
--- a/src/plugins/value/engine/subdivided_evaluation.ml
+++ b/src/plugins/value/engine/subdivided_evaluation.ml
@@ -231,7 +231,9 @@ let compare_bound ival_compare_bound v1 v2 =
       let f1 = Cvalue.V.project_ival v1 in
       let f2 = Cvalue.V.project_ival v2 in
       ival_compare_bound f1 f2
-    with Cvalue.V.Not_based_on_null -> assert false
+    (* Cannot compare pointers. This case can however happens on subdivisions
+       of a pointer subexpression to reduce a bigger numeric expression. *)
+    with Cvalue.V.Not_based_on_null -> 0
 
 let has_greater_min_bound = compare_bound Ival.has_greater_min_bound
 let has_smaller_max_bound = compare_bound Ival.has_smaller_max_bound
diff --git a/src/plugins/variadic/generic.ml b/src/plugins/variadic/generic.ml
index d7298e5b82029e29df4500a8fe4aeba123e0cd67..586d6041d62af0615c852996638b45362bfb81e5 100644
--- a/src/plugins/variadic/generic.ml
+++ b/src/plugins/variadic/generic.ml
@@ -58,12 +58,13 @@ let translate_type = function
 
 let add_vpar vi =
   let formals = Cil.getFormalsDecl vi in
+  let n_formals, g_formals = List.partition (fun v -> not v.vghost) formals in
   (* Add the vpar formal once *)
   if not (List.exists (fun vi -> vi.vname = vpar_name) formals) then
     begin
       (* Register the new formal *)
       let new_formal = Cil.makeFormalsVarDecl vpar in
-      let new_formals = formals @ [new_formal] in
+      let new_formals = n_formals @ [new_formal] @ g_formals in
       Cil.unsafeSetFormalsDecl vi new_formals
     end
 
diff --git a/src/plugins/variadic/tests/defined/maintain-formals-order.i b/src/plugins/variadic/tests/defined/maintain-formals-order.i
new file mode 100644
index 0000000000000000000000000000000000000000..4c525164291ee7619d63f6e5165cfc88458ca923
--- /dev/null
+++ b/src/plugins/variadic/tests/defined/maintain-formals-order.i
@@ -0,0 +1,16 @@
+/*@ requires c == 0 && x == 1 ; */
+void f(int x,...) /*@ ghost(int c) */ {
+  /*@ ghost int g = c; */
+}
+
+/*@ requires c == 0 && x == 1 && y == 2; */
+void g(int x, int y,...) /*@ ghost(int c) */ {
+  /*@ ghost int g = c; */
+}
+
+void main(void){
+  f(1) /*@ ghost(0) */;
+  f(1, 2, 3) /*@ ghost(0) */;
+
+  g(1, 2, 3, 4) /*@ ghost(0) */;
+}
diff --git a/src/plugins/variadic/tests/defined/oracle/maintain-formals-order.res.oracle b/src/plugins/variadic/tests/defined/oracle/maintain-formals-order.res.oracle
new file mode 100644
index 0000000000000000000000000000000000000000..814fcfccf9b5141dbf6b66536f66b7bafc37085d
--- /dev/null
+++ b/src/plugins/variadic/tests/defined/oracle/maintain-formals-order.res.oracle
@@ -0,0 +1,58 @@
+[variadic] tests/defined/maintain-formals-order.i:2: 
+  Declaration of variadic function f.
+[variadic] tests/defined/maintain-formals-order.i:7: 
+  Declaration of variadic function g.
+[variadic] tests/defined/maintain-formals-order.i:12: 
+  Generic translation of call to variadic function.
+[variadic] tests/defined/maintain-formals-order.i:13: 
+  Generic translation of call to variadic function.
+[variadic] tests/defined/maintain-formals-order.i:15: 
+  Generic translation of call to variadic function.
+[eva] Analyzing a complete application starting at main
+[eva] Computing initial state
+[eva] Initial state computed
+[eva] done for function main
+[eva] ====== VALUES COMPUTED ======
+[eva:final-states] Values at end of function f:
+  g_0 ∈ {0}
+[eva:final-states] Values at end of function g:
+  g_0 ∈ {0}
+[eva:final-states] Values at end of function main:
+  
+/* Generated by Frama-C */
+/*@ requires c ≡ 0 ∧ x ≡ 1; */
+void f(int x, void * const *__va_params) /*@ ghost (int c) */
+{
+  /*@ ghost int g_0 = c; */
+  return;
+}
+
+/*@ requires c ≡ 0 ∧ x ≡ 1 ∧ y ≡ 2; */
+void g(int x, int y, void * const *__va_params) /*@ ghost (int c) */
+{
+  /*@ ghost int g_0 = c; */
+  return;
+}
+
+void main(void)
+{
+  {
+    void *__va_args[1] = {(void *)0};
+    f(1,(void * const *)(__va_args)) /*@ ghost (0) */;
+  }
+  {
+    int __va_arg0 = 2;
+    int __va_arg1 = 3;
+    void *__va_args_5[2] = {& __va_arg0, & __va_arg1};
+    f(1,(void * const *)(__va_args_5)) /*@ ghost (0) */;
+  }
+  {
+    int __va_arg0_7 = 3;
+    int __va_arg1_9 = 4;
+    void *__va_args_11[2] = {& __va_arg0_7, & __va_arg1_9};
+    g(1,2,(void * const *)(__va_args_11)) /*@ ghost (0) */;
+  }
+  return;
+}
+
+
diff --git a/src/plugins/wp/Conditions.ml b/src/plugins/wp/Conditions.ml
index d6e531f56be84457ef273df9c4db17a9d8391ccd..1ff6550e70594e0042b4520ed530a9c3a98ef8cd 100644
--- a/src/plugins/wp/Conditions.ml
+++ b/src/plugins/wp/Conditions.ml
@@ -1595,9 +1595,11 @@ struct
     let visited = ref Tset.empty in
     let rec term_is_init_in_states states t =
       let raise_if_is_init t s =
-        match Mstate.lookup s t with
-        | Mlval(_, KInit) | Mchunk(_, KInit) -> raise Found
-        | _ -> ()
+        if Lang.F.is_primitive t then ()
+        else
+          match Mstate.lookup s t with
+          | Mlval(_, KInit) | Mchunk(_, KInit) -> raise Found
+          | _ -> ()
       in
       if Tset.mem t !visited then ()
       else begin
diff --git a/src/plugins/wp/tests/wp_bts/bts_2471.i b/src/plugins/wp/tests/wp_bts/bts_2471.i
index 2419c0debd8c56f0daafc2f0bdae517aadb72fff..a25c144dafc34fea9b4067ea4e9e953d1ff1505e 100644
--- a/src/plugins/wp/tests/wp_bts/bts_2471.i
+++ b/src/plugins/wp/tests/wp_bts/bts_2471.i
@@ -4,7 +4,6 @@
 
 /* run.config_qualif
    OPT: -wp-timeout 1
-   OPT: -wp-prover native:alt-ergo -wp-timeout 1
    OPT: -wp-prover native:coq
  */
 
diff --git a/src/plugins/wp/tests/wp_bts/oracle_qualif/bts_2471.1.res.oracle b/src/plugins/wp/tests/wp_bts/oracle_qualif/bts_2471.1.res.oracle
index ffb3913bc3829c2336a99250827f72c490e1ca85..daef8736024e638253e9724c9732a577d90cb7df 100644
--- a/src/plugins/wp/tests/wp_bts/oracle_qualif/bts_2471.1.res.oracle
+++ b/src/plugins/wp/tests/wp_bts/oracle_qualif/bts_2471.1.res.oracle
@@ -1,12 +1,13 @@
-# frama-c -wp -wp-timeout 1 [...]
+# frama-c -wp [...]
 [kernel] Parsing tests/wp_bts/bts_2471.i (no preprocessing)
 [wp] Running WP plugin...
 [wp] Warning: Missing RTE guards
-[wp] Warning: native support for alt-ergo is deprecated, use why3 instead
+[wp] Warning: native support for coq is deprecated, use tip instead
 [wp] 1 goal scheduled
-[wp] [Alt-Ergo (native)] Goal typed_foo_assert_ko : Unsuccess
+[wp] [Coq] Goal typed_foo_assert_ko : Default tactic
+[wp] [Coq (native)] Goal typed_foo_assert_ko : Unsuccess
 [wp] Proved goals:    0 / 1
-  Alt-Ergo (native):    0  (unsuccess: 1)
+  Coq (native):    0  (unsuccess: 1)
 ------------------------------------------------------------
  Functions                 WP     Alt-Ergo  Total   Success
   foo                       -        -        1       0.0%
diff --git a/src/plugins/wp/tests/wp_bts/oracle_qualif/bts_2471.2.res.oracle b/src/plugins/wp/tests/wp_bts/oracle_qualif/bts_2471.2.res.oracle
deleted file mode 100644
index daef8736024e638253e9724c9732a577d90cb7df..0000000000000000000000000000000000000000
--- a/src/plugins/wp/tests/wp_bts/oracle_qualif/bts_2471.2.res.oracle
+++ /dev/null
@@ -1,14 +0,0 @@
-# frama-c -wp [...]
-[kernel] Parsing tests/wp_bts/bts_2471.i (no preprocessing)
-[wp] Running WP plugin...
-[wp] Warning: Missing RTE guards
-[wp] Warning: native support for coq is deprecated, use tip instead
-[wp] 1 goal scheduled
-[wp] [Coq] Goal typed_foo_assert_ko : Default tactic
-[wp] [Coq (native)] Goal typed_foo_assert_ko : Unsuccess
-[wp] Proved goals:    0 / 1
-  Coq (native):    0  (unsuccess: 1)
-------------------------------------------------------------
- Functions                 WP     Alt-Ergo  Total   Success
-  foo                       -        -        1       0.0%
-------------------------------------------------------------
diff --git a/src/plugins/wp/tests/wp_gallery/frama_c_hashtbl_solved.c b/src/plugins/wp/tests/wp_gallery/frama_c_hashtbl_solved.c
deleted file mode 100644
index f52b6b9b19f46f34e7f32691ce5d112d23ce556e..0000000000000000000000000000000000000000
--- a/src/plugins/wp/tests/wp_gallery/frama_c_hashtbl_solved.c
+++ /dev/null
@@ -1,329 +0,0 @@
-/* run.config
-   OPT: -wp-no-print -wp-rte
-*/
-
-/* run.config_qualif
-   OPT: -wp-prover=script,alt-ergo -wp-prop=-left_unproved -then -wp-rte -wp -wp-prop=-left_unproved
-*/
-
-/* ******************************* */
-/* Solution de TP donné par Julien */
-/* ******************************* */
-
-/* -------------------------------------------------------------------------- */
-/*
-  Ce fichier fournit une petite librairie de tables de hachage simplifiées:
-  elles ne sont pas dynamiques et, en particulier, pas redimensionnables.
-
-  Votre but est:
-  1. écrire la spécification ACSL des fonctions fournies à partir de leurs
-  spécifications informelles (mais pas du code...)
-  2. prouver que chaque fonction satisfait la spécification écrite en 1.
-  3. prouver l'absence d'erreurs à l'exécution via l'option -wp-rte.
-*/
-/* -------------------------------------------------------------------------- */
-
-#include <limits.h>
-
-/* -------------------------------------------------------------------------- */
-/*
-  Chaines de caractères simplifiées:
-  toutes les chaînes de caractères de ce fichier seront supposées de longueurs
-  STRING_LEN.
-
-  La fonction [eq_string] est fournie avec sa spécification formelle déjà
-  prouvée. Vous n'avez donc rien à faire pour cette fonction \o/.
-
-  Astuce: le prédicat [EqString] peut éventuellement être utile...
-*/
-/* -------------------------------------------------------------------------- */
-
-#define STRING_LEN 20
-
-/*@ predicate EqString(char *s1, char *s2) =
-  @   \forall integer i; 0 <= i < STRING_LEN ==> s1[i] == s2[i];
-  @ */
-
-/*@ requires \valid_read(s1 + (0 .. STRING_LEN - 1));
-  @ requires \valid_read(s2 + (0 .. STRING_LEN - 1));
-  @ assigns \nothing;
-  @
-  @ behavior eq:
-  @   assumes EqString(s1, s2);
-  @   ensures \result == 1;
-  @
-  @ behavior not_eq:
-  @   assumes ! EqString(s1, s2);
-  @   ensures \result == 0;
-  @
-  @ complete behaviors;
-  @ disjoint behaviors;
-  @ */
-int eq_string(const char *s1, const char *s2) {
-  int i;
-  /*@ loop invariant 0 <= i <= STRING_LEN;
-    @ loop invariant \forall integer j; 0 <= j < i ==> s1[j] == s2[j];
-    @ loop assigns i;
-    @ loop variant STRING_LEN - i;
-    @*/
-  for(i = 0; i < STRING_LEN; i++)
-    if (s1[i] != s2[i]) return 0;
-  return 1;
-}
-
-/* -------------------------------------------------------------------------- */
-/*
-  Structures de données.
-
-  Les tables de hachage associent ici des clés sous forme de chaînes de
-  caractères à des valeurs entières. Une fonction de hachage sur les
-  chaînes de caractères vous est fournie.
-
-  Les tables de hachage sont représentées par leur nombre d'éléments et un
-  tableau de "buckets" de longueur HASHTBL_LEN.
-
-  Les "buckets" sont eux-même des tableaux de couples (clé, valeur)
-  (individuellement appelé "bucket") dont toutes les clés ont le même
-  haché. Chaque tableau est de longueur fixe, BUCKET_LEN, mais le nombre
-  d'éléments stockés dans celui-ci peut varier.
-*/
-/* -------------------------------------------------------------------------- */
-
-#define BUCKET_LEN 10
-#define HASHTBL_LEN 17
-
-typedef struct {
-  char *key; // clé, sous forme de chaînes de caractères (simplifiées)
-  int value; // valeur associée à la clé
-} Bucket;
-
-typedef struct {
-  Bucket buckets[BUCKET_LEN]; // tableau de couples (clé, valeur)
-  int size;                   // nombre d'éléments stockés dans le tableau
-} Buckets;
-
-typedef struct {
-  Buckets data[HASHTBL_LEN];  // tableau de buckets
-  int size;               // nombre d'éléments stockés dans la table de hachage
-} Hashtbl;
-
-/* -------------------------------------------------------------------------- */
-/*
-  Fonction de hachage fournie: vous n'avez là non plus rien à faire \o/.
-
-  La postcondition de la fonction [hash] ne peut pas être prouvée sans donner
-  une définition à la fonction logique [Hash]. Ce travail n'est pas demandé ici
-  et cette postcondition restera donc toujours non prouvée. Ce devrait être
-  la seule...
-
-  Astuce: la fonction logique [HashIndex] de l'axiomatique [Hash] n'est pas
-  donnée que pour faire jolie. Vous avez aussi le droit d'ajouter vos propres
-  définitions de prédicats et de fonctions...
-*/
-/* -------------------------------------------------------------------------- */
-
-/*@ axiomatic Hash {
-  @   logic unsigned long Hash(char *s) reads(s + (0 .. ));
-  @   // [Hash] est un modèle abstrait de la fonction de hash codée en C
-  @   // ci-dessous
-  @
-  @   logic integer HashIndex(Hashtbl *tbl, char *k) = Hash(k) % HASHTBL_LEN;
-  @ } */
-
-/*@ requires \valid_read(s + (0 .. STRING_LEN - 1));
-  @ assigns \nothing;
-  @ ensures left_unproved: \result == Hash(s);
-  @ */
-unsigned long hash(const char *s) {
-  unsigned long h = 5381;
-  int i;
-  /*@ loop invariant 0 <= i <= STRING_LEN;
-    @ loop assigns h, i;
-    @ loop variant STRING_LEN - i; */
-  for(i = 0; i < STRING_LEN; i++) {
-    if (s[i]) break;
-    h = ((h << 5) + h) + s[i];
-  }
-  return h;
-}
-
-/* -------------------------------------------------------------------------- */
-/*
-  Fonctions logiques et prédicats additionnels utiles.
-*/
-/* -------------------------------------------------------------------------- */
-
-/*@
-  @ predicate valid_tbl(Hashtbl *tbl) =
-  @   \valid(tbl->data+(0 .. HASHTBL_LEN - 1));
-  @
-  @ predicate valid_buckets(Hashtbl *tbl) =
-  @   \forall integer i;
-  @     0 <= i < HASHTBL_LEN ==>
-  @     \valid(tbl->data[i].buckets + (0 .. BUCKET_LEN - 1));
-  @
-  @ predicate valid_read_keys(Hashtbl *tbl) =
-  @   \forall integer i, j;
-  @     0 <= i < HASHTBL_LEN ==>
-  @     0 <= j < tbl->data[i].size ==>
-  @     \valid_read(tbl->data[i].buckets[j].key + (0 .. STRING_LEN - 1));
-  @
-  @ logic integer buckets_size(Hashtbl *tbl, char *k) =
-  @   tbl->data[HashIndex(tbl, k)].size;
-  @
-  @ logic Bucket bucket(Hashtbl *tbl, char *k, integer i) =
-  @   tbl->data[HashIndex(tbl, k)].buckets[i];
-  @
-  @ */
-
-/* -------------------------------------------------------------------------- */
-/*
-  Exercice 0 (échauffement):
-
-  La fonction [size] retourne le nombre d'éléments d'une table.
-*/
-/* -------------------------------------------------------------------------- */
-
-/*@ requires \valid(tbl);
-  @ assigns \nothing;
-  @ ensures \result == tbl->size;
-  @ */
-int size(const Hashtbl *tbl) {
-  return tbl->size;
-}
-
-/* -------------------------------------------------------------------------- */
-/*
-  Exercice 1:
-
-  La fonction [init] initialise une table de hachage contenant 0 élément.
-  En particulier, chaque buckets contient 0 élément.
-*/
-/* -------------------------------------------------------------------------- */
-
-/*@ requires \valid(tbl);
-  @ requires valid_tbl(tbl);
-  @ assigns tbl->size, tbl->data[0 .. HASHTBL_LEN - 1];
-  @ ensures tbl->size == 0;
-  @ ensures \forall integer i; 0 <= i < HASHTBL_LEN ==> tbl->data[i].size == 0;
-  @ */
-void init(Hashtbl *tbl){
-  int i;
-  tbl->size = 0;
-  /*@ loop invariant 0 <= i <= HASHTBL_LEN;
-    @ loop invariant \forall integer k; 0 <= k < i ==> tbl->data[k].size == 0;
-    @ loop assigns i, tbl->data[0 .. HASHTBL_LEN - 1].size;
-    @ loop variant HASHTBL_LEN - i;
-    @ */
-  for(i = 0; i < HASHTBL_LEN; i++)
-    tbl->data[i].size = 0;
-}
-
-/* -------------------------------------------------------------------------- */
-/*
-  Exercice 2:
-
-  La fonction [add] ajouter un couple (clé, valeur) dans la table de hachage
-  s'il y a suffisamment de places. Si tel est le cas, elle retourne 0.
-
-  S'il n'y a pas suffisamment de places, la fonction ne fait rien et retourne
-  -1.
-
-  Conseil: lorsque la table est modifiée, bien penser à spécifier les nouvelles
-  tailles et l'emplacement du couple ajouté.
-*/
-/* -------------------------------------------------------------------------- */
-
-/*@ requires \valid(tbl);
-  @ requires valid_tbl(tbl);
-  @ requires valid_buckets(tbl);
-  @ requires \valid_read(k + (0 .. STRING_LEN - 1));
-  @ requires 0 <= tbl->size < INT_MAX;
-  @ requires \forall integer i;
-  @   0 <= i < HASHTBL_LEN ==>
-  @   0 <= tbl->data[i].size <= BUCKET_LEN;
-  @
-  @ assigns tbl->data[HashIndex(tbl, k)], tbl->size;
-  @
-  @ behavior nominal:
-  @   assumes buckets_size(tbl, k) < BUCKET_LEN;
-  @   assigns tbl->data[HashIndex(tbl, k)], tbl->size;
-  @   ensures \result == 0;
-  @   ensures tbl->size == \old(tbl->size) + 1;
-  @   ensures buckets_size(tbl, k) == buckets_size{Old}(tbl, k) + 1;
-  @   ensures bucket(tbl, k, buckets_size{Old}(tbl, k)).key == k;
-  @   ensures bucket(tbl, k, buckets_size{Old}(tbl, k)).value == d;
-  @ behavior full:
-  @   assumes buckets_size(tbl, k) == BUCKET_LEN;
-  @   assigns \nothing;
-  @   ensures \result == -1;
-  @
-  @ complete behaviors;
-  @ disjoint behaviors;
-  @ */
-int add(Hashtbl *tbl, char *k, int d) {
-  Bucket new_entry;
-  unsigned int h = hash(k) % HASHTBL_LEN;
-  if (tbl->data[h].size >= BUCKET_LEN)
-    return -1;
-  new_entry.key = k;
-  new_entry.value = d;
-  tbl->data[h].buckets[tbl->data[h].size] = new_entry;
-  tbl->data[h].size++;
-  tbl->size++;
-  return 0;
-}
-
-/* -------------------------------------------------------------------------- */
-/*
-  Exercice 3:
-
-  La fonction [mem_binding] retourne 1 si le couple (clé, valeur) [k, v] donné
-  en entrée est présent dans la table de hachage. Elle retourne 0 sinon.
-*/
-/* -------------------------------------------------------------------------- */
-
-/*@ requires \valid(tbl);
-  @ requires valid_tbl(tbl);
-  @ requires valid_buckets(tbl);
-  @ requires valid_read_keys(tbl);
-  @ requires \valid_read(k + (0 .. STRING_LEN - 1));
-  @ requires \forall integer i;
-  @   0 <= i < HASHTBL_LEN ==>
-  @   0 <= tbl->data[i].size < BUCKET_LEN;
-  @
-  @ assigns \nothing;
-  @
-  @ behavior found:
-  @   assumes \exists integer i; 0 <= i < buckets_size(tbl, k) &&
-  @     EqString(k, bucket(tbl, k, i).key) && v == bucket(tbl, k, i).value;
-  @   ensures \result == 1;
-  @
-  @ behavior not_found:
-  @   assumes \forall integer i; 0 <= i < buckets_size(tbl, k) ==>
-  @     (! EqString(k, bucket(tbl, k, i).key)
-  @     || tbl->data[HashIndex(tbl, k)].buckets[i].value != v);
-  @     // note: Alt-Ergo does not manage to prove it if written
-  @     // bucket(tbl, k, i).value != v
-  @     // so disappointing :-(
-  @   ensures \result == 0;
-  @
-  @ complete behaviors;
-  @ disjoint behaviors;
-  @ */
-int mem_binding(const Hashtbl *tbl, const char *k, int v) {
-  int i, h = hash(k) % HASHTBL_LEN;
-  /*@ loop invariant 0 <= i <= tbl->data[h].size;
-    @ loop invariant \forall integer j; 0 <= j < i ==>
-    @  (! EqString(k, tbl->data[h].buckets[j].key)
-    @  || tbl->data[h].buckets[j].value != v);
-    @ loop assigns i;
-    @ loop variant tbl->data[h].size - i;
-    @ */
-  for(i = 0; i < tbl->data[h].size; i++) {
-    if (eq_string(k, tbl->data[h].buckets[i].key)
-        && tbl->data[h].buckets[i].value == v)
-      return 1;
-  }
-  return 0;
-}
diff --git a/src/plugins/wp/tests/wp_gallery/oracle/frama_c_hashtbl_solved.res.oracle b/src/plugins/wp/tests/wp_gallery/oracle/frama_c_hashtbl_solved.res.oracle
deleted file mode 100644
index 2429963d412aaa3b426504d27c25d7c2fc60722a..0000000000000000000000000000000000000000
--- a/src/plugins/wp/tests/wp_gallery/oracle/frama_c_hashtbl_solved.res.oracle
+++ /dev/null
@@ -1,153 +0,0 @@
-# frama-c -wp -wp-rte [...]
-[kernel] Parsing tests/wp_gallery/frama_c_hashtbl_solved.c (with preprocessing)
-[wp] Running WP plugin...
-[rte] annotating function add
-[rte] annotating function eq_string
-[rte] annotating function hash
-[rte] annotating function init
-[rte] annotating function mem_binding
-[rte] annotating function size
-[wp] Goal typed_eq_string_complete_eq_not_eq : trivial
-[wp] Goal typed_eq_string_disjoint_eq_not_eq : trivial
-[wp] Goal typed_eq_string_loop_invariant_preserved : not tried
-[wp] Goal typed_eq_string_loop_invariant_established : not tried
-[wp] Goal typed_eq_string_loop_invariant_2_preserved : not tried
-[wp] Goal typed_eq_string_loop_invariant_2_established : not tried
-[wp] Goal typed_eq_string_assert_rte_mem_access : not tried
-[wp] Goal typed_eq_string_assert_rte_mem_access_2 : not tried
-[wp] Goal typed_eq_string_assert_rte_signed_overflow : not tried
-[wp] Goal typed_eq_string_loop_assigns : trivial
-[wp] Goal typed_eq_string_assigns_part1 : not tried
-[wp] Goal typed_eq_string_assigns_part2 : not tried
-[wp] Goal typed_eq_string_assigns_part3 : not tried
-[wp] Goal typed_eq_string_assigns_part4 : not tried
-[wp] Goal typed_eq_string_loop_variant_decrease : not tried
-[wp] Goal typed_eq_string_loop_variant_positive : not tried
-[wp] Goal typed_eq_string_eq_ensures : not tried
-[wp] Goal typed_eq_string_not_eq_ensures : not tried
-[wp] Goal typed_hash_ensures_left_unproved : not tried
-[wp] Goal typed_hash_loop_invariant_preserved : not tried
-[wp] Goal typed_hash_loop_invariant_established : not tried
-[wp] Goal typed_hash_assert_rte_mem_access : not tried
-[wp] Goal typed_hash_assert_rte_mem_access_2 : not tried
-[wp] Goal typed_hash_assert_rte_signed_overflow : not tried
-[wp] Goal typed_hash_loop_assigns : trivial
-[wp] Goal typed_hash_assigns_part1 : not tried
-[wp] Goal typed_hash_assigns_part2 : not tried
-[wp] Goal typed_hash_loop_variant_decrease : not tried
-[wp] Goal typed_hash_loop_variant_positive : not tried
-[wp] Goal typed_size_ensures : not tried
-[wp] Goal typed_size_assert_rte_mem_access : not tried
-[wp] Goal typed_size_assigns : not tried
-[wp] Goal typed_init_ensures : not tried
-[wp] Goal typed_init_ensures_2 : not tried
-[wp] Goal typed_init_assert_rte_mem_access : not tried
-[wp] Goal typed_init_loop_invariant_preserved : not tried
-[wp] Goal typed_init_loop_invariant_established : not tried
-[wp] Goal typed_init_loop_invariant_2_preserved : not tried
-[wp] Goal typed_init_loop_invariant_2_established : not tried
-[wp] Goal typed_init_assert_rte_index_bound : not tried
-[wp] Goal typed_init_assert_rte_index_bound_2 : not tried
-[wp] Goal typed_init_assert_rte_mem_access_2 : not tried
-[wp] Goal typed_init_assert_rte_signed_overflow : not tried
-[wp] Goal typed_init_loop_assigns_part1 : trivial
-[wp] Goal typed_init_loop_assigns_part2 : not tried
-[wp] Goal typed_init_assigns_part1 : not tried
-[wp] Goal typed_init_assigns_part2 : not tried
-[wp] Goal typed_init_assigns_part3 : not tried
-[wp] Goal typed_init_loop_variant_decrease : not tried
-[wp] Goal typed_init_loop_variant_positive : not tried
-[wp] Goal typed_add_complete_full_nominal : not tried
-[wp] Goal typed_add_disjoint_full_nominal : not tried
-[wp] Goal typed_add_assert_rte_index_bound : not tried
-[wp] Goal typed_add_assert_rte_mem_access : not tried
-[wp] Goal typed_add_assert_rte_index_bound_2 : not tried
-[wp] Goal typed_add_assert_rte_index_bound_3 : not tried
-[wp] Goal typed_add_assert_rte_index_bound_4 : not tried
-[wp] Goal typed_add_assert_rte_index_bound_5 : not tried
-[wp] Goal typed_add_assert_rte_mem_access_2 : not tried
-[wp] Goal typed_add_assert_rte_mem_access_3 : not tried
-[wp] Goal typed_add_assert_rte_index_bound_6 : not tried
-[wp] Goal typed_add_assert_rte_mem_access_4 : not tried
-[wp] Goal typed_add_assert_rte_mem_access_5 : not tried
-[wp] Goal typed_add_assert_rte_signed_overflow : not tried
-[wp] Goal typed_add_assert_rte_mem_access_6 : not tried
-[wp] Goal typed_add_assert_rte_mem_access_7 : not tried
-[wp] Goal typed_add_assert_rte_signed_overflow_2 : not tried
-[wp] Goal typed_add_assigns_exit : trivial
-[wp] Goal typed_add_assigns_normal_part1 : trivial
-[wp] Goal typed_add_assigns_normal_part2 : not tried
-[wp] Goal typed_add_assigns_normal_part3 : not tried
-[wp] Goal typed_add_assigns_normal_part4 : not tried
-[wp] Goal typed_add_assigns_normal_part5 : not tried
-[wp] Goal typed_add_assigns_normal_part6 : not tried
-[wp] Goal typed_add_assigns_normal_part7 : not tried
-[wp] Goal typed_add_assigns_normal_part8 : not tried
-[wp] Goal typed_add_assigns_normal_part9 : not tried
-[wp] Goal typed_add_call_hash_requires : not tried
-[wp] Goal typed_add_nominal_ensures : not tried
-[wp] Goal typed_add_nominal_ensures_2 : not tried
-[wp] Goal typed_add_nominal_ensures_3 : not tried
-[wp] Goal typed_add_nominal_ensures_4 : not tried
-[wp] Goal typed_add_nominal_ensures_5 : not tried
-[wp] Goal typed_add_nominal_assigns_exit : trivial
-[wp] Goal typed_add_nominal_assigns_normal_part1 : trivial
-[wp] Goal typed_add_nominal_assigns_normal_part2 : not tried
-[wp] Goal typed_add_nominal_assigns_normal_part3 : not tried
-[wp] Goal typed_add_nominal_assigns_normal_part4 : not tried
-[wp] Goal typed_add_nominal_assigns_normal_part5 : not tried
-[wp] Goal typed_add_nominal_assigns_normal_part6 : not tried
-[wp] Goal typed_add_nominal_assigns_normal_part7 : not tried
-[wp] Goal typed_add_nominal_assigns_normal_part8 : not tried
-[wp] Goal typed_add_nominal_assigns_normal_part9 : not tried
-[wp] Goal typed_add_full_ensures : not tried
-[wp] Goal typed_add_full_assigns_exit : trivial
-[wp] Goal typed_add_full_assigns_normal_part1 : trivial
-[wp] Goal typed_add_full_assigns_normal_part2 : not tried
-[wp] Goal typed_add_full_assigns_normal_part3 : not tried
-[wp] Goal typed_add_full_assigns_normal_part4 : not tried
-[wp] Goal typed_add_full_assigns_normal_part5 : not tried
-[wp] Goal typed_add_full_assigns_normal_part6 : not tried
-[wp] Goal typed_add_full_assigns_normal_part7 : not tried
-[wp] Goal typed_add_full_assigns_normal_part8 : not tried
-[wp] Goal typed_add_full_assigns_normal_part9 : not tried
-[wp] Goal typed_mem_binding_complete_found_not_found : not tried
-[wp] Goal typed_mem_binding_disjoint_found_not_found : not tried
-[wp] Goal typed_mem_binding_loop_invariant_preserved : not tried
-[wp] Goal typed_mem_binding_loop_invariant_established : not tried
-[wp] Goal typed_mem_binding_loop_invariant_2_preserved : not tried
-[wp] Goal typed_mem_binding_loop_invariant_2_established : not tried
-[wp] Goal typed_mem_binding_assert_rte_index_bound : not tried
-[wp] Goal typed_mem_binding_assert_rte_index_bound_2 : not tried
-[wp] Goal typed_mem_binding_assert_rte_mem_access : not tried
-[wp] Goal typed_mem_binding_assert_rte_index_bound_3 : not tried
-[wp] Goal typed_mem_binding_assert_rte_index_bound_4 : not tried
-[wp] Goal typed_mem_binding_assert_rte_index_bound_5 : not tried
-[wp] Goal typed_mem_binding_assert_rte_index_bound_6 : not tried
-[wp] Goal typed_mem_binding_assert_rte_mem_access_2 : not tried
-[wp] Goal typed_mem_binding_assert_rte_index_bound_7 : not tried
-[wp] Goal typed_mem_binding_assert_rte_index_bound_8 : not tried
-[wp] Goal typed_mem_binding_assert_rte_index_bound_9 : not tried
-[wp] Goal typed_mem_binding_assert_rte_index_bound_10 : not tried
-[wp] Goal typed_mem_binding_assert_rte_mem_access_3 : not tried
-[wp] Goal typed_mem_binding_assert_rte_signed_overflow : not tried
-[wp] Goal typed_mem_binding_loop_assigns_part1 : trivial
-[wp] Goal typed_mem_binding_loop_assigns_part2 : not tried
-[wp] Goal typed_mem_binding_assigns_exit_part1 : trivial
-[wp] Goal typed_mem_binding_assigns_exit_part2 : not tried
-[wp] Goal typed_mem_binding_assigns_exit_part3 : not tried
-[wp] Goal typed_mem_binding_assigns_exit_part4 : not tried
-[wp] Goal typed_mem_binding_assigns_normal_part1 : trivial
-[wp] Goal typed_mem_binding_assigns_normal_part2 : not tried
-[wp] Goal typed_mem_binding_assigns_normal_part3 : not tried
-[wp] Goal typed_mem_binding_assigns_normal_part4 : not tried
-[wp] Goal typed_mem_binding_assigns_normal_part5 : not tried
-[wp] Goal typed_mem_binding_assigns_normal_part6 : not tried
-[wp] Goal typed_mem_binding_assigns_normal_part7 : not tried
-[wp] Goal typed_mem_binding_loop_variant_decrease : not tried
-[wp] Goal typed_mem_binding_loop_variant_positive : not tried
-[wp] Goal typed_mem_binding_call_hash_requires : not tried
-[wp] Goal typed_mem_binding_call_eq_string_requires : not tried
-[wp] Goal typed_mem_binding_call_eq_string_requires_2 : not tried
-[wp] Goal typed_mem_binding_found_ensures : not tried
-[wp] Goal typed_mem_binding_not_found_ensures : not tried
diff --git a/src/plugins/wp/tests/wp_gallery/oracle/string-compare.res.oracle b/src/plugins/wp/tests/wp_gallery/oracle/string-compare.res.oracle
new file mode 100644
index 0000000000000000000000000000000000000000..0c5741ea36b8b38350a2110b5dbc622c93d6c527
--- /dev/null
+++ b/src/plugins/wp/tests/wp_gallery/oracle/string-compare.res.oracle
@@ -0,0 +1,67 @@
+# frama-c -wp -wp-rte [...]
+[kernel] Parsing tests/wp_gallery/string-compare.c (with preprocessing)
+[wp] Running WP plugin...
+[rte] annotating function main
+[rte] annotating function stringCompare
+[rte] annotating function stringLength
+[wp] [CFG] Goal stringCompare_exits_never : Valid (Unreachable)
+[wp] [CFG] Goal stringLength_exits_never : Valid (Unreachable)
+[wp] Goal typed_stringCompare_complete_SomeDifferent_allEqual : trivial
+[wp] Goal typed_stringCompare_disjoint_SomeDifferent_allEqual : trivial
+[wp] Goal typed_stringCompare_loop_invariant_equal_preserved : not tried
+[wp] Goal typed_stringCompare_loop_invariant_equal_established : not tried
+[wp] Goal typed_stringCompare_loop_invariant_gauge_preserved : not tried
+[wp] Goal typed_stringCompare_loop_invariant_gauge_established : not tried
+[wp] Goal typed_stringCompare_loop_invariant_gauge_s1_preserved : not tried
+[wp] Goal typed_stringCompare_loop_invariant_gauge_s1_established : not tried
+[wp] Goal typed_stringCompare_loop_invariant_gauge_s2_preserved : not tried
+[wp] Goal typed_stringCompare_loop_invariant_gauge_s2_established : not tried
+[wp] Goal typed_stringCompare_loop_invariant_not_eos_preserved : not tried
+[wp] Goal typed_stringCompare_loop_invariant_not_eos_established : not tried
+[wp] Goal typed_stringCompare_loop_invariant_strlen_s1_preserved : not tried
+[wp] Goal typed_stringCompare_loop_invariant_strlen_s1_established : not tried
+[wp] Goal typed_stringCompare_loop_invariant_strlen_s2_preserved : not tried
+[wp] Goal typed_stringCompare_loop_invariant_strlen_s2_established : not tried
+[wp] Goal typed_stringCompare_assert_rte_mem_access : not tried
+[wp] Goal typed_stringCompare_assert_rte_mem_access_2 : not tried
+[wp] Goal typed_stringCompare_assert_rte_mem_access_3 : not tried
+[wp] Goal typed_stringCompare_assert_different : not tried
+[wp] Goal typed_stringCompare_assert_rte_mem_access_4 : not tried
+[wp] Goal typed_stringCompare_assert_rte_mem_access_5 : not tried
+[wp] Goal typed_stringCompare_assert_rte_signed_overflow : not tried
+[wp] Goal typed_stringCompare_assert_rte_signed_overflow_2 : not tried
+[wp] Goal typed_stringCompare_loop_assigns_part1 : trivial
+[wp] Goal typed_stringCompare_loop_assigns_part2 : not tried
+[wp] Goal typed_stringCompare_loop_assigns_part3 : not tried
+[wp] Goal typed_stringCompare_assigns_part1 : not tried
+[wp] Goal typed_stringCompare_assigns_part2 : not tried
+[wp] Goal typed_stringCompare_assigns_part3 : not tried
+[wp] Goal typed_stringCompare_assigns_part4 : not tried
+[wp] Goal typed_stringCompare_assigns_part5 : not tried
+[wp] Goal typed_stringCompare_assigns_part6 : not tried
+[wp] Goal typed_stringCompare_assigns_part7 : not tried
+[wp] Goal typed_stringCompare_assigns_part8 : not tried
+[wp] Goal typed_stringCompare_assigns_part9 : not tried
+[wp] Goal typed_stringCompare_allEqual_ensures : not tried
+[wp] Goal typed_stringCompare_SomeDifferent_ensures : not tried
+[wp] Goal typed_stringLength_ensures_rightResult : not tried
+[wp] Goal typed_stringLength_ensures_rightEndCharacter : not tried
+[wp] Goal typed_stringLength_loop_invariant_preserved : not tried
+[wp] Goal typed_stringLength_loop_invariant_established : not tried
+[wp] Goal typed_stringLength_loop_invariant_2_preserved : not tried
+[wp] Goal typed_stringLength_loop_invariant_2_established : not tried
+[wp] Goal typed_stringLength_assert_rte_mem_access : not tried
+[wp] Goal typed_stringLength_loop_assigns_part1 : trivial
+[wp] Goal typed_stringLength_loop_assigns_part2 : not tried
+[wp] Goal typed_stringLength_assigns_part1 : not tried
+[wp] Goal typed_stringLength_assigns_part2 : not tried
+[wp] Goal typed_stringLength_assigns_part3 : not tried
+[wp] Goal typed_stringLength_assigns_part4 : not tried
+[wp] Goal typed_stringLength_assigns_part5 : not tried
+[wp] Goal typed_main_ensures : not tried
+[wp] Goal typed_main_exits_never : trivial
+[wp] Goal typed_main_assert : not tried
+[wp] Goal typed_main_assigns_exit : trivial
+[wp] Goal typed_main_assigns_normal_part1 : trivial
+[wp] Goal typed_main_assigns_normal_part2 : not tried
+[wp] Goal typed_main_call_stringCompare_requires_validStrings : not tried
diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.res.oracle b/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.res.oracle
deleted file mode 100644
index b9066d9921a764ee6e240b742d1f8f5c6387d265..0000000000000000000000000000000000000000
--- a/src/plugins/wp/tests/wp_gallery/oracle_qualif/frama_c_hashtbl_solved.res.oracle
+++ /dev/null
@@ -1,181 +0,0 @@
-# frama-c -wp [...]
-[kernel] Parsing tests/wp_gallery/frama_c_hashtbl_solved.c (with preprocessing)
-[wp] Running WP plugin...
-[wp] Warning: Missing RTE guards
-[wp] 102 goals scheduled
-[wp] [Qed] Goal typed_eq_string_complete_eq_not_eq : Valid
-[wp] [Qed] Goal typed_eq_string_disjoint_eq_not_eq : Valid
-[wp] [Alt-Ergo] Goal typed_eq_string_loop_invariant_preserved : Valid
-[wp] [Qed] Goal typed_eq_string_loop_invariant_established : Valid
-[wp] [Alt-Ergo] Goal typed_eq_string_loop_invariant_2_preserved : Valid
-[wp] [Qed] Goal typed_eq_string_loop_invariant_2_established : Valid
-[wp] [Qed] Goal typed_eq_string_loop_assigns : Valid
-[wp] [Qed] Goal typed_eq_string_assigns_part1 : Valid
-[wp] [Qed] Goal typed_eq_string_assigns_part2 : Valid
-[wp] [Qed] Goal typed_eq_string_assigns_part3 : Valid
-[wp] [Qed] Goal typed_eq_string_assigns_part4 : Valid
-[wp] [Qed] Goal typed_eq_string_loop_variant_decrease : Valid
-[wp] [Qed] Goal typed_eq_string_loop_variant_positive : Valid
-[wp] [Alt-Ergo] Goal typed_eq_string_eq_ensures : Valid
-[wp] [Alt-Ergo] Goal typed_eq_string_not_eq_ensures : Valid
-[wp] [Alt-Ergo] Goal typed_hash_loop_invariant_preserved : Valid
-[wp] [Qed] Goal typed_hash_loop_invariant_established : Valid
-[wp] [Qed] Goal typed_hash_loop_assigns : Valid
-[wp] [Qed] Goal typed_hash_assigns_part1 : Valid
-[wp] [Qed] Goal typed_hash_assigns_part2 : Valid
-[wp] [Qed] Goal typed_hash_loop_variant_decrease : Valid
-[wp] [Qed] Goal typed_hash_loop_variant_positive : Valid
-[wp] [Qed] Goal typed_size_ensures : Valid
-[wp] [Qed] Goal typed_size_assigns : Valid
-[wp] [Alt-Ergo] Goal typed_init_ensures : Valid
-[wp] [Alt-Ergo] Goal typed_init_ensures_2 : Valid
-[wp] [Alt-Ergo] Goal typed_init_loop_invariant_preserved : Valid
-[wp] [Qed] Goal typed_init_loop_invariant_established : Valid
-[wp] [Alt-Ergo] Goal typed_init_loop_invariant_2_preserved : Valid
-[wp] [Qed] Goal typed_init_loop_invariant_2_established : Valid
-[wp] [Qed] Goal typed_init_loop_assigns_part1 : Valid
-[wp] [Qed] Goal typed_init_loop_assigns_part2 : Valid
-[wp] [Qed] Goal typed_init_assigns_part1 : Valid
-[wp] [Qed] Goal typed_init_assigns_part2 : Valid
-[wp] [Script] Goal typed_init_assigns_part3 : Valid
-[wp] [Qed] Goal typed_init_loop_variant_decrease : Valid
-[wp] [Qed] Goal typed_init_loop_variant_positive : Valid
-[wp] [Alt-Ergo] Goal typed_add_complete_full_nominal : Valid
-[wp] [Alt-Ergo] Goal typed_add_disjoint_full_nominal : Valid
-[wp] [Qed] Goal typed_add_assigns_exit : Valid
-[wp] [Qed] Goal typed_add_assigns_normal_part1 : Valid
-[wp] [Qed] Goal typed_add_assigns_normal_part2 : Valid
-[wp] [Qed] Goal typed_add_assigns_normal_part3 : Valid
-[wp] [Qed] Goal typed_add_assigns_normal_part4 : Valid
-[wp] [Qed] Goal typed_add_assigns_normal_part5 : Valid
-[wp] [Alt-Ergo] Goal typed_add_assigns_normal_part6 : Valid
-[wp] [Alt-Ergo] Goal typed_add_assigns_normal_part7 : Valid
-[wp] [Qed] Goal typed_add_assigns_normal_part8 : Valid
-[wp] [Qed] Goal typed_add_assigns_normal_part9 : Valid
-[wp] [Qed] Goal typed_add_call_hash_requires : Valid
-[wp] [Alt-Ergo] Goal typed_add_nominal_ensures : Valid
-[wp] [Alt-Ergo] Goal typed_add_nominal_ensures_2 : Valid
-[wp] [Alt-Ergo] Goal typed_add_nominal_ensures_3 : Valid
-[wp] [Alt-Ergo] Goal typed_add_nominal_ensures_4 : Valid
-[wp] [Alt-Ergo] Goal typed_add_nominal_ensures_5 : Valid
-[wp] [Qed] Goal typed_add_nominal_assigns_exit : Valid
-[wp] [Qed] Goal typed_add_nominal_assigns_normal_part1 : Valid
-[wp] [Qed] Goal typed_add_nominal_assigns_normal_part2 : Valid
-[wp] [Qed] Goal typed_add_nominal_assigns_normal_part3 : Valid
-[wp] [Qed] Goal typed_add_nominal_assigns_normal_part4 : Valid
-[wp] [Qed] Goal typed_add_nominal_assigns_normal_part5 : Valid
-[wp] [Alt-Ergo] Goal typed_add_nominal_assigns_normal_part6 : Valid
-[wp] [Alt-Ergo] Goal typed_add_nominal_assigns_normal_part7 : Valid
-[wp] [Qed] Goal typed_add_nominal_assigns_normal_part8 : Valid
-[wp] [Qed] Goal typed_add_nominal_assigns_normal_part9 : Valid
-[wp] [Alt-Ergo] Goal typed_add_full_ensures : Valid
-[wp] [Qed] Goal typed_add_full_assigns_exit : Valid
-[wp] [Qed] Goal typed_add_full_assigns_normal_part1 : Valid
-[wp] [Qed] Goal typed_add_full_assigns_normal_part2 : Valid
-[wp] [Qed] Goal typed_add_full_assigns_normal_part3 : Valid
-[wp] [Qed] Goal typed_add_full_assigns_normal_part4 : Valid
-[wp] [Qed] Goal typed_add_full_assigns_normal_part5 : Valid
-[wp] [Alt-Ergo] Goal typed_add_full_assigns_normal_part6 : Valid
-[wp] [Alt-Ergo] Goal typed_add_full_assigns_normal_part7 : Valid
-[wp] [Alt-Ergo] Goal typed_add_full_assigns_normal_part8 : Valid
-[wp] [Qed] Goal typed_add_full_assigns_normal_part9 : Valid
-[wp] [Alt-Ergo] Goal typed_mem_binding_complete_found_not_found : Valid
-[wp] [Alt-Ergo] Goal typed_mem_binding_disjoint_found_not_found : Valid
-[wp] [Alt-Ergo] Goal typed_mem_binding_loop_invariant_preserved : Valid
-[wp] [Alt-Ergo] Goal typed_mem_binding_loop_invariant_established : Valid
-[wp] [Alt-Ergo] Goal typed_mem_binding_loop_invariant_2_preserved : Valid
-[wp] [Qed] Goal typed_mem_binding_loop_invariant_2_established : Valid
-[wp] [Qed] Goal typed_mem_binding_loop_assigns_part1 : Valid
-[wp] [Qed] Goal typed_mem_binding_loop_assigns_part2 : Valid
-[wp] [Qed] Goal typed_mem_binding_assigns_exit_part1 : Valid
-[wp] [Qed] Goal typed_mem_binding_assigns_exit_part2 : Valid
-[wp] [Qed] Goal typed_mem_binding_assigns_exit_part3 : Valid
-[wp] [Qed] Goal typed_mem_binding_assigns_exit_part4 : Valid
-[wp] [Qed] Goal typed_mem_binding_assigns_normal_part1 : Valid
-[wp] [Qed] Goal typed_mem_binding_assigns_normal_part2 : Valid
-[wp] [Qed] Goal typed_mem_binding_assigns_normal_part3 : Valid
-[wp] [Qed] Goal typed_mem_binding_assigns_normal_part4 : Valid
-[wp] [Qed] Goal typed_mem_binding_assigns_normal_part5 : Valid
-[wp] [Qed] Goal typed_mem_binding_assigns_normal_part6 : Valid
-[wp] [Qed] Goal typed_mem_binding_assigns_normal_part7 : Valid
-[wp] [Qed] Goal typed_mem_binding_loop_variant_decrease : Valid
-[wp] [Qed] Goal typed_mem_binding_loop_variant_positive : Valid
-[wp] [Qed] Goal typed_mem_binding_call_hash_requires : Valid
-[wp] [Qed] Goal typed_mem_binding_call_eq_string_requires : Valid
-[wp] [Alt-Ergo] Goal typed_mem_binding_call_eq_string_requires_2 : Valid
-[wp] [Alt-Ergo] Goal typed_mem_binding_found_ensures : Valid
-[wp] [Alt-Ergo] Goal typed_mem_binding_not_found_ensures : Valid
-[wp] Proved goals:  102 / 102
-  Qed:            69 
-  Script:          1 
-  Alt-Ergo:       32
-------------------------------------------------------------
- Functions                 WP     Alt-Ergo  Total   Success
-  eq_string                11        4       15       100%
-  hash                      6        1        7       100%
-  size                      2        -        2       100%
-  init                      8        4       13       100%
-  add                      24       15       39       100%
-  mem_binding              18        8       26       100%
-------------------------------------------------------------
-[wp] Running WP plugin...
-[rte] annotating function add
-[rte] annotating function eq_string
-[rte] annotating function hash
-[rte] annotating function init
-[rte] annotating function mem_binding
-[rte] annotating function size
-[wp] 41 goals scheduled
-[wp] [Alt-Ergo] Goal typed_eq_string_assert_rte_mem_access : Valid
-[wp] [Alt-Ergo] Goal typed_eq_string_assert_rte_mem_access_2 : Valid
-[wp] [Alt-Ergo] Goal typed_eq_string_assert_rte_signed_overflow : Valid
-[wp] [Alt-Ergo] Goal typed_hash_assert_rte_mem_access : Valid
-[wp] [Qed] Goal typed_hash_assert_rte_mem_access_2 : Valid
-[wp] [Alt-Ergo] Goal typed_hash_assert_rte_signed_overflow : Valid
-[wp] [Alt-Ergo] Goal typed_size_assert_rte_mem_access : Valid
-[wp] [Alt-Ergo] Goal typed_init_assert_rte_mem_access : Valid
-[wp] [Qed] Goal typed_init_assert_rte_index_bound : Valid
-[wp] [Qed] Goal typed_init_assert_rte_index_bound_2 : Valid
-[wp] [Alt-Ergo] Goal typed_init_assert_rte_mem_access_2 : Valid
-[wp] [Alt-Ergo] Goal typed_init_assert_rte_signed_overflow : Valid
-[wp] [Alt-Ergo] Goal typed_add_assert_rte_index_bound : Valid
-[wp] [Alt-Ergo] Goal typed_add_assert_rte_mem_access : Valid
-[wp] [Qed] Goal typed_add_assert_rte_index_bound_2 : Valid
-[wp] [Alt-Ergo] Goal typed_add_assert_rte_index_bound_3 : Valid
-[wp] [Qed] Goal typed_add_assert_rte_index_bound_4 : Valid
-[wp] [Qed] Goal typed_add_assert_rte_index_bound_5 : Valid
-[wp] [Alt-Ergo] Goal typed_add_assert_rte_mem_access_2 : Valid
-[wp] [Qed] Goal typed_add_assert_rte_mem_access_3 : Valid
-[wp] [Qed] Goal typed_add_assert_rte_index_bound_6 : Valid
-[wp] [Alt-Ergo] Goal typed_add_assert_rte_mem_access_4 : Valid
-[wp] [Qed] Goal typed_add_assert_rte_mem_access_5 : Valid
-[wp] [Alt-Ergo] Goal typed_add_assert_rte_signed_overflow : Valid
-[wp] [Alt-Ergo] Goal typed_add_assert_rte_mem_access_6 : Valid
-[wp] [Alt-Ergo] Goal typed_add_assert_rte_mem_access_7 : Valid
-[wp] [Alt-Ergo] Goal typed_add_assert_rte_signed_overflow_2 : Valid
-[wp] [Alt-Ergo] Goal typed_mem_binding_assert_rte_index_bound : Valid
-[wp] [Alt-Ergo] Goal typed_mem_binding_assert_rte_index_bound_2 : Valid
-[wp] [Alt-Ergo] Goal typed_mem_binding_assert_rte_mem_access : Valid
-[wp] [Qed] Goal typed_mem_binding_assert_rte_index_bound_3 : Valid
-[wp] [Qed] Goal typed_mem_binding_assert_rte_index_bound_4 : Valid
-[wp] [Qed] Goal typed_mem_binding_assert_rte_index_bound_5 : Valid
-[wp] [Alt-Ergo] Goal typed_mem_binding_assert_rte_index_bound_6 : Valid
-[wp] [Alt-Ergo] Goal typed_mem_binding_assert_rte_mem_access_2 : Valid
-[wp] [Qed] Goal typed_mem_binding_assert_rte_index_bound_7 : Valid
-[wp] [Qed] Goal typed_mem_binding_assert_rte_index_bound_8 : Valid
-[wp] [Qed] Goal typed_mem_binding_assert_rte_index_bound_9 : Valid
-[wp] [Qed] Goal typed_mem_binding_assert_rte_index_bound_10 : Valid
-[wp] [Alt-Ergo] Goal typed_mem_binding_assert_rte_mem_access_3 : Valid
-[wp] [Alt-Ergo] Goal typed_mem_binding_assert_rte_signed_overflow : Valid
-[wp] Proved goals:   41 / 41
-  Qed:            16 
-  Alt-Ergo:       25
-------------------------------------------------------------
- Functions                 WP     Alt-Ergo  Total   Success
-  eq_string                11        7       18       100%
-  hash                      7        3       10       100%
-  size                      2        1        3       100%
-  init                     10        7       18       100%
-  add                      30       24       54       100%
-  mem_binding              25       15       40       100%
-------------------------------------------------------------
diff --git a/src/plugins/wp/tests/wp_gallery/oracle_qualif/string-compare.res.oracle b/src/plugins/wp/tests/wp_gallery/oracle_qualif/string-compare.res.oracle
new file mode 100644
index 0000000000000000000000000000000000000000..48ad48fb860195d2301df4b58092b1e8086305dc
--- /dev/null
+++ b/src/plugins/wp/tests/wp_gallery/oracle_qualif/string-compare.res.oracle
@@ -0,0 +1,89 @@
+# frama-c -wp [...]
+[kernel] Parsing tests/wp_gallery/string-compare.c (with preprocessing)
+[wp] Running WP plugin...
+[wp] [CFG] Goal stringCompare_exits_never : Valid (Unreachable)
+[wp] [CFG] Goal stringLength_exits_never : Valid (Unreachable)
+[wp] Warning: Missing RTE guards
+[wp] 51 goals scheduled
+[wp] [Qed] Goal typed_stringCompare_complete_SomeDifferent_allEqual : Valid
+[wp] [Qed] Goal typed_stringCompare_disjoint_SomeDifferent_allEqual : Valid
+[wp] [Alt-Ergo] Goal typed_stringCompare_loop_invariant_equal_preserved : Valid
+[wp] [Qed] Goal typed_stringCompare_loop_invariant_equal_established : Valid
+[wp] [Alt-Ergo] Goal typed_stringCompare_loop_invariant_gauge_preserved : Valid
+[wp] [Qed] Goal typed_stringCompare_loop_invariant_gauge_established : Valid
+[wp] [Alt-Ergo] Goal typed_stringCompare_loop_invariant_gauge_s1_preserved : Valid
+[wp] [Qed] Goal typed_stringCompare_loop_invariant_gauge_s1_established : Valid
+[wp] [Alt-Ergo] Goal typed_stringCompare_loop_invariant_gauge_s2_preserved : Valid
+[wp] [Qed] Goal typed_stringCompare_loop_invariant_gauge_s2_established : Valid
+[wp] [Alt-Ergo] Goal typed_stringCompare_loop_invariant_not_eos_preserved : Valid
+[wp] [Qed] Goal typed_stringCompare_loop_invariant_not_eos_established : Valid
+[wp] [Alt-Ergo] Goal typed_stringCompare_loop_invariant_strlen_s1_preserved : Valid
+[wp] [Alt-Ergo] Goal typed_stringCompare_loop_invariant_strlen_s1_established : Valid
+[wp] [Alt-Ergo] Goal typed_stringCompare_loop_invariant_strlen_s2_preserved : Valid
+[wp] [Alt-Ergo] Goal typed_stringCompare_loop_invariant_strlen_s2_established : Valid
+[wp] [Alt-Ergo] Goal typed_stringCompare_assert_different : Valid
+[wp] [Qed] Goal typed_stringCompare_loop_assigns_part1 : Valid
+[wp] [Qed] Goal typed_stringCompare_loop_assigns_part2 : Valid
+[wp] [Qed] Goal typed_stringCompare_loop_assigns_part3 : Valid
+[wp] [Qed] Goal typed_stringCompare_assigns_part1 : Valid
+[wp] [Qed] Goal typed_stringCompare_assigns_part2 : Valid
+[wp] [Qed] Goal typed_stringCompare_assigns_part3 : Valid
+[wp] [Qed] Goal typed_stringCompare_assigns_part4 : Valid
+[wp] [Qed] Goal typed_stringCompare_assigns_part5 : Valid
+[wp] [Qed] Goal typed_stringCompare_assigns_part6 : Valid
+[wp] [Qed] Goal typed_stringCompare_assigns_part7 : Valid
+[wp] [Qed] Goal typed_stringCompare_assigns_part8 : Valid
+[wp] [Qed] Goal typed_stringCompare_assigns_part9 : Valid
+[wp] [Alt-Ergo] Goal typed_stringCompare_allEqual_ensures : Valid
+[wp] [Alt-Ergo] Goal typed_stringCompare_SomeDifferent_ensures : Valid
+[wp] [Alt-Ergo] Goal typed_stringLength_ensures_rightResult : Valid
+[wp] [Alt-Ergo] Goal typed_stringLength_ensures_rightEndCharacter : Valid
+[wp] [Alt-Ergo] Goal typed_stringLength_loop_invariant_preserved : Valid
+[wp] [Qed] Goal typed_stringLength_loop_invariant_established : Valid
+[wp] [Alt-Ergo] Goal typed_stringLength_loop_invariant_2_preserved : Valid
+[wp] [Qed] Goal typed_stringLength_loop_invariant_2_established : Valid
+[wp] [Qed] Goal typed_stringLength_loop_assigns_part1 : Valid
+[wp] [Qed] Goal typed_stringLength_loop_assigns_part2 : Valid
+[wp] [Qed] Goal typed_stringLength_assigns_part1 : Valid
+[wp] [Qed] Goal typed_stringLength_assigns_part2 : Valid
+[wp] [Qed] Goal typed_stringLength_assigns_part3 : Valid
+[wp] [Qed] Goal typed_stringLength_assigns_part4 : Valid
+[wp] [Qed] Goal typed_stringLength_assigns_part5 : Valid
+[wp] [Alt-Ergo] Goal typed_main_ensures : Valid
+[wp] [Qed] Goal typed_main_exits_never : Valid
+[wp] [Qed] Goal typed_main_assert : Valid
+[wp] [Qed] Goal typed_main_assigns_exit : Valid
+[wp] [Qed] Goal typed_main_assigns_normal_part1 : Valid
+[wp] [Qed] Goal typed_main_assigns_normal_part2 : Valid
+[wp] [Alt-Ergo] Goal typed_main_call_stringCompare_requires_validStrings : Valid
+[wp] Proved goals:   51 / 51
+  Qed:            33 
+  Alt-Ergo:       18
+------------------------------------------------------------
+ Functions                 WP     Alt-Ergo  Total   Success
+  stringCompare            19       12       31       100%
+  stringLength              9        4       13       100%
+  main                      5        2        7       100%
+------------------------------------------------------------
+[wp] Running WP plugin...
+[rte] annotating function main
+[rte] annotating function stringCompare
+[rte] annotating function stringLength
+[wp] 8 goals scheduled
+[wp] [Alt-Ergo] Goal typed_stringCompare_assert_rte_mem_access : Valid
+[wp] [Alt-Ergo] Goal typed_stringCompare_assert_rte_mem_access_2 : Valid
+[wp] [Qed] Goal typed_stringCompare_assert_rte_mem_access_3 : Valid
+[wp] [Qed] Goal typed_stringCompare_assert_rte_mem_access_4 : Valid
+[wp] [Alt-Ergo] Goal typed_stringCompare_assert_rte_mem_access_5 : Valid
+[wp] [Alt-Ergo] Goal typed_stringCompare_assert_rte_signed_overflow : Valid
+[wp] [Alt-Ergo] Goal typed_stringCompare_assert_rte_signed_overflow_2 : Valid
+[wp] [Alt-Ergo] Goal typed_stringLength_assert_rte_mem_access : Valid
+[wp] Proved goals:    8 / 8
+  Qed:             2 
+  Alt-Ergo:        6
+------------------------------------------------------------
+ Functions                 WP     Alt-Ergo  Total   Success
+  stringCompare            21       17       38       100%
+  stringLength              9        5       14       100%
+  main                      5        2        7       100%
+------------------------------------------------------------
diff --git a/src/plugins/wp/tests/wp_gallery/string-compare.c b/src/plugins/wp/tests/wp_gallery/string-compare.c
new file mode 100644
index 0000000000000000000000000000000000000000..950ed7f72d78a0e34da6241c20251f29787cde37
--- /dev/null
+++ b/src/plugins/wp/tests/wp_gallery/string-compare.c
@@ -0,0 +1,75 @@
+/* run.config
+   OPT: -wp-no-print -wp-rte
+*/
+
+/* run.config_qualif
+   OPT: -then -wp-rte -wp
+*/
+
+#include <stdint.h>
+#include <string.h>
+#include <stdio.h>
+
+/*@ requires validStrings: valid_read_string(s1) && valid_read_string(s2);
+    assigns \nothing ;
+    allocates \nothing ;
+    frees \nothing ;
+    exits never: \false ;
+    behavior allEqual:
+        assumes \forall integer k; 0 <= k <= strlen(s1) ==> s1[k] == s2[k];
+        ensures \result == 0;
+    behavior SomeDifferent:
+        assumes \exists integer k; 0 <= k <= strlen(s1) && s1[k] != s2[k];
+        ensures \result != 0;
+
+    disjoint behaviors;
+    complete behaviors; */
+int stringCompare(const char* s1, const char* s2) {
+    if (s1 == s2)
+        return 0;
+
+    /*@ loop invariant strlen_s1: 0 <= strlen(s1) <= \at(strlen(s1), Pre);
+        loop invariant strlen_s2: 0 <= strlen(s2) <= \at(strlen(s2), Pre);
+        loop invariant gauge_s1: s1 + strlen(s1) == \at(s1 + strlen(s1), Pre);
+        loop invariant gauge_s2: s2 + strlen(s2) == \at(s2 + strlen(s2), Pre);
+        loop invariant gauge: \at(strlen(s1), Pre) - strlen(s1) == \at(strlen(s2), Pre) - strlen(s2);
+        loop invariant equal: \forall integer j; 0<= j < \at(strlen(s1), Pre) - strlen(s1) ==> \at(s1,Pre)[j] == \at(s2,Pre)[j];
+        loop invariant not_eos: \forall integer j; 0<= j < \at(strlen(s1), Pre) - strlen(s1) ==> \at(s1,Pre)[j] != 0;
+        loop assigns s1, s2; */
+    while (*s1 == *(s2++))
+    {
+       if (*(s1++) == '\0')
+         return 0;
+    }
+
+    //@ assert different: \let k = \at(strlen(s1), Pre) - strlen(s1) ; \at(s1,Pre)[k] != \at(s2,Pre)[k];
+    return *(s1) - *(--s2);
+}
+
+/*@ requires validString: valid_string(str);
+    requires validLength: 0 <= strlen(str) < SIZE_MAX;
+    assigns \nothing ;
+    exits never: \false ;
+    ensures rightResult: \result == strlen(\old(str));
+    ensures rightEndCharacter: str[\result] == '\0' ;  */
+size_t stringLength(const char* str) {
+  const char* s = str ;
+
+  /*@ loop assigns s ;
+      loop invariant s + strlen(s) == \at(str + strlen(str),Pre);
+      loop invariant 0 <= strlen(s) <= \at(strlen(str),Pre); */
+  while (*s++ != '\0');
+  return --s - str;
+}
+
+/*@ assigns \nothing ;
+    exits never: \false ;
+    ensures \result != 0 ;*/
+int main(void) {
+
+   const char hello[] = { 'h', 'e', 'l', 'l', 'o', '\0'};
+   const char helli[] =  { 'h', 'e', 'l', 'l', 'i', '\0'};
+
+   /*@ assert \valid_read(&hello[0]) && \valid_read(&helli[0]) ; */
+   return stringCompare(hello, helli);
+} 
diff --git a/src/plugins/wp/tests/wp_hoare/model_lookup.i b/src/plugins/wp/tests/wp_hoare/model_lookup.i
new file mode 100644
index 0000000000000000000000000000000000000000..ab8f168e9fa962f72a586f459b0671242b41c6f1
--- /dev/null
+++ b/src/plugins/wp/tests/wp_hoare/model_lookup.i
@@ -0,0 +1,14 @@
+/* run.config
+   OPT: -wp-prop C
+*/
+/* run.config_qualif
+   DONTRUN:
+*/
+
+void foo(int y){
+  int x ;
+  // This assertion SHALL BE VISIBLE in the VC generated for C
+  //@ assert 0 <= y <= 4 ==> \false ;
+  x = 1 ;
+  //@ check C: x == y ;
+}
diff --git a/src/plugins/wp/tests/wp_hoare/oracle/model_lookup.res.oracle b/src/plugins/wp/tests/wp_hoare/oracle/model_lookup.res.oracle
new file mode 100644
index 0000000000000000000000000000000000000000..21c6e1bbce770fc3066946956093ce2196b4242b
--- /dev/null
+++ b/src/plugins/wp/tests/wp_hoare/oracle/model_lookup.res.oracle
@@ -0,0 +1,17 @@
+# frama-c -wp [...]
+[kernel] Parsing tests/wp_hoare/model_lookup.i (no preprocessing)
+[wp] Running WP plugin...
+[wp] Warning: Missing RTE guards
+------------------------------------------------------------
+  Function foo
+------------------------------------------------------------
+
+Goal Check 'C' (file tests/wp_hoare/model_lookup.i, line 13):
+Assume {
+  Type: is_sint32(y).
+  (* Assertion *)
+  Have: ((0 <= y) -> ((y <= 4) -> false)).
+}
+Prove: y = 1.
+
+------------------------------------------------------------
diff --git a/tests/builtins/diff_apron b/tests/builtins/diff_apron
index 138fb410e262c773d22565a154e37ee6eab65e31..befd75c34a2d5c9b2763732afa55aac09a3e621c 100644
--- a/tests/builtins/diff_apron
+++ b/tests/builtins/diff_apron
@@ -1,134 +1,3 @@
-diff tests/builtins/oracle/Longinit_sequencer.res.oracle tests/builtins/oracle_apron/Longinit_sequencer.res.oracle
-59,62c59,78
-< [eva] tests/builtins/long_init.c:29: Reusing old results for call to subanalyze
-< [eva] tests/builtins/long_init.c:29: Reusing old results for call to subanalyze
-< [eva] tests/builtins/long_init.c:29: Reusing old results for call to subanalyze
-< [eva] tests/builtins/long_init.c:29: Reusing old results for call to subanalyze
----
-> [eva] computing for function subanalyze <- analyze <- init_inner <- init_outer <- 
->                           main.
->   Called from tests/builtins/long_init.c:29.
-> [eva] Recording results for subanalyze
-> [eva] Done for function subanalyze
-> [eva] computing for function subanalyze <- analyze <- init_inner <- init_outer <- 
->                           main.
->   Called from tests/builtins/long_init.c:29.
-> [eva] Recording results for subanalyze
-> [eva] Done for function subanalyze
-> [eva] computing for function subanalyze <- analyze <- init_inner <- init_outer <- 
->                           main.
->   Called from tests/builtins/long_init.c:29.
-> [eva] Recording results for subanalyze
-> [eva] Done for function subanalyze
-> [eva] computing for function subanalyze <- analyze <- init_inner <- init_outer <- 
->                           main.
->   Called from tests/builtins/long_init.c:29.
-> [eva] Recording results for subanalyze
-> [eva] Done for function subanalyze
-148,149c164,211
-< [eva] tests/builtins/long_init.c:93: Reusing old results for call to analyze
-< [eva] tests/builtins/long_init.c:94: Reusing old results for call to analyze
----
-> [eva] computing for function analyze <- main.
->   Called from tests/builtins/long_init.c:93.
-> [eva] computing for function subanalyze <- analyze <- main.
->   Called from tests/builtins/long_init.c:29.
-> [eva] Recording results for subanalyze
-> [eva] Done for function subanalyze
-> [eva] computing for function subanalyze <- analyze <- main.
->   Called from tests/builtins/long_init.c:29.
-> [eva] Recording results for subanalyze
-> [eva] Done for function subanalyze
-> [eva] computing for function subanalyze <- analyze <- main.
->   Called from tests/builtins/long_init.c:29.
-> [eva] Recording results for subanalyze
-> [eva] Done for function subanalyze
-> [eva] computing for function subanalyze <- analyze <- main.
->   Called from tests/builtins/long_init.c:29.
-> [eva] Recording results for subanalyze
-> [eva] Done for function subanalyze
-> [eva] computing for function subanalyze <- analyze <- main.
->   Called from tests/builtins/long_init.c:29.
-> [eva] Recording results for subanalyze
-> [eva] Done for function subanalyze
-> [eva] Recording results for analyze
-> [eva] Done for function analyze
-> [eva] computing for function analyze <- main.
->   Called from tests/builtins/long_init.c:94.
-> [eva] computing for function subanalyze <- analyze <- main.
->   Called from tests/builtins/long_init.c:29.
-> [eva] Recording results for subanalyze
-> [eva] Done for function subanalyze
-> [eva] computing for function subanalyze <- analyze <- main.
->   Called from tests/builtins/long_init.c:29.
-> [eva] Recording results for subanalyze
-> [eva] Done for function subanalyze
-> [eva] computing for function subanalyze <- analyze <- main.
->   Called from tests/builtins/long_init.c:29.
-> [eva] Recording results for subanalyze
-> [eva] Done for function subanalyze
-> [eva] computing for function subanalyze <- analyze <- main.
->   Called from tests/builtins/long_init.c:29.
-> [eva] Recording results for subanalyze
-> [eva] Done for function subanalyze
-> [eva] computing for function subanalyze <- analyze <- main.
->   Called from tests/builtins/long_init.c:29.
-> [eva] Recording results for subanalyze
-> [eva] Done for function subanalyze
-> [eva] Recording results for analyze
-> [eva] Done for function analyze
-320c382
-<   tests/builtins/result/Longinit_sequencer.sav
----
->   tests/builtins/result_apron/Longinit_sequencer.sav
-411,414c473,488
-< [eva] tests/builtins/long_init2.c:29: Reusing old results for call to subanalyze
-< [eva] tests/builtins/long_init2.c:29: Reusing old results for call to subanalyze
-< [eva] tests/builtins/long_init2.c:29: Reusing old results for call to subanalyze
-< [eva] tests/builtins/long_init2.c:29: Reusing old results for call to subanalyze
----
-> [eva] computing for function subanalyze <- analyze <- main.
->   Called from tests/builtins/long_init2.c:29.
-> [eva] Recording results for subanalyze
-> [eva] Done for function subanalyze
-> [eva] computing for function subanalyze <- analyze <- main.
->   Called from tests/builtins/long_init2.c:29.
-> [eva] Recording results for subanalyze
-> [eva] Done for function subanalyze
-> [eva] computing for function subanalyze <- analyze <- main.
->   Called from tests/builtins/long_init2.c:29.
-> [eva] Recording results for subanalyze
-> [eva] Done for function subanalyze
-> [eva] computing for function subanalyze <- analyze <- main.
->   Called from tests/builtins/long_init2.c:29.
-> [eva] Recording results for subanalyze
-> [eva] Done for function subanalyze
-556c630
-<   tests/builtins/result/Longinit_sequencer.sav
----
->   tests/builtins/result_apron/Longinit_sequencer.sav
-643,646c717,732
-< [eva] tests/builtins/long_init3.c:29: Reusing old results for call to subanalyze
-< [eva] tests/builtins/long_init3.c:29: Reusing old results for call to subanalyze
-< [eva] tests/builtins/long_init3.c:29: Reusing old results for call to subanalyze
-< [eva] tests/builtins/long_init3.c:29: Reusing old results for call to subanalyze
----
-> [eva] computing for function subanalyze <- analyze <- main.
->   Called from tests/builtins/long_init3.c:29.
-> [eva] Recording results for subanalyze
-> [eva] Done for function subanalyze
-> [eva] computing for function subanalyze <- analyze <- main.
->   Called from tests/builtins/long_init3.c:29.
-> [eva] Recording results for subanalyze
-> [eva] Done for function subanalyze
-> [eva] computing for function subanalyze <- analyze <- main.
->   Called from tests/builtins/long_init3.c:29.
-> [eva] Recording results for subanalyze
-> [eva] Done for function subanalyze
-> [eva] computing for function subanalyze <- analyze <- main.
->   Called from tests/builtins/long_init3.c:29.
-> [eva] Recording results for subanalyze
-> [eva] Done for function subanalyze
 diff tests/builtins/oracle/allocated.0.res.oracle tests/builtins/oracle_apron/allocated.0.res.oracle
 260a261,263
 > [eva] tests/builtins/allocated.c:127: Call to builtin __fc_vla_alloc
diff --git a/tests/builtins/diff_bitwise b/tests/builtins/diff_bitwise
index e2e2efc04cf4b7157d7d1d23eed26b1e58c1983f..98cc819af464d4d56ee7b45393da6c4b1eb5dc02 100644
--- a/tests/builtins/diff_bitwise
+++ b/tests/builtins/diff_bitwise
@@ -1,12 +1,3 @@
-diff tests/builtins/oracle/Longinit_sequencer.res.oracle tests/builtins/oracle_bitwise/Longinit_sequencer.res.oracle
-320c320
-<   tests/builtins/result/Longinit_sequencer.sav
----
->   tests/builtins/result_bitwise/Longinit_sequencer.sav
-556c556
-<   tests/builtins/result/Longinit_sequencer.sav
----
->   tests/builtins/result_bitwise/Longinit_sequencer.sav
 diff tests/builtins/oracle/allocated.0.res.oracle tests/builtins/oracle_bitwise/allocated.0.res.oracle
 260a261,263
 > [eva] tests/builtins/allocated.c:127: Call to builtin __fc_vla_alloc
diff --git a/tests/builtins/diff_equalities b/tests/builtins/diff_equalities
index 3956b94f2499324860cf5298288352ab3e415043..45b1a53ba8801c496b17d1222d3f3a99a3c659cc 100644
--- a/tests/builtins/diff_equalities
+++ b/tests/builtins/diff_equalities
@@ -1,12 +1,3 @@
-diff tests/builtins/oracle/Longinit_sequencer.res.oracle tests/builtins/oracle_equalities/Longinit_sequencer.res.oracle
-320c320
-<   tests/builtins/result/Longinit_sequencer.sav
----
->   tests/builtins/result_equalities/Longinit_sequencer.sav
-556c556
-<   tests/builtins/result/Longinit_sequencer.sav
----
->   tests/builtins/result_equalities/Longinit_sequencer.sav
 diff tests/builtins/oracle/alloc_weak.res.oracle tests/builtins/oracle_equalities/alloc_weak.res.oracle
 36,37d35
 < [eva:alarm] tests/builtins/alloc_weak.c:30: Warning: 
diff --git a/tests/builtins/diff_gauges b/tests/builtins/diff_gauges
index ca4a1580fa4e366cd777744846c0120ddd2509ba..aed43a80b458bfa6d5b81eceee67c7bd4ede2dff 100644
--- a/tests/builtins/diff_gauges
+++ b/tests/builtins/diff_gauges
@@ -1,12 +1,3 @@
-diff tests/builtins/oracle/Longinit_sequencer.res.oracle tests/builtins/oracle_gauges/Longinit_sequencer.res.oracle
-320c320
-<   tests/builtins/result/Longinit_sequencer.sav
----
->   tests/builtins/result_gauges/Longinit_sequencer.sav
-556c556
-<   tests/builtins/result/Longinit_sequencer.sav
----
->   tests/builtins/result_gauges/Longinit_sequencer.sav
 diff tests/builtins/oracle/linked_list.0.res.oracle tests/builtins/oracle_gauges/linked_list.0.res.oracle
 1122a1123,1128
 > [eva] computing for function printf_va_1 <- main.
diff --git a/tests/builtins/diff_octagons b/tests/builtins/diff_octagons
index c2b18889ac58a637ec38f7f04c918867bbe336b8..d091e1809e5189e23acb6a6d970b7b1b81b6a635 100644
--- a/tests/builtins/diff_octagons
+++ b/tests/builtins/diff_octagons
@@ -1,12 +1,3 @@
-diff tests/builtins/oracle/Longinit_sequencer.res.oracle tests/builtins/oracle_octagons/Longinit_sequencer.res.oracle
-320c320
-<   tests/builtins/result/Longinit_sequencer.sav
----
->   tests/builtins/result_octagons/Longinit_sequencer.sav
-556c556
-<   tests/builtins/result/Longinit_sequencer.sav
----
->   tests/builtins/result_octagons/Longinit_sequencer.sav
 diff tests/builtins/oracle/allocated.0.res.oracle tests/builtins/oracle_octagons/allocated.0.res.oracle
 273c273
 <   j ∈ [1..2147483647]
diff --git a/tests/builtins/diff_symblocs b/tests/builtins/diff_symblocs
index f640a0f73229eb6388e8c2b9526126abe4f4eeaa..f1bda9cc8ce275efb1caebe25785b40bea3b6104 100644
--- a/tests/builtins/diff_symblocs
+++ b/tests/builtins/diff_symblocs
@@ -1,12 +1,3 @@
-diff tests/builtins/oracle/Longinit_sequencer.res.oracle tests/builtins/oracle_symblocs/Longinit_sequencer.res.oracle
-320c320
-<   tests/builtins/result/Longinit_sequencer.sav
----
->   tests/builtins/result_symblocs/Longinit_sequencer.sav
-556c556
-<   tests/builtins/result/Longinit_sequencer.sav
----
->   tests/builtins/result_symblocs/Longinit_sequencer.sav
 diff tests/builtins/oracle/alloc_weak.res.oracle tests/builtins/oracle_symblocs/alloc_weak.res.oracle
 36,37d35
 < [eva:alarm] tests/builtins/alloc_weak.c:30: Warning: 
diff --git a/tests/builtins/long_init.c b/tests/builtins/long_init.c
deleted file mode 100644
index c244b17b5e377a30cd1b3c1707309d7afd422031..0000000000000000000000000000000000000000
--- a/tests/builtins/long_init.c
+++ /dev/null
@@ -1,108 +0,0 @@
-/* run.config*
-   DONTRUN: tests run by Longinit_sequencer.i
-*/
-
-#include <stdlib.h>
-
-#define N1 10
-#define N2 50
-#define N3 10
-
-volatile int nondet;
-
-int a1[N1];
-struct st {
-  unsigned long t[N2];
-  double d[N3];
-} stuff;
-
-double subanalyze(double *d) {
-  return *d < 15 ? 1.0 : *d / 15.0;
-}
-
-double analyze(int *a, unsigned long *b, double *c) {
-  int i;
-  double res = 0.0;
-  /*@ slevel 5; */
-  for (i = 0; i < 5; i++) {
-    res += a[i + 3] + b[i * 2] + c[i + 1];
-    res += subanalyze(&c[i + 1]);
-  }
-  return res;
-}
-
-char garbled_mix = (char) "abc";
-char *s = "abc";
-//int another_global = 42; // from init_global2.c
-//int yet_another_global = 43; // from init_global3.c
-double *pr, *pr2, *pr_escaping, **ppr;
-int *alloc1, *alloc2, *alloc3;
-
-double dmin(double *pd1, double *pd2) {
-  if (*pd1 < *pd2) return *pd1;
-  else return *pd2;
-}
-
-int fun(int k) {
-  return k+1;
-}
-
-typedef int (*i_fp_i)(int);
-i_fp_i fp = &fun;
-
-/*@ assigns a1[..], stuff, pr, pr2, pr_escaping, alloc1, alloc2
-      \from \nothing; */
-void init_inner(int n, char const *tea) {
-  int i;
-  /*@ slevel N3; */
-  for (i = 0; i < N1; i++) {
-    a1[i] = i;
-  }
-  for (i = 0; i < N2; i++) {
-    stuff.t[i] = a1[i/5] + 3;
-  }
-  for (i = 0; i < N3; i++) {
-    stuff.d[i] = 3.125 * i;
-  }
-  /*@ slevel 0; */
-  double r = analyze(a1, stuff.t, stuff.d);
-  double r2 = analyze(a1, stuff.t+1, stuff.d+1);
-  pr = nondet ? &r : &r2;
-  pr2 = &r2;
-  pr_escaping = &r2;
-  alloc1 = malloc(sizeof(int*));
-  *alloc1 = (int) alloc1;
-  alloc2 = malloc(2*sizeof(int));
-  *alloc2 = 37;
-  free(alloc2);
-}
-
-int inited;
-
-/*@ assigns a1[..], stuff, pr, pr2, pr_escaping, alloc1, alloc2, inited
-      \from \nothing; */
-void init_outer() {
-    init_inner(13, "tea");
-    inited = 1;
-}
-
-int main() {
-  init_outer();
-  char *sa = s;
-  Frama_C_dump_each();
-  double r = analyze(a1, stuff.t, stuff.d);
-  double r2 = analyze(a1, stuff.t+1, stuff.d+1);
-  pr = nondet ? &r : &r2;
-  pr2 = nondet ? &r : &r2;
-  ppr = nondet ? &pr : &pr2;
-  double dm = dmin(pr, *ppr);
-  int res_from_fp = (*fp)(31);
-  int res = (int)r % 256;
-  *alloc1 = inited;
-  int local = *alloc1;
-  free(alloc1);
-  alloc3 = malloc(sizeof(int));
-  //local = another_global; // from init_global2.c
-  //int local2 = yet_another_global; // from init_global3.c
-  return 0;
-}
diff --git a/tests/builtins/long_init2.c b/tests/builtins/long_init2.c
deleted file mode 100644
index 065358b2e68c111dec1dbeaaa9636b5bc9ee7e69..0000000000000000000000000000000000000000
--- a/tests/builtins/long_init2.c
+++ /dev/null
@@ -1,108 +0,0 @@
-/* run.config*
-   DONTRUN: tests run by Longinit_sequencer.i
-*/
-
-#include <stdlib.h>
-
-#define N1 10
-#define N2 50
-#define N3 10
-
-volatile int nondet;
-
-int a1[N1];
-struct st {
-  unsigned long t[N2];
-  double d[N3];
-} stuff;
-
-double subanalyze(double *d) {
-  return *d < 15 ? 1.0 : *d / 15.0;
-}
-
-double analyze(int *a, unsigned long *b, double *c) {
-  int i;
-  double res = 0.0;
-  /*@ slevel 5; */
-  for (i = 0; i < 5; i++) {
-    res += a[i + 3] + b[i * 2] + c[i + 1];
-    res += subanalyze(&c[i + 1]);
-  }
-  return res;
-}
-
-char garbled_mix = (char) "abc";
-char *s = "abc";
-int another_global = 42;
-//int yet_another_global = 43; // from init_global3.c
-double *pr, *pr2, *pr_escaping, **ppr;
-int *alloc1, *alloc2, *alloc3;
-
-double dmin(double *pd1, double *pd2) {
-  if (*pd1 < *pd2) return *pd1;
-  else return *pd2;
-}
-
-int fun(int k) {
-  return k+1;
-}
-
-typedef int (*i_fp_i)(int);
-i_fp_i fp = &fun;
-
-/*@ assigns a1[..], stuff, pr, pr2, pr_escaping, alloc1, alloc2
-      \from \nothing; */
-void init_inner(int n, char const *tea) {
-  int i;
-  /*@ slevel N3; */
-  for (i = 0; i < N1; i++) {
-    a1[i] = i;
-  }
-  for (i = 0; i < N2; i++) {
-    stuff.t[i] = a1[i/5] + 3;
-  }
-  for (i = 0; i < N3; i++) {
-    stuff.d[i] = 3.125 * i;
-  }
-  /*@ slevel 0; */
-  double r = analyze(a1, stuff.t, stuff.d);
-  double r2 = analyze(a1, stuff.t+1, stuff.d+1);
-  pr = nondet ? &r : &r2;
-  pr2 = &r2;
-  pr_escaping = &r2;
-  alloc1 = malloc(sizeof(int*));
-  *alloc1 = (int) alloc1;
-  alloc2 = malloc(2*sizeof(int));
-  *alloc2 = 37;
-  free(alloc2);
-}
-
-int inited;
-
-/*@ assigns a1[..], stuff, pr, pr2, pr_escaping, alloc1, alloc2, inited
-      \from \nothing; */
-void init_outer() {
-    init_inner(13, "tea");
-    inited = 1;
-}
-
-int main() {
-  init_outer();
-  char *sa = s;
-  Frama_C_dump_each();
-  double r = analyze(a1, stuff.t, stuff.d);
-  double r2 = analyze(a1, stuff.t+1, stuff.d+1);
-  pr = nondet ? &r : &r2;
-  pr2 = nondet ? &r : &r2;
-  ppr = nondet ? &pr : &pr2;
-  double dm = dmin(pr, *ppr);
-  int res_from_fp = (*fp)(31);
-  int res = (int)r % 256;
-  *alloc1 = inited;
-  int local = *alloc1;
-  free(alloc1);
-  alloc3 = malloc(sizeof(int));
-  local = another_global;
-  //int local2 = yet_another_global; // from init_global3.c
-  return 0;
-}
diff --git a/tests/builtins/long_init3.c b/tests/builtins/long_init3.c
deleted file mode 100644
index b3b97e7aee3843079508e5a32d403045ec253e08..0000000000000000000000000000000000000000
--- a/tests/builtins/long_init3.c
+++ /dev/null
@@ -1,108 +0,0 @@
-/* run.config*
-   DONTRUN: tests run by Longinit_sequencer.i
-*/
-
-#include <stdlib.h>
-
-#define N1 10
-#define N2 50
-#define N3 10
-
-volatile int nondet;
-
-int a1[N1];
-struct st {
-  unsigned long t[N2];
-  double d[N3];
-} stuff;
-
-double subanalyze(double *d) {
-  return *d < 15 ? 1.0 : *d / 15.0;
-}
-
-double analyze(int *a, unsigned long *b, double *c) {
-  int i;
-  double res = 0.0;
-  /*@ slevel 5; */
-  for (i = 0; i < 5; i++) {
-    res += a[i + 3] + b[i * 2] + c[i + 1];
-    res += subanalyze(&c[i + 1]);
-  }
-  return res;
-}
-
-char garbled_mix = (char) "abc";
-char *s = "abc";
-int another_global = 42;
-int yet_another_global = 43;
-double *pr, *pr2, *pr_escaping, **ppr;
-int *alloc1, *alloc2, *alloc3;
-
-double dmin(double *pd1, double *pd2) {
-  if (*pd1 < *pd2) return *pd1;
-  else return *pd2;
-}
-
-int fun(int k) {
-  return k+1;
-}
-
-typedef int (*i_fp_i)(int);
-i_fp_i fp = &fun;
-
-/*@ assigns a1[..], stuff, pr, pr2, pr_escaping, alloc1, alloc2
-      \from \nothing; */
-void init_inner(int n, char const *tea) {
-  int i;
-  /*@ slevel N3; */
-  for (i = 0; i < N1; i++) {
-    a1[i] = i;
-  }
-  for (i = 0; i < N2; i++) {
-    stuff.t[i] = a1[i/5] + 3;
-  }
-  for (i = 0; i < N3; i++) {
-    stuff.d[i] = 3.125 * i;
-  }
-  /*@ slevel 0; */
-  double r = analyze(a1, stuff.t, stuff.d);
-  double r2 = analyze(a1, stuff.t+1, stuff.d+1);
-  pr = nondet ? &r : &r2;
-  pr2 = &r2;
-  pr_escaping = &r2;
-  alloc1 = malloc(sizeof(int*));
-  *alloc1 = (int) alloc1;
-  alloc2 = malloc(2*sizeof(int));
-  *alloc2 = 37;
-  free(alloc2);
-}
-
-int inited;
-
-/*@ assigns a1[..], stuff, pr, pr2, pr_escaping, alloc1, alloc2, inited
-      \from \nothing; */
-void init_outer() {
-    init_inner(13, "tea");
-    inited = 1;
-}
-
-int main() {
-  init_outer();
-  char *sa = s;
-  Frama_C_dump_each();
-  double r = analyze(a1, stuff.t, stuff.d);
-  double r2 = analyze(a1, stuff.t+1, stuff.d+1);
-  pr = nondet ? &r : &r2;
-  pr2 = nondet ? &r : &r2;
-  ppr = nondet ? &pr : &pr2;
-  double dm = dmin(pr, *ppr);
-  int res_from_fp = (*fp)(31);
-  int res = (int)r % 256;
-  *alloc1 = inited;
-  int local = *alloc1;
-  free(alloc1);
-  alloc3 = malloc(sizeof(int));
-  local = another_global;
-  int local2 = yet_another_global;
-  return 0;
-}
diff --git a/tests/fc_script/oracle/make-wrapper.res b/tests/fc_script/oracle/make-wrapper.res
index 9faa818ae65c5e1aa39fdd07142c63896fb6e6cc..18747999ef64bba9e9fd47673c4c03caacef85f2 100644
--- a/tests/fc_script/oracle/make-wrapper.res
+++ b/tests/fc_script/oracle/make-wrapper.res
@@ -1,10 +1,10 @@
 
-Command: ../../bin/frama-c  -kernel-warn-key annot:missing-spec=abort -kernel-warn-key typing:implicit-function-declaration=abort   -cpp-extra-args="" make-wrapper.c make-wrapper2.c(B
+Command: ../../bin/frama-c -kernel-warn-key annot:missing-spec=abort -kernel-warn-key typing:implicit-function-declaration=abort -cpp-extra-args= make-wrapper.c make-wrapper2.c
 
 [kernel] Parsing make-wrapper.c (with preprocessing)
 [kernel] Parsing make-wrapper2.c (with preprocessing)
 
-Command: ../../bin/frama-c  -kernel-warn-key annot:missing-spec=abort -kernel-warn-key typing:implicit-function-declaration=abort  -eva -eva-no-print -eva-no-show-progress -eva-msg-key=-initial-state -eva-print-callstacks -eva-warn-key alarm=inactive -no-deps-print -no-calldeps-print -eva-warn-key garbled-mix -calldeps -from-verbose 0   -eva-warn-key builtins:missing-spec=abort (B
+Command: ../../bin/frama-c -kernel-warn-key annot:missing-spec=abort -kernel-warn-key typing:implicit-function-declaration=abort -eva -eva-no-print -eva-no-show-progress -eva-msg-key=-initial-state -eva-print-callstacks -eva-warn-key alarm=inactive -no-deps-print -no-calldeps-print -eva-warn-key garbled-mix -calldeps -from-verbose 0 -eva-warn-key builtins:missing-spec=abort
 
 [eva] Analyzing a complete application starting at main
 [eva] Computing initial state
diff --git a/tests/slicing/min_call.i b/tests/slicing/min_call.c
similarity index 82%
rename from tests/slicing/min_call.i
rename to tests/slicing/min_call.c
index a06325b8a588960a7b3d3c0978a35b97bf7fd4d8..68ec3eade51dc8f01b2cd7023028eb47dc3cc8a1 100644
--- a/tests/slicing/min_call.i
+++ b/tests/slicing/min_call.c
@@ -5,6 +5,6 @@
 */
 
 /* dummy source file in order to test minimal calls feature
- * on select_return.c  */
+ * on select_return.i  */
 
-#include "tests/slicing/select_return.c"
+#include "tests/slicing/select_return.i"
diff --git a/tests/slicing/oracle/min_call.res.oracle b/tests/slicing/oracle/min_call.res.oracle
index df7c7535627961707aa541e3bca3af9b477e230d..c994a5af1ffa202026776e227c6113e34047aa75 100644
--- a/tests/slicing/oracle/min_call.res.oracle
+++ b/tests/slicing/oracle/min_call.res.oracle
@@ -1,4 +1,594 @@
-[kernel] Parsing tests/slicing/min_call.i (no preprocessing)
-[kernel] User Error: cannot find entry point `g'.
-  Please use option `-main' for specifying a valid entry point.
-[kernel] Frama-C aborted: invalid user input.
+[kernel] Parsing tests/slicing/min_call.c (with preprocessing)
+[kernel:typing:implicit-function-declaration] tests/slicing/select_return.i:45: Warning: 
+  Calling undeclared function f. Old style K&R code?
+[eva] Analyzing an incomplete application starting at g
+[eva] Computing initial state
+[eva] Initial state computed
+[eva:initial-state] Values of globals at initialization
+  G ∈ [--..--]
+  H ∈ [--..--]
+  I ∈ [--..--]
+[eva] computing for function k <- g.
+  Called from tests/slicing/select_return.i:44.
+[eva] computing for function get <- k <- g.
+  Called from tests/slicing/select_return.i:35.
+[kernel:annot:missing-spec] tests/slicing/select_return.i:35: Warning: 
+  Neither code nor specification for function get, generating default assigns from the prototype
+[eva] using specification for function get
+[eva] Done for function get
+[eva] computing for function send_bis <- k <- g.
+  Called from tests/slicing/select_return.i:39.
+[kernel:annot:missing-spec] tests/slicing/select_return.i:39: Warning: 
+  Neither code nor specification for function send_bis, generating default assigns from the prototype
+[eva] using specification for function send_bis
+[eva] Done for function send_bis
+[eva] Recording results for k
+[eva] Done for function k
+[eva] computing for function f <- g.
+  Called from tests/slicing/select_return.i:45.
+[eva] computing for function k <- f <- g.
+  Called from tests/slicing/select_return.i:49.
+[eva] computing for function get <- k <- f <- g.
+  Called from tests/slicing/select_return.i:35.
+[eva] Done for function get
+[eva] computing for function send_bis <- k <- f <- g.
+  Called from tests/slicing/select_return.i:39.
+[eva] Done for function send_bis
+[eva] Recording results for k
+[eva] Done for function k
+[eva] computing for function k <- f <- g.
+  Called from tests/slicing/select_return.i:50.
+[eva] computing for function get <- k <- f <- g.
+  Called from tests/slicing/select_return.i:35.
+[eva] Done for function get
+[eva] computing for function send_bis <- k <- f <- g.
+  Called from tests/slicing/select_return.i:39.
+[eva] Done for function send_bis
+[eva] Recording results for k
+[eva] Done for function k
+[eva] computing for function k <- f <- g.
+  Called from tests/slicing/select_return.i:51.
+[eva] computing for function get <- k <- f <- g.
+  Called from tests/slicing/select_return.i:35.
+[eva] Done for function get
+[eva] computing for function send_bis <- k <- f <- g.
+  Called from tests/slicing/select_return.i:39.
+[eva] Done for function send_bis
+[eva] Recording results for k
+[eva] Done for function k
+[eva] computing for function send <- f <- g.
+  Called from tests/slicing/select_return.i:53.
+[kernel:annot:missing-spec] tests/slicing/select_return.i:53: Warning: 
+  Neither code nor specification for function send, generating default assigns from the prototype
+[eva] using specification for function send
+[eva] Done for function send
+[eva] Recording results for f
+[eva] Done for function f
+[eva] Recording results for g
+[eva] done for function g
+[from] Computing for function k
+[from] Computing for function get <-k
+[from] Done for function get
+[from] Computing for function send_bis <-k
+[from] Done for function send_bis
+[from] Done for function k
+[from] Computing for function f
+[from] Computing for function send <-f
+[from] Done for function send
+[from] Done for function f
+[from] Computing for function g
+[from] Done for function g
+[from] ====== DEPENDENCIES COMPUTED ======
+  These dependencies hold at termination for the executions that terminate:
+[from] Function get:
+  \result FROM y
+[from] Function send:
+  NO EFFECTS
+[from] Function send_bis:
+  NO EFFECTS
+[from] Function k:
+  G FROM b
+  H FROM c
+  \result FROM a
+[from] Function f:
+  G FROM \nothing
+  H FROM \nothing
+  \result FROM y
+[from] Function g:
+  G FROM \nothing
+  H FROM \nothing
+[from] ====== END OF DEPENDENCIES ======
+[slicing] initializing slicing ...
+[pdg] computing for function k
+[pdg] done for function k
+[slicing] applying all slicing requests...
+[slicing] applying 1 actions...
+[slicing] applying actions: 1/1...
+[pdg] computing for function f
+[pdg] done for function f
+[pdg] computing for function g
+[pdg] done for function g
+Project1 - result1 :
+[slicing] exporting project to 'Sliced code'...
+[slicing] applying all slicing requests...
+[slicing] applying 0 actions...
+[sparecode] remove unused global declarations from project 'Sliced code tmp'
+[sparecode] removed unused global declarations in new project 'Sliced code'
+/* Generated by Frama-C */
+int get(int y);
+
+/*@ assigns \nothing; */
+void send_bis(int x);
+
+void k_slice_1(int d)
+{
+  int cond = get(d);
+  if (cond) send_bis(d);
+  return;
+}
+
+void f_slice_1(void);
+
+void g(void)
+{
+  k_slice_1(0);
+  f_slice_1();
+  return;
+}
+
+void f_slice_1(void)
+{
+  k_slice_1(0);
+  k_slice_1(0);
+  k_slice_1(0);
+  return;
+}
+
+
+Project1 - result2 :
+int G;
+int H;
+int I;
+/*@ assigns \result;
+    assigns \result \from y; */
+int get(int y);
+
+/*@ assigns \nothing; */
+void send(int x);
+
+/*@ assigns \nothing; */
+void send_bis(int x);
+
+Print slice = k_slice_2: (InCtrl: <[ S ], [---]>)
+                         (In4: <[--d], [---]>)
+
+/**/int k(/* <[---], [---]> */ int a, /* <[---], [---]> */ int b,
+          /* <[---], [---]> */ int c, /* <[--d], [---]> */ int d)
+{
+  /* sig call:
+    (InCtrl: <[ S ], [---]>)
+    (In1: <[ S ], [---]>)
+    (OutRet: <[ S ], [---]>) */
+  /* undetermined call */
+  /* <[ S ], [---]> */
+  /* <[ S ], [---]> */ int cond = get(d);
+  /* <[---], [---]> */
+  G = b;
+  /* <[---], [---]> */
+  H = c;
+  /* <[ S ], [---]> */
+  if (cond) {
+    /* sig call: (InCtrl: <[ S ], [---]>)
+                 (In1: <[ S ], [---]>) */
+    /* undetermined call */
+    /* <[ S ], [---]> */
+    send_bis(d);
+  }
+  /* <[---], [---]> */
+  return a;
+}
+
+Print slice = k_slice_1: (InCtrl: <[ S ], [ S ]>)
+                         (In4: <[--d], [ S ]>)
+
+/**/int k(/* <[---], [---]> */ int a, /* <[---], [---]> */ int b,
+          /* <[---], [---]> */ int c, /* <[--d], [ S ]> */ int d)
+{
+  /* sig call:
+    (InCtrl: <[ S ], [ S ]>)
+    (In1: <[ S ], [ S ]>)
+    (OutRet: <[ S ], [ S ]>) */
+  /* call to source function */
+  /* <[ S ], [ S ]> */
+  /* <[ S ], [ S ]> */ int cond = get(d);
+  /* <[---], [---]> */
+  G = b;
+  /* <[---], [---]> */
+  H = c;
+  /* <[ S ], [ S ]> */
+  if (cond) {
+    /* sig call: (InCtrl: <[ S ], [ S ]>)
+                 (In1: <[ S ], [ S ]>) */
+    /* call to source function */
+    /* <[ S ], [ S ]> */
+    send_bis(d);
+  }
+  /* <[---], [---]> */
+  return a;
+}
+
+int f(int y);
+
+Print slice = g_slice_1: (InCtrl: <[--d], [ S ]>)
+
+/**/void g(/* <[---], [---]> */ int b, /* <[---], [---]> */ int c)
+{
+  /* <[---], [---]> */ int r;
+  /* sig call: (InCtrl: <[--d], [ S ]>)
+               (In4: <[--d], [ S ]>) */
+  /* call to k_slice_1: (InCtrl: <[ S ], [ S ]>)
+                        (In4: <[--d], [ S ]>) */
+  /* <[--d], [ S ]> */
+  /* <[---], [---]> */ int r = k(0,0,c,0);
+  /* sig call: (InCtrl: <[--d], [ S ]>) */
+  /* call to f_slice_1: (InCtrl: <[--d], [ S ]>) */
+  /* <[--d], [ S ]> */
+  f(b);
+  /* <[---], [---]> */
+  return;
+}
+
+Print slice = f_slice_1: (InCtrl: <[--d], [ S ]>)
+
+/**/int f(/* <[---], [---]> */ int y)
+{
+  /* <[---], [---]> */ int r;
+  /* <[---], [---]> */ int z;
+  /* sig call: (InCtrl: <[--d], [ S ]>)
+               (In4: <[--d], [ S ]>) */
+  /* call to k_slice_1: (InCtrl: <[ S ], [ S ]>)
+                        (In4: <[--d], [ S ]>) */
+  /* <[--d], [ S ]> */
+  k(0,0,0,0);
+  /* sig call: (InCtrl: <[--d], [ S ]>)
+               (In4: <[--d], [ S ]>) */
+  /* call to k_slice_1: (InCtrl: <[ S ], [ S ]>)
+                        (In4: <[--d], [ S ]>) */
+  /* <[--d], [ S ]> */
+  /* <[---], [---]> */ int r = k(0,y,0,0);
+  /* sig call: (InCtrl: <[--d], [ S ]>)
+               (In4: <[--d], [ S ]>) */
+  /* call to k_slice_1: (InCtrl: <[ S ], [ S ]>)
+                        (In4: <[--d], [ S ]>) */
+  /* <[--d], [ S ]> */
+  /* <[---], [---]> */ int z = k(G,0,0,0);
+  /*@ slice pragma expr z; */ /* <[---], [---]> */
+                              ;
+  /* invisible call */ /* <[---], [---]> */
+  send(z);
+  /* <[---], [---]> */
+  return z;
+}
+
+Slicing project worklist [default] =
+[k_slice_2 = choose_call for call 6][k_slice_2 = choose_call for call 1]
+
+[slicing] exporting project to 'Sliced code'...
+[slicing] applying all slicing requests...
+[slicing] applying 2 actions...
+[slicing] applying actions: 1/2...
+[slicing] applying actions: 2/2...
+[sparecode] remove unused global declarations from project 'Sliced code tmp'
+[sparecode] removed unused global declarations in new project 'Sliced code'
+/* Generated by Frama-C */
+int get(int y);
+
+/*@ assigns \nothing; */
+void send_bis(int x);
+
+void k_slice_2(int d)
+{
+  int cond = get(d);
+  if (cond) send_bis(d);
+  return;
+}
+
+void k_slice_1(int d)
+{
+  int cond = get(d);
+  if (cond) send_bis(d);
+  return;
+}
+
+void f_slice_1(void);
+
+void g(void)
+{
+  k_slice_1(0);
+  f_slice_1();
+  return;
+}
+
+void f_slice_1(void)
+{
+  k_slice_1(0);
+  k_slice_1(0);
+  k_slice_1(0);
+  return;
+}
+
+
+[slicing] reinitializing slicing ...
+Slicing project worklist [default] =
+[k = (n:17 ,<[--d], [---]>)]
+
+[slicing] applying all slicing requests...
+[slicing] applying 1 actions...
+[slicing] applying actions: 1/1...
+Project3 - result :
+int G;
+int H;
+int I;
+/*@ assigns \result;
+    assigns \result \from y; */
+int get(int y);
+
+/*@ assigns \nothing; */
+void send(int x);
+
+/*@ assigns \nothing; */
+void send_bis(int x);
+
+Print slice = k_slice_1: (InCtrl: <[--d], [ S ]>)
+                         (In4: <[--d], [ S ]>)
+
+/**/int k(/* <[---], [---]> */ int a, /* <[---], [---]> */ int b,
+          /* <[---], [---]> */ int c, /* <[--d], [ S ]> */ int d)
+{
+  /* sig call:
+    (InCtrl: <[--d], [ S ]>)
+    (In1: <[--d], [ S ]>)
+    (OutRet: <[--d], [ S ]>) */
+  /* call to source function */
+  /* <[--d], [ S ]> */
+  /* <[--d], [ S ]> */ int cond = get(d);
+  /* <[---], [---]> */
+  G = b;
+  /* <[---], [---]> */
+  H = c;
+  /* <[--d], [ S ]> */
+  if (cond) {
+    /* sig call: (InCtrl: <[--d], [ S ]>)
+                 (In1: <[---], [ S ]>) */
+    /* call to source function */
+    /* <[--d], [ S ]> */
+    send_bis(d);
+  }
+  /* <[---], [---]> */
+  return a;
+}
+
+int f(int y);
+
+Print slice = g_slice_1: (InCtrl: <[--d], [ S ]>)
+
+/**/void g(/* <[---], [---]> */ int b, /* <[---], [---]> */ int c)
+{
+  /* <[---], [---]> */ int r;
+  /* sig call: (InCtrl: <[--d], [ S ]>)
+               (In4: <[--d], [ S ]>) */
+  /* call to k_slice_1: (InCtrl: <[--d], [ S ]>)
+                        (In4: <[--d], [ S ]>) */
+  /* <[--d], [ S ]> */
+  /* <[---], [---]> */ int r = k(0,0,c,0);
+  /* sig call: (InCtrl: <[--d], [ S ]>) */
+  /* call to f_slice_1: (InCtrl: <[--d], [ S ]>) */
+  /* <[--d], [ S ]> */
+  f(b);
+  /* <[---], [---]> */
+  return;
+}
+
+Print slice = f_slice_1: (InCtrl: <[--d], [ S ]>)
+
+/**/int f(/* <[---], [---]> */ int y)
+{
+  /* <[---], [---]> */ int r;
+  /* <[---], [---]> */ int z;
+  /* sig call: (InCtrl: <[--d], [ S ]>)
+               (In4: <[--d], [ S ]>) */
+  /* call to k_slice_1: (InCtrl: <[--d], [ S ]>)
+                        (In4: <[--d], [ S ]>) */
+  /* <[--d], [ S ]> */
+  k(0,0,0,0);
+  /* sig call: (InCtrl: <[--d], [ S ]>)
+               (In4: <[--d], [ S ]>) */
+  /* call to k_slice_1: (InCtrl: <[--d], [ S ]>)
+                        (In4: <[--d], [ S ]>) */
+  /* <[--d], [ S ]> */
+  /* <[---], [---]> */ int r = k(0,y,0,0);
+  /* sig call: (InCtrl: <[--d], [ S ]>)
+               (In4: <[--d], [ S ]>) */
+  /* call to k_slice_1: (InCtrl: <[--d], [ S ]>)
+                        (In4: <[--d], [ S ]>) */
+  /* <[--d], [ S ]> */
+  /* <[---], [---]> */ int z = k(G,0,0,0);
+  /*@ slice pragma expr z; */ /* <[---], [---]> */
+                              ;
+  /* invisible call */ /* <[---], [---]> */
+  send(z);
+  /* <[---], [---]> */
+  return z;
+}
+
+Slicing project worklist [default] =
+
+
+[slicing] exporting project to 'Sliced code'...
+[slicing] applying all slicing requests...
+[slicing] applying 0 actions...
+[sparecode] remove unused global declarations from project 'Sliced code tmp'
+[sparecode] removed unused global declarations in new project 'Sliced code'
+/* Generated by Frama-C */
+int get(int y);
+
+/*@ assigns \nothing; */
+void send_bis(int x);
+
+void k_slice_1(int d)
+{
+  int cond = get(d);
+  if (cond) send_bis(d);
+  return;
+}
+
+void f_slice_1(void);
+
+void g(void)
+{
+  k_slice_1(0);
+  f_slice_1();
+  return;
+}
+
+void f_slice_1(void)
+{
+  k_slice_1(0);
+  k_slice_1(0);
+  k_slice_1(0);
+  return;
+}
+
+
+[slicing] reinitializing slicing ...
+[slicing] applying all slicing requests...
+[slicing] applying 0 actions...
+Slicing project worklist [default] =
+[f = (n:26 ,<[acd], [---]>)(n:33 ,<[acd], [---]>)(n:41 ,<[acd], [---]>)][g = (n:60 ,
+<[acd],
+[---]>)]
+
+Slicing project worklist [default] =
+[f_slice_1 = choose_call for call 17][f_slice_1 = choose_call for call 16][f_slice_1 = choose_call for call 15][g = propagate (n:68 ,
+<[acd],
+[---]>)][Appli : calls to f][g = (n:60 ,<[acd], [---]>)]
+
+[slicing] applying all slicing requests...
+[slicing] applying 6 actions...
+[slicing] applying actions: 1/6...
+[slicing] applying actions: 2/6...
+[slicing] applying actions: 3/6...
+[slicing] applying actions: 4/6...
+[slicing] applying actions: 5/6...
+[slicing] applying actions: 6/6...
+Project3 - result :
+int G;
+int H;
+int I;
+/*@ assigns \result;
+    assigns \result \from y; */
+int get(int y);
+
+/*@ assigns \nothing; */
+void send(int x);
+
+/*@ assigns \nothing; */
+void send_bis(int x);
+
+Print slice = k_slice_1: 
+
+/**/int k(/* <[---], [---]> */ int a, /* <[---], [---]> */ int b,
+          /* <[---], [---]> */ int c, /* <[---], [---]> */ int d)
+{
+  /* invisible call */ /* <[---], [---]> */
+  /* <[---], [---]> */ int cond = get(d);
+  /* <[---], [---]> */
+  G = b;
+  /* <[---], [---]> */
+  H = c;
+  /* <[---], [---]> */
+  if (cond) {
+    /* invisible call */ /* <[---], [---]> */
+    send_bis(d);
+  }
+  /* <[---], [---]> */
+  return a;
+}
+
+int f(int y);
+
+Print slice = g_slice_1: (InCtrl: <[acd], [---]>)
+
+/**/void g(/* <[---], [---]> */ int b, /* <[---], [---]> */ int c)
+{
+  /* <[---], [---]> */ int r;
+  /* sig call: (InCtrl: <[acd], [---]>) */
+  /* call to k_slice_1:  */
+  /* <[acd], [---]> */
+  /* <[---], [---]> */ int r = k(0,0,c,0);
+  /* sig call: (InCtrl: <[acd], [---]>) */
+  /* call to f_slice_1: (InCtrl: <[acd], [---]>) */
+  /* <[acd], [---]> */
+  f(b);
+  /* <[---], [---]> */
+  return;
+}
+
+Print slice = f_slice_1: (InCtrl: <[acd], [---]>)
+
+/**/int f(/* <[---], [---]> */ int y)
+{
+  /* <[---], [---]> */ int r;
+  /* <[---], [---]> */ int z;
+  /* sig call: (InCtrl: <[acd], [---]>) */
+  /* call to k_slice_1:  */
+  /* <[acd], [---]> */
+  k(0,0,0,0);
+  /* sig call: (InCtrl: <[acd], [---]>) */
+  /* call to k_slice_1:  */
+  /* <[acd], [---]> */
+  /* <[---], [---]> */ int r = k(0,y,0,0);
+  /* sig call: (InCtrl: <[acd], [---]>) */
+  /* call to k_slice_1:  */
+  /* <[acd], [---]> */
+  /* <[---], [---]> */ int z = k(G,0,0,0);
+  /*@ slice pragma expr z; */ /* <[---], [---]> */
+                              ;
+  /* invisible call */ /* <[---], [---]> */
+  send(z);
+  /* <[---], [---]> */
+  return z;
+}
+
+Slicing project worklist [default] =
+
+
+[slicing] exporting project to 'Sliced code'...
+[slicing] applying all slicing requests...
+[slicing] applying 0 actions...
+[sparecode] remove unused global declarations from project 'Sliced code tmp'
+[sparecode] removed unused global declarations in new project 'Sliced code'
+/* Generated by Frama-C */
+void k_slice_1(void)
+{
+  return;
+}
+
+void f_slice_1(void);
+
+void g(void)
+{
+  k_slice_1();
+  f_slice_1();
+  return;
+}
+
+void f_slice_1(void)
+{
+  k_slice_1();
+  k_slice_1();
+  k_slice_1();
+  return;
+}
+
+
diff --git a/tests/slicing/oracle/select_simple.res.oracle b/tests/slicing/oracle/select_simple.res.oracle
index 949dafe57ce17bcae121d73a5090c252a2039ea0..2a4d181dd9645e21781a1e0eb6d89408dd52e570 100644
--- a/tests/slicing/oracle/select_simple.res.oracle
+++ b/tests/slicing/oracle/select_simple.res.oracle
@@ -1,4 +1,430 @@
-[kernel] Parsing tests/slicing/select_simple.i (no preprocessing)
-[kernel] User Error: cannot find entry point `main'.
-  Please use option `-main' for specifying a valid entry point.
-[kernel] Frama-C aborted: invalid user input.
+[kernel] Parsing tests/slicing/select_simple.c (with preprocessing)
+[eva] Analyzing a complete application starting at main
+[eva] Computing initial state
+[eva] Initial state computed
+[eva:initial-state] Values of globals at initialization
+  Unknown ∈ {0}
+  G ∈ {0}
+  S ∈ {0}
+  S1 ∈ {0}
+  S2 ∈ {0}
+[eva:alarm] tests/slicing/simple_intra_slice.i:99: Warning: 
+  signed overflow. assert -2147483648 ≤ uninit - 1;
+[eva] tests/slicing/simple_intra_slice.i:98: starting to merge loop iterations
+[eva:alarm] tests/slicing/simple_intra_slice.i:99: Warning: 
+  signed overflow. assert Unknown + 1 ≤ 2147483647;
+[eva:alarm] tests/slicing/simple_intra_slice.i:99: Warning: 
+  signed overflow. assert -2147483648 ≤ Unknown - 1;
+[eva:alarm] tests/slicing/simple_intra_slice.i:101: Warning: 
+  signed overflow. assert -2147483648 ≤ uninit2 - 1;
+[eva] tests/slicing/simple_intra_slice.i:100: starting to merge loop iterations
+[eva:alarm] tests/slicing/simple_intra_slice.i:101: Warning: 
+  signed overflow. assert S.a + 1 ≤ 2147483647;
+[eva:alarm] tests/slicing/simple_intra_slice.i:101: Warning: 
+  signed overflow. assert -2147483648 ≤ S.a - 1;
+[eva] computing for function f2 <- main.
+  Called from tests/slicing/simple_intra_slice.i:103.
+[eva] computing for function f1 <- f2 <- main.
+  Called from tests/slicing/simple_intra_slice.i:23.
+[eva] Recording results for f1
+[eva] Done for function f1
+[eva] Recording results for f2
+[eva] Done for function f2
+[eva] computing for function f3 <- main.
+  Called from tests/slicing/simple_intra_slice.i:104.
+[eva] Recording results for f3
+[eva] Done for function f3
+[eva] computing for function f4 <- main.
+  Called from tests/slicing/simple_intra_slice.i:105.
+[eva] Recording results for f4
+[eva] Done for function f4
+[eva] computing for function f5 <- main.
+  Called from tests/slicing/simple_intra_slice.i:106.
+[eva] Recording results for f5
+[eva] Done for function f5
+[eva] computing for function f6 <- main.
+  Called from tests/slicing/simple_intra_slice.i:107.
+[eva:alarm] tests/slicing/simple_intra_slice.i:71: Warning: 
+  signed overflow. assert -2147483648 ≤ 10 * n;
+[eva:alarm] tests/slicing/simple_intra_slice.i:71: Warning: 
+  signed overflow. assert 10 * n ≤ 2147483647;
+[eva] Recording results for f6
+[eva] Done for function f6
+[eva:alarm] tests/slicing/simple_intra_slice.i:107: Warning: 
+  signed overflow. assert res + tmp_3 ≤ 2147483647;
+                   (tmp_3 from f6(Unknown))
+[eva] computing for function f7 <- main.
+  Called from tests/slicing/simple_intra_slice.i:108.
+[eva:alarm] tests/slicing/simple_intra_slice.i:79: Warning: 
+  signed overflow. assert S.a + 3 ≤ 2147483647;
+[eva:alarm] tests/slicing/simple_intra_slice.i:82: Warning: 
+  signed overflow. assert s0.a + 1 ≤ 2147483647;
+[eva] Recording results for f7
+[eva] Done for function f7
+[eva] computing for function f8 <- main.
+  Called from tests/slicing/simple_intra_slice.i:110.
+[eva] Recording results for f8
+[eva] Done for function f8
+[eva] computing for function f8 <- main.
+  Called from tests/slicing/simple_intra_slice.i:112.
+[eva] Recording results for f8
+[eva] Done for function f8
+[eva] Recording results for main
+[eva] done for function main
+[from] Computing for function f1
+[from] Done for function f1
+[from] Computing for function f2
+[from] Done for function f2
+[from] Computing for function f3
+[from] Done for function f3
+[from] Computing for function f4
+[from] Done for function f4
+[from] Computing for function f5
+[from] Done for function f5
+[from] Computing for function f6
+[from] Done for function f6
+[from] Computing for function f7
+[from] Done for function f7
+[from] Computing for function f8
+[from] Done for function f8
+[from] Computing for function main
+[from] Done for function main
+[from] ====== DEPENDENCIES COMPUTED ======
+  These dependencies hold at termination for the executions that terminate:
+[from] Function f1:
+  G FROM x
+  \result FROM y
+[from] Function f2:
+  G FROM \nothing
+  \result FROM \nothing
+[from] Function f3:
+  G FROM Unknown; c (and SELF)
+  \result FROM Unknown; c
+[from] Function f4:
+  G FROM Unknown; c (and SELF)
+  \result FROM Unknown; c
+[from] Function f5:
+  G FROM Unknown; G; c (and SELF)
+  \result FROM Unknown; c
+[from] Function f6:
+  \result FROM Unknown; n
+[from] Function f7:
+  S.a FROM S.a; s0
+   {.b; .c} FROM S.a; s0 (and SELF)
+[from] Function f8:
+  S1.a FROM S1.a; S2.a; ps (and SELF)
+    .b FROM S1.b; S2.b; ps (and SELF)
+  S2.a FROM S1.a; S2.a; ps (and SELF)
+    .b FROM S1.b; S2.b; ps (and SELF)
+[from] Function main:
+  Unknown FROM Unknown (and SELF)
+  G FROM Unknown
+  S.a FROM S
+   {.b; .c} FROM S (and SELF)
+  S1.a FROM Unknown; S1.a; S2.a (and SELF)
+    .b FROM Unknown; S1.b; S2.b (and SELF)
+  S2.a FROM Unknown; S1.a; S2.a (and SELF)
+    .b FROM Unknown; S1.b; S2.b (and SELF)
+  \result FROM Unknown
+[from] ====== END OF DEPENDENCIES ======
+[slicing] initializing slicing ...
+[pdg] computing for function f1
+[pdg] done for function f1
+Slicing project worklist [default] =
+[f1_slice_1 = (n:11(restrict to G) ,<[--d], [---]>)]
+
+[slicing] exporting project to 'Sliced code'...
+[slicing] applying all slicing requests...
+[slicing] applying 1 actions...
+[slicing] applying actions: 1/1...
+[sparecode] remove unused global declarations from project 'Sliced code tmp'
+[sparecode] removed unused global declarations in new project 'Sliced code'
+/* Generated by Frama-C */
+int G;
+void f1_slice_1(int x)
+{
+  int a = 1;
+  G = x + a;
+  return;
+}
+
+
+[slicing] reinitializing slicing ...
+Slicing project worklist [default] =
+[f1_slice_1 = (n:13(restrict to __retres) ,<[--d], [---]>)]
+
+[slicing] exporting project to 'Sliced code'...
+[slicing] applying all slicing requests...
+[slicing] applying 1 actions...
+[slicing] applying actions: 1/1...
+[sparecode] remove unused global declarations from project 'Sliced code tmp'
+[sparecode] removed unused global declarations in new project 'Sliced code'
+/* Generated by Frama-C */
+int f1_slice_1(int y)
+{
+  int __retres;
+  int b = 2;
+  __retres = y + b;
+  return __retres;
+}
+
+
+[slicing] reinitializing slicing ...
+[pdg] computing for function f2
+[pdg] done for function f2
+Slicing project worklist [default] =
+[f2_slice_1 = (n:28(restrict to tmp) ,<[--d], [---]>)]
+
+[slicing] exporting project to 'Sliced code'...
+[slicing] applying all slicing requests...
+[slicing] applying 1 actions...
+[slicing] applying actions: 1/1...
+[sparecode] remove unused global declarations from project 'Sliced code tmp'
+[sparecode] removed unused global declarations in new project 'Sliced code'
+/* Generated by Frama-C */
+int f1_slice_1(int y)
+{
+  int __retres;
+  int b = 2;
+  __retres = y + b;
+  return __retres;
+}
+
+int f2_slice_1(void)
+{
+  int tmp;
+  int c = 3;
+  tmp = f1_slice_1(c);
+  return tmp;
+}
+
+
+[slicing] reinitializing slicing ...
+[pdg] computing for function f6
+[pdg] done for function f6
+Slicing project worklist [default] =
+[f6_slice_1 = (n:32(restrict to n) ,<[--d], [---]>)(n:42(restrict to 
+n) ,<[--d], [---]>)]
+
+[slicing] exporting project to 'Sliced code'...
+[slicing] applying all slicing requests...
+[slicing] applying 1 actions...
+[slicing] applying actions: 1/1...
+[sparecode] remove unused global declarations from project 'Sliced code tmp'
+[sparecode] removed unused global declarations in new project 'Sliced code'
+/* Generated by Frama-C */
+int Unknown;
+void f6_slice_1(int n)
+{
+  while (n < 10) {
+    if (Unknown > 3) break;
+    if (n % 2) continue;
+    n ++;
+  }
+  return;
+}
+
+
+[slicing] reinitializing slicing ...
+[pdg] computing for function f7
+[pdg] done for function f7
+[slicing] reinitializing slicing ...
+Impossible to select 'retres' for a void function (f7)
+Slicing project worklist [default] =
+[f7_slice_1 = (n:63(restrict to S.a) ,<[--d], [---]>)(n:65(restrict to 
+S.a) ,<[--d], [---]>)]
+
+[slicing] exporting project to 'Sliced code'...
+[slicing] applying all slicing requests...
+[slicing] applying 1 actions...
+[slicing] applying actions: 1/1...
+[sparecode] remove unused global declarations from project 'Sliced code tmp'
+[sparecode] removed unused global declarations in new project 'Sliced code'
+/* Generated by Frama-C */
+struct __anonstruct_Tstr_1 {
+   int a ;
+   int b ;
+   int c ;
+};
+typedef struct __anonstruct_Tstr_1 Tstr;
+Tstr S;
+void f7_slice_1(Tstr s0)
+{
+  int x = S.a;
+  if (x > 0) S.a += 3;
+  else {
+    (s0.a) ++;
+    S = s0;
+  }
+  return;
+}
+
+
+[slicing] reinitializing slicing ...
+Slicing project worklist [default] =
+[f7_slice_1 = (UndefIn S.b:<[--d], [---]>)(n:65(restrict to S.b) ,<[--d],
+                                                                  [---]>)]
+
+[slicing] exporting project to 'Sliced code'...
+[slicing] applying all slicing requests...
+[slicing] applying 1 actions...
+[slicing] applying actions: 1/1...
+[sparecode] remove unused global declarations from project 'Sliced code tmp'
+[sparecode] removed unused global declarations in new project 'Sliced code'
+/* Generated by Frama-C */
+struct __anonstruct_Tstr_1 {
+   int a ;
+   int b ;
+   int c ;
+};
+typedef struct __anonstruct_Tstr_1 Tstr;
+Tstr S;
+void f7_slice_1(Tstr s0)
+{
+  int x = S.a;
+  if (! (x > 0)) {
+    (s0.a) ++;
+    S = s0;
+  }
+  return;
+}
+
+
+[slicing] reinitializing slicing ...
+Slicing project worklist [default] =
+[f7_slice_1 = (UndefIn S{.b; .c}:<[--d], [---]>)(n:63(restrict to S.a) ,
+<[--d],
+[---]>)(n:65(restrict to S.a) ,<[--d], [---]>)(n:65(restrict to S{.b; .c}) ,
+<[--d],
+[---]>)]
+
+[slicing] exporting project to 'Sliced code'...
+[slicing] applying all slicing requests...
+[slicing] applying 1 actions...
+[slicing] applying actions: 1/1...
+[sparecode] remove unused global declarations from project 'Sliced code tmp'
+[sparecode] removed unused global declarations in new project 'Sliced code'
+/* Generated by Frama-C */
+struct __anonstruct_Tstr_1 {
+   int a ;
+   int b ;
+   int c ;
+};
+typedef struct __anonstruct_Tstr_1 Tstr;
+Tstr S;
+void f7_slice_1(Tstr s0)
+{
+  int x = S.a;
+  if (x > 0) S.a += 3;
+  else {
+    (s0.a) ++;
+    S = s0;
+  }
+  return;
+}
+
+
+[slicing] reinitializing slicing ...
+[slicing] reinitializing slicing ...
+[pdg] computing for function f8
+[pdg] done for function f8
+Impossible to select this data : XXX in f7
+Slicing project worklist [default] =
+[f8_slice_1 = (n:71(restrict to S1.a) ,<[--d], [---]>)(n:71(restrict to 
+S2.a) ,<[--d], [---]>)(n:77(restrict to S2.a) ,<[--d], [---]>)(n:76(restrict to 
+S1.a) ,<[--d], [---]>)]
+
+[slicing] exporting project to 'Sliced code'...
+[slicing] applying all slicing requests...
+[slicing] applying 1 actions...
+[slicing] applying actions: 1/1...
+[sparecode] remove unused global declarations from project 'Sliced code tmp'
+[sparecode] removed unused global declarations in new project 'Sliced code'
+/* Generated by Frama-C */
+struct __anonstruct_Tstr_1 {
+   int a ;
+   int b ;
+   int c ;
+};
+typedef struct __anonstruct_Tstr_1 Tstr;
+void f8_slice_1(Tstr *ps)
+{
+  (ps->a) ++;
+  return;
+}
+
+
+[slicing] reinitializing slicing ...
+Slicing project worklist [default] =
+[f8_slice_1 = (n:72(restrict to S1.b) ,<[--d], [---]>)(n:72(restrict to 
+S2.b) ,<[--d], [---]>)(n:75(restrict to S2.b) ,<[--d], [---]>)(n:74(restrict to 
+S1.b) ,<[--d], [---]>)]
+
+[slicing] exporting project to 'Sliced code'...
+[slicing] applying all slicing requests...
+[slicing] applying 1 actions...
+[slicing] applying actions: 1/1...
+[sparecode] remove unused global declarations from project 'Sliced code tmp'
+[sparecode] removed unused global declarations in new project 'Sliced code'
+/* Generated by Frama-C */
+struct __anonstruct_Tstr_1 {
+   int a ;
+   int b ;
+   int c ;
+};
+typedef struct __anonstruct_Tstr_1 Tstr;
+void f8_slice_1(Tstr *ps)
+{
+  (ps->b) ++;
+  return;
+}
+
+
+[slicing] reinitializing slicing ...
+Slicing project worklist [default] =
+[f8_slice_1 = (UndefIn S1.c;
+S2.c:<[--d], [---]>)]
+
+[slicing] exporting project to 'Sliced code'...
+[slicing] applying all slicing requests...
+[slicing] applying 1 actions...
+[slicing] applying actions: 1/1...
+[sparecode] remove unused global declarations from project 'Sliced code tmp'
+[sparecode] removed unused global declarations in new project 'Sliced code'
+/* Generated by Frama-C */
+void f8_slice_1(void)
+{
+  return;
+}
+
+
+[slicing] reinitializing slicing ...
+Slicing project worklist [default] =
+[f8_slice_1 = (UndefIn S1.c;
+S2.c:<[--d], [---]>)(n:71(restrict to S1.a) ,<[--d], [---]>)(n:72(restrict to 
+S1.b) ,<[--d], [---]>)(n:71(restrict to S2.a) ,<[--d], [---]>)(n:72(restrict to 
+S2.b) ,<[--d], [---]>)(n:75(restrict to S2.b) ,<[--d], [---]>)(n:77(restrict to 
+S2.a) ,<[--d], [---]>)(n:74(restrict to S1.b) ,<[--d], [---]>)(n:76(restrict to 
+S1.a) ,<[--d], [---]>)]
+
+[slicing] exporting project to 'Sliced code'...
+[slicing] applying all slicing requests...
+[slicing] applying 1 actions...
+[slicing] applying actions: 1/1...
+[sparecode] remove unused global declarations from project 'Sliced code tmp'
+[sparecode] removed unused global declarations in new project 'Sliced code'
+/* Generated by Frama-C */
+struct __anonstruct_Tstr_1 {
+   int a ;
+   int b ;
+   int c ;
+};
+typedef struct __anonstruct_Tstr_1 Tstr;
+void f8_slice_1(Tstr *ps)
+{
+  (ps->a) ++;
+  (ps->b) ++;
+  return;
+}
+
+
diff --git a/tests/slicing/select_simple.i b/tests/slicing/select_simple.c
similarity index 85%
rename from tests/slicing/select_simple.i
rename to tests/slicing/select_simple.c
index 28face32afaf3a7c8e2dbf76ff7cdbb1ca51221f..6efa6fae65686dc81fea12a581d744db6abb5218 100644
--- a/tests/slicing/select_simple.i
+++ b/tests/slicing/select_simple.c
@@ -6,4 +6,4 @@
 
 /* dummy source file in order to test select_simple.ml */
 
-#include "tests/slicing/simple_intra_slice.c"
+#include "tests/slicing/simple_intra_slice.i"
diff --git a/tests/value/diff_apron b/tests/value/diff_apron
index 2ba17244e29404e5b12a718153ff2bc88c017c05..b8f9fbe7d8c8bbc8d910d97e3d71e2b1413b6746 100644
--- a/tests/value/diff_apron
+++ b/tests/value/diff_apron
@@ -72,148 +72,193 @@ diff tests/value/oracle/auto_loop_unroll.0.res.oracle tests/value/oracle_apron/a
 <   Frama_C_show_each_32_80: [0..2147483647]
 ---
 > [eva] tests/value/auto_loop_unroll.c:82: Frama_C_show_each_32_80: [0..164]
-49,52c32
-< [eva:alarm] tests/value/auto_loop_unroll.c:86: Warning: 
+55,56d37
+< [eva:alarm] tests/value/auto_loop_unroll.c:88: Warning: 
 <   signed overflow. assert res + 1 ≤ 2147483647;
-< [eva] tests/value/auto_loop_unroll.c:90: 
-<   Frama_C_show_each_11_111: [0..2147483647]
----
-> [eva] tests/value/auto_loop_unroll.c:90: Frama_C_show_each_11_111: [11..111]
-60,61d39
-< [eva:alarm] tests/value/auto_loop_unroll.c:96: Warning: 
+60,62c41
+< [eva:alarm] tests/value/auto_loop_unroll.c:93: Warning: 
 <   signed overflow. assert res + 1 ≤ 2147483647;
-72c50,53
-< [eva] tests/value/auto_loop_unroll.c:103: Reusing old results for call to incr
+< [eva] tests/value/auto_loop_unroll.c:95: Frama_C_show_each_101: [0..2147483647]
+---
+> [eva] tests/value/auto_loop_unroll.c:95: Frama_C_show_each_101: {101}
+71c50,53
+< [eva] tests/value/auto_loop_unroll.c:101: Reusing old results for call to incr
 ---
 > [eva] computing for function incr <- various_loops <- main.
->   Called from tests/value/auto_loop_unroll.c:103.
+>   Called from tests/value/auto_loop_unroll.c:101.
 > [eva] Recording results for incr
 > [eva] Done for function incr
-82c63,66
-< [eva] tests/value/auto_loop_unroll.c:103: Reusing old results for call to incr
+81c63,66
+< [eva] tests/value/auto_loop_unroll.c:101: Reusing old results for call to incr
 ---
 > [eva] computing for function incr <- various_loops <- main.
->   Called from tests/value/auto_loop_unroll.c:103.
+>   Called from tests/value/auto_loop_unroll.c:101.
 > [eva] Recording results for incr
 > [eva] Done for function incr
-91c75,78
-< [eva] tests/value/auto_loop_unroll.c:103: Reusing old results for call to incr
+90c75,78
+< [eva] tests/value/auto_loop_unroll.c:101: Reusing old results for call to incr
 ---
 > [eva] computing for function incr <- various_loops <- main.
->   Called from tests/value/auto_loop_unroll.c:103.
+>   Called from tests/value/auto_loop_unroll.c:101.
 > [eva] Recording results for incr
 > [eva] Done for function incr
-108c95,98
-< [eva] tests/value/auto_loop_unroll.c:102: Reusing old results for call to incr
+107c95,98
+< [eva] tests/value/auto_loop_unroll.c:100: Reusing old results for call to incr
 ---
 > [eva] computing for function incr <- various_loops <- main.
->   Called from tests/value/auto_loop_unroll.c:102.
+>   Called from tests/value/auto_loop_unroll.c:100.
 > [eva] Recording results for incr
 > [eva] Done for function incr
-115,116d104
+114,115d104
 < [eva:alarm] tests/value/auto_loop_unroll.c:14: Warning: 
 <   signed overflow. assert g + 1 ≤ 2147483647;
-119c107,110
-< [eva] tests/value/auto_loop_unroll.c:102: Reusing old results for call to incr
----
-> [eva] computing for function incr <- various_loops <- main.
->   Called from tests/value/auto_loop_unroll.c:102.
-> [eva] Recording results for incr
-> [eva] Done for function incr
-124,125c115,122
-< [eva] tests/value/auto_loop_unroll.c:101: Reusing old results for call to incr_g
-< [eva] tests/value/auto_loop_unroll.c:102: Reusing old results for call to incr
+118c107,110
+< [eva] tests/value/auto_loop_unroll.c:100: Reusing old results for call to incr
 ---
-> [eva] computing for function incr_g <- various_loops <- main.
->   Called from tests/value/auto_loop_unroll.c:101.
-> [eva] Recording results for incr_g
-> [eva] Done for function incr_g
-> [eva] computing for function incr <- various_loops <- main.
->   Called from tests/value/auto_loop_unroll.c:102.
-> [eva] Recording results for incr
-> [eva] Done for function incr
-130,131c127,134
-< [eva] tests/value/auto_loop_unroll.c:101: Reusing old results for call to incr_g
-< [eva] tests/value/auto_loop_unroll.c:102: Reusing old results for call to incr
----
-> [eva] computing for function incr_g <- various_loops <- main.
->   Called from tests/value/auto_loop_unroll.c:101.
-> [eva] Recording results for incr_g
-> [eva] Done for function incr_g
 > [eva] computing for function incr <- various_loops <- main.
->   Called from tests/value/auto_loop_unroll.c:102.
+>   Called from tests/value/auto_loop_unroll.c:100.
 > [eva] Recording results for incr
 > [eva] Done for function incr
-134,135d136
+121,122d112
 < [eva:alarm] tests/value/auto_loop_unroll.c:18: Warning: 
 <   signed overflow. assert i + 1 ≤ 2147483647;
-138c139
-< [eva] tests/value/auto_loop_unroll.c:105: Frama_C_show_each_25: [0..2147483647]
+125c115
+< [eva] tests/value/auto_loop_unroll.c:103: Frama_C_show_each_25: [0..2147483647]
 ---
-> [eva] tests/value/auto_loop_unroll.c:105: Frama_C_show_each_25: {25}
-144c145,146
-< [eva] tests/value/auto_loop_unroll.c:114: Frama_C_show_each_120: [0..2147483647]
+> [eva] tests/value/auto_loop_unroll.c:103: Frama_C_show_each_25: {25}
+131c121,122
+< [eva] tests/value/auto_loop_unroll.c:112: Frama_C_show_each_120: [0..2147483647]
 ---
-> [eva] tests/value/auto_loop_unroll.c:114: 
+> [eva] tests/value/auto_loop_unroll.c:112: 
 >   Frama_C_show_each_120: [15..2147483647]
-160,161d161
-< [eva:alarm] tests/value/auto_loop_unroll.c:136: Warning: 
+133,136c124
+< [eva:alarm] tests/value/auto_loop_unroll.c:120: Warning: 
 <   signed overflow. assert res + 1 ≤ 2147483647;
-168c168
-<   Frama_C_show_each_imprecise: [0..2147483647]
+< [eva] tests/value/auto_loop_unroll.c:122: 
+<   Frama_C_show_each_32_64: [0..2147483647]
 ---
->   Frama_C_show_each_imprecise: [10..2147483647]
-170,174c170,174
-< [eva:alarm] tests/value/auto_loop_unroll.c:156: Warning: 
+> [eva] tests/value/auto_loop_unroll.c:122: Frama_C_show_each_32_64: [0..65]
+152,153d139
+< [eva:alarm] tests/value/auto_loop_unroll.c:145: Warning: 
 <   signed overflow. assert res + 1 ≤ 2147483647;
-< [eva] tests/value/auto_loop_unroll.c:158: 
+160c146
 <   Frama_C_show_each_imprecise: [0..2147483647]
-< [eva] tests/value/auto_loop_unroll.c:163: Reusing old results for call to incr_g
 ---
-> [eva] tests/value/auto_loop_unroll.c:158: Frama_C_show_each_imprecise: {10}
-> [eva] computing for function incr_g <- complex_loops <- main.
->   Called from tests/value/auto_loop_unroll.c:163.
-> [eva] Recording results for incr_g
-> [eva] Done for function incr_g
-188,193c188,196
-< [eva] tests/value/auto_loop_unroll.c:163: Reusing old results for call to incr_g
-< [eva] tests/value/auto_loop_unroll.c:163: Reusing old results for call to incr_g
-< [eva:alarm] tests/value/auto_loop_unroll.c:165: Warning: 
+>   Frama_C_show_each_imprecise: [10..2147483647]
+178,183c164,172
+< [eva] tests/value/auto_loop_unroll.c:162: Reusing old results for call to incr_g
+< [eva] tests/value/auto_loop_unroll.c:162: Reusing old results for call to incr_g
+< [eva:alarm] tests/value/auto_loop_unroll.c:164: Warning: 
 <   signed overflow. assert res + 1 ≤ 2147483647;
-< [eva] tests/value/auto_loop_unroll.c:167: 
+< [eva] tests/value/auto_loop_unroll.c:166: 
 <   Frama_C_show_each_imprecise: [0..2147483647]
 ---
 > [eva] computing for function incr_g <- complex_loops <- main.
->   Called from tests/value/auto_loop_unroll.c:163.
+>   Called from tests/value/auto_loop_unroll.c:162.
 > [eva] Recording results for incr_g
 > [eva] Done for function incr_g
 > [eva] computing for function incr_g <- complex_loops <- main.
->   Called from tests/value/auto_loop_unroll.c:163.
+>   Called from tests/value/auto_loop_unroll.c:162.
 > [eva] Recording results for incr_g
 > [eva] Done for function incr_g
-> [eva] tests/value/auto_loop_unroll.c:167: Frama_C_show_each_imprecise: [0..64]
-195,198c198
-< [eva:alarm] tests/value/auto_loop_unroll.c:174: Warning: 
+> [eva] tests/value/auto_loop_unroll.c:166: Frama_C_show_each_imprecise: [0..64]
+185,188c174
+< [eva:alarm] tests/value/auto_loop_unroll.c:173: Warning: 
 <   signed overflow. assert res + 1 ≤ 2147483647;
-< [eva] tests/value/auto_loop_unroll.c:176: 
+< [eva] tests/value/auto_loop_unroll.c:175: 
 <   Frama_C_show_each_imprecise: [0..2147483647]
 ---
-> [eva] tests/value/auto_loop_unroll.c:176: Frama_C_show_each_imprecise: [0..9]
-200,203c200
-< [eva:alarm] tests/value/auto_loop_unroll.c:182: Warning: 
+> [eva] tests/value/auto_loop_unroll.c:175: Frama_C_show_each_imprecise: [0..9]
+190,191d175
+< [eva:alarm] tests/value/auto_loop_unroll.c:181: Warning: 
 <   signed overflow. assert res + 1 ≤ 2147483647;
-< [eva] tests/value/auto_loop_unroll.c:184: 
+195c179
 <   Frama_C_show_each_imprecise: [0..2147483647]
 ---
-> [eva] tests/value/auto_loop_unroll.c:184: Frama_C_show_each_imprecise: [0..64]
-210c207
+>   Frama_C_show_each_imprecise: [64..2147483647]
+201,203c185
+< [eva:alarm] tests/value/auto_loop_unroll.c:193: Warning: 
+<   signed overflow. assert res + 1 ≤ 2147483647;
+< [eva] tests/value/auto_loop_unroll.c:195: Frama_C_show_each_11: [0..2147483647]
+---
+> [eva] tests/value/auto_loop_unroll.c:195: Frama_C_show_each_11: {11}
+205,207c187
+< [eva:alarm] tests/value/auto_loop_unroll.c:198: Warning: 
+<   signed overflow. assert res + 1 ≤ 2147483647;
+< [eva] tests/value/auto_loop_unroll.c:200: Frama_C_show_each_12: [0..2147483647]
+---
+> [eva] tests/value/auto_loop_unroll.c:200: Frama_C_show_each_12: {12}
+209,210d188
+< [eva:alarm] tests/value/auto_loop_unroll.c:204: Warning: 
+<   signed overflow. assert res + 1 ≤ 2147483647;
+212a191,192
+> [eva:alarm] tests/value/auto_loop_unroll.c:204: Warning: 
+>   signed overflow. assert res + 1 ≤ 2147483647;
+216,217d195
+< [eva:alarm] tests/value/auto_loop_unroll.c:209: Warning: 
+<   signed overflow. assert res + 1 ≤ 2147483647;
+219a198,199
+> [eva:alarm] tests/value/auto_loop_unroll.c:209: Warning: 
+>   signed overflow. assert res + 1 ≤ 2147483647;
+223,224d202
+< [eva:alarm] tests/value/auto_loop_unroll.c:217: Warning: 
+<   signed overflow. assert res + 1 ≤ 2147483647;
+228,231c206
+< [eva:alarm] tests/value/auto_loop_unroll.c:222: Warning: 
+<   signed overflow. assert res + 1 ≤ 2147483647;
+< [eva] tests/value/auto_loop_unroll.c:226: 
+<   Frama_C_show_each_11_111: [0..2147483647]
+---
+> [eva] tests/value/auto_loop_unroll.c:226: Frama_C_show_each_11_111: [11..111]
+239,241c214
+< [eva:alarm] tests/value/auto_loop_unroll.c:236: Warning: 
+<   signed overflow. assert res + 1 ≤ 2147483647;
+< [eva] tests/value/auto_loop_unroll.c:238: Frama_C_show_each_20: [0..2147483647]
+---
+> [eva] tests/value/auto_loop_unroll.c:238: Frama_C_show_each_20: [20..2147483646]
+243,244d215
+< [eva:alarm] tests/value/auto_loop_unroll.c:241: Warning: 
+<   signed overflow. assert res + 1 ≤ 2147483647;
+247c218,220
+< [eva] tests/value/auto_loop_unroll.c:243: Frama_C_show_each_21: [0..2147483647]
+---
+> [eva:alarm] tests/value/auto_loop_unroll.c:241: Warning: 
+>   signed overflow. assert res + 1 ≤ 2147483647;
+> [eva] tests/value/auto_loop_unroll.c:243: Frama_C_show_each_21: {21}
+253,255c226,227
+< [eva:alarm] tests/value/auto_loop_unroll.c:250: Warning: 
+<   signed overflow. assert res + 1 ≤ 2147483647;
+< [eva] tests/value/auto_loop_unroll.c:254: Frama_C_show_each_30: [0..2147483647]
+---
+> [eva] tests/value/auto_loop_unroll.c:254: Frama_C_show_each_30: {30}
+> [eva] tests/value/auto_loop_unroll.c:258: starting to merge loop iterations
+258,259c230,231
+< [eva] tests/value/auto_loop_unroll.c:258: starting to merge loop iterations
+< [eva] tests/value/auto_loop_unroll.c:263: Frama_C_show_each_top: [0..2147483647]
+---
+> [eva] tests/value/auto_loop_unroll.c:263: 
+>   Frama_C_show_each_top: [31..2147483647]
+261,263c233
+< [eva:alarm] tests/value/auto_loop_unroll.c:267: Warning: 
+<   signed overflow. assert res + 1 ≤ 2147483647;
+< [eva] tests/value/auto_loop_unroll.c:272: Frama_C_show_each_32: [0..2147483647]
+---
+> [eva] tests/value/auto_loop_unroll.c:272: Frama_C_show_each_32: {32}
+268c238
+<   Frama_C_show_each_33_inf: [0..2147483647]
+---
+>   Frama_C_show_each_33_inf: [33..2147483647]
+272,273d241
+< [eva:alarm] tests/value/auto_loop_unroll.c:283: Warning: 
+<   signed overflow. assert res + 1 ≤ 2147483647;
+281c249
 <   __retres ∈ [1..2147483647]
 ---
 >   __retres ∈ [1..25]
-212c209
+283c251
 <   g ∈ [1..2147483647]
 ---
->   g ∈ [1..63]
+>   g ∈ [1..126]
 diff tests/value/oracle/auto_loop_unroll.1.res.oracle tests/value/oracle_apron/auto_loop_unroll.1.res.oracle
 15,18c15
 < [eva:alarm] tests/value/auto_loop_unroll.c:31: Warning: 
@@ -230,230 +275,273 @@ diff tests/value/oracle/auto_loop_unroll.1.res.oracle tests/value/oracle_apron/a
 ---
 > [eva] tests/value/auto_loop_unroll.c:41: Frama_C_show_each_imprecise: {100}
 58c52,55
-< [eva] tests/value/auto_loop_unroll.c:103: Reusing old results for call to incr
+< [eva] tests/value/auto_loop_unroll.c:101: Reusing old results for call to incr
 ---
 > [eva] computing for function incr <- various_loops <- main.
->   Called from tests/value/auto_loop_unroll.c:103.
+>   Called from tests/value/auto_loop_unroll.c:101.
 > [eva] Recording results for incr
 > [eva] Done for function incr
 67c64,67
-< [eva] tests/value/auto_loop_unroll.c:103: Reusing old results for call to incr
+< [eva] tests/value/auto_loop_unroll.c:101: Reusing old results for call to incr
 ---
 > [eva] computing for function incr <- various_loops <- main.
->   Called from tests/value/auto_loop_unroll.c:103.
+>   Called from tests/value/auto_loop_unroll.c:101.
 > [eva] Recording results for incr
 > [eva] Done for function incr
 76c76,79
-< [eva] tests/value/auto_loop_unroll.c:103: Reusing old results for call to incr
+< [eva] tests/value/auto_loop_unroll.c:101: Reusing old results for call to incr
 ---
 > [eva] computing for function incr <- various_loops <- main.
->   Called from tests/value/auto_loop_unroll.c:103.
+>   Called from tests/value/auto_loop_unroll.c:101.
 > [eva] Recording results for incr
 > [eva] Done for function incr
 85c88,91
-< [eva] tests/value/auto_loop_unroll.c:103: Reusing old results for call to incr
+< [eva] tests/value/auto_loop_unroll.c:101: Reusing old results for call to incr
 ---
 > [eva] computing for function incr <- various_loops <- main.
->   Called from tests/value/auto_loop_unroll.c:103.
+>   Called from tests/value/auto_loop_unroll.c:101.
 > [eva] Recording results for incr
 > [eva] Done for function incr
 94c100,103
-< [eva] tests/value/auto_loop_unroll.c:103: Reusing old results for call to incr
+< [eva] tests/value/auto_loop_unroll.c:101: Reusing old results for call to incr
 ---
 > [eva] computing for function incr <- various_loops <- main.
->   Called from tests/value/auto_loop_unroll.c:103.
+>   Called from tests/value/auto_loop_unroll.c:101.
 > [eva] Recording results for incr
 > [eva] Done for function incr
 103c112,115
-< [eva] tests/value/auto_loop_unroll.c:103: Reusing old results for call to incr
+< [eva] tests/value/auto_loop_unroll.c:101: Reusing old results for call to incr
 ---
 > [eva] computing for function incr <- various_loops <- main.
->   Called from tests/value/auto_loop_unroll.c:103.
+>   Called from tests/value/auto_loop_unroll.c:101.
 > [eva] Recording results for incr
 > [eva] Done for function incr
 112c124,127
-< [eva] tests/value/auto_loop_unroll.c:103: Reusing old results for call to incr
+< [eva] tests/value/auto_loop_unroll.c:101: Reusing old results for call to incr
 ---
 > [eva] computing for function incr <- various_loops <- main.
->   Called from tests/value/auto_loop_unroll.c:103.
+>   Called from tests/value/auto_loop_unroll.c:101.
 > [eva] Recording results for incr
 > [eva] Done for function incr
 121c136,139
-< [eva] tests/value/auto_loop_unroll.c:103: Reusing old results for call to incr
+< [eva] tests/value/auto_loop_unroll.c:101: Reusing old results for call to incr
 ---
 > [eva] computing for function incr <- various_loops <- main.
->   Called from tests/value/auto_loop_unroll.c:103.
+>   Called from tests/value/auto_loop_unroll.c:101.
 > [eva] Recording results for incr
 > [eva] Done for function incr
 130c148,151
-< [eva] tests/value/auto_loop_unroll.c:103: Reusing old results for call to incr
+< [eva] tests/value/auto_loop_unroll.c:101: Reusing old results for call to incr
 ---
 > [eva] computing for function incr <- various_loops <- main.
->   Called from tests/value/auto_loop_unroll.c:103.
+>   Called from tests/value/auto_loop_unroll.c:101.
 > [eva] Recording results for incr
 > [eva] Done for function incr
 139c160,163
-< [eva] tests/value/auto_loop_unroll.c:103: Reusing old results for call to incr
+< [eva] tests/value/auto_loop_unroll.c:101: Reusing old results for call to incr
 ---
 > [eva] computing for function incr <- various_loops <- main.
->   Called from tests/value/auto_loop_unroll.c:103.
+>   Called from tests/value/auto_loop_unroll.c:101.
 > [eva] Recording results for incr
 > [eva] Done for function incr
 148c172,175
-< [eva] tests/value/auto_loop_unroll.c:103: Reusing old results for call to incr
+< [eva] tests/value/auto_loop_unroll.c:101: Reusing old results for call to incr
 ---
 > [eva] computing for function incr <- various_loops <- main.
->   Called from tests/value/auto_loop_unroll.c:103.
+>   Called from tests/value/auto_loop_unroll.c:101.
 > [eva] Recording results for incr
 > [eva] Done for function incr
 157c184,187
-< [eva] tests/value/auto_loop_unroll.c:103: Reusing old results for call to incr
+< [eva] tests/value/auto_loop_unroll.c:101: Reusing old results for call to incr
 ---
 > [eva] computing for function incr <- various_loops <- main.
->   Called from tests/value/auto_loop_unroll.c:103.
+>   Called from tests/value/auto_loop_unroll.c:101.
 > [eva] Recording results for incr
 > [eva] Done for function incr
 166c196,199
-< [eva] tests/value/auto_loop_unroll.c:103: Reusing old results for call to incr
+< [eva] tests/value/auto_loop_unroll.c:101: Reusing old results for call to incr
 ---
 > [eva] computing for function incr <- various_loops <- main.
->   Called from tests/value/auto_loop_unroll.c:103.
+>   Called from tests/value/auto_loop_unroll.c:101.
 > [eva] Recording results for incr
 > [eva] Done for function incr
 175c208,211
-< [eva] tests/value/auto_loop_unroll.c:103: Reusing old results for call to incr
+< [eva] tests/value/auto_loop_unroll.c:101: Reusing old results for call to incr
 ---
 > [eva] computing for function incr <- various_loops <- main.
->   Called from tests/value/auto_loop_unroll.c:103.
+>   Called from tests/value/auto_loop_unroll.c:101.
 > [eva] Recording results for incr
 > [eva] Done for function incr
 184c220,223
-< [eva] tests/value/auto_loop_unroll.c:103: Reusing old results for call to incr
+< [eva] tests/value/auto_loop_unroll.c:101: Reusing old results for call to incr
 ---
 > [eva] computing for function incr <- various_loops <- main.
->   Called from tests/value/auto_loop_unroll.c:103.
+>   Called from tests/value/auto_loop_unroll.c:101.
 > [eva] Recording results for incr
 > [eva] Done for function incr
 193c232,235
-< [eva] tests/value/auto_loop_unroll.c:103: Reusing old results for call to incr
+< [eva] tests/value/auto_loop_unroll.c:101: Reusing old results for call to incr
 ---
 > [eva] computing for function incr <- various_loops <- main.
->   Called from tests/value/auto_loop_unroll.c:103.
+>   Called from tests/value/auto_loop_unroll.c:101.
 > [eva] Recording results for incr
 > [eva] Done for function incr
 202c244,247
-< [eva] tests/value/auto_loop_unroll.c:103: Reusing old results for call to incr
+< [eva] tests/value/auto_loop_unroll.c:101: Reusing old results for call to incr
 ---
 > [eva] computing for function incr <- various_loops <- main.
->   Called from tests/value/auto_loop_unroll.c:103.
+>   Called from tests/value/auto_loop_unroll.c:101.
 > [eva] Recording results for incr
 > [eva] Done for function incr
 211c256,259
-< [eva] tests/value/auto_loop_unroll.c:103: Reusing old results for call to incr
+< [eva] tests/value/auto_loop_unroll.c:101: Reusing old results for call to incr
 ---
 > [eva] computing for function incr <- various_loops <- main.
->   Called from tests/value/auto_loop_unroll.c:103.
+>   Called from tests/value/auto_loop_unroll.c:101.
 > [eva] Recording results for incr
 > [eva] Done for function incr
 220c268,271
-< [eva] tests/value/auto_loop_unroll.c:103: Reusing old results for call to incr
+< [eva] tests/value/auto_loop_unroll.c:101: Reusing old results for call to incr
 ---
 > [eva] computing for function incr <- various_loops <- main.
->   Called from tests/value/auto_loop_unroll.c:103.
+>   Called from tests/value/auto_loop_unroll.c:101.
 > [eva] Recording results for incr
 > [eva] Done for function incr
 229c280,283
-< [eva] tests/value/auto_loop_unroll.c:103: Reusing old results for call to incr
+< [eva] tests/value/auto_loop_unroll.c:101: Reusing old results for call to incr
 ---
 > [eva] computing for function incr <- various_loops <- main.
->   Called from tests/value/auto_loop_unroll.c:103.
+>   Called from tests/value/auto_loop_unroll.c:101.
 > [eva] Recording results for incr
 > [eva] Done for function incr
 238c292,295
-< [eva] tests/value/auto_loop_unroll.c:103: Reusing old results for call to incr
+< [eva] tests/value/auto_loop_unroll.c:101: Reusing old results for call to incr
 ---
 > [eva] computing for function incr <- various_loops <- main.
->   Called from tests/value/auto_loop_unroll.c:103.
+>   Called from tests/value/auto_loop_unroll.c:101.
 > [eva] Recording results for incr
 > [eva] Done for function incr
 247c304,307
-< [eva] tests/value/auto_loop_unroll.c:103: Reusing old results for call to incr
+< [eva] tests/value/auto_loop_unroll.c:101: Reusing old results for call to incr
 ---
 > [eva] computing for function incr <- various_loops <- main.
->   Called from tests/value/auto_loop_unroll.c:103.
+>   Called from tests/value/auto_loop_unroll.c:101.
 > [eva] Recording results for incr
 > [eva] Done for function incr
 256c316,319
-< [eva] tests/value/auto_loop_unroll.c:103: Reusing old results for call to incr
+< [eva] tests/value/auto_loop_unroll.c:101: Reusing old results for call to incr
 ---
 > [eva] computing for function incr <- various_loops <- main.
->   Called from tests/value/auto_loop_unroll.c:103.
+>   Called from tests/value/auto_loop_unroll.c:101.
 > [eva] Recording results for incr
 > [eva] Done for function incr
 265c328,331
-< [eva] tests/value/auto_loop_unroll.c:103: Reusing old results for call to incr
+< [eva] tests/value/auto_loop_unroll.c:101: Reusing old results for call to incr
 ---
 > [eva] computing for function incr <- various_loops <- main.
->   Called from tests/value/auto_loop_unroll.c:103.
+>   Called from tests/value/auto_loop_unroll.c:101.
 > [eva] Recording results for incr
 > [eva] Done for function incr
 274c340,343
-< [eva] tests/value/auto_loop_unroll.c:103: Reusing old results for call to incr
+< [eva] tests/value/auto_loop_unroll.c:101: Reusing old results for call to incr
 ---
 > [eva] computing for function incr <- various_loops <- main.
->   Called from tests/value/auto_loop_unroll.c:103.
+>   Called from tests/value/auto_loop_unroll.c:101.
 > [eva] Recording results for incr
 > [eva] Done for function incr
-294,295d362
-< [eva:alarm] tests/value/auto_loop_unroll.c:136: Warning: 
+296,297d364
+< [eva:alarm] tests/value/auto_loop_unroll.c:145: Warning: 
 <   signed overflow. assert res + 1 ≤ 2147483647;
-302c369
+304c371
 <   Frama_C_show_each_imprecise: [0..2147483647]
 ---
 >   Frama_C_show_each_imprecise: [10..2147483647]
-304,308c371,375
-< [eva:alarm] tests/value/auto_loop_unroll.c:156: Warning: 
-<   signed overflow. assert res + 1 ≤ 2147483647;
-< [eva] tests/value/auto_loop_unroll.c:158: 
-<   Frama_C_show_each_imprecise: [0..2147483647]
-< [eva] tests/value/auto_loop_unroll.c:163: Reusing old results for call to incr_g
----
-> [eva] tests/value/auto_loop_unroll.c:158: Frama_C_show_each_imprecise: {10}
-> [eva] computing for function incr_g <- complex_loops <- main.
->   Called from tests/value/auto_loop_unroll.c:163.
-> [eva] Recording results for incr_g
-> [eva] Done for function incr_g
 322,327c389,397
-< [eva] tests/value/auto_loop_unroll.c:163: Reusing old results for call to incr_g
-< [eva] tests/value/auto_loop_unroll.c:163: Reusing old results for call to incr_g
-< [eva:alarm] tests/value/auto_loop_unroll.c:165: Warning: 
+< [eva] tests/value/auto_loop_unroll.c:162: Reusing old results for call to incr_g
+< [eva] tests/value/auto_loop_unroll.c:162: Reusing old results for call to incr_g
+< [eva:alarm] tests/value/auto_loop_unroll.c:164: Warning: 
 <   signed overflow. assert res + 1 ≤ 2147483647;
-< [eva] tests/value/auto_loop_unroll.c:167: 
+< [eva] tests/value/auto_loop_unroll.c:166: 
 <   Frama_C_show_each_imprecise: [0..2147483647]
 ---
 > [eva] computing for function incr_g <- complex_loops <- main.
->   Called from tests/value/auto_loop_unroll.c:163.
+>   Called from tests/value/auto_loop_unroll.c:162.
 > [eva] Recording results for incr_g
 > [eva] Done for function incr_g
 > [eva] computing for function incr_g <- complex_loops <- main.
->   Called from tests/value/auto_loop_unroll.c:163.
+>   Called from tests/value/auto_loop_unroll.c:162.
 > [eva] Recording results for incr_g
 > [eva] Done for function incr_g
-> [eva] tests/value/auto_loop_unroll.c:167: Frama_C_show_each_imprecise: [0..64]
+> [eva] tests/value/auto_loop_unroll.c:166: Frama_C_show_each_imprecise: [0..64]
 329,332c399
-< [eva:alarm] tests/value/auto_loop_unroll.c:174: Warning: 
+< [eva:alarm] tests/value/auto_loop_unroll.c:173: Warning: 
 <   signed overflow. assert res + 1 ≤ 2147483647;
-< [eva] tests/value/auto_loop_unroll.c:176: 
+< [eva] tests/value/auto_loop_unroll.c:175: 
 <   Frama_C_show_each_imprecise: [0..2147483647]
 ---
-> [eva] tests/value/auto_loop_unroll.c:176: Frama_C_show_each_imprecise: [0..9]
-334,337c401
-< [eva:alarm] tests/value/auto_loop_unroll.c:182: Warning: 
+> [eva] tests/value/auto_loop_unroll.c:175: Frama_C_show_each_imprecise: [0..9]
+334,335d400
+< [eva:alarm] tests/value/auto_loop_unroll.c:181: Warning: 
 <   signed overflow. assert res + 1 ≤ 2147483647;
-< [eva] tests/value/auto_loop_unroll.c:184: 
+339c404
 <   Frama_C_show_each_imprecise: [0..2147483647]
 ---
-> [eva] tests/value/auto_loop_unroll.c:184: Frama_C_show_each_imprecise: [0..64]
+>   Frama_C_show_each_imprecise: [64..2147483647]
+344c409
+< [eva:loop-unroll] tests/value/auto_loop_unroll.c:192: Automatic loop unrolling.
+---
+> [eva] tests/value/auto_loop_unroll.c:192: starting to merge loop iterations
+346c411
+< [eva:loop-unroll] tests/value/auto_loop_unroll.c:197: Automatic loop unrolling.
+---
+> [eva] tests/value/auto_loop_unroll.c:197: starting to merge loop iterations
+348,353c413,429
+< [eva:loop-unroll] tests/value/auto_loop_unroll.c:203: Automatic loop unrolling.
+< [eva] tests/value/auto_loop_unroll.c:206: Frama_C_show_each_0_13: [0..13]
+< [eva:loop-unroll] tests/value/auto_loop_unroll.c:208: Automatic loop unrolling.
+< [eva] tests/value/auto_loop_unroll.c:211: Frama_C_show_each_0_14: [0..14]
+< [eva:loop-unroll] tests/value/auto_loop_unroll.c:214: Automatic loop unrolling.
+< [eva] tests/value/auto_loop_unroll.c:219: Frama_C_show_each_0_15: [0..15]
+---
+> [eva] tests/value/auto_loop_unroll.c:203: starting to merge loop iterations
+> [eva:alarm] tests/value/auto_loop_unroll.c:203: Warning: 
+>   signed overflow. assert -2147483648 ≤ i_0 - 1;
+> [eva:alarm] tests/value/auto_loop_unroll.c:204: Warning: 
+>   signed overflow. assert res + 1 ≤ 2147483647;
+> [eva] tests/value/auto_loop_unroll.c:206: 
+>   Frama_C_show_each_0_13: [0..2147483647]
+> [eva] tests/value/auto_loop_unroll.c:208: starting to merge loop iterations
+> [eva:alarm] tests/value/auto_loop_unroll.c:208: Warning: 
+>   signed overflow. assert -2147483648 ≤ i_1 - 1;
+> [eva:alarm] tests/value/auto_loop_unroll.c:209: Warning: 
+>   signed overflow. assert res + 1 ≤ 2147483647;
+> [eva] tests/value/auto_loop_unroll.c:211: 
+>   Frama_C_show_each_0_14: [0..2147483647]
+> [eva] tests/value/auto_loop_unroll.c:214: starting to merge loop iterations
+> [eva] tests/value/auto_loop_unroll.c:219: 
+>   Frama_C_show_each_0_15: [0..2147483647]
+364c440,444
+< [eva:loop-unroll] tests/value/auto_loop_unroll.c:240: Automatic loop unrolling.
+---
+> [eva] tests/value/auto_loop_unroll.c:240: starting to merge loop iterations
+> [eva:alarm] tests/value/auto_loop_unroll.c:240: Warning: 
+>   signed overflow. assert -2147483648 ≤ i - 1;
+> [eva:alarm] tests/value/auto_loop_unroll.c:241: Warning: 
+>   signed overflow. assert res + 1 ≤ 2147483647;
+375c455,456
+< [eva] tests/value/auto_loop_unroll.c:263: Frama_C_show_each_top: [0..2147483647]
+---
+> [eva] tests/value/auto_loop_unroll.c:263: 
+>   Frama_C_show_each_top: [31..2147483647]
+391,392d471
+< [eva:alarm] tests/value/auto_loop_unroll.c:283: Warning: 
+<   signed overflow. assert res + 1 ≤ 2147483647;
+425,426c504,505
+<   i ∈ {-1}
+<   res ∈ {21}
+---
+>   i ∈ [-2147483648..20]
+>   res ∈ [0..2147483647]
 diff tests/value/oracle/backward_add_ptr.res.oracle tests/value/oracle_apron/backward_add_ptr.res.oracle
 71c71,74
 < [eva] tests/value/backward_add_ptr.c:91: Reusing old results for call to gm
@@ -1149,8 +1237,8 @@ diff tests/value/oracle/offsetmap.1.res.oracle tests/value/oracle_apron/offsetma
 >   b ∈ {0; 1}
 >   a7 ∈ {1}
 diff tests/value/oracle/partitioning-annots.4.res.oracle tests/value/oracle_apron/partitioning-annots.4.res.oracle
-14,15d13
-< [eva:alarm] tests/value/partitioning-annots.c:134: Warning: 
+15,16d14
+< [eva:alarm] tests/value/partitioning-annots.c:138: Warning: 
 <   division by zero. assert j ≢ 0;
 diff tests/value/oracle/precise_locations.res.oracle tests/value/oracle_apron/precise_locations.res.oracle
 32,35c32,47
@@ -1394,6 +1482,7 @@ diff tests/value/oracle/undefined_sequence.1.res.oracle tests/value/oracle_apron
 >   Called from tests/value/undefined_sequence.i:54.
 > [eva] Recording results for g
 > [eva] Done for function g
+Only in tests/value/oracle: unit_tests.res.oracle
 diff tests/value/oracle/unroll.res.oracle tests/value/oracle_apron/unroll.res.oracle
 13,14d12
 < [eva:alarm] tests/value/unroll.i:34: Warning: 
diff --git a/tests/value/diff_bitwise b/tests/value/diff_bitwise
index f3d9227dd921eafcae4091aea38d785407838400..7ef9494da776c8a2e342d1f3be2eacc46a36d1e6 100644
--- a/tests/value/diff_bitwise
+++ b/tests/value/diff_bitwise
@@ -24,10 +24,10 @@ diff tests/value/oracle/addition.res.oracle tests/value/oracle_bitwise/addition.
 ---
 >   p10 ∈ {{ garbled mix of &{p1} }}
 diff tests/value/oracle/bitwise.res.oracle tests/value/oracle_bitwise/bitwise.res.oracle
-79c79,82
-< [eva] tests/value/bitwise.i:144: Frama_C_show_each_dead: {0}
+98c98,101
+< [eva] tests/value/bitwise.i:158: Frama_C_show_each_dead: {0}
 ---
-> [eva] tests/value/bitwise.i:142: 
+> [eva] tests/value/bitwise.i:156: 
 >   The evaluation of the expression x & 2
 >   led to bottom without alarms:
 >   at this point the product of states has no possible concretization.
@@ -51,3 +51,4 @@ diff tests/value/oracle/logic_ptr_cast.res.oracle tests/value/oracle_bitwise/log
 <   The imprecision originates from Arithmetic {tests/value/logic_ptr_cast.i:8}
 ---
 > [eva] tests/value/logic_ptr_cast.i:8: Assigning imprecise value to p.
+Only in tests/value/oracle: unit_tests.res.oracle
diff --git a/tests/value/diff_equalities b/tests/value/diff_equalities
index 4ebaf82ffdec6a7011177a7b539a9e0fb8113c45..f07475f33aa61831526cdf8a686726438a8e2707 100644
--- a/tests/value/diff_equalities
+++ b/tests/value/diff_equalities
@@ -121,18 +121,18 @@ diff tests/value/oracle/alias.6.res.oracle tests/value/oracle_equalities/alias.6
 ---
 >   x ∈ {33}
 diff tests/value/oracle/auto_loop_unroll.0.res.oracle tests/value/oracle_equalities/auto_loop_unroll.0.res.oracle
-82c82,85
-< [eva] tests/value/auto_loop_unroll.c:103: Reusing old results for call to incr
+81c81,84
+< [eva] tests/value/auto_loop_unroll.c:101: Reusing old results for call to incr
 ---
 > [eva] computing for function incr <- various_loops <- main.
->   Called from tests/value/auto_loop_unroll.c:103.
+>   Called from tests/value/auto_loop_unroll.c:101.
 > [eva] Recording results for incr
 > [eva] Done for function incr
-91c94,97
-< [eva] tests/value/auto_loop_unroll.c:103: Reusing old results for call to incr
+90c93,96
+< [eva] tests/value/auto_loop_unroll.c:101: Reusing old results for call to incr
 ---
 > [eva] computing for function incr <- various_loops <- main.
->   Called from tests/value/auto_loop_unroll.c:103.
+>   Called from tests/value/auto_loop_unroll.c:101.
 > [eva] Recording results for incr
 > [eva] Done for function incr
 diff tests/value/oracle/backward_add_ptr.res.oracle tests/value/oracle_equalities/backward_add_ptr.res.oracle
@@ -688,7 +688,7 @@ diff tests/value/oracle/non_natural.res.oracle tests/value/oracle_equalities/non
 > [kernel] tests/value/non_natural.i:39: 
 >   more than 200(12500) elements to enumerate. Approximating.
 diff tests/value/oracle/nonlin.res.oracle tests/value/oracle_equalities/nonlin.res.oracle
-188c188
+194c194
 <   q ∈ {{ &x + [-400..400],0%4 }}
 ---
 >   q ∈ {{ &x }}
@@ -867,3 +867,4 @@ diff tests/value/oracle/struct2.res.oracle tests/value/oracle_equalities/struct2
 <            [9].a}; s1; s2; s5.e[0].b; s6.b; s8; tabl[0..1]; tab1[0..1];
 ---
 >            [9].a}; s1; s2; s5.e[0].b; s6.b; s8; tabl[0..1]; tab1[0];
+Only in tests/value/oracle: unit_tests.res.oracle
diff --git a/tests/value/diff_gauges b/tests/value/diff_gauges
index 55a5986c6614e0f6ee962fda6b7aa5413b05a8fc..f6010fb62ca6b8e732c4cdfb986167352b43e100 100644
--- a/tests/value/diff_gauges
+++ b/tests/value/diff_gauges
@@ -47,20 +47,98 @@ diff tests/value/oracle/auto_loop_unroll.0.res.oracle tests/value/oracle_gauges/
 <   Frama_C_show_each_32_80: [0..2147483647]
 ---
 > [eva] tests/value/auto_loop_unroll.c:82: Frama_C_show_each_32_80: [32..83]
-49,52c32
-< [eva:alarm] tests/value/auto_loop_unroll.c:86: Warning: 
+55,56d37
+< [eva:alarm] tests/value/auto_loop_unroll.c:88: Warning: 
 <   signed overflow. assert res + 1 ≤ 2147483647;
-< [eva] tests/value/auto_loop_unroll.c:90: 
+58c39
+<   Frama_C_show_each_40_50: [0..2147483647]
+---
+>   Frama_C_show_each_40_50: [40..1073741861]
+133,136c114
+< [eva:alarm] tests/value/auto_loop_unroll.c:120: Warning: 
+<   signed overflow. assert res + 1 ≤ 2147483647;
+< [eva] tests/value/auto_loop_unroll.c:122: 
+<   Frama_C_show_each_32_64: [0..2147483647]
+---
+> [eva] tests/value/auto_loop_unroll.c:122: Frama_C_show_each_32_64: [32..65]
+185,188c163
+< [eva:alarm] tests/value/auto_loop_unroll.c:173: Warning: 
+<   signed overflow. assert res + 1 ≤ 2147483647;
+< [eva] tests/value/auto_loop_unroll.c:175: 
+<   Frama_C_show_each_imprecise: [0..2147483647]
+---
+> [eva] tests/value/auto_loop_unroll.c:175: Frama_C_show_each_imprecise: [1..9]
+190,191d164
+< [eva:alarm] tests/value/auto_loop_unroll.c:181: Warning: 
+<   signed overflow. assert res + 1 ≤ 2147483647;
+195c168
+<   Frama_C_show_each_imprecise: [0..2147483647]
+---
+>   Frama_C_show_each_imprecise: [64..2147483647]
+201,203c174
+< [eva:alarm] tests/value/auto_loop_unroll.c:193: Warning: 
+<   signed overflow. assert res + 1 ≤ 2147483647;
+< [eva] tests/value/auto_loop_unroll.c:195: Frama_C_show_each_11: [0..2147483647]
+---
+> [eva] tests/value/auto_loop_unroll.c:195: Frama_C_show_each_11: {11}
+205,207c176
+< [eva:alarm] tests/value/auto_loop_unroll.c:198: Warning: 
+<   signed overflow. assert res + 1 ≤ 2147483647;
+< [eva] tests/value/auto_loop_unroll.c:200: Frama_C_show_each_12: [0..2147483647]
+---
+> [eva] tests/value/auto_loop_unroll.c:200: Frama_C_show_each_12: {12}
+209,210d177
+< [eva:alarm] tests/value/auto_loop_unroll.c:204: Warning: 
+<   signed overflow. assert res + 1 ≤ 2147483647;
+212a180,181
+> [eva:alarm] tests/value/auto_loop_unroll.c:204: Warning: 
+>   signed overflow. assert res + 1 ≤ 2147483647;
+216,217d184
+< [eva:alarm] tests/value/auto_loop_unroll.c:209: Warning: 
+<   signed overflow. assert res + 1 ≤ 2147483647;
+219a187,188
+> [eva:alarm] tests/value/auto_loop_unroll.c:209: Warning: 
+>   signed overflow. assert res + 1 ≤ 2147483647;
+223,224d191
+< [eva:alarm] tests/value/auto_loop_unroll.c:217: Warning: 
+<   signed overflow. assert res + 1 ≤ 2147483647;
+228,231c195
+< [eva:alarm] tests/value/auto_loop_unroll.c:222: Warning: 
+<   signed overflow. assert res + 1 ≤ 2147483647;
+< [eva] tests/value/auto_loop_unroll.c:226: 
 <   Frama_C_show_each_11_111: [0..2147483647]
 ---
-> [eva] tests/value/auto_loop_unroll.c:90: Frama_C_show_each_11_111: [11..111]
-60,61d39
-< [eva:alarm] tests/value/auto_loop_unroll.c:96: Warning: 
+> [eva] tests/value/auto_loop_unroll.c:226: Frama_C_show_each_11_111: [11..111]
+239,241c203
+< [eva:alarm] tests/value/auto_loop_unroll.c:236: Warning: 
 <   signed overflow. assert res + 1 ≤ 2147483647;
-63c41
-<   Frama_C_show_each_40_50: [0..2147483647]
+< [eva] tests/value/auto_loop_unroll.c:238: Frama_C_show_each_20: [0..2147483647]
 ---
->   Frama_C_show_each_40_50: [40..1073741861]
+> [eva] tests/value/auto_loop_unroll.c:238: Frama_C_show_each_20: [20..2147483646]
+243,244d204
+< [eva:alarm] tests/value/auto_loop_unroll.c:241: Warning: 
+<   signed overflow. assert res + 1 ≤ 2147483647;
+247c207,209
+< [eva] tests/value/auto_loop_unroll.c:243: Frama_C_show_each_21: [0..2147483647]
+---
+> [eva:alarm] tests/value/auto_loop_unroll.c:241: Warning: 
+>   signed overflow. assert res + 1 ≤ 2147483647;
+> [eva] tests/value/auto_loop_unroll.c:243: Frama_C_show_each_21: {21}
+253,255c215,216
+< [eva:alarm] tests/value/auto_loop_unroll.c:250: Warning: 
+<   signed overflow. assert res + 1 ≤ 2147483647;
+< [eva] tests/value/auto_loop_unroll.c:254: Frama_C_show_each_30: [0..2147483647]
+---
+> [eva] tests/value/auto_loop_unroll.c:254: Frama_C_show_each_30: {30}
+> [eva] tests/value/auto_loop_unroll.c:258: starting to merge loop iterations
+258d218
+< [eva] tests/value/auto_loop_unroll.c:258: starting to merge loop iterations
+261,263c221
+< [eva:alarm] tests/value/auto_loop_unroll.c:267: Warning: 
+<   signed overflow. assert res + 1 ≤ 2147483647;
+< [eva] tests/value/auto_loop_unroll.c:272: Frama_C_show_each_32: [0..2147483647]
+---
+> [eva] tests/value/auto_loop_unroll.c:272: Frama_C_show_each_32: {32}
 diff tests/value/oracle/auto_loop_unroll.1.res.oracle tests/value/oracle_gauges/auto_loop_unroll.1.res.oracle
 15,18c15
 < [eva:alarm] tests/value/auto_loop_unroll.c:31: Warning: 
@@ -76,6 +154,105 @@ diff tests/value/oracle/auto_loop_unroll.1.res.oracle tests/value/oracle_gauges/
 <   Frama_C_show_each_imprecise: [0..2147483647]
 ---
 > [eva] tests/value/auto_loop_unroll.c:41: Frama_C_show_each_imprecise: {100}
+329,332c323
+< [eva:alarm] tests/value/auto_loop_unroll.c:173: Warning: 
+<   signed overflow. assert res + 1 ≤ 2147483647;
+< [eva] tests/value/auto_loop_unroll.c:175: 
+<   Frama_C_show_each_imprecise: [0..2147483647]
+---
+> [eva] tests/value/auto_loop_unroll.c:175: Frama_C_show_each_imprecise: [1..9]
+334,335d324
+< [eva:alarm] tests/value/auto_loop_unroll.c:181: Warning: 
+<   signed overflow. assert res + 1 ≤ 2147483647;
+339c328
+<   Frama_C_show_each_imprecise: [0..2147483647]
+---
+>   Frama_C_show_each_imprecise: [64..2147483647]
+385a375,458
+> [eva] tests/value/auto_loop_unroll.c:276: 
+>   Trace partitioning superposing up to 200 states
+> [eva] tests/value/auto_loop_unroll.c:276: 
+>   Trace partitioning superposing up to 300 states
+> [eva] tests/value/auto_loop_unroll.c:276: 
+>   Trace partitioning superposing up to 400 states
+> [eva] tests/value/auto_loop_unroll.c:276: 
+>   Trace partitioning superposing up to 500 states
+> [eva] tests/value/auto_loop_unroll.c:276: 
+>   Trace partitioning superposing up to 600 states
+> [eva] tests/value/auto_loop_unroll.c:276: 
+>   Trace partitioning superposing up to 700 states
+> [eva] tests/value/auto_loop_unroll.c:276: 
+>   Trace partitioning superposing up to 800 states
+> [eva] tests/value/auto_loop_unroll.c:276: 
+>   Trace partitioning superposing up to 900 states
+> [eva] tests/value/auto_loop_unroll.c:276: 
+>   Trace partitioning superposing up to 1000 states
+> [eva] tests/value/auto_loop_unroll.c:276: 
+>   Trace partitioning superposing up to 1100 states
+> [eva] tests/value/auto_loop_unroll.c:276: 
+>   Trace partitioning superposing up to 1200 states
+> [eva] tests/value/auto_loop_unroll.c:276: 
+>   Trace partitioning superposing up to 1300 states
+> [eva] tests/value/auto_loop_unroll.c:276: 
+>   Trace partitioning superposing up to 1400 states
+> [eva] tests/value/auto_loop_unroll.c:276: 
+>   Trace partitioning superposing up to 1500 states
+> [eva] tests/value/auto_loop_unroll.c:276: 
+>   Trace partitioning superposing up to 1600 states
+> [eva] tests/value/auto_loop_unroll.c:276: 
+>   Trace partitioning superposing up to 1700 states
+> [eva] tests/value/auto_loop_unroll.c:276: 
+>   Trace partitioning superposing up to 1800 states
+> [eva] tests/value/auto_loop_unroll.c:276: 
+>   Trace partitioning superposing up to 1900 states
+> [eva] tests/value/auto_loop_unroll.c:276: 
+>   Trace partitioning superposing up to 2000 states
+> [eva] tests/value/auto_loop_unroll.c:276: 
+>   Trace partitioning superposing up to 2100 states
+> [eva] tests/value/auto_loop_unroll.c:276: 
+>   Trace partitioning superposing up to 2200 states
+> [eva] tests/value/auto_loop_unroll.c:276: 
+>   Trace partitioning superposing up to 2300 states
+> [eva] tests/value/auto_loop_unroll.c:276: 
+>   Trace partitioning superposing up to 2400 states
+> [eva] tests/value/auto_loop_unroll.c:276: 
+>   Trace partitioning superposing up to 2500 states
+> [eva] tests/value/auto_loop_unroll.c:276: 
+>   Trace partitioning superposing up to 2600 states
+> [eva] tests/value/auto_loop_unroll.c:276: 
+>   Trace partitioning superposing up to 2700 states
+> [eva] tests/value/auto_loop_unroll.c:276: 
+>   Trace partitioning superposing up to 2800 states
+> [eva] tests/value/auto_loop_unroll.c:276: 
+>   Trace partitioning superposing up to 2900 states
+> [eva] tests/value/auto_loop_unroll.c:276: 
+>   Trace partitioning superposing up to 3000 states
+> [eva] tests/value/auto_loop_unroll.c:276: 
+>   Trace partitioning superposing up to 3100 states
+> [eva] tests/value/auto_loop_unroll.c:276: 
+>   Trace partitioning superposing up to 3200 states
+> [eva] tests/value/auto_loop_unroll.c:276: 
+>   Trace partitioning superposing up to 3300 states
+> [eva] tests/value/auto_loop_unroll.c:276: 
+>   Trace partitioning superposing up to 3400 states
+> [eva] tests/value/auto_loop_unroll.c:276: 
+>   Trace partitioning superposing up to 3500 states
+> [eva] tests/value/auto_loop_unroll.c:276: 
+>   Trace partitioning superposing up to 3600 states
+> [eva] tests/value/auto_loop_unroll.c:276: 
+>   Trace partitioning superposing up to 3700 states
+> [eva] tests/value/auto_loop_unroll.c:276: 
+>   Trace partitioning superposing up to 3800 states
+> [eva] tests/value/auto_loop_unroll.c:276: 
+>   Trace partitioning superposing up to 3900 states
+> [eva] tests/value/auto_loop_unroll.c:276: 
+>   Trace partitioning superposing up to 4000 states
+> [eva] tests/value/auto_loop_unroll.c:276: 
+>   Trace partitioning superposing up to 4100 states
+> [eva] tests/value/auto_loop_unroll.c:276: 
+>   Trace partitioning superposing up to 4200 states
+> [eva] tests/value/auto_loop_unroll.c:276: 
+>   Trace partitioning superposing up to 4300 states
 diff tests/value/oracle/bad_loop.res.oracle tests/value/oracle_gauges/bad_loop.res.oracle
 6a7
 > [eva] tests/value/bad_loop.i:12: starting to merge loop iterations
@@ -1047,6 +1224,7 @@ diff tests/value/oracle/undefined_sequence.0.res.oracle tests/value/oracle_gauge
 > [eva] tests/value/undefined_sequence.i:43: starting to merge loop iterations
 101a103
 > [eva] tests/value/undefined_sequence.i:49: starting to merge loop iterations
+Only in tests/value/oracle: unit_tests.res.oracle
 diff tests/value/oracle/unroll.res.oracle tests/value/oracle_gauges/unroll.res.oracle
 13,14d12
 < [eva:alarm] tests/value/unroll.i:34: Warning: 
diff --git a/tests/value/diff_octagons b/tests/value/diff_octagons
index 8786bf632829b31384a2e29cf003d97301b6a853..60823ae538cd11a1439e74d6916dda01dca0c8c1 100644
--- a/tests/value/diff_octagons
+++ b/tests/value/diff_octagons
@@ -33,6 +33,20 @@ diff tests/value/oracle/alias.6.res.oracle tests/value/oracle_octagons/alias.6.r
 >   tz1 ∈ {1}
 >   tz2 ∈ {1}
 >   tz3 ∈ {1}
+diff tests/value/oracle/auto_loop_unroll.0.res.oracle tests/value/oracle_octagons/auto_loop_unroll.0.res.oracle
+211,212d210
+< [eva:alarm] tests/value/auto_loop_unroll.c:203: Warning: 
+<   signed overflow. assert -2147483648 ≤ i_0 - 1;
+218,219d215
+< [eva:alarm] tests/value/auto_loop_unroll.c:208: Warning: 
+<   signed overflow. assert -2147483648 ≤ i_1 - 1;
+245,246d240
+< [eva:alarm] tests/value/auto_loop_unroll.c:240: Warning: 
+<   signed overflow. assert -2147483648 ≤ i - 1;
+306c300
+<   i ∈ [-2147483648..20]
+---
+>   i ∈ {-1}
 diff tests/value/oracle/bitfield.res.oracle tests/value/oracle_octagons/bitfield.res.oracle
 138a139,141
 > [eva] tests/value/bitfield.i:71: 
@@ -238,23 +252,23 @@ diff tests/value/oracle/non_natural.res.oracle tests/value/oracle_octagons/non_n
 > [kernel] tests/value/non_natural.i:39: 
 >   more than 200(12500) elements to enumerate. Approximating.
 diff tests/value/oracle/nonlin.res.oracle tests/value/oracle_octagons/nonlin.res.oracle
-107a108,109
-> [eva:nonlin] tests/value/nonlin.c:65: non-linear 'x * x', lv 'x'
-> [eva:nonlin] tests/value/nonlin.c:65: subdividing on x
-110a113,115
-> [eva:nonlin] tests/value/nonlin.c:66: subdividing on x
-> [eva:nonlin] tests/value/nonlin.c:66: non-linear 'y * y', lv 'y'
-> [eva:nonlin] tests/value/nonlin.c:66: subdividing on y
-113a119,120
-> [eva:nonlin] tests/value/nonlin.c:68: non-linear 'z * x + x * y', lv 'x'
-> [eva:nonlin] tests/value/nonlin.c:68: subdividing on x
-151a159,160
-> [eva:nonlin] tests/value/nonlin.c:112: non-linear 'x * x', lv 'x'
-> [eva:nonlin] tests/value/nonlin.c:112: subdividing on x
-154a164
-> [eva:nonlin] tests/value/nonlin.c:113: subdividing on x
-155a166
-> [eva:nonlin] tests/value/nonlin.c:115: subdividing on x
+113a114,115
+> [eva:nonlin] tests/value/nonlin.c:71: non-linear 'x * x', lv 'x'
+> [eva:nonlin] tests/value/nonlin.c:71: subdividing on x
+116a119,121
+> [eva:nonlin] tests/value/nonlin.c:72: subdividing on x
+> [eva:nonlin] tests/value/nonlin.c:72: non-linear 'y * y', lv 'y'
+> [eva:nonlin] tests/value/nonlin.c:72: subdividing on y
+119a125,126
+> [eva:nonlin] tests/value/nonlin.c:74: non-linear 'z * x + x * y', lv 'x'
+> [eva:nonlin] tests/value/nonlin.c:74: subdividing on x
+157a165,166
+> [eva:nonlin] tests/value/nonlin.c:118: non-linear 'x * x', lv 'x'
+> [eva:nonlin] tests/value/nonlin.c:118: subdividing on x
+160a170
+> [eva:nonlin] tests/value/nonlin.c:119: subdividing on x
+161a172
+> [eva:nonlin] tests/value/nonlin.c:121: subdividing on x
 diff tests/value/oracle/plevel.res.oracle tests/value/oracle_octagons/plevel.res.oracle
 12d11
 < [eva] Recording results for main
@@ -386,6 +400,7 @@ diff tests/value/oracle/test.0.res.oracle tests/value/oracle_octagons/test.0.res
 <   j ∈ [-1073741822..1]
 ---
 >   j ∈ {-1; 0; 1}
+Only in tests/value/oracle: unit_tests.res.oracle
 diff tests/value/oracle/unroll.res.oracle tests/value/oracle_octagons/unroll.res.oracle
 22c22
 <   G ∈ [17739..2147483647]
diff --git a/tests/value/diff_symblocs b/tests/value/diff_symblocs
index a2095316e27d0cc8c465e64167fb860f90af592c..a03b0b46bdb9405bb44d74b683245c7fc1b0b4a3 100644
--- a/tests/value/diff_symblocs
+++ b/tests/value/diff_symblocs
@@ -326,3 +326,4 @@ diff tests/value/oracle/test.0.res.oracle tests/value/oracle_symblocs/test.0.res
 <   tmp ∈ [--..--] or UNINITIALIZED
 ---
 >   tmp ∈ [-2147483647..2147483647] or UNINITIALIZED
+Only in tests/value/oracle: unit_tests.res.oracle
diff --git a/tests/value/nonlin.c b/tests/value/nonlin.c
index 1a05ef68d3147308ca183a5a8b6a18b65e876d76..2fe0f90f17a8ee5072ccd76445e60dfa44ad7708 100644
--- a/tests/value/nonlin.c
+++ b/tests/value/nonlin.c
@@ -16,9 +16,15 @@ void subdivide_pointer () {
   int *q = p + i - i;
   /* The complete expression is a singleton: no subdivision. */
   y = *(&y + i - i);
-  /* The complete expression is an imprecise integer: subdivision (but not
+  /* The complete expression is an imprecise integer: subdivision (but no
      reduction, as it cannot improve the bounds of the result). */
   y = *(p + i - i);
+  /* The subexpression contains a pointer, but the complete expression is an
+     integer, and the subdivision can reduce its value. */
+  int t[10] = {0, 1, 2, 4, 5, 6, 7, 8, 9};
+  p = &t[0];
+  i = Frama_C_interval(0, 10);
+  y = *(p + i - i);
   /* The splitted lvalue contains a pointer value: no subdivision. */
   i = v ? i : (int) &x;
   y = *(p + i - i);
diff --git a/tests/value/oracle/nonlin.res.oracle b/tests/value/oracle/nonlin.res.oracle
index 433ce49eaa0ba5fe807e8a83e3c7550bb2c62d67..5e56b1da308cf04d6375e24a853686f31a88fb09 100644
--- a/tests/value/oracle/nonlin.res.oracle
+++ b/tests/value/oracle/nonlin.res.oracle
@@ -24,28 +24,28 @@
        [31] ∈ {5}
        [32..35] ∈ {0}
 [eva] computing for function subdivide_integer <- main.
-  Called from tests/value/nonlin.c:119.
-[eva:nonlin] tests/value/nonlin.c:31: 
+  Called from tests/value/nonlin.c:125.
+[eva:nonlin] tests/value/nonlin.c:37: 
   non-linear '((int)z + 675) * ((int)z + 675)', lv 'z'
-[eva:nonlin] tests/value/nonlin.c:31: subdividing on z
-[eva:nonlin] tests/value/nonlin.c:32: 
+[eva:nonlin] tests/value/nonlin.c:37: subdividing on z
+[eva:nonlin] tests/value/nonlin.c:38: 
   non-linear '((int)z + 17817) * ((int)z + 17817)', lv 'z'
-[eva:nonlin] tests/value/nonlin.c:32: subdividing on z
-[eva:alarm] tests/value/nonlin.c:32: Warning: 
+[eva:nonlin] tests/value/nonlin.c:38: subdividing on z
+[eva:alarm] tests/value/nonlin.c:38: Warning: 
   signed overflow.
   assert (int)((int)z + 17817) * (int)((int)z + 17817) ≤ 2147483647;
-[eva:nonlin] tests/value/nonlin.c:39: 
+[eva:nonlin] tests/value/nonlin.c:45: 
   non-linear '(i2 + (long long)3) * (i2 + (long long)3)', lv 'i2'
-[eva:nonlin] tests/value/nonlin.c:39: non-linear 'i1 * i1', lv 'i1'
-[eva:nonlin] tests/value/nonlin.c:39: subdividing on i2
-[eva:nonlin] tests/value/nonlin.c:39: subdividing on i1
-[eva:alarm] tests/value/nonlin.c:43: Warning: assertion got status unknown.
-[eva:nonlin] tests/value/nonlin.c:44: non-linear '(int)idx * (int)idx', lv 'idx'
-[eva:nonlin] tests/value/nonlin.c:44: subdividing on idx
+[eva:nonlin] tests/value/nonlin.c:45: non-linear 'i1 * i1', lv 'i1'
+[eva:nonlin] tests/value/nonlin.c:45: subdividing on i2
+[eva:nonlin] tests/value/nonlin.c:45: subdividing on i1
+[eva:alarm] tests/value/nonlin.c:49: Warning: assertion got status unknown.
+[eva:nonlin] tests/value/nonlin.c:50: non-linear '(int)idx * (int)idx', lv 'idx'
+[eva:nonlin] tests/value/nonlin.c:50: subdividing on idx
 [eva] Recording results for subdivide_integer
 [eva] Done for function subdivide_integer
 [eva] computing for function subdivide_pointer <- main.
-  Called from tests/value/nonlin.c:120.
+  Called from tests/value/nonlin.c:126.
 [eva] computing for function Frama_C_interval <- subdivide_pointer <- main.
   Called from tests/value/nonlin.c:12.
 [eva] using specification for function Frama_C_interval
@@ -63,97 +63,103 @@
 [eva:nonlin] tests/value/nonlin.c:21: subdividing on i
 [eva:alarm] tests/value/nonlin.c:21: Warning: 
   out of bounds read. assert \valid_read((p + i) - i);
-[eva:alarm] tests/value/nonlin.c:23: Warning: 
+[eva] computing for function Frama_C_interval <- subdivide_pointer <- main.
+  Called from tests/value/nonlin.c:26.
+[eva] tests/value/nonlin.c:26: 
+  function Frama_C_interval: precondition 'order' got status valid.
+[eva] Done for function Frama_C_interval
+[eva:nonlin] tests/value/nonlin.c:27: subdividing on i
+[eva:alarm] tests/value/nonlin.c:29: Warning: 
   pointer downcast. assert (unsigned int)(&x) ≤ 2147483647;
-[eva:alarm] tests/value/nonlin.c:24: Warning: 
+[eva:alarm] tests/value/nonlin.c:30: Warning: 
   out of bounds read. assert \valid_read((p + i) - i);
 [eva] Recording results for subdivide_pointer
 [eva] Done for function subdivide_pointer
 [eva] computing for function subdivide_several_variables <- main.
-  Called from tests/value/nonlin.c:121.
+  Called from tests/value/nonlin.c:127.
 [eva] computing for function Frama_C_interval <- subdivide_several_variables <- 
                           main.
-  Called from tests/value/nonlin.c:51.
-[eva] tests/value/nonlin.c:51: 
+  Called from tests/value/nonlin.c:57.
+[eva] tests/value/nonlin.c:57: 
   function Frama_C_interval: precondition 'order' got status valid.
 [eva] Done for function Frama_C_interval
 [eva] computing for function Frama_C_interval <- subdivide_several_variables <- 
                           main.
-  Called from tests/value/nonlin.c:52.
-[eva] tests/value/nonlin.c:52: 
+  Called from tests/value/nonlin.c:58.
+[eva] tests/value/nonlin.c:58: 
   function Frama_C_interval: precondition 'order' got status valid.
 [eva] Done for function Frama_C_interval
 [eva] computing for function Frama_C_interval <- subdivide_several_variables <- 
                           main.
-  Called from tests/value/nonlin.c:53.
-[eva] tests/value/nonlin.c:53: 
+  Called from tests/value/nonlin.c:59.
+[eva] tests/value/nonlin.c:59: 
   function Frama_C_interval: precondition 'order' got status valid.
 [eva] Done for function Frama_C_interval
 [eva] computing for function Frama_C_interval <- subdivide_several_variables <- 
                           main.
-  Called from tests/value/nonlin.c:54.
-[eva] tests/value/nonlin.c:54: 
+  Called from tests/value/nonlin.c:60.
+[eva] tests/value/nonlin.c:60: 
   function Frama_C_interval: precondition 'order' got status valid.
 [eva] Done for function Frama_C_interval
-[eva:nonlin] tests/value/nonlin.c:56: non-linear 'x * x', lv 'x'
-[eva:nonlin] tests/value/nonlin.c:56: non-linear 'y * y', lv 'y'
-[eva:nonlin] tests/value/nonlin.c:56: subdividing on x
-[eva:nonlin] tests/value/nonlin.c:56: subdividing on y
-[eva:nonlin] tests/value/nonlin.c:60: non-linear 'x * x', lv 'x'
-[eva:nonlin] tests/value/nonlin.c:60: non-linear '((x * x) * y) * y', lv 'y'
-[eva:nonlin] tests/value/nonlin.c:60: subdividing on x
-[eva:nonlin] tests/value/nonlin.c:60: subdividing on y
-[eva:nonlin] tests/value/nonlin.c:62: non-linear 'x * y - y * x', lv 'y, x'
-[eva:nonlin] tests/value/nonlin.c:62: subdividing on x, y
-[eva:nonlin] tests/value/nonlin.c:65: 
+[eva:nonlin] tests/value/nonlin.c:62: non-linear 'x * x', lv 'x'
+[eva:nonlin] tests/value/nonlin.c:62: non-linear 'y * y', lv 'y'
+[eva:nonlin] tests/value/nonlin.c:62: subdividing on x
+[eva:nonlin] tests/value/nonlin.c:62: subdividing on y
+[eva:nonlin] tests/value/nonlin.c:66: non-linear 'x * x', lv 'x'
+[eva:nonlin] tests/value/nonlin.c:66: non-linear '((x * x) * y) * y', lv 'y'
+[eva:nonlin] tests/value/nonlin.c:66: subdividing on x
+[eva:nonlin] tests/value/nonlin.c:66: subdividing on y
+[eva:nonlin] tests/value/nonlin.c:68: non-linear 'x * y - y * x', lv 'y, x'
+[eva:nonlin] tests/value/nonlin.c:68: subdividing on x, y
+[eva:nonlin] tests/value/nonlin.c:71: 
   non-linear '(x * x - (2 * x) * y) + y * y', lv 'y, x'
-[eva:nonlin] tests/value/nonlin.c:65: subdividing on x, y
-[eva:nonlin] tests/value/nonlin.c:66: 
+[eva:nonlin] tests/value/nonlin.c:71: subdividing on x, y
+[eva:nonlin] tests/value/nonlin.c:72: 
   non-linear '(x * x + y * y) - (2 * x) * y', lv 'y, x'
-[eva:nonlin] tests/value/nonlin.c:66: subdividing on x, y
-[eva:nonlin] tests/value/nonlin.c:68: 
+[eva:nonlin] tests/value/nonlin.c:72: subdividing on x, y
+[eva:nonlin] tests/value/nonlin.c:74: 
   non-linear '(z * x + x * y) + y * z', lv 'z, y, x'
-[eva:nonlin] tests/value/nonlin.c:68: non-linear 'w * w', lv 'w'
-[eva:nonlin] tests/value/nonlin.c:68: subdividing on x, y, z
-[eva:nonlin] tests/value/nonlin.c:68: subdividing on w
+[eva:nonlin] tests/value/nonlin.c:74: non-linear 'w * w', lv 'w'
+[eva:nonlin] tests/value/nonlin.c:74: subdividing on x, y, z
+[eva:nonlin] tests/value/nonlin.c:74: subdividing on w
 [eva] Recording results for subdivide_several_variables
 [eva] Done for function subdivide_several_variables
 [eva] computing for function subdivide_table <- main.
-  Called from tests/value/nonlin.c:122.
-[eva] tests/value/nonlin.c:87: loop invariant got status valid.
-[eva] tests/value/nonlin.c:88: starting to merge loop iterations
-[eva:nonlin] tests/value/nonlin.c:89: 
+  Called from tests/value/nonlin.c:128.
+[eva] tests/value/nonlin.c:93: loop invariant got status valid.
+[eva] tests/value/nonlin.c:94: starting to merge loop iterations
+[eva:nonlin] tests/value/nonlin.c:95: 
   non-linear '(4 + ((x >> 2) * 3 << 2)) + x % 4', lv 'x'
-[eva:nonlin] tests/value/nonlin.c:89: subdividing on x
+[eva:nonlin] tests/value/nonlin.c:95: subdividing on x
 [eva] Recording results for subdivide_table
 [eva] Done for function subdivide_table
 [eva] computing for function subdivide_reduced_value <- main.
-  Called from tests/value/nonlin.c:123.
-[eva:nonlin] tests/value/nonlin.c:101: non-linear 't1[i] - t2[i]', lv 'i'
-[eva:nonlin] tests/value/nonlin.c:101: subdividing on i
-[eva:alarm] tests/value/nonlin.c:101: Warning: 
+  Called from tests/value/nonlin.c:129.
+[eva:nonlin] tests/value/nonlin.c:107: non-linear 't1[i] - t2[i]', lv 'i'
+[eva:nonlin] tests/value/nonlin.c:107: subdividing on i
+[eva:alarm] tests/value/nonlin.c:107: Warning: 
   accessing out of bounds index. assert 0 ≤ i;
-[eva:alarm] tests/value/nonlin.c:101: Warning: 
+[eva:alarm] tests/value/nonlin.c:107: Warning: 
   accessing out of bounds index. assert i < 2;
 [eva] Recording results for subdivide_reduced_value
 [eva] Done for function subdivide_reduced_value
 [eva] computing for function local_subdivide <- main.
-  Called from tests/value/nonlin.c:124.
+  Called from tests/value/nonlin.c:130.
 [eva] computing for function Frama_C_interval <- local_subdivide <- main.
-  Called from tests/value/nonlin.c:107.
-[eva] tests/value/nonlin.c:107: 
+  Called from tests/value/nonlin.c:113.
+[eva] tests/value/nonlin.c:113: 
   function Frama_C_interval: precondition 'order' got status valid.
 [eva] Done for function Frama_C_interval
 [eva] computing for function Frama_C_interval <- local_subdivide <- main.
-  Called from tests/value/nonlin.c:108.
-[eva] tests/value/nonlin.c:108: 
+  Called from tests/value/nonlin.c:114.
+[eva] tests/value/nonlin.c:114: 
   function Frama_C_interval: precondition 'order' got status valid.
 [eva] Done for function Frama_C_interval
-[eva:nonlin] tests/value/nonlin.c:112: 
+[eva:nonlin] tests/value/nonlin.c:118: 
   non-linear '(x * x - (2 * x) * y) + y * y', lv 'y, x'
-[eva:nonlin] tests/value/nonlin.c:112: subdividing on x, y
-[eva:nonlin] tests/value/nonlin.c:113: subdividing on x, y
-[eva:nonlin] tests/value/nonlin.c:115: subdividing on x, y
+[eva:nonlin] tests/value/nonlin.c:118: subdividing on x, y
+[eva:nonlin] tests/value/nonlin.c:119: subdividing on x, y
+[eva:nonlin] tests/value/nonlin.c:121: subdividing on x, y
 [eva] Recording results for local_subdivide
 [eva] Done for function local_subdivide
 [eva] Recording results for main
@@ -181,11 +187,21 @@
   idx ∈ [0..10]
 [eva:final-states] Values at end of function subdivide_pointer:
   Frama_C_entropy_source ∈ [--..--]
-  y ∈ [-10..10]
+  y ∈ [--..--]
   x ∈ [-10..10]
-  p ∈ {{ &x }}
-  i ∈ {{ NULL + [0..100] ; (int)&x }}
+  p ∈ {{ &t[0] }}
+  i ∈ {{ NULL + [0..10] ; (int)&x }}
   q ∈ {{ &x + [-400..400],0%4 }}
+  t[0] ∈ {0}
+   [1] ∈ {1}
+   [2] ∈ {2}
+   [3] ∈ {4}
+   [4] ∈ {5}
+   [5] ∈ {6}
+   [6] ∈ {7}
+   [7] ∈ {8}
+   [8] ∈ {9}
+   [9] ∈ {0}
 [eva:final-states] Values at end of function subdivide_reduced_value:
   t1[0] ∈ {0}
     [1] ∈ {1}
@@ -256,7 +272,7 @@
 [inout] Inputs for function subdivide_integer:
     v; vs
 [inout] Out (internal) for function subdivide_pointer:
-    Frama_C_entropy_source; y; x; p; i; q
+    Frama_C_entropy_source; y; x; p; i; q; t[0..9]
 [inout] Inputs for function subdivide_pointer:
     Frama_C_entropy_source; v
 [inout] Out (internal) for function subdivide_reduced_value: