123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447(**************************************************************************)(* *)(* This file is part of Frama-C. *)(* *)(* Copyright (C) 2007-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). *)(* *)(**************************************************************************)openCil_typesopenLocationslet()=Db.Value.compute:=Analysis.computelet()=Parameters.ForceValues.set_output_dependencies[Self.state]letmain()=(* Value computations *)ifParameters.ForceValues.get()thenAnalysis.compute();ifAnalysis.is_computed()thenRed_statuses.report()let()=Db.Main.extendmain(* "access" functions before evaluation, registered in Db.Value *)letaccess_value_of_lvalkinstrlv=letstate=Db.Value.get_statekinstrinsnd(!Db.Value.eval_lvalNonestatelv)letaccess_value_of_exprkinstre=letstate=Db.Value.get_statekinstrin!Db.Value.eval_exprstateeletaccess_value_of_locationkinstrloc=letstate=Db.Value.get_statekinstrinDb.Value.findstatelocletfind_deps_term_no_transitivity_statestatet=tryletenv=Eval_terms.env_only_herestateinletr=Eval_terms.eval_term~alarm_mode:Eval_terms.Ignoreenvtinr.Eval_terms.ldepswithEval_terms.LogicEvalError_->raiseDb.From.Not_lvalletfind_deps_no_transitivitystmtexpr=Results.(beforestmt|>expr_depsexpr)letfind_deps_no_transitivity_statestateexpr=Results.(in_cvalue_statestate|>expr_depsexpr)leteval_predicate~pre~herep=letopenEval_termsinletenv=env_annot~pre~here()inmatcheval_predicateenvpwith|True->Property_status.True|False->Property_status.False_if_reachable|Unknown->Property_status.Dont_knowlet()=Db.Value.is_called:=Function_calls.is_called;Db.Value.callers:=Function_calls.callsites;Db.Value.use_spec_instead_of_definition:=Function_calls.use_spec_instead_of_definition;Db.Value.assigns_outputs_to_zone:=(funs~resulta->Logic_inout.assigns_outputs_to_zone~resultsa);Db.Value.assigns_inputs_to_zone:=Logic_inout.assigns_inputs_to_zone;Db.Value.access:=access_value_of_lval;Db.Value.access_location:=access_value_of_location;Db.Value.access_expr:=access_value_of_expr;Db.Value.Logic.eval_predicate:=eval_predicate;Db.Value.valid_behaviors:=Logic_inout.valid_behaviors;Db.From.find_deps_term_no_transitivity_state:=find_deps_term_no_transitivity_state;Db.From.find_deps_no_transitivity:=find_deps_no_transitivity;Db.From.find_deps_no_transitivity_state:=find_deps_no_transitivity_state;(* -------------------------------------------------------------------------- *)(* Register Evaluation Functions *)(* -------------------------------------------------------------------------- *)openEvalmoduleCVal=structincludeMain_values.CValletstructure=Abstract.Value.Leaf(key,(moduleMain_values.CVal))endmoduleVal=structincludeCValincludeStructure.Open(Abstract.Value)(CVal)letreducet=tendmoduleEva=Evaluation.Make(Val)(Main_locations.PLoc)(Cvalue_domain.State)letinject_cvaluestate=state,Locals_scoping.bottom()letbot_value=function|`Bottom->Cvalue.V.bottom|`Valuev->vletbot_state=function|`Bottom->Cvalue.Model.bottom|`Values->sletupdatevaluationstate=letdomain_valuation=Eva.to_domain_valuationvaluationinbot_state(Cvalue_domain.State.updatedomain_valuationstate>>-:fst)letreceval_depsstatee=matche.enodewith|SizeOf_|SizeOfE_|SizeOfStr_|AlignOf_|AlignOfE_|Const_->Locations.Zone.bottom|Lvallv->eval_deps_lvalstatelv|BinOp(_,e1,e2,_)->Locations.Zone.join(eval_depsstatee1)(eval_depsstatee2)|CastE(_,e)|UnOp(_,e,_)->eval_depsstatee|AddrOflv|StartOflv->eval_deps_addrstatelvandeval_deps_lvalstatelv=letfor_writing=falseinletdeps=eval_deps_addrstatelvinletloc=fst(Eva.lvaluate~for_writingstatelv)>>-:fun(_valuation,loc,_typ)->locinmatchlocwith|`Bottom->deps|`Valueloc->letdeps_lv=Precise_locs.enumerate_valid_bitsReadlocinLocations.Zone.joindepsdeps_lvandeval_deps_addrstate(h,o:lval)=Locations.Zone.join(eval_deps_hoststateh)(eval_deps_offsetstateo)andeval_deps_hoststateh=matchhwith|Var_->Locations.Zone.bottom|Meme->eval_depsstateeandeval_deps_offsetstateo=matchowith|NoOffset->Locations.Zone.bottom|Field(_,o)->eval_deps_offsetstateo|Index(i,o)->Locations.Zone.join(eval_depsstatei)(eval_deps_offsetstateo)letnotify_optwith_alarmsalarms=Option.iter(funmode->Alarmset.notifymodealarms)with_alarmsleteval_expr_with_valuation?with_alarmsdepsstateexpr=letstate=inject_cvaluestateinletdeps=matchdepswith|None->None|Somedeps->letdeps'=eval_depsstateexprinSome(Locations.Zone.joindeps'deps)inleteval,alarms=Eva.evaluatestateexprinnotify_optwith_alarmsalarms;matchevalwith|`Bottom->(Cvalue.Model.bottom,deps,Cvalue.V.bottom),None|`Value(valuation,result)->letstate=updatevaluationstatein(state,deps,result),Somevaluation(* Compatibility layer between the old API of eval_exprs and the new evaluation
scheme. *)moduleEval=structleteval_expr?with_alarmsstateexpr=letstate=inject_cvaluestateinleteval,alarms=Eva.evaluate~reduction:falsestateexprinnotify_optwith_alarmsalarms;bot_value(eval>>-:snd)leteval_lval?with_alarmsdepsstatelval=letexpr=Eva_utils.lval_to_explvalinletres,valuation=eval_expr_with_valuation?with_alarmsdepsstateexprinlettyp=matchvaluationwith|None->Cil.typeOfLvallval|Somevaluation->matchEva.Valuation.find_locvaluationlvalwith|`Valuerecord->record.typ|`Top->Cil.typeOfLvallvalinletstate,deps,v=resinstate,deps,v,typleteval_expr_with_deps_state?with_alarmsdepsstateexpr=fst(eval_expr_with_valuation?with_alarmsdepsstateexpr)letreduce_by_condstateexprpositive=letstate=inject_cvaluestateinleteval,_alarms=Eva.reducestateexprpositiveinbot_state(eval>>-:funvaluation->updatevaluationstate)letlval_to_precise_loc_deps_state?with_alarms~depsstate~reduce_valid_index:(_:bool)lval=ifnot(Cvalue.Model.is_reachablestate)thenstate,deps,Precise_locs.loc_bottom,(Cil.typeOfLvallval)elseletstate=inject_cvaluestateinletdeps=matchdepswith|None->None|Somedeps->letdeps'=eval_deps_addrstatelvalinSome(Locations.Zone.joindeps'deps)inleteval,alarms=Eva.lvaluate~for_writing:falsestatelvalinnotify_optwith_alarmsalarms;matchevalwith|`Bottom->Cvalue.Model.bottom,deps,Precise_locs.loc_bottom,(Cil.typeOfLvallval)|`Value(valuation,loc,typ)->updatevaluationstate,deps,loc,typletlval_to_loc_deps_state?with_alarms~depsstate~reduce_valid_indexlv=letstate,deps,pl,typ=lval_to_precise_loc_deps_state?with_alarms~depsstate~reduce_valid_indexlvinstate,deps,Precise_locs.imprecise_locationpl,typletlval_to_precise_loc_state?with_alarmsstatelv=letstate,_,r,typ=lval_to_precise_loc_deps_state?with_alarms~deps:None~reduce_valid_index:(Kernel.SafeArrays.get())statelvinstate,r,typandlval_to_loc_state?with_alarmsstatelv=letstate,_,r,typ=lval_to_loc_deps_state?with_alarms~deps:None~reduce_valid_index:(Kernel.SafeArrays.get())statelvinstate,r,typletlval_to_precise_loc?with_alarmsstatelv=let_,r,_typ=lval_to_precise_loc_state?with_alarmsstatelvinrletlval_to_loc?with_alarmsstatelv=let_,r,_typ=lval_to_loc_state?with_alarmsstatelvinrletresolv_func_vinfo?with_alarmsdepsstatefuncexp=letopenCil_typesinletstate=inject_cvaluestateinletdeps=matchfuncexp.enodewith|Lval(Var_,NoOffset)->deps|Lval(Memv,_)->beginmatchdepswith|None->None|Somedeps->letdeps'=eval_depsstatevinSome(Locations.Zone.joindeps'deps)end|_->assertfalseinletkfs,alarms=Eva.eval_function_expfuncexpstateinnotify_optwith_alarmsalarms;letkfs=matchkfswith|`Bottom->Kernel_function.Hptset.empty|`Valuekfs->List.fold_left(funacc(kf,_)->Kernel_function.Hptset.addkfacc)Kernel_function.Hptset.emptykfsinkfs,depsendmoduletypeEval=moduletypeofEval(* Functions to register in Db.Value that depend on evaluation functions. *)moduleExport(Eval:Eval)=structopenEvalletlval_to_loc_with_deps_state?with_alarmsstate~depslv=let_state,deps,r,_=lval_to_loc_deps_state?with_alarms~deps:(Somedeps)~reduce_valid_index:(Kernel.SafeArrays.get())statelvinOption.value~default:Locations.Zone.bottomdeps,rletlval_to_loc_with_depskinstr?with_alarms~depslv=letstate=Db.Value.noassert_get_statekinstrinlval_to_loc_with_deps_state?with_alarmsstate~depslvletlval_to_loc_kinstrkinstr?with_alarmslv=letstate=Db.Value.noassert_get_statekinstrinlval_to_loc?with_alarmsstatelvletlval_to_precise_loc_with_deps_state_alarm?with_alarmsstate~depslv=let_state,deps,ploc,_=lval_to_precise_loc_deps_state?with_alarms~deps~reduce_valid_index:(Kernel.SafeArrays.get())statelvinletdeps=Option.value~default:Locations.Zone.bottomdepsindeps,plocletlval_to_precise_loc_with_deps_state=lval_to_precise_loc_with_deps_state_alarm?with_alarms:Noneletlval_to_zonekinstr?with_alarmslv=letstate_to_joined_zonestateacc=let_,r=lval_to_precise_loc_with_deps_state_alarm?with_alarmsstate~deps:Nonelvinletzone=Precise_locs.enumerate_valid_bitsReadrinLocations.Zone.joinacczoneinDb.Value.fold_state_callstackstate_to_joined_zoneLocations.Zone.bottom~after:falsekinstrletlval_to_zone_statestatelv=let_,r=lval_to_precise_loc_with_deps_statestate~deps:NonelvinPrecise_locs.enumerate_valid_bitsReadrletlval_to_zone_with_deps_statestate~for_writing~depslv=letdeps,r=lval_to_precise_loc_with_deps_statestate~depslvinletr=(* No write effect if [lv] is const *)iffor_writing&&(Eva_utils.is_const_write_invalid(Cil.typeOfLvallv))thenPrecise_locs.loc_bottomelserinletaccess=iffor_writingthenWriteelseReadinletzone=Precise_locs.enumerate_valid_bitsaccessrinletexact=Precise_locs.valid_cardinal_zero_or_one~for_writingrindeps,zone,exactletlval_to_offsetmap_aux?with_alarmsstatelv=letloc=Locations.valid_partRead(lval_to_loc?with_alarmsstatelv)inmatchloc.Locations.sizewith|Int_Base.Top->None|Int_Base.Valuesize->matchCvalue.Model.copy_offsetmaploc.Locations.locsizestatewith|`Bottom->None|`Valuem->Somemletlval_to_offsetmapkinstr?with_alarmslv=letstate=Db.Value.noassert_get_statekinstrinlval_to_offsetmap_aux?with_alarmsstatelvletlval_to_offsetmap_statestatelv=lval_to_offsetmap_auxstatelvletexpr_to_kernel_function_state?with_alarmsstate~depsexp=letr,deps=resolv_func_vinfo?with_alarmsdepsstateexpinOption.value~default:Locations.Zone.bottomdeps,rletexpr_to_kernel_functionkinstr?with_alarms~depsexp=letstate_to_joined_kernel_functionstate(z_acc,kf_acc)=letz,kf=expr_to_kernel_function_state?with_alarmsstate~depsexpinLocations.Zone.joinzz_acc,Kernel_function.Hptset.unionkfkf_accinDb.Value.fold_state_callstackstate_to_joined_kernel_function((matchdepswithNone->Locations.Zone.bottom|Somez->z),Kernel_function.Hptset.empty)~after:falsekinstrletexpr_to_kernel_function_state=expr_to_kernel_function_state?with_alarms:NoneendmoduletypeExport=moduletypeof(Export(Eval))letregister(moduleEval:Eval)(moduleExport:Export)=letopenExportinDb.Value.eval_expr:=Eval.eval_expr;Db.Value.eval_expr_with_state:=(fun?with_alarmsstateexpr->let(s,_,v)=Eval.eval_expr_with_deps_state?with_alarmsNonestateexprins,v);Db.Value.reduce_by_cond:=Eval.reduce_by_cond;Db.Value.eval_lval:=(fun?with_alarmsdepsstatelval->let_,deps,r,_=Eval.eval_lval?with_alarmsdepsstatelvalindeps,r);Db.Value.lval_to_loc_with_deps:=lval_to_loc_with_deps;Db.Value.lval_to_loc_with_deps_state:=lval_to_loc_with_deps_state?with_alarms:None;Db.Value.lval_to_loc:=lval_to_loc_kinstr;Db.Value.lval_to_loc_state:=Eval.lval_to_loc?with_alarms:None;Db.Value.lval_to_zone_state:=lval_to_zone_state;Db.Value.lval_to_zone:=lval_to_zone;Db.Value.lval_to_zone_with_deps_state:=lval_to_zone_with_deps_state;Db.Value.lval_to_precise_loc_state:=Eval.lval_to_precise_loc_state;Db.Value.lval_to_precise_loc_with_deps_state:=lval_to_precise_loc_with_deps_state;Db.Value.lval_to_offsetmap:=lval_to_offsetmap;Db.Value.lval_to_offsetmap_state:=lval_to_offsetmap_state;Db.Value.expr_to_kernel_function:=expr_to_kernel_function;Db.Value.expr_to_kernel_function_state:=expr_to_kernel_function_state;()let()=Db.Value.initial_state_only_globals:=Analysis.cvalue_initial_statelet()=Db.Value.verify_assigns_froms:=Logic_inout.verify_assignslet()=leteval=(moduleEval:Eval)inletexport=(moduleExport((valeval:Eval)):Export)inregisterevalexport;;(*
Local Variables:
compile-command: "make -C ../../.."
End:
*)