123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325(**************************************************************************)(* *)(* This file is part of the Frama-C's E-ACSL plug-in. *)(* *)(* Copyright (C) 2012-2023 *)(* 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). *)(* *)(**************************************************************************)let()=Plugin.is_share_visible()moduleP=Plugin.Register(structletname="E-ACSL"letshortname="e-acsl"lethelp="Executable ANSI/ISO C Specification Language --- runtime \
assertion checker generator"end)includePmoduleRun=False(structletoption_name="-e-acsl"lethelp="generate a new project where E-ACSL annotations are \
translated to executable C code"end)moduleProject_name=String(structletoption_name="-e-acsl-project"lethelp="the name of the generated project is <prj> \
(default to \"e-acsl\")"letdefault="e-acsl"letarg_name="prj"end)moduleValid=False(structletoption_name="-e-acsl-valid"lethelp="translate annotation which have been proven valid"end)moduleGmp_only=False(structletoption_name="-e-acsl-gmp-only"lethelp="always use GMP integers instead of C integral types"end)moduleTemporal_validity=False(structletoption_name="-e-acsl-temporal-validity"lethelp="enable temporal analysis in valid annotations"end)moduleValidate_format_strings=False(structletoption_name="-e-acsl-validate-format-strings"lethelp="enable runtime validation of stdio.h format functions"end)moduleReplace_libc_functions=False(structletoption_name="-e-acsl-replace-libc-functions"lethelp="replace some libc functions (such as strcpy) with built-in\
RTL alternatives"end)moduleFull_mtracking=False(structletoption_name="-e-acsl-full-mtracking"lethelp="maximal memory-related instrumentation"end)let()=Full_mtracking.add_aliases~deprecated:true["-e-acsl-full-mmodel"]moduleBuiltins=String_set(structletoption_name="-e-acsl-builtins"letarg_name=""lethelp="C functions which can be used in the E-ACSL specifications"end)moduleAssert_print_data=True(structletoption_name="-e-acsl-assert-print-data"lethelp="print data contributing to the failed assertion along with \
the runtime error message"end)moduleConcurrency=False(structletoption_name="-e-acsl-concurrency"lethelp="activate the concurrency support of E-ACSL. The option \
implies -e-acsl-full-mtracking."end)moduleFunctions=Kernel_function_set(structletoption_name="-e-acsl-functions"letarg_name="f1, ..., fn"lethelp="only annotations in functions f1, ..., fn are checked at \
runtime"end)moduleInstrument=Kernel_function_set(structletoption_name="-e-acsl-instrument"letarg_name="f1, ..., fn"lethelp="only instrument functions f1, ..., fn. \
Be aware that runtime verdicts may become partial."end)moduleWidening_arguments_base=Int(structletdefault=1letoption_name="-e-acsl-widening-arguments-base"letarg_name="n"lethelp="widening strategy for arguments of recursive functions."end)let()=Widening_arguments_base.set_range~min:0~max:2moduleWidening_arguments=String_map(structincludeDatatype.Inttypekey=stringletto_string~key:_i=matchiwith|None->None|Somei->Some(string_of_inti)letof_string~key:_~prev:_s=matchswith|None->None|Somes->Some(int_of_strings)end)(structletdefault=Datatype.String.Map.emptyletoption_name="-e-acsl-widening-arguments"letarg_name=""lethelp="widening strategy for arguments of functions on a case by case \
basis."end)moduleWidening_output_base=Int(structletdefault=1letoption_name="-e-acsl-widening-output-base"letarg_name="n"lethelp="wideining strategy for output of recursive functions."end)let()=Widening_output_base.set_range~min:0~max:2moduleWidening_output=String_map(structincludeDatatype.Inttypekey=stringletto_string~key:_i=matchiwith|None->None|Somei->Some(string_of_inti)letof_string~key:_~prev:_s=matchswith|None->None|Somes->Some(int_of_strings)end)(structletdefault=Datatype.String.Map.emptyletoption_name="-e-acsl-widening-output"letarg_name=""lethelp="widening strategy for output of recursive functions on a case
by case basis."end)let()=Parameter_customize.set_grouphelpmoduleVersion=False(structletoption_name="-e-acsl-version"lethelp="version of plug-in E-ACSL"end)letversion()=ifVersion.get()thenbeginLog.print_on_output(funfmt->Format.fprintffmt"Version of plug-in E-ACSL: %s@?"Local_config.version);raiseCmdline.Exitendlet()=Cmdline.run_after_configuring_stageversionletparameter_states=[Valid.self;Gmp_only.self;Full_mtracking.self;Builtins.self;Temporal_validity.self;Validate_format_strings.self;Functions.self;Instrument.self;Widening_arguments_base.self;Widening_arguments.self;Widening_output.self;Widening_output_base.self]letemitter=Emitter.create"E_ACSL"[Emitter.Code_annot;Emitter.Funspec]~correctness:[Functions.parameter;Instrument.parameter;Validate_format_strings.parameter;Temporal_validity.parameter]~tuning:[Gmp_only.parameter;Valid.parameter;Replace_libc_functions.parameter;Full_mtracking.parameter;Widening_output_base.parameter;Widening_arguments.parameter;Widening_output_base.parameter;Widening_output.parameter]letmust_visit()=Run.get()moduleDkey=structletprepare=register_category"preparation"letlogic_normalizer=register_category"analysis:logic_normalizer"letbound_variables=register_category"analysis:bound_variables"letinterval=register_category"analysis:interval_inference"letmtracking=register_category"analysis:memory_tracking"lettyping=register_category"analysis:typing"letlabels=register_category"analysis:labels"lettranslation=register_category"translation"letenv=register_category"translation:env"endletsetup?(rtl=false)()=(* Variadic translation *)ifPlugin.is_present"variadic"thenbeginletopt_name="-variadic-translation"inifDynamic.Parameter.Bool.getopt_name()thenbeginifrtlthen(* If we are translating the RTL project, then we need to deactivate the
variadic translation. Indeed since we are translating the RTL in
isolation, we do not now if the variadic functions are used by the
user project and we cannot monomorphise them accordingly. *)Dynamic.Parameter.Bool.offopt_name()elseifValidate_format_strings.get()thenbeginifAst.is_computed()thenabort"The variadic translation is incompatible with E-ACSL option \
'%s'.@ Please use option '-variadic-no-translation'."Validate_format_strings.option_name;warning~once:true"deactivating variadic translation";Dynamic.Parameter.Bool.offopt_name();endendend;(* Concurrency support *)ifConcurrency.get()thenbeginifFull_mtracking.is_set()&¬(Full_mtracking.get())thenabort"The memory tracking dataflow analysis is incompatible@ \
with the concurrency support of E-ACSL.@ \
Please use option '-e-acsl-full-mtracking'.";ifnotrtl&¬(Full_mtracking.is_set())thenfeedback"Due to the large number of function pointers in concurrent@ \
code, the memory tracking dataflow analysis is deactivated@ \
when activating the concurrency support of E-ACSL.";Full_mtracking.on();ifTemporal_validity.get()thenabort"The temporal analysis in valid annotations is incompatible@ \
with the concurrency support of E-ACSL.@ \
Please use '-e-acsl-no-temporal-validity' or '-e-acsl-no-concurrency'@ \
to deactivate one or the other.";ifrtlthenKernel.CppExtraArgs.add"-DE_ACSL_CONCURRENCY_PTHREAD"end;(* Additionnal kernel options while parsing the RTL project. *)ifrtlthenbeginKernel.Keep_unused_specified_functions.off();Kernel.CppExtraArgs.add(Format.asprintf" -DE_ACSL_MACHDEP=%s"(Kernel.Machdep.get()));end(*
Local Variables:
compile-command: "make -C ../../../.."
End:
*)