123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264(**************************************************************************)(* *)(* 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_types(** *)(* -------------------------------------------------------------------------- *)(** {2 Lattice structure } *)(* -------------------------------------------------------------------------- *)includeLattice_boundsincludeBottom.Operators(* -------------------------------------------------------------------------- *)(** {2 Types for the evaluations } *)(* -------------------------------------------------------------------------- *)(* Forward evaluation. *)type'twith_alarms='t*Alarmset.ttype'tevaluated='tor_bottomwith_alarms(* This monad propagates the `Bottom value if needed and join the potential
alarms returned during the evaluation. *)let(>>=)(t,a)f=matchtwith|`Bottom->`Bottom,a|`Valuet->lett',a'=ftint',Alarmset.combineaa'(* Use this monad if the following function returns a simple value. *)let(>>=:)(t,a)f=matchtwith|`Bottom->`Bottom,a|`Valuet->lett'=ftin`Valuet',a(* Use this monad if the following function returns no alarms. *)let(>>=.)(t,a)f=matchtwith|`Bottom->`Bottom,a|`Valuet->lett'=ftint',a(* Backward evaluation. *)type'areduced=[`Bottom|`Unreduced|`Valueof'a](* -------------------------------------------------------------------------- *)(** {2 Cache for the evaluations } *)(* -------------------------------------------------------------------------- *)(* State of the reduction of an abstract value. *)typereductness=|Unreduced(* No reduction. *)|Reduced(* A reduction has been performed for this expression. *)|Created(* The abstract value has been created. *)|Dull(* Reduction is pointless for this expression. *)(* Right values with 'undefined' and 'escaping addresses' flags. *)type'aflagged_value={v:'aor_bottom;initialized:bool;escaping:bool;}moduleFlagged_Value=structletbottom={v=`Bottom;initialized=true;escaping=false;}letequalequalv1v2=Bottom.equalequalv1.vv2.v&&v1.initialized=v2.initialized&&v1.escaping=v2.escapingletjoinjoinv1v2={v=Bottom.joinjoinv1.vv2.v;initialized=v1.initialized&&v2.initialized;escaping=v1.escaping||v2.escaping}letpretty_flagsfmtvalue=matchvalue.initialized,value.escapingwith|false,true->Format.pp_print_stringfmt"UNINITIALIZED or ESCAPINGADDR"|false,false->Format.pp_print_stringfmt"UNINITIALIZED"|true,true->Format.pp_print_stringfmt"ESCAPINGADDR"|true,false->Format.pp_print_stringfmt"BOTTOM"letprettyppfmtvalue=matchvalue.vwith|`Bottom->pretty_flagsfmtvalue|`Valuev->ifvalue.initialized&¬value.escapingthenppfmtvelseFormat.fprintffmt"%a or %a"ppvpretty_flagsvalueend(* Data record associated to each evaluated expression. *)type('a,'origin)record_val={value:'aflagged_value;(* The resulting abstract value *)origin:'originoption;(* The origin of the abstract value *)reductness:reductness;(* The state of reduction. *)val_alarms:Alarmset.t(* The emitted alarms during the evaluation. *)}(* Data record associated to each evaluated left-value. *)type'arecord_loc={loc:'a;(* The location of the left-value. *)typ:typ;(* *)loc_alarms:Alarmset.t(* The emitted alarms during the evaluation. *)}(* Results of an evaluation: the results of all intermediate calculation (the
value of each expression and the location of each lvalue) are cached in a
map. *)moduletypeValuation=sigtypettypevalue(* Abstract value. *)typeorigin(* Origin of values. *)typeloc(* Abstract memory location. *)valempty:tvalfind:t->exp->(value,origin)record_valor_topvaladd:t->exp->(value,origin)record_val->tvalfold:(exp->(value,origin)record_val->'a->'a)->t->'a->'avalfind_loc:t->lval->locrecord_locor_topvalremove:t->exp->tvalremove_loc:t->lval->tend(* Returns the list of the subexpressions of [expr] that contain [subexpr],
without [subexpr] itself. *)letcompute_englobing_subexpr~subexpr~expr=letmerge=Extlib.merge_opt(fun_->(@))()in(* Returns [Some] of the list of subexpressions of [expr] that contain
[subexpr], apart [subexpr] itself, or [None] if [subexpr] does not appear
in [expr]. *)letreccomputeexpr=ifCil_datatype.ExpStructEq.equalexprsubexprthenSome[]elseletsublist=matchexpr.enodewith|UnOp(_,e,_)|CastE(_,e)->computee|BinOp(_,e1,e2,_)->merge(computee1)(computee2)|Lval(host,offset)->merge(compute_hosthost)(compute_offsetoffset)|_->NoneinOption.map(funl->expr::l)sublistandcompute_host=function|Var_->None|Meme->computeeandcompute_offsetoffset=matchoffsetwith|NoOffset->None|Field(_,offset)->compute_offsetoffset|Index(index,offset)->merge(computeindex)(compute_offsetoffset)inOption.value~default:[](computeexpr)moduleEnglobing=Datatype.Pair_with_collections(Cil_datatype.ExpStructEq)(Cil_datatype.ExpStructEq)(structletmodule_name="Subexpressions"end)moduleSubExprs=Datatype.List(Cil_datatype.Exp)moduleEnglobingSubexpr=State_builder.Hashtbl(Englobing.Hashtbl)(SubExprs)(structletname="Value.Eval.Englobing_subexpressions"letsize=32letdependencies=[Ast.self]end)letcompute_englobing_subexpr~subexpr~expr=EnglobingSubexpr.memo(fun(expr,subexpr)->compute_englobing_subexpr~subexpr~expr)(expr,subexpr)moduleClear_Valuation(Valuation:Valuation)=structletclear_englobing_exprsvaluation~expr~subexpr=letenglobing=compute_englobing_subexpr~subexpr~exprinletremovevaluationexpr=letvaluation=Valuation.removevaluationexprinmatchexpr.enodewith|Lvallval->Valuation.remove_locvaluationlval|_->valuationinList.fold_leftremovevaluationenglobingend(* -------------------------------------------------------------------------- *)(** {2 Types of assignments } *)(* -------------------------------------------------------------------------- *)type'locleft_value={lval:lval;lloc:'loc;ltyp:typ;}(* Assigned values. *)type('loc,'value)assigned=|Assignof'value|Copyof'locleft_value*'valueflagged_valueletvalue_assigned=function|Assignv->`Valuev|Copy(_,copied)->copied.vtype'locationlogic_dependency={term:identified_term;direct:bool;location:'locationoption;}type'locationlogic_assign=|Assignsofidentified_term*'locationlogic_dependencylist|Allocatesofidentified_term|Freesofidentified_term(* -------------------------------------------------------------------------- *)(** {2 Interprocedural Analysis } *)(* -------------------------------------------------------------------------- *)type('loc,'value)argument={formal:varinfo;concrete:exp;avalue:('loc,'value)assigned;}type('loc,'value)call={kf:kernel_function;callstack:Callstack.t;arguments:('loc,'value)argumentlist;rest:(exp*('loc,'value)assigned)list;return:varinfooption;}typerecursion={depth:int;substitution:(varinfo*varinfo)list;base_substitution:Base.substitution;withdrawal:varinfolist;base_withdrawal:Base.Hptset.t;}typecacheable=Cacheable|NoCache|NoCacheCallers(*
Local Variables:
compile-command: "make -C ../../.."
End:
*)