123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124(****************************************************************************)(* *)(* This file is part of MOPSA, a Modular Open Platform for Static Analysis. *)(* *)(* Copyright (C) 2017-2019 The MOPSA Project. *)(* *)(* This program is free software: 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, either version 3 of the License, or *)(* (at your option) any later version. *)(* *)(* This program 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. *)(* *)(* You should have received a copy of the GNU Lesser General Public License *)(* along with this program. If not, see <http://www.gnu.org/licenses/>. *)(* *)(****************************************************************************)(** Inter-procedural iterator by inlining. *)openMopsaopenSig.Abstraction.StatelessopenAstopenCommon(** {2 Domain definition} *)(** ===================== *)moduleDomain=struct(** Domain identification *)(** ===================== *)includeGenStatelessDomainId(structletname="universal.iterators.interproc.inlining"end)letchecks=[](** Command-line options *)(** ==================== *)let()=import_shared_option"universal.iterators.interproc.common.renaming"name(** Initialization *)(** ============== *)letinitprogman(flow:'aflow)=Flow.set_ctx(Flow.get_ctxflow|>add_ctxContext.callstack_ctx_keyempty_callstack)flow|>Post.return|>Option.some(** Computation of post-conditions *)(** ============================== *)letexecstmtmanflow=letrange=stmt.srangeinmatchskindstmtwith|S_return(Somee)->letret=find_ctxreturn_key(Flow.get_ctxflow)inletflow=man.exec(mk_add_marker(M_returnrange)range)flow|>post_to_flowmaninman.exec(mk_add_varretrange)flow>>%?funflow->man.exec(mk_assign(mk_varretrange)erange)flow>>%?funflow->letcur=Flow.getT_curman.latticeflowinFlow.add(T_return(range))curman.latticeflow|>Flow.removeT_cur|>Post.return|>OptionExt.return|S_returnNone->letflow=man.exec(mk_add_marker(M_returnrange)range)flow|>post_to_flowmaninletcur=Flow.getT_curman.latticeflowinFlow.add(T_returnrange)curman.latticeflow|>Flow.removeT_cur|>Post.return|>OptionExt.return|_->None(** Evaluation of expressions *)(** ========================= *)letevalexpmanflow=letrange=erangeexpinmatchekindexpwith|E_call({ekind=E_function(User_definedf)},args)->ifman.lattice.is_bottom(Flow.getT_curman.latticeflow)thenCases.emptyflow|>OptionExt.returnelseletparams,locals,body,post=init_fun_paramsfargsrangemanflowinletret=matchf.fun_return_typewith|None->None|Some_->matchf.fun_return_varwith|Somev->Somev|None->Some(mk_returnexp)inpost>>%inlinefparamslocalsbodyretrangeman|>Option.some|_->Noneletask___=Noneletprint_expr____=()endlet()=register_stateless_domain(moduleDomain)