123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163(**************************************************************************)(* *)(* 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_typesopenCil_datatypeletnul_exp=Cil.kinteger64~loc:Location.unknown~repr:"0.."~kind:IIntInteger.zeroletis_nul_exp=Cil_datatype.ExpStructEq.equalnul_expmoduleHL=Lval.HashtblmoduleHE=Exp.Hashtblletcached_lval=HL.create23letcached_exp=HE.create37letclear_cache()=HL.clearcached_lval;HE.clearcached_expexceptionExplicit_pointer_addressoflocationletcheck_cast_compatibilityetyp=lettype_of_e=Cil.typeOfein(* emit a warning for unsafe casts, but not for the NULL pointer *)ifCil.need_casttyptype_of_e&¬(Cil.isZeroe)thenOptions.warning~once:true~source:(fst@@e.eloc)~wkey:Options.Warn.unsafe_cast"unsafe cast from %a to %a"Printer.pp_typtype_of_ePrinter.pp_typtypletrecsimplify_offseto=matchowith|NoOffset->NoOffset|Field(f,o)->Field(f,simplify_offseto)|Index(_e,o)->Index(nul_exp,simplify_offseto)letrecsimplify_lval(h,o)=tryHL.findcached_lval(h,o)withNot_found->letres=(simplify_hosth,simplify_offseto)inHL.addcached_lval(h,o)res;resandsimplify_hosth=matchhwith|Var_->h|Meme->letsimp_e=simplify_expeinifis_nul_expsimp_ethenraise(Explicit_pointer_addresse.eloc)elseMemsimp_eandsimplify_expe=tryHE.findcached_expewithNot_found->letres=matche.enodewith|CastE(typ,e)->check_cast_compatibilityetyp;simplify_expe|Lvallv->{ewithenode=Lval(simplify_lvallv)}|AddrOflv|StartOflv->{ewithenode=AddrOf(simplify_lvallv)}|BinOp(PlusPI,e1,_,_)|BinOp(MinusPI,e1,_,_)->beginmatch(simplify_expe1).enodewith|Lval_|AddrOf_asnode->{ewithenode=node}|_->raise(Explicit_pointer_addresse1.eloc)end|_->einHE.addcached_experes;resmoduleLvalOrRef=structtypet=Lvaloflval|Refoflvalletprettyl=letprintffmtx=matchxwith|Lvallv->ffmtlv|Reflv->Format.fprintffmt"&%a"flvinifOptions.is_debug_key_enabledOptions.DebugKeys.lvalsthenprintCil_types_debug.pp_lvallelseprintPrinter.pp_lvallletfrom_expe=lete=simplify_expeinmatche.enodewithLvallv->Some(Lvallv)|AddrOflv->Some(Reflv)|_->Noneletis_pointerx=matchxwith|Ref_->true|Lvallv->lett=Cil.typeOfLvallvinmatchCil.unrollTypetwithTPtr_|TArray_->true|_->falseendmoduleLval=structtypet=lvalletsimplifyx=simplify_lvalxletcompare=Cil_datatype.LvalStructEq.compareletprettyl=ifOptions.is_debug_key_enabledOptions.DebugKeys.lvalsthenCil_types_debug.pp_lvallelsePrinter.pp_lvallletpoints_tolv=Mem(Cil.dummy_exp(Lvallv)),NoOffsetendletdecompose_lvallv1:(lval*offset)list=letreclist_of_offset(o:offset):(offset*offset)list=matchowithNoOffset->[NoOffset,o]|Index(e,ofs)->letli=List.map(fun(o1,o2)->(Index(e,o1),o2))(list_of_offsetofs)in(NoOffset,o)::li|Field(f,ofs)->letli=List.map(fun(o1,o2)->(Field(f,o1),o2))(list_of_offsetofs)in(NoOffset,o)::liinletlv,off=Cil.removeOffsetLvallv1inList.map(fun(o1,o2)->Cil.addOffsetLvalo1lv,o2)(list_of_offsetoff)