123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144(**************************************************************************)(* *)(* This file is part of WP plug-in of Frama-C. *)(* *)(* Copyright (C) 2007-2024 *)(* CEA (Commissariat a l'energie atomique et aux energies *)(* 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). *)(* *)(**************************************************************************)(* -------------------------------------------------------------------------- *)(* --- Memory Model --- *)(* -------------------------------------------------------------------------- *)openLangopenLang.FmoduleL=Qed.Logicletlibrary="memory"letty_fst_arg=function|Somel::_->l|_->raiseNot_foundletl_havoc=Qed.Engine.F_call"havoc"letl_set_init=Qed.Engine.F_call"set_init"letp_eqmem=Lang.extern_fp~library"eqmem"letf_havoc=Lang.extern_f~library~typecheck:ty_fst_arg~link:l_havoc"havoc"letp_framed=Lang.extern_fp~coloring:true~library"framed"(* m-pointer -> prop *)letp_sconst=Lang.extern_fp~coloring:true~library"sconst"(* int-memory -> prop *)letf_set_init=Lang.extern_f~library~typecheck:ty_fst_arg~link:l_set_init"set_init"letp_cinits=Lang.extern_fp~coloring:true~library"cinits"(* initializaton-table -> prop *)letp_is_init_r=Lang.extern_fp~library"is_init_range"letp_monotonic=Lang.extern_fp~library"monotonic_init"(* -------------------------------------------------------------------------- *)(* --- Utilities --- *)(* -------------------------------------------------------------------------- *)lett_memt=L.Array(MemAddr.t_addr,t)lett_malloc=L.Array(L.Int,L.Int)lett_init=L.Array(MemAddr.t_addr,L.Bool)letcinitsmemory=p_callp_cinits[memory]letsconstmemory=p_callp_sconst[memory]letframedmemory=p_callp_framed[memory](* -------------------------------------------------------------------------- *)(* --- Simplifier for 'havoc' --- *)(* -------------------------------------------------------------------------- *)(* havoc(m_undef, havoc(_undef,m0,p0,a0), p1,a1) =
- havoc(m_undef, m0, p1,a1) WHEN included (p1,a1,p0,a0) *)letr_havoc=function|[undef1;m1;p1;a1]->beginmatchF.reprm1with|L.Fun(f,[_undef0;m0;p0;a0])whenf==f_havoc->beginletopenQed.LogicinmatchMemAddr.is_included[p0;a0;p1;a1]with|Yes->F.e_funf_havoc[undef1;m0;p1;a1]|_->raiseNot_foundend|_->raiseNot_foundend|_->raiseNot_found(* havoc(undef,m,p,a)[k] =
- m[k] WHEN separated (p,a,k,1)
- undef[k] WHEN NOT separated (p,a,k,1)
*)letr_get_havocesks=matches,kswith|[undef;m;p;a],[k]->beginmatchMemAddr.is_separated[p;a;k;e_one]with|L.Yes->F.e_getmk|L.No->F.e_getundefk|_->raiseNot_foundend|_->raiseNot_found(* -------------------------------------------------------------------------- *)(* --- Simplifiers Registration --- *)(* -------------------------------------------------------------------------- *)let()=Context.registerbeginfun()->F.set_builtinf_havocr_havoc;F.set_builtin_getf_havocr_get_havoc;end(* -------------------------------------------------------------------------- *)(* --- Frame Conditions --- *)(* -------------------------------------------------------------------------- *)moduleT=Definitions.Triggerletframes~addr:p~offset:n~sizeof:s?(basename="mem")tau=lett_mem=L.Array(MemAddr.t_addr,tau)inletm=F.e_var(Lang.freshvar~basenamet_mem)inletm'=F.e_var(Lang.freshvar~basenamet_mem)inletp'=F.e_var(Lang.freshvar~basename:"q"MemAddr.t_addr)inletn'=F.e_var(Lang.freshvar~basename:"n"L.Int)inletmh=F.e_funf_havoc[m';m;p';n']inletv'=F.e_var(Lang.freshvar~basename:"v"tau)inletmeq=F.p_callp_eqmem[m;m';p';n']inletdiff=F.p_callMemAddr.p_separated[p;n;p';s]inletsep=F.p_callMemAddr.p_separated[p;n;p';n']inletinc=F.p_callMemAddr.p_included[p;n;p';n']inletteq=T.of_predmeqin["update",[],[diff],m,e_setmp'v';"eqmem",[teq],[inc;meq],m,m';"havoc",[],[sep],m,mh;](* -------------------------------------------------------------------------- *)(* --- Unsupported Unions --- *)(* -------------------------------------------------------------------------- *)letwkey=Wp_parameters.register_warn_category"union"letunsupported_union(fd:Cil_types.fieldinfo)=ifnotfd.fcomp.cstructthenWp_parameters.warning~once:true~wkey"Accessing union fields with WP might be unsound.@\n\
Please refer to WP manual."(* -------------------------------------------------------------------------- *)