Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Source file commons.ml
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274(**************************************************************************)(* *)(* This file is part of the Frama-C's Luncov plug-in. *)(* *)(* Copyright (C) 2012-2022 *)(* 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 LICENSE) *)(* *)(**************************************************************************)openCil_typesletlabel_function_name="__PC__LABEL"letbind_function_name="__PC__LABEL_BINDINGS"letstarting_time=ref0.(** Checks if the provided expression is a string constant *)letreccil_isStringexp=matchexp.enodewith|Const(CStrstr)->Somestr|CastE(_,exp)->cil_isStringexp|_->Noneletto_lval_expvarinfo=(* transform a varinfo into expression *)Cil.dummy_exp(Lval(Cil.varvarinfo))letlocation_stringloc=letline=(fstloc).Filepath.pos_lnuminletfile=Filename.basename(Filepath.Normalized.to_pretty_string(fstloc).Filepath.pos_path)infile^":"^string_of_intlineletreclast_elementlist=matchlistwith|[]->None|[e]->Some(e)|_::t->last_elementtletdump_ast?file?name()=letfile=matchfilewithSomefile->file|None->Ast.get()inletname=matchnamewith|Somename->name|None->letproject=Project.get_name(Project.current())in".luncov_dump_"^project^".c"inletout=open_outnameinletf=Format.formatter_of_out_channeloutinPrinter.pp_fileffile;Format.pp_print_flushf();close_outoutletsuceed_or_dump_ast?file?namefarg=tryfargwithe->letfile=matchfilewithSomefile->file|None->Ast.get()inletname=matchnamewith|Somename->name|None->letproject=Project.get_name(Project.current())in".luncov_dump_"^project^".c"inat_exit(fun()->dump_ast~file~name());raiseetype'aokko=Okof'a|Koofexnletwith_project?selectionprj(f:'a->'b)(arg:'a):'b=letg()=tryOk(farg)withe->KoeinmatchProject.on?selectionprjg()with|Koe->raisee|Okres->resletis_label_stmtstmtlblid=matchstmt.skindwith|Instr(Call(None,{enode=(Lval(Var{vname=name},NoOffset))},idexp::_::tagexp::_,_))whenname=label_function_name->beginmatchCil.isIntegeridexp,cil_isStringtagexpwith|Someid,Some_->ifInteger.to_int_exnid=lblidthentrue,trueelsetrue,false|_->false,falseend|_->false,falseletcopy_parameters?srcdst=letopenWpinletwp_prm_states=[Wp_parameters.Model.self;Wp_parameters.RTE.self;Wp_parameters.ExtEqual.self;Wp_parameters.ExternArrays.self;Wp_parameters.Literals.self;Wp_parameters.Provers.self;Wp_parameters.Steps.self;Wp_parameters.Timeout.self;Wp_parameters.ProofTrace.self;Wp_parameters.Procs.self;Wp_parameters.Print.self;Wp_parameters.Simpl.self;Wp_parameters.Prune.self;Wp_parameters.Let.self;Wp_parameters.Clean.self;Wp_parameters.Cache.self;]inletselection=State_selection.of_listwp_prm_statesinProject.copy~selection?srcdstclassvariable_harvesterexprs=objectinheritVisitor.frama_c_inplacemethod!vexpre=matche.enodewith|Lval_|AddrOf_|StartOf_->exprs:=Cil_datatype.ExpStructEq.Set.adde!exprs;Cil.SkipChildren|_->Cil.DoChildrenmethod!vstmt_auxs=matchs.skindwith|Instr_(*Voir pour skip children en cas de Call*)(*MD: qu'est-ce que ça veut dire?*)|Return_|If_|Switch_->(* the actual bodies of if/switch are not visited, see vblock*)Cil.DoChildren|_->Cil.SkipChildrenmethod!vblock_=Cil.SkipChildrenendletcollect_variablesstmt=letvars=refCil_datatype.ExpStructEq.Set.emptyinlet_=Visitor.visitFramacStmt(newvariable_harvestervars)stmtin!varsletcollect_fun_paramfdec=List.fold_left(funaccv->Cil_datatype.ExpStructEq.Set.add(to_lval_expv)acc)Cil_datatype.ExpStructEq.Set.emptyfdec.sformals(* Create a predicate from an operator, an expression, and an integer *)letconst_to_predopexpcst=letvar=Logic_utils.expr_to_term~coerce:trueexpinletvalue=Cil.lconstantcstinLogic_const.prel(op,var,value)(* Create a predicate asserting the interval of some expression *)letinterval_to_exp~aboutminmax=ifOption.is_someminthenletrmin=const_to_predRgeabout(Option.getmin)inifOption.is_somemaxthenletrmax=const_to_predRleabout(Option.getmax)inSome(Logic_const.pands[rmin;rmax])elseSomerminelseifOption.is_somemaxthenSome(const_to_predRleabout(Option.getmax))elseNoneletinterval_to_congruence_explvminmaxremmodulo=(* convertit interval+ congruence en prédicat *)letres=interval_to_exp~about:lvminmaxinifInteger.equalmoduloInteger.onethenreselseletvar=Logic_utils.expr_to_term~coerce:truelvinletcst_mod=Cil.lconstantmoduloinletcst_rem=Cil.lconstantreminletltyp=Logic_utils.coerce_type(Cil.typeOflv)inletleft=Logic_const.term(TBinOp(Mod,var,cst_mod))ltypinletcongru_assert=Logic_const.prel(Req,left,cst_rem)inifOption.is_someresthenSome(Logic_const.pands[(Option.getres);congru_assert])elseSomecongru_assertletmax_enumerate=8(** Create a predicate from an interval ([ival]) about some expression *)letpred_of_ival~about:lveiv=ifIval.is_bottomivthenNone(* Should be FALSE ?? *)elseifIval.is_singleton_intivthenSome(const_to_predReqlve(Ival.project_intiv))elseifIval.is_intivthenmatchIval.project_small_setivwith|SomelcwhenList.lengthlc<=max_enumerate->letpredlc=List.map(funv->const_to_predReqlvev)lcinSome(Logic_const.porspredlc)|_->letmin,max,rem,modulo=Ival.min_max_r_modivininterval_to_congruence_explveminmaxremmoduloelseNoneexceptionProject_Ival_FailexceptionProject_Ival_Unreachableletival_of_exp~at:stmtexpr=assert(Eva.Analysis.is_computed());(* first check if the state is actually reachable *)ifEva.Results.is_reachablestmtthen(matchEva.Results.(beforestmt|>eval_expexpr|>as_ival)with|Okiv->iv|Error_->raiseProject_Ival_Fail)elseraiseProject_Ival_Unreachableletexp_to_pred~atexpr=tryletival=ival_of_exp~atexprinletpred=pred_of_ival~about:exprivalinbeginmatchpredwith|Somep->Options.debug"Projecting %a on sid:%d → Ok (%a)"Printer.pp_expexprat.sidPrinter.pp_predicate_nodep.pred_content|None->Options.debug"Projecting %a on sid:%d → Ok (None)"Printer.pp_expexprat.sidend;predwith|Project_Ival_Fail->Options.debug"Projecting: %a on sid:%d → failed"Printer.pp_expexprat.sid;None|Project_Ival_Unreachable->Options.debug"Can't get %a value in stmt:[%d] code unreachable"Printer.pp_expexprat.sid;Noneletrecnumbered_backupnfilepath=letfilepathn=filepath^"."^string_of_intninifSys.file_existsfilepathnthennumbered_backup(n+1)filepathelseSys.renamefilepathfilepathnletbackupfilepath=ifSys.file_existsfilepaththennumbered_backup1filepathletreplace_or_add_listtblkeyvalue=ifHashtbl.memtblkeythenbeginletold=Hashtbl.findtblkeyinHashtbl.replacetblkey(value::old)endelseHashtbl.addtblkey[value]