123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195(**************************************************************************)(* *)(* 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_typesopenLocationsopenVisitorclassvirtualdo_it_=object(self)inherit[Zone.t]Cumulative_analysis.cumulative_visitorassupervalmutableinputs=Zone.bottommethodbottom=Zone.bottommethodresult=inputsmethodjoinnew_=inputs<-Zone.joinnew_inputs;method!vstmt_auxs=matchs.skindwith|UnspecifiedSequenceseq->List.iter(fun(stmt,_,_,_,_)->ignore(visitFramacStmt(self:>frama_c_visitor)stmt))seq;Cil.SkipChildren(* do not visit the additional lvals *)|_->super#vstmt_auxs(* On assignment and addrof, only read the lvalue address. *)methodprivateread_addresslv=letrequest=Eva.Results.before_kinstrself#current_kinstrinletdeps=Eva.Results.address_depslvrequestinself#joindepsmethod!vlvallv=letrequest=Eva.Results.before_kinstrself#current_kinstrinletdeps=Eva.Results.lval_depslvrequestinself#joindeps;Cil.SkipChildrenmethodprivatedo_arg_callsstmtfargs=letdeps=Eva.Results.(beforestmt|>expr_depsf)inself#joindeps;let()=matchEva.Results.(beforestmt|>eval_calleef)with|Okcallees->List.iter(funkf->self#join(self#compute_kfkf))callees|Error(Top|DisabledDomain)->self#joinZone.top;|ErrorBottom->()inList.iter(fune->ignore(visitFramacExpr(self:>frama_c_visitor)e))args;method!vinsti=letstmt=Option.getself#current_stmtinifEva.Results.is_reachablestmtthenbeginmatchiwith|Set(lv,exp,_)->self#read_addresslv;ignore(visitFramacExpr(self:>frama_c_visitor)exp);Cil.SkipChildren|Local_init(v,AssignIniti,_)->letrecauxlv=function|SingleInite->self#read_addresslv;ignore(visitFramacExpr(self:>frama_c_visitor)e)|CompoundInit(ct,initl)->(* No need to consider implicit zero-initializers, for which
nothing is read. *)letimplicit=falseinletdoinitoi_()=ignore(visitFramacOffset(self:>frama_c_visitor)o);aux(Cil.addOffsetLvalolv)iinCil.foldLeftCompound~implicit~doinit~ct~initl~acc:()inaux(Cil.varv)i;Cil.SkipChildren|Call(lv_opt,exp,args,_)->Option.iterself#read_addresslv_opt;self#do_arg_callsstmtexpargs;Cil.SkipChildren|Local_init(v,ConsInit(f,args,Plain_func),_)->self#read_address(Cil.varv);self#do_arg_callsstmt(Cil.evarf)args;Cil.SkipChildren|Local_init(v,ConsInit(f,args,Constructor),_)->self#do_arg_callsstmt(Cil.evarf)(Cil.mkAddrOfViv::args);Cil.SkipChildren|Skip_|Asm_|Code_annot_->Cil.DoChildrenendelseCil.SkipChildrenmethod!vexprexp=matchexp.enodewith|AddrOflv|StartOflv->self#read_addresslv;Cil.SkipChildren|SizeOfE_|AlignOfE_|SizeOf_|AlignOf_->(* we're not evaluating an expression here: there's no input. *)Cil.SkipChildren|_->Cil.DoChildrenmethodcompute_funspeckf=letstate=self#specialize_state_on_callkfinletbehaviors=Eva.Logic_inout.valid_behaviorskfstateinletassigns=Ast_info.merge_assignsbehaviorsinEva.Logic_inout.assigns_inputs_to_zonestateassignsmethodclean_kf_result(_:kernel_function)(r:Locations.Zone.t)=rendmoduleAnalysis=Cumulative_analysis.Make(structletanalysis_name="inputs"typet=Locations.Zone.tmoduleT=Locations.Zoneclassvirtualdo_it=do_it_end)letget_internal=Analysis.kernel_functionmoduleExternals=Kernel_function.Make_Table(Locations.Zone)(structletname="Inout.Inputs.Externals"letdependencies=[Analysis.Memo.self]letsize=17end)letget_external=Externals.memo(funkf->Zone.filter_base(Eva.Logic_inout.accept_base~formals:false~locals:falsekf)(get_internalkf))letget_with_formalskf=Zone.filter_base(Eva.Logic_inout.accept_base~formals:true~locals:falsekf)(get_internalkf)letcompute_externalkf=ignore(get_externalkf)letpretty_externalfmtkf=Format.fprintffmt"@[Inputs for function %a:@\n@[<hov 2> %a@]@]@\n"Kernel_function.prettykfZone.pretty(get_externalkf)letpretty_with_formalsfmtkf=Format.fprintffmt"@[Inputs (with formals) for function %a:@\n@[<hov 2> %a@]@]@\n"Kernel_function.prettykfZone.pretty(get_with_formalskf)let()=Db.Inputs.self_internal:=Analysis.Memo.self;Db.Inputs.self_external:=Externals.self;Db.Inputs.self_with_formals:=Analysis.Memo.self;Db.Inputs.get_internal:=get_internal;Db.Inputs.get_external:=get_external;Db.Inputs.get_with_formals:=get_with_formals;Db.Inputs.compute:=compute_external;Db.Inputs.display:=pretty_external;Db.Inputs.display_with_formals:=pretty_with_formals;Db.Inputs.statement:=Analysis.statement;Db.Inputs.expr:=Analysis.expr(*
Local Variables:
compile-command: "make -C ../../.."
End:
*)