123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180(**************************************************************************)(* *)(* 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_datatypeopenPdg_typesopenPdgIndextypedata_info=((PdgTypes.Node.t*Locations.Zone.toption)list*Locations.Zone.toption)optiontypectrl_info=PdgTypes.Node.tlisttypedecl_info=PdgTypes.Node.tlistletzone_info_nodespdgdata_info=letadd_info_nodespdg(nodes_acc,undef_acc)info=letstmt=info.Logic_deps.kiinletbefore=info.Logic_deps.beforeinletzone=info.Logic_deps.zoneinPdg_parameters.debug~level:2"[pdg:annotation] need %a %s stmt %d@."Locations.Zone.prettyzone(ifbeforethen"before"else"after")stmt.sid;letnodes,undef_loc=Sets.find_location_nodes_at_stmtpdgstmt~beforezoneinletundef_acc=matchundef_acc,undef_locwith|None,_->undef_loc|_,None->undef_acc|Somez1,Somez2->Some(Locations.Zone.joinz1z2)in(nodes@nodes_acc,undef_acc)inmatchdata_infowith|None->None(* To_zone.xxx didn't manage to compute the zone *)|Somedata_info->letdata_dpds=([],None)inletdata_dpds=List.fold_left(add_info_nodespdg)data_dpdsdata_infoinSomedata_dpdsletget_decl_nodespdgdecl_info=letadd_decl_nodesdecl_varnodes_acc=letnode=Sets.find_decl_var_nodepdgdecl_varinnode::nodes_accinVarinfo.Set.foldadd_decl_nodesdecl_info[]letfind_nodes_for_function_contractpdgf_interpret=letkf=PdgTypes.Pdg.get_kfpdginlet(data_info,decl_label_info)=f_interpretkfinletdata_dpds=zone_info_nodespdgdata_infoinletdecl_nodes=(* No way to get stmt from labels of at construct into function contracts *)get_decl_nodespdgdecl_label_info.Logic_deps.varindecl_nodes,data_dpdsletfind_fun_precond_nodes(pdg:PdgTypes.Pdg.t)p=letf_interpretkf=letf_ctx=Logic_deps.mk_ctx_func_contract~before:truekfinLogic_deps.from_predpf_ctxinfind_nodes_for_function_contractpdgf_interpretletfind_fun_postcond_nodespdgp=letf_interpretkf=letf_ctx=Logic_deps.mk_ctx_func_contract~before:falsekfinLogic_deps.from_predpf_ctxinletnodes,deps=find_nodes_for_function_contractpdgf_interpretinletnodes=(* find is \result is used in p, and if it is the case,
* add the node [Sets.find_output_node pdg]
* to the returned list of nodes.
*)ifLogic_deps.to_result_from_predpthen(Sets.find_output_nodepdg)::nodeselsenodesinnodes,depsletfind_fun_variant_nodespdgt=letf_interpretkf=letf_ctx=Logic_deps.mk_ctx_func_contract~before:truekfinLogic_deps.from_termtf_ctxinfind_nodes_for_function_contractpdgf_interpretletfind_code_annot_nodespdgstmtannot=Pdg_parameters.debug"[pdg:annotation] CodeAnnot-%d stmt %d : %a @."annot.annot_idstmt.sidPrinter.pp_code_annotationannot;ifEva.Results.is_reachablestmtthenbeginletkf=PdgTypes.Pdg.get_kfpdginlet(data_info,decl_label_info),pragmas=Logic_deps.from_stmt_annotannot(stmt,kf)inletdata_dpds=zone_info_nodespdgdata_infoinletdecl_nodes=get_decl_nodespdgdecl_label_info.Logic_deps.varinletlabels=decl_label_info.Logic_deps.lblinletstmt_key=Key.stmt_keystmtinletstmt_node=matchstmt_keywith|Key.Stmt_->Sets.find_stmt_nodepdgstmt|Key.CallStmt_->Sets.find_call_ctrl_nodepdgstmt|_->assertfalseinletctrl_dpds=Sets.direct_ctrl_dpdspdgstmt_nodeinletadd_stmt_nodessacc=trySets.find_stmt_and_blocks_nodespdgs@accwithNot_found->accin(* can safely ignore pragmas.ctrl
* because we already have the ctrl dpds from the stmt node. *)letstmt_pragmas=pragmas.Logic_deps.stmtinletctrl_dpds=Stmt.Set.foldadd_stmt_nodesstmt_pragmasctrl_dpdsinletadd_label_nodeslacc=matchlwith|StmtLabelstmt->(* TODO: we could be more precise here if we knew which label
* is really useful... *)letaddaccl=try(Sets.find_label_nodepdg!stmtl)::accwithNot_found->accinList.fold_leftaddacc(!stmt).labels|FormalLabel_|BuiltinLabel_->accinletctrl_dpds=Logic_label.Set.foldadd_label_nodeslabelsctrl_dpdsinifPdg_parameters.debug_atleast2thenbeginletpfmt(n,z)=matchzwith|None->PdgTypes.Node.prettyfmtn|Somez->Format.fprintffmt"%a(%a)"PdgTypes.Node.prettynLocations.Zone.prettyzinletplfmtl=List.iter(funn->Format.fprintffmt" %a"pn)linPdg_parameters.debug" ctrl nodes = %a"PdgTypes.Node.pretty_listctrl_dpds;Pdg_parameters.debug" decl nodes = %a"PdgTypes.Node.pretty_listdecl_nodes;matchdata_dpdswith|None->Pdg_parameters.debug" data nodes = None (failed to compute)"|Some(data_nodes,data_undef)->beginPdg_parameters.debug" data nodes = %a"pldata_nodes;matchdata_undefwith|None->()|Somedata_undef->Pdg_parameters.debug" data undef = %a"Locations.Zone.prettydata_undef;endend;ctrl_dpds,decl_nodes,data_dpdsendelsebeginPdg_parameters.debug~level:2"[pdg:annotation] CodeAnnot-%d : unreachable stmt ! @."annot.annot_id;raiseNot_found(* unreachable statement *)end(*
Local Variables:
compile-command: "make -C ../../.."
End:
*)