123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345(**************************************************************************)(* *)(* SPDX-License-Identifier LGPL-2.1 *)(* Copyright (C) *)(* CEA (Commissariat à l'énergie atomique et aux énergies alternatives) *)(* *)(**************************************************************************)includePlugin.Register(structletname="Eva"letshortname="eva"lethelp="automatically computes variation domains for the variables of the program"end)(* Makes the help message of various categories mandatory. *)letregister_category~help=register_category~helpletregister_warn_category~help=register_warn_category~helplet()=add_plugin_output_aliases~visible:false~deprecated:true["value";"val"](* Do not add dependencies to Kernel parameters here, but at the top of
Parameters. *)letkernel_dependencies=[Ast.self;Alarms.self;Annotations.code_annot_state;]letproxy=State_builder.Proxy.(create"eva"Forwardkernel_dependencies)letstate=State_builder.Proxy.getproxyletclear_results()=Project.clear~selection:(State_selection.with_dependenciesstate)()(* Current state of the analysis *)typecomputation_state=NotComputed|Computing|Computed|AbortedmoduleComputationState=structletto_string=function|NotComputed->"NotComputed"|Computing->"Computing"|Computed->"Computed"|Aborted->"Aborted"modulePrototype=structincludeDatatype.Serializable_undefinedtypet=computation_stateletname="Eva.Analysis.ComputationState"letprettyfmts=Format.pp_print_stringfmt(to_strings)letreprs=[NotComputed;Computing;Computed;Aborted]letdependencies=[state]letdefault()=NotComputedendmoduleDatatype'=Datatype.Make(Prototype)include(State_builder.Ref(Datatype')(Prototype))endexceptionAbortletis_computed()=matchComputationState.get()with|Computed|Aborted->true|NotComputed|Computing->false(* ----- Debug categories --------------------------------------------------- *)letdkey_initial_state=register_category"initial-state"~default:true~help:"at the start of the analysis, \
print the initial value of global variables"letdkey_final_states=register_category"final-states"~default:true~help:"at the end of the analysis, print final values inferred \
at the return point of each analyzed function "letdkey_summary=register_category"summary"~default:true~help:"print a summary of the analysis at the end, including coverage \
and alarm numbers"letdkey_pointer_comparison=register_category"pointer-comparison"~help:"messages about the evaluation of pointer comparisons"letdkey_cvalue_domain=register_category"d-cvalue"~default:true~help:"print states of the cvalue domain on some user directives"letdkey_iterator=register_category"iterator"~help:"debug messages about the fixpoint engine on the control-flow graph \
of functions"letdkey_widening=register_category"widening"~help:"print a message at each point where the analysis applies a widening"letdkey_partition=register_category"partition"~default:true~help:"messages about states partitioning"letdkey_split_return=register_category"split-return"~default:true~help:"messages related to option -eva-split-return"letdkey_precision_settings=register_category"precision-settings"~default:true~help:"messages about the automatic configuration of the analysis by \
option -eva-precision"letdkey_callstacks=register_category"callstacks"~help:"print the current callstack alongside some messages"letdkey_callstack_hash=register_category"callstack-hash"~help:"additionally print the current callstack hash in some messages"letdkey_include_string_literal=register_category"include-string-literals"~help:"when printing a state, \
also include globals representing string literals"(* ----- Warning categories ------------------------------------------------- *)letwkey_alarm=register_warn_category"alarm"~help:"warnings for each possible undefined behavior detected \
by the analysis"letwkey_locals_escaping=register_warn_category"locals-escaping"~help:"a pointer p points to an out of scope local variable \
(any use of p also generates an alarm)"let_wkey_garbled_mix=register_warn_category"garbled-mix"~help:"warnings about very imprecise values inferred for pointers, \
named garbled mix"~default:Log.Wfeedbackletwkey_garbled_mix_write=register_warn_category"garbled-mix:write"~help:"the interpretation of an assignment creates a garbled mix"~default:Log.Wfeedbackletwkey_garbled_mix_assigns=register_warn_category"garbled-mix:assigns"~help:"the interpretation of a specification creates a garbled mix"~default:Log.Wfeedbackletwkey_garbled_mix_summary=register_warn_category"garbled-mix:summary"~help:"list the origins of garbled mix at the end of an analysis"~default:Log.Wfeedbacklet_wkey_builtins=register_warn_category"builtins"~help:"warnings related to builtins used to interpret some libc functions"letwkey_builtins_missing_spec=register_warn_category"builtins:missing-spec"~help:"the ACSL specification on which a builtin soundness relies is missing"letwkey_builtins_override=register_warn_category"builtins:override"~help:"a builtin overrides a function definition, which is therefore \
not analyzed"let_wkey_libc=register_warn_category"libc"~help:"warnings related to the interpretation of the standard C library"letwkey_libc_unsupported_spec=register_warn_category"libc:unsupported-spec"~help:"the ACSL specification of a libc function is not supported by Eva"let_wkey_loop_unroll=register_warn_category"loop-unroll"~help:"messages about automatic loop unrolling from option \
-eva-auto-loop-unroll"~default:Log.Wfeedbackletwkey_loop_unroll_auto=register_warn_category"loop-unroll:auto"~help:"a loop is automatically unrolled by the analysis"letwkey_loop_unroll_partial=register_warn_category"loop-unroll:partial"~help:"a loop has been partially but not completely unrolled"letwkey_missing_loop_unroll=register_warn_category"loop-unroll:missing"~help:"a loop has no unroll annotation"~default:Log.Winactiveletwkey_missing_loop_unroll_for=register_warn_category"loop-unroll:missing:for"~help:"a for loop has no unroll annotation"~default:Log.Winactiveletwkey_signed_overflow=register_warn_category"signed-overflow"~help:"two's complement is used to interpret a signed overflow \
(when signed overflow alarms are disabled)"let_wkey_assigns=register_warn_category"assigns"~help:"warnings related to the interpretation of assigns clauses \
in ACSL specification"letwkey_invalid_assigns=register_warn_category"assigns:invalid-location"~help:"the memory location targeted by an assigns clause is invalid \
in at least one analysis state"~default:Log.Wfeedbackletwkey_missing_assigns=register_warn_category"assigns:missing"~help:"assigns clauses are missing or incomplete from an ACSL \
specification on which the analysis soundness relies"~default:Log.Werrorletwkey_missing_assigns_result=register_warn_category"assigns:missing-result"~help:"an assigns \\result clause is missing from an ACSL specification \
on which the analysis soundness relies"letwkey_experimental=register_warn_category"experimental"~help:"an experimental feature of Eva is enabled"letwkey_unknown_size=register_warn_category"unknown-size"~help:"the analysis cannot compute the size of a variable, \
which will thus be very imprecise"letwkey_ensures_false=register_warn_category"ensures-false"~help:"a post-condition evaluates to false; \
there might be an error in the specification"letwkey_watchpoint=register_warn_category"watchpoint"~help:"undocumented"~default:Log.Wfeedbackletwkey_recursion=register_warn_category"recursion"~help:"a recursive call is analyzed"~default:Log.Wfeedbackletwkey_acsl=register_warn_category"acsl"~help:"messages about evaluation of ACSL terms and predicates"~default:Log.Wfeedbackletwkey_acsl_unsupported=register_warn_category"acsl:unsupported"~help:"messages about ACSL terms not supported by Eva"~default:Log.Wfeedback(* ----- Log with positions ------------------------------------------------- *)type'apretty_printer=?emitwith:(Log.event->unit)->?once:bool->?pos:Position.t->?current:bool->?source:Fclib.Filepath.position->?stacktrace:bool->?append:(Format.formatter->unit)->?echo:bool->('a,Format.formatter,unit)format->'atype('a,'b)pretty_aborter=?pos:Position.t->?current:bool->?source:Fclib.Filepath.position->?stacktrace:bool->?append:(Format.formatter->unit)->?echo:bool->('a,Format.formatter,unit,'b)format4->'aletappend_callstack?(stacktrace=false)?append~callstackfmt=letpretty_hashfmtcs=ifis_debug_key_enableddkey_callstack_hashthenFormat.fprintffmt"<%a> "Callstack.pretty_hashcsinOption.iter(funappend->appendfmt)append;ifstacktrace&&is_debug_key_enableddkey_callstacksthenmatchcallstackwith|None->()|Somecs->(* note: the "\n" before the pretty print of the stack is required by:
FRAMAC_LIB/analysis-scripts/make_wrapper.py *)Format.fprintffmt"@\nstack: @[<hv>%a%a@]"pretty_hashcsCallstack.prettycsletlift_aborter(aborter:('a,'b)Log.pretty_aborter):('a,'b)pretty_aborter=fun?pos?current?source?stacktrace?append->(* Extract source location *)matchposwith|Somepos->letcallstack=Position.callstackposinletsource=Option.value~default:(Position.pospos)source(* Append callstack if requested *)andappend=append_callstack?stacktrace?append~callstackinaborter?current:None~source~append|None->letcallstack=Callstack.get_current()inletappend=append_callstack?stacktrace?append~callstackinaborter?current?source~appendletlift_printer(printer:'aLog.pretty_printer):'apretty_printer=fun?emitwith?once->lift_aborter(printer?emitwith?once)letresult?level?dkey=lift_printer(result?level?dkey)letfeedback?ontty?level?dkey=lift_printer(feedback?ontty?level?dkey)letdebug?level?dkey=lift_printer(debug?level?dkey)letwarning?wkey:'apretty_printer=lift_printer(warning?wkey)letalarm?emitwith=warning~wkey:wkey_alarm?emitwithleterror?emitwith=lift_printererror?emitwithletabort?pos=lift_aborterabort?posletfailure?emitwith=lift_printerfailure?emitwithletfatal?pos=lift_aborterfatal?pos