123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184(****************************************************************************)(* *)(* 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/>. *)(* *)(****************************************************************************)(** Abstract value representation *)openQueryopenAst.ConstantopenAst.ExpropenAst.TypopenAst.VisitoropenMopsa_utilsopenLocationtype_avalue_kind=..typeavalue_pool={pool_typ:'v.'vavalue_kind->typ;pool_bottom:'v.'vavalue_kind->'v;pool_top:'v.'vavalue_kind->'v;pool_join:'v.'vavalue_kind->'v->'v->'v;pool_meet:'v.'vavalue_kind->'v->'v->'v;pool_compare:'v'w.'vavalue_kind->'v->'wavalue_kind->'w->int;pool_print:'v.'vavalue_kind->Format.formatter->'v->unit;}typeavalue_info={typ:'v.avalue_pool->'vavalue_kind->typ;bottom:'v.avalue_pool->'vavalue_kind->'v;top:'v.avalue_pool->'vavalue_kind->'v;join:'v.avalue_pool->'vavalue_kind->'v->'v->'v;meet:'v.avalue_pool->'vavalue_kind->'v->'v->'v;compare:'v'w.avalue_pool->'vavalue_kind->'v->'wavalue_kind->'w->int;print:'v.avalue_pool->'vavalue_kind->Format.formatter->'v->unit;}letpool=ref{pool_bottom=(letf:typea.aavalue_kind->a=funavk->Exceptions.panic"Bottom of unregistered avalue"inf);pool_top=(letf:typea.aavalue_kind->a=funavk->Exceptions.panic"Top of unregistered avalue"inf);pool_join=(letf:typea.aavalue_kind->a->a->a=funavk->Exceptions.panic"Join of unregistered avalue"inf);pool_meet=(letf:typea.aavalue_kind->a->a->a=funavk->Exceptions.panic"Meet of unregistered avalue"inf);pool_compare=(letf:typeab.aavalue_kind->a->bavalue_kind->b->int=funavk1av1avk2av2->compare(Obj.Extension_constructor.of_valavk1|>Obj.Extension_constructor.id)(Obj.Extension_constructor.of_valavk2|>Obj.Extension_constructor.id)inf);pool_print=(letf:typea.aavalue_kind->Format.formatter->a->unit=funavkfmtav->Exceptions.panic"Print of unregistered avalue"inf);pool_typ=(letf:typea.aavalue_kind->typ=funavk->Exceptions.panic"Type of unregistered avalue"inf);}letregister_avalueinfo=letold_pool=!poolinpool:={pool_bottom=(letf:typea.aavalue_kind->a=funavk->info.bottomold_poolavkinf);pool_top=(letf:typea.aavalue_kind->a=funavk->info.topold_poolavkinf);pool_join=(letf:typea.aavalue_kind->a->a->a=funavkav1av2->info.joinold_poolavkav1av2inf);pool_meet=(letf:typea.aavalue_kind->a->a->a=funavkav1av2->info.meetold_poolavkav1av2inf);pool_compare=(letf:typeab.aavalue_kind->a->bavalue_kind->b->int=funavk1av1avk2av2->info.compareold_poolavk1av1avk2av2inf);pool_print=(letf:typea.aavalue_kind->Format.formatter->a->unit=funavkfmtav->info.printold_poolavkfmtavinf);pool_typ=(letf:typea.aavalue_kind->typ=funavk->info.typold_poolavkinf);}lettype_of_avalueavk=!pool.pool_typavkletbottom_avalueavk=!pool.pool_bottomavklettop_avalueavk=!pool.pool_topavkletjoin_avalueavkav1av2=!pool.pool_joinavkav1av2letmeet_avalueavkav1av2=!pool.pool_meetavkav1av2letcompare_avalueavk1av1avk2av2=!pool.pool_compareavk1av1avk2av2letpp_avalueavkfmtav=!pool.pool_printavkfmtavtypeconstant+=C_avalue:'vavalue_kind*'v->constantlet()=register_constant{print=(funnextfmtc->matchcwith|C_avalue(avk,av)->pp_avalueavkfmtav|_->nextfmtc);compare=(funnextc1c2->matchc1,c2with|C_avalue(avk1,av1),C_avalue(avk2,av2)->compare_avalueavk1av1avk2av2|_->nextc1c2);}letmk_avalue_constantavkav=C_avalue(avk,av)letmk_avalue_expravkavrange=mk_constant(mk_avalue_constantavkav)~etyp:(type_of_avalueavk)rangetype('a,_)query+=Q_avalue:expr*'vavalue_kind->('a,'v)queryletmk_avalue_queryeavk=Q_avalue(e,avk)let()=register_query{join=(letf:typear.query_pool->(a,r)query->r->r->r=funpoolqueryxy->matchquerywith|Q_avalue(e,avk)->join_avalueavkxy|_->pool.pool_joinqueryxyinf);meet=(letf:typear.query_pool->(a,r)query->r->r->r=funpoolqueryxy->matchquerywith|Q_avalue(e,avk)->meet_avalueavkxy|_->pool.pool_meetqueryxyinf);}