123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490(**************************************************************************)(* *)(* 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). *)(* *)(**************************************************************************)(** Export the slicing project *)(**/**)openCil_typesopenCilopenPdg_types(**/**)moduleVisibility(SliceName:sigvalget:kernel_function->bool->int->stringend)=structexceptionEraseAssignsexceptionEraseAllocationtypeproj=unittypetransform={slice:SlicingInternals.fct_slice;src_visible:bool(* whether the src function of the slice is visible and
can be used to give names *);keep_body:bool(* if false and the function has a body, the body will be
removed. Ignored otherwise *);}typefct=|Iffoftransform|Isrcofbool(* same meaning as keep_body *)|Iprotoletkeep_bodykf=Kernel_function.is_definitionkf&¬(Eva.Analysis.use_spec_instead_of_definitionkf)(* _project is left to comply with a module signature defined outside
the slicing module (in filter) *)letfct_info_projkf=letfi=SlicingMacros.get_kf_fikfinletslices=SlicingMacros.fi_slicesfiinletsrc_visible=Fct_slice.is_src_fun_visiblekfinSlicingParameters.debug~level:1"[SlicingTransform.Visibility.fct_info] processing %a (%d slices/src %svisible)"Kernel_function.prettykf(List.lengthslices)(ifsrc_visiblethen""else"not ");letneed_addr=(Kernel_function.get_vikf).vaddrofinletsrc_name_used=src_visible||need_addrinletkeep_body=keep_bodykfinletinfo_list=List.map(funff->Iff{slice=ff;src_visible=src_name_used;keep_body})slicesinifsrc_visiblethenIsrckeep_body::info_listelseifneed_addrthenIproto::info_list(* TODO for #344 *)elseinfo_listletfct_namesvarff=letname=matchffwith|Isrc_|Iproto->letkf_entry,_=Globals.entry_point()inletvi_entry=Kernel_function.get_vikf_entryinifCil_datatype.Varinfo.equalsvarvi_entrythensvar.vname^"_orig"elsesvar.vname|Iff{slice=ff;src_visible}->letkf=SlicingMacros.get_ff_kfffinletff_num=ff.SlicingInternals.ff_idinSliceName.getkfsrc_visibleff_numinSlicingParameters.debug~level:2"[SlicingTransform.Visibility.fct_name] get fct_name = %s"name;nameletvisible_markm=not(SlicingMarks.is_bottom_markm)letparam_visibleff_optn=matchff_optwith|Isrc_|Iproto->true|Iff{slice=ff}->visible_mark(Fct_slice.get_param_markffn)letbody_visibleff_opt=matchff_optwith|Iproto->false|Isrckeep->keep|Iff{keep_body}->keep_bodyletinst_visibleff_optinst=matchff_optwith|Isrc_->true|Iproto->false|Iff{slice=ff}->letm=Fct_slice.get_stmt_markffinstinvisible_markmletlabel_visibleff_optinstlabel=matchff_optwith|Isrc_->true|Iproto->false|Iff{slice=ff}->letm=Fct_slice.get_label_markffinstlabelinletv=visible_markminSlicingParameters.debug~level:2"[SlicingTransform.Visibility.label_visible] label %a is %svisible"Printer.pp_labellabel(ifvthen""else"in");vletdata_in_visibleffdata_in=matchdata_inwith|None->true|Somedata_in->(* it is too difficult to know if the callers of this slice
* compute [data_in] or not, but let's see if, by chance,
* some data have been selected manually... *)letm=Fct_slice.get_input_loc_under_markffdata_ininletv=visible_markminSlicingParameters.debug~level:2"[SlicingTransform.Visibility.data_in_visible] data %a is %svisible"Locations.Zone.prettydata_in(ifvthen""else"in");vletall_nodes_visibleffnodes=letis_visiblevisin=letm=Fct_slice.get_node_markffninifSlicingMarks.is_bottom_markmthenbeginSlicingParameters.debug~level:3"[SlicingTransform.Visibility.all_nodes_visible] node %a invisible"(Pdg.Api.pretty_nodetrue)n;falseendelsevisiinList.fold_leftis_visibletruenodesexceptionNoDataInfoletdata_nodes_visibleff(decl_nodes,data_info)=letkeep_annots=SlicingParameters.Mode.KeepAnnotations.get()inSlicingParameters.debug~level:2"[SlicingTransform.Visibility.data_nodes_visible (with keep_annots = %s)] ?"(ifkeep_annotsthen"true"else"false");letdecls_visible=all_nodes_visibleffdecl_nodesinifkeep_annotsthendecls_visibleelsematchdata_infowith|None->raiseNoDataInfo|Some(data_nodes,data_in)->letis_data_visiblevisi(n,z)=letkey=PdgTypes.Node.elem_keyninletkey=matchz,keywith|Somez,PdgIndex.Key.SigCallKey(call,PdgIndex.Signature.Out(PdgIndex.Signature.OutLocout_z))->letz=Locations.Zone.narrowzout_zinPdgIndex.Key.call_output_key(PdgIndex.Key.call_from_idcall)z|_,_->keyinletm=Fct_slice.get_node_key_markffkeyinifSlicingMarks.is_bottom_markmthenbeginSlicingParameters.debug~level:2"[SlicingTransform.Visibility.data_nodes_visible]@\n\
node %a invisible"(Pdg.Api.pretty_nodetrue)n;falseendelsevisiinletvisible=decls_visible&&data_in_visibleffdata_ininletdata_visible=List.fold_leftis_data_visiblevisibledata_nodesindata_visible(* work-around to avoid outputting annotations with type errors:
in case we end up with NotImplemented somewhere, we keep the annotation
iff all C variables occurring in there are visible.
*)letall_logic_var_visible,all_logic_var_visible_identified_term,all_logic_var_visible_term,all_logic_var_visible_assigns,all_logic_var_visible_deps=letmoduleExn=structexceptionInvisibleendinletvisff=objectinheritVisitor.frama_c_inplacemethod!vlogic_var_usev=matchv.lv_originwithNone->DoChildren|Somevwhenv.vformal&¬(visible_mark(Fct_slice.get_param_markff(Kernel_function.get_formal_positionv(SlicingMacros.get_ff_kfff)+1)))(* For some reason, pdg counts parameters starting
from 1 *)->raiseExn.Invisible|Somevwhennotv.vglob&¬(visible_mark(Fct_slice.get_local_var_markffv))->raiseExn.Invisible|Some_->DoChildrenendin(funffpred->tryignore(Visitor.visitFramacPredicate(visff)pred);truewithExn.Invisible->false),(funffterm->tryignore(Visitor.visitFramacIdTerm(visff)term);truewithExn.Invisible->false),(funffterm->tryignore(Visitor.visitFramacTerm(visff)term);truewithExn.Invisible->false),(funff(b,_)->tryignore(Visitor.visitFramacTerm(visff)b.it_content);truewithExn.Invisible->false),(funffd->tryignore(Visitor.visitFramacTerm(visff)d.it_content);truewithExn.Invisible->false)letannotation_visibleff_optstmtannot=SlicingParameters.debug~current:true~level:2"[SlicingTransform.Visibility.annotation_visible] ?";Eva.Results.is_reachablestmt&&Alarms.findannot=None&&(* Always drop alarms: the alarms table
in the new project is not synchronized *)matchff_optwith|Isrc_->true|Iproto->false|Iff{slice=ff}->letkf=SlicingMacros.get_ff_kfffinletpdg=Pdg.Api.getkfintryletctrl_nodes,decl_nodes,data_info=Pdg.Api.find_code_annot_nodespdgstmtannotinletdata_visible=data_nodes_visibleff(decl_nodes,data_info)inletvisible=((all_nodes_visibleffctrl_nodes)&&data_visible)inSlicingParameters.debug~level:2"[SlicingTransform.Visibility.annotation_visible] -> %s"(ifvisiblethen"yes"else"no");visiblewith|NoDataInfo->SlicingParameters.debug~level:2"[SlicingTransform.Visibility.annotation_visible] \
not implemented -> invisible";false|Logic_deps.NYImsg->SlicingParameters.warning~current:true~once:true"Dropping unsupported ACSL annotation";SlicingParameters.debug~level:2"[SlicingTransform.Visibility.annotation_visible] \
%s -> invisible"msg;falseletfun_precond_visibleff_optp=SlicingParameters.debug~level:2"[SlicingTransform.Visibility.fun_precond_visible] %a ?"Printer.pp_predicatep;letvisible=matchff_optwith|Isrc_->true|Iproto->true|Iff{slice=ff}->letkf=SlicingMacros.get_ff_kfffinletpdg=Pdg.Api.getkfintryletnodes=Pdg.Api.find_fun_precond_nodespdgpindata_nodes_visibleffnodeswithNoDataInfo->all_logic_var_visibleffpinSlicingParameters.debug~level:2"[SlicingTransform.Visibility.precond_visible] -> %s"(ifvisiblethen"yes"else"no");visibleletfun_postcond_visibleff_optp=SlicingParameters.debug~level:2"[SlicingTransform.Visibility.fun_postcond_visible] %a ?"Printer.pp_predicatep;letvisible=matchff_optwith|Isrc_->true|Iproto->true|Iff{slice=ff}->letkf=SlicingMacros.get_ff_kfffinletpdg=Pdg.Api.getkfintryletnodes=Pdg.Api.find_fun_postcond_nodespdgpindata_nodes_visibleffnodeswithNoDataInfo->all_logic_var_visibleffpinSlicingParameters.debug~level:2"[SlicingTransform.Visibility.fun_postcond_visible] -> %s"(ifvisiblethen"yes"else"no");visibleletfun_variant_visibleff_optv=SlicingParameters.debug~level:2"[SlicingTransform.Visibility.fun_variant_visible] %a ?"Printer.pp_termv;letvisible=matchff_optwith|Isrc_->true|Iproto->true|Iff{slice=ff}->letkf=SlicingMacros.get_ff_kfffinletpdg=Pdg.Api.getkfintryletnodes=Pdg.Api.find_fun_variant_nodespdgvindata_nodes_visibleffnodeswithNoDataInfo->all_logic_var_visible_termffvinSlicingParameters.debug~level:2"[SlicingTransform.Visibility.fun_variant_visible] -> %s"(ifvisiblethen"yes"else"no");visibleletfun_frees_visibleff_optv=letkeep_annots=SlicingParameters.Mode.KeepAnnotations.get()inSlicingParameters.debug~level:2"[SlicingTransform.Visibility.fun_frees_visible \
(with keep_annots = %B)] ?"keep_annots;ifnotkeep_annotsthenraiseEraseAllocation;letvisible=matchff_optwith|Isrc_->true|Iproto->true|Iff{slice=ff}->all_logic_var_visible_identified_termffvinSlicingParameters.debug~level:2"[SlicingTransform.Visibility.fun_frees_visible] -> %s"(ifvisiblethen"yes"else"no");visibleletfun_allocates_visibleff_optv=letkeep_annots=SlicingParameters.Mode.KeepAnnotations.get()inSlicingParameters.debug~level:2"[SlicingTransform.Visibility.fun_allocates_visible \
(with keep_annots = %B)] ?"keep_annots;ifnotkeep_annotsthenraiseEraseAllocation;letvisible=matchff_optwith|Isrc_->true|Iproto->true|Iff{slice=ff}->all_logic_var_visible_identified_termffvinSlicingParameters.debug~level:2"[SlicingTransform.Visibility.fun_allocates_visible] -> %s"(ifvisiblethen"yes"else"no");visibleletfun_assign_visibleff_optv=letkeep_annots=SlicingParameters.Mode.KeepAnnotations.get()inSlicingParameters.debug~level:2"[SlicingTransform.Visibility.fun_assign_visible \
(with keep_annots = %B)] ?"keep_annots;ifnotkeep_annotsthenraiseEraseAssigns;letvisible=matchff_optwith|Isrc_->true|Iproto->true|Iff{slice=ff}->all_logic_var_visible_assignsffvinSlicingParameters.debug~level:2"[SlicingTransform.Visibility.fun_assign_visible] -> %s"(ifvisiblethen"yes"else"no");visibleletfun_deps_visibleff_optv=letkeep_annots=SlicingParameters.Mode.KeepAnnotations.get()inSlicingParameters.debug~level:2"[SlicingTransform.Visibility.fun_deps_visible \
(with keep_annots = %B)] ?"keep_annots;letvisible=matchff_optwith|Isrc_->true|Iproto->true|Iff{slice=ff}->all_logic_var_visible_depsffvinSlicingParameters.debug~level:2"[SlicingTransform.Visibility.fun_deps_visible] -> %s"(ifvisiblethen"yes"else"no");visibleletloc_var_visibleff_optvar=matchff_optwith|Isrc_->true|Iproto->false|Iff{slice=ff}->letm=Fct_slice.get_local_var_markffvarinvisible_markmletres_call_visibleffcall_stmt=matchffwith|Isrc_->true|Iproto->false|Iff{slice=ff}->letkey=PdgIndex.Key.call_outret_keycall_stmtinlet_,ff_marks=ff.SlicingInternals.ff_marksintryletm=PdgIndex.FctIndex.find_infoff_markskeyinvisible_markmwithNot_found->falseletresult_visible_kfff=matchffwith|Isrc_|Iproto->true|Iff{slice=ff}->letkey=PdgIndex.Key.output_keyinlet_,ff_marks=ff.SlicingInternals.ff_marksintryletm=PdgIndex.FctIndex.find_infoff_markskeyinvisible_markmwithNot_found->false(* _project is left to comply with a module signature defined outside
the slicing module (in filter) *)letcalled_info(_project,ff)call_stmt=letinfo=matchffwith|Isrc_|Iproto->None|Iff{slice=ff}->trylet_,ff_marks=ff.SlicingInternals.ff_marksinletcalled,_=PdgIndex.FctIndex.find_callff_markscall_stmtinmatchcalledwith|None|Some(None)->SlicingParameters.error"Undefined called function call-%d\n"call_stmt.sid;assertfalse|Some(Some(SlicingInternals.CallSrc_))->None|Some(Some(SlicingInternals.CallSliceff))->letkf_ff=SlicingMacros.get_ff_kfffin(* BY: no idea why this is not the same code as in fct_info *)letsrc_visible=Fct_slice.is_src_fun_visiblekf_ffinletkeep_body=keep_bodykf_ffinSome(kf_ff,Iff{slice=ff;src_visible;keep_body})withNot_found->(* the functor should call [called_info] only for visible calls *)assertfalseinSlicingParameters.debug~level:2"[SlicingTransform.Visibility.called_info] called_info stmt %d -> %s@."call_stmt.sid(ifinfo=Nonethen"src"else"some slice");infoletcond_edge_visible_ff_opts=Eva.Results.condition_truth_valuesendletdefault_slice_nameskf_src_visibleff_num=letfname=Kernel_function.get_namekfinletkf_entry,_=Globals.entry_point()inifKernel_function.equalkfkf_entrythenfnameelsePrintf.sprintf"%s_slice_%d"fnameff_numletextract~f_slice_namesnew_proj_name=SlicingParameters.feedback~level:1"exporting project to '%s'..."new_proj_name;SlicingParameters.feedback~level:1"applying all slicing requests...";SlicingProject.apply_all_actions();SlicingParameters.feedback~level:2"done (applying all slicing requests).";letmoduleS=structletget=f_slice_namesendinletmoduleVisi=Visibility(S)inletmoduleTransform=Filter.F(Visi)inlettmp_prj=Transform.build_cil_file(new_proj_name^" tmp")()inletnew_prj=Sparecode.Register.rm_unused_globals~new_proj_name~project:tmp_prj()inProject.remove~project:tmp_prj();letctx=Parameter_state.get_selection_context()inProject.copy~selection:ctxnew_prj;SlicingParameters.feedback~level:2"done (exporting project to '%s')."new_proj_name;new_prj(*
Local Variables:
compile-command: "make -C ../../.."
End:
*)