123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308(**************************************************************************)(* *)(* 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)includePmoduleGroup=structletwidening=add_group"Tweaking integer analysis (experts only)"endmoduleRun=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, which have function contracts and \
additional runtime safe-guards"end)moduleFull_mtracking=False(structletoption_name="-e-acsl-full-mtracking"lethelp="maximal memory-related instrumentation"end)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(structlet()=Parameter_customize.set_groupGroup.wideningletdefault=1letoption_name="-e-acsl-widening-arguments-base"letarg_name="n"lethelp="tweak integer analysis by using <n> as a default value for \
arguments during the widening of recursive functions. \
May be used to improve performance of integer arithmetics \
at the cost of a slower compilation time."end)let()=Widening_arguments_base.set_range~min:0~max:2moduleWidening_arguments=String_map(Value_int)(structlet()=Parameter_customize.set_groupGroup.wideningletdefault=Datatype.String.Map.emptyletoption_name="-e-acsl-widening-arguments"letarg_name=""lethelp=Format.asprintf"like %s, but defines specific values for individual functions. \
For example f1:3,f2:4 uses the values 3 and 4 for f1 and f2."Widening_arguments_base.nameend)moduleWidening_output_base=Int(structlet()=Parameter_customize.set_groupGroup.wideningletdefault=1letoption_name="-e-acsl-widening-output-base"letarg_name="n"lethelp=Format.asprintf"like %s, but defines a value for results (and not arguments)"Widening_arguments_base.nameend)let()=Widening_output_base.set_range~min:0~max:2moduleWidening_output=String_map(Value_int)(structlet()=Parameter_customize.set_groupGroup.wideningletdefault=Datatype.String.Map.emptyletoption_name="-e-acsl-widening-output"letarg_name=""lethelp=Format.asprintf"like %s, but defines values for results (and not arguments)"Widening_arguments.nameend)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"letrte=register_category"analysis:rte"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