123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291(**************************************************************************)(* *)(* SPDX-License-Identifier LGPL-2.1 *)(* Copyright (C) *)(* CEA (Commissariat à l'énergie atomique et aux énergies alternatives) *)(* *)(**************************************************************************)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)moduleInterlang=False(structletoption_name="-e-acsl-interlang"lethelp="try compilation based on intermediate language"end)moduleInterlang_force=False(structletoption_name="-e-acsl-interlang-force"lethelp="crash if interlang compilation fails"end)moduleInterlang_opt=True(structletoption_name="-e-acsl-interlang-opt"lethelp="enables optimisations while generating the intermediate \
language."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(Value_int)(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(Value_int)(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)letparameter_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"letinductive=lethelp="extraction of an executable form from \
(certain forms of) inductive predicate definitions"inregister_category~help"analysis:inductive"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"letinterlang_translation=lethelp="translation from the intermediate language to Cil"inregister_category~help"interlang:translation"letinterlang_not_covered=lethelp="encountered constructs unsupported by indirect compilation scheme"inregister_category~help"interlang:not_covered"letinterlang_print_opt=lethelp="prints a comparison with non-optimized expressions"inregister_category~help"interlang:print_opt"endletsetup?(rtl=false)()=(* Variadic translation *)ifKernel.VariadicTranslation.get()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. *)Kernel.VariadicTranslation.off()elseifValidate_format_strings.get()thenbeginifAst.is_computed()thenabort"The variadic translation is incompatible with E-ACSL option \
'%s'.@ Please use option '-no-variadic-translation'."Validate_format_strings.option_name;warning~once:true"deactivating variadic translation";Kernel.VariadicTranslation.off()endend;(* 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;(* Additional kernel options while parsing the RTL project. *)ifrtlthenbeginKernel.KeepUnusedFunctions.set"none";Kernel.CppExtraArgs.add(Format.asprintf" -DE_ACSL_MACHDEP=%s"(Kernel.Machdep.get()));end