From df8107fc3305ca1a81558a88f2ae7cfc9344b13b Mon Sep 17 00:00:00 2001 From: Kostyantyn Vorobyov <kostyantyn.vorobyov@cea.fr> Date: Mon, 5 Dec 2016 14:44:19 +0100 Subject: [PATCH] Updates to --rte option of e-acsl-gcc.sh as per changes to RTE plugin --- src/plugins/e-acsl/man/e-acsl-gcc.sh.1 | 7 +- src/plugins/e-acsl/scripts/e-acsl-gcc.sh | 131 +++++++++++++++-------- 2 files changed, 91 insertions(+), 47 deletions(-) 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 6658f67ce76..80d993bde4b 100644 --- a/src/plugins/e-acsl/man/e-acsl-gcc.sh.1 +++ b/src/plugins/e-acsl/man/e-acsl-gcc.sh.1 @@ -124,13 +124,14 @@ annotate a source program with assertions using a run of an RTE plugin prior to E-ACSL. \fIOPTSTRING\fP is a comma-separated string that specifies the types of generated assertions. Valid arguments are: + \fImem\fP \- valid pointer or array accesses. - \fIint\fP \- integer overflows. - \fIfloat\fP \- casts from floating-point to integer. + \fIint-overflow\fP \- integer overflows. + \fIfloat-to-int\fP \- casts from floating-point to integer. \fIdiv\fP \- division by zero. - \fIret\fP \- return value in non-void functions. \fIprecond\fP \- function calls based on contracts. \fIshift\fP \- left and right shifts by a value out of bounds. + \fpointer-call\fP - annotate functions calls through pointers. \fIall\fP \- all of the above. .TP .B -m, --memory-model=\fI<model> diff --git a/src/plugins/e-acsl/scripts/e-acsl-gcc.sh b/src/plugins/e-acsl/scripts/e-acsl-gcc.sh index c3db69f4c4c..defbe3aeb23 100755 --- a/src/plugins/e-acsl/scripts/e-acsl-gcc.sh +++ b/src/plugins/e-acsl/scripts/e-acsl-gcc.sh @@ -68,54 +68,97 @@ realpath() { fi } -# Process option string for RTE plugin +# Split a comma-separated string into a whitespace-separated string, remove +# all duplicates and trailing, leading or multiple spaces +tokenize() { + echo -n "$@" \ + | sed -e 's/\s//g' -e 's/,/ /g' -e 's/\s\+/\n/g' \ + | sort -u \ + | tr '\n' ' ' \ + | sed 's/\s*$//' +} + +# Given a token (first argument) and a list (remaining arguments) +# evaluate to true if the token is in the list, and to false otherwise +has_token() { + local token="$1" + shift + for opt in $@; do + [ "$opt" = "$token" ] && return 0 + done + return 1 +} + +# Given a token (first argument) and a list (remaining arguments) +# print all elements of the list as long as they differ from the token +fetch_token() { + local token="$1" + shift + for opt in $@; do + [ "$opt" = "$token" ] || echo $opt + done +} + +# Generate option string for RTE plugin based on the value given via --rte flag rte_options() { - local optstring="$1" - local start="-rte -rte-warn" - local opts="-rte-no-all" - # RTE integer overflow options coming from Frama-C, presently - # they are enabled by default, so they should be negated - local intopts="-no-warn-signed-overflow -no-warn-unsigned-overflow" - local vopts="mem,int,float,div,ret,precond,shift,all" - local all="" - - for opt in $(echo $optstring | tr ',' ' '); do - case $opt in - mem) # valid pointer or array access - opts="$opts -rte-mem" - ;; - int) # integer overflows - intopts="-warn-signed-overflow -warn-unsigned-overflow" - ;; - float) # casts from floating-point to integer - opts="$opts -rte-float-to-int" - ;; - div) # division by zero - opts="$opts -rte-div" - ;; - ret) # return - ;; - precond) # function calls based on contracts - opts="$opts -rte-precond" - ;; - shift) # left and right shifts by a value out of bounds - opts="$opts -rte-shift" - ;; - all) # all assertions - all=1 - ;; - *) - return 1; - ;; - esac + # RTE options + local rte_opts="int-overflow,mem,float-to-int,div,precond,shift,pointer-call" + local inp_opts="$1" # Comma-separated string of input RTE options + local generated_fc="" # Generated Frama-C options + local geterated_rte="" # Generated RTE options + + # Clean-up option strings + local ropts="$(tokenize $rte_opts)" + local sopts="$(tokenize $inp_opts)" + + # If there is 'all' keyword found enable all assertions + if has_token all "$sopts"; then + sopts="$ropts" + fi + + # Check that all rte options provided at input are valid, i.e., a subset of + # the options given via $rte_opts + for sopt in $sopts; do + if ! has_token $sopt "$ropts"; then + echo "$sopt" + return 1 + fi done - if [ -n "$all" ]; then - echo $start -rte-all -then + # RTE integer overflow options coming from Frama-C + if has_token int-overflow "$sopts"; then + generated_fc="-warn-signed-overflow -warn-unsigned-overflow" else - echo $start $opts $intopts -then + generated_fc="-no-warn-signed-overflow -no-warn-unsigned-overflow" + fi + + # Remove 'int-overflow' (which is relevant for Frama-C), remaining option + # keywords belong to RTE, i.e., for each keyword KW in $ropts there exists + # either -rte-<KW> and -rte-no-<KW> + sopts="$(fetch_token int-overflow "$sopts")" + ropts="$(fetch_token int-overflow "$ropts")" + + if [ -n "$sopts" ]; then + while test -n "$ropts"; do + local rem="$(echo $ropts | sed 's/[a-z\-]\+//')" + local fst="$(echo $ropts | sed "s/$rem$//")" + ropts="$rem" + + local prefix="-rte-no" + if has_token "$fst" "$sopts"; then + prefix="-rte" + fi + geterated_rte="$geterated_rte $prefix-$fst" + done + fi + + local rte="-no-rte" + if [ -n "$geterated_rte" ]; then + rte="-rte" fi - return 0; + + echo $generated_fc $rte $geterated_rte -then + return 0 } # Locate available E-ACSL memory models @@ -390,7 +433,7 @@ do # Runtime assertion generation --rte|-a) shift; - OPTION_RTE=`rte_options $1` + OPTION_RTE="`rte_options $1`" error "Invalid argument $1 to --rte|-a option" $? shift; ;; -- GitLab