123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166(**************************************************************************)(* *)(* This file is part of WP plug-in of Frama-C. *)(* *)(* Copyright (C) 2007-2023 *)(* 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). *)(* *)(**************************************************************************)openCil_typesmoduleCompleteness=structmoduleKfParam=structincludeCil_datatype.Kfletlabel=NoneendmoduleData=Datatype.Pair(Datatype.Bool)(Datatype.Function(KfParam)(Datatype.Unit))includeState_builder.Hashtbl(Cil_datatype.Kf.Hashtbl)(Data)(structletname="RefUsage.AssignsCompleteness.Callbacks"letsize=17letdependencies=[Ast.self]end)endexceptionIncomplete_assignsof(stringlist*string)letwkey_pedantic=Wp_parameters.register_warn_category"pedantic-assigns"type('a,'b)result=Okof'a|Errorof'bletcollect_assignskf=letopt_tryfp=functionNone->fp|Somex->Somexinletfold_assignsbhv=letfolder_aacc=matcha,accwith|WritesAny,_->None|_,None->Somea|_,Someacc->Some(Logic_utils.concat_assignsacca)inAnnotations.fold_assignsfolderkfbhvNoneinletfind_default()=matchfold_assignsCil.default_behavior_namewith|None->None|Somex->Some[x]inletincompletes=ref[]inletfind_complete()=letfold_behaviorsnames=letfolderlname=match(fold_assignsname)with|None->raise(Incomplete_assigns(names,name))|Somea->a::lintrySome(List.fold_leftfolder[]names)withIncomplete_assigns(bhv_l,b)->incompletes:=(bhv_l,b)::!incompletes;NoneinAnnotations.fold_complete(fun_->opt_tryfold_behaviors)kfNonein(* First:
- try to find default behavior assigns, if we cannot get it
- try to find a "complete behaviors" set where each behavior has assigns
As assigns and froms are over-approximations, the result (if it exists)
must cover all assigned memory locations and all data dependencies.
*)matchopt_tryfind_complete()(opt_tryfind_default()None)with|None->Error!incompletes|Somer->Okrletpretty_behaviors_errorsfmtl=letpp_complete=Pretty_utils.pp_list~pre:"{"~suf:"}"~sep:", "Format.pp_print_stringinletpp_bhv_errorfmt(bhv_l,name)=Format.fprintffmt"- in complete behaviors: %a@\n No assigns for (at least) '%s'@\n"pp_completebhv_lnameinmatchlwith|[]->Format.fprintffmt""|l->Format.fprintffmt"%a"(Pretty_utils.pp_listpp_bhv_error)lletcheck_assignskfassigns=letcomplete=(true,fun_->())inletincomplete(_status,current)warning=letnew_warningkf=currentkf;warningkf;in(false,new_warning)inletvassignsacca=letres_t=Kernel_function.get_return_typekfinletassigns_result({it_content=t},_)=Logic_utils.is_resulttinletfroms=matchawithWritesAny->[]|Writesl->linletacc=ifCil.isPointerTyperes_t&¬(List.existsassigns_resultfroms)thenincompleteaccbeginfunkf->Wp_parameters.warning~wkey:wkey_pedantic~once:true~source:(fst(Kernel_function.get_locationkf))"No 'assigns \\result \\from ...' specification for function '%a'\
returning pointer type.@ Callers assumptions might be imprecise."Kernel_function.prettykf;endelseaccinletvfromacc=function|t,FromAnywhenLogic_typing.is_pointer_typet.it_content.term_type->incompleteaccbeginfun_kf->Wp_parameters.warning~wkey:wkey_pedantic~once:true~source:(fstt.it_content.term_loc)"No \\from specification for assigned pointer '%a'.@ \
Callers assumptions might be imprecise."Cil_printer.pp_identified_termtend|_->accinList.fold_leftvfromaccfromsinmatchassignswith|Errorl->false,beginfunkf->Wp_parameters.warning~wkey:wkey_pedantic~once:true~source:(fst(Kernel_function.get_locationkf))"No 'assigns' specification for function '%a'.@\n%a\
Callers assumptions might be imprecise."Kernel_function.prettykfpretty_behaviors_errorslend|Okl->List.fold_leftvassignscompletelletmemo_computekf=Completeness.memo(funkf->check_assignskf(collect_assignskf))kfletcomputekf=ignore(memo_computekf)letis_completekf=fst(memo_computekf)letwarnkf=snd(memo_computekf)kf