package frama-c
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>
Platform dedicated to the analysis of source code written in C
Install
dune-project
Dependency
Authors
-
MMichele Alberti
-
TThibaud Antignac
-
GGergö Barany
-
PPatrick Baudin
-
NNicolas Bellec
-
TThibaut Benjamin
-
AAllan Blanchard
-
LLionel Blatter
-
FFrançois Bobot
-
RRichard Bonichon
-
VVincent Botbol
-
QQuentin Bouillaguet
-
DDavid Bühler
-
ZZakaria Chihani
-
SSylvain Chiron
-
LLoïc Correnson
-
JJulien Crétin
-
PPascal Cuoq
-
ZZaynah Dargaye
-
BBasile Desloges
-
JJean-Christophe Filliâtre
-
PPhilippe Herrmann
-
JJordan Ischard
-
MMaxime Jacquemin
-
BBenjamin Jorge
-
FFlorent Kirchner
-
AAlexander Kogtenkov
-
RRemi Lazarini
-
TTristan Le Gall
-
KKilyan Le Gallic
-
JJean-Christophe Léchenet
-
MMatthieu Lemerre
-
DDara Ly
-
DDavid Maison
-
CClaude Marché
-
AAndré Maroneze
-
TThibault Martin
-
FFonenantsoa Maurica
-
MMelody Méaulle
-
BBenjamin Monate
-
NNicky Mouha
-
YYannick Moy
-
PPierre Nigron
-
AAnne Pacalet
-
VValentin Perrelle
-
GGuillaume Petiot
-
DDario Pinto
-
VVirgile Prevosto
-
AArmand Puccetti
-
FFélix Ridoux
-
VVirgile Robles
-
JJan Rochel
-
MMuriel Roger
-
CCécile Ruet-Cros
-
JJulien Signoles
-
FFabien Siron
-
NNicolas Stouls
-
HHugo Thievenaz
-
KKostyantyn Vorobyov
-
BBoris Yakobowski
Maintainers
Sources
frama-c-33.0-Arsenic.tar.gz
sha256=9c1cbffd28bb33c17a668107e39c96e4ae7378a3d8249f69b47afc7ee964e9b8
doc/src/frama-c-region.core/annot.ml.html
Source file annot.ml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329(**************************************************************************) (* *) (* SPDX-License-Identifier LGPL-2.1 *) (* Copyright (C) *) (* CEA (Commissariat à l'énergie atomique et aux énergies alternatives) *) (* *) (**************************************************************************) open Cil_types open Memory open Logic (* -------------------------------------------------------------------------- *) (* --- Utils --- *) (* -------------------------------------------------------------------------- *) module Vmap = Cil_datatype.Varinfo.Map let iadd_term env t = ignore @@ add_term env t let add_iterm env = function { it_content = t } -> add_term env t let add_ipred env ip = add_predicate env ip.ip_content.tp_statement (* -------------------------------------------------------------------------- *) (* --- Process Assigns (From) --- *) (* -------------------------------------------------------------------------- *) let wkey = Options.register_warn_category ~help:"Missing assigns or assigns-\\from" ~default:Werror "froms" let add_write env lv tgt = Memory.add_write tgt @@ Access.Term(env.context,lv) let dpoints_to env deps = merge_points_to @@ List.fold_left (fun d t -> merge_domain d (add_iterm env t)) pure deps let add_dpoints_to env tgt = function | Some src -> Memory.add_points_to tgt src | None -> let loc = Access.location env.context in Options.warning ~wkey ~source:(fst loc) "No pointer found in assigns-\\from to pointer location(s)" let add_points_to env tgt = function | FromAny -> let loc = Access.location env.context in Options.warning ~wkey ~source:(fst loc) "Missing \\from in assigns to pointer location(s)" | From [] -> () (* avoid warning for purely allocating functions *) | From deps -> add_dpoints_to env tgt @@ dpoints_to env deps let rec store env lv ty tgt deps = match Ast_types.unroll_skel ty with | TNamed _ | TVoid -> () (* should not occur *) | TPtr _ | TFun _ | TBuiltin_va_list -> add_write env lv tgt ; add_dpoints_to env tgt (Lazy.force deps) | TInt _ | TFloat _ | TEnum _ -> add_write env lv tgt | TArray(te,_) -> let re = Memory.add_index tgt te in let ofs = TIndex (Logic_const.trange (None,None), TNoOffset) in let lve = Logic_const.addTermOffsetLval ofs lv in store env lve te re deps | TComp { cfields } -> List.iter (fun fd -> let ofs = TField(fd,TNoOffset) in let lvf = Logic_const.addTermOffsetLval ofs lv in let tgf = Memory.add_field tgt fd in store env lvf fd.ftype tgf deps ) @@ Option.value ~default:[] cfields let is_ctype lt ty = Logic_const.plain_or_set (fun lt -> match Ast_types.unroll_logic lt with | Ctype tr -> Cil_datatype.Typ.equal ty tr | _ -> false ) lt let add_write_compound env lv ty tgt from = let copies, others = List.partition_map (fun d -> let t = d.it_content in match t.term_node with | TLval ls when is_ctype t.term_type ty -> Left (t.term_loc,ls) | _ -> Right d) (match from with FromAny -> [] | From ws -> ws) in begin List.iter (fun (loc,ls) -> Memory.merge tgt @@ snd @@ add_addr_lval ~loc env ls) copies ; if copies = [] || others <> [] then store env lv ty tgt (lazy (dpoints_to env others)) ; end let add_writes_from ~loc env (lv : term_lval) ~(from:deps) = let ty,tgt = add_addr_lval ~loc env lv in if Ast_types.is_arithmetic ty then add_write env lv tgt else if Ast_types.is_fun_or_ptr ty then begin add_write env lv tgt ; add_points_to env tgt from ; end else if Ast_types.is_struct_or_union ty then add_write_compound env lv ty tgt from else Options.not_yet_implemented ~source:(fst loc) "Unsupported assigns to type (%a)" Printer.pp_typ ty let is_result = function (TResult _,_) -> true | _ -> false let rec add_assigns_from env ~iscalled ~from tgt = match tgt.term_node with | TLval lv -> begin let loc = tgt.term_loc in match iscalled with | Some result -> if is_result lv then result := true ; add_writes_from env ~loc lv ~from | None -> ignore (add_addr_lval ~loc env lv) end | Tat(t,_) -> add_assigns_from env ~iscalled ~from t | Tunion ts | Tinter ts -> List.iter (add_assigns_from env ~iscalled ~from) ts | Tcomprehension _ -> Options.not_yet_implemented ~source:(fst tgt.term_loc) "Unsupported set-comprehension" | Tlet _ -> Options.not_yet_implemented ~source:(fst tgt.term_loc) "Unsupported \\let-assigns" | Tif (c,tt,te) -> add_predicate env c ; add_assigns_from env ~iscalled ~from tt ; add_assigns_from env ~iscalled ~from te ; | TConst _ | TSizeOf _ | TSizeOfE _ | TAlignOf _ | TAlignOfE _ | TUnOp _ | TBinOp _ | TCast _ | TAddrOf _ | TStartOf _ | Tapp _ | Tlambda _ | TDataCons _ | Tbase_addr _ | Toffset (_, _) | Tblock_length _ | Tnull | TUpdate _ | Ttypeof _ | Ttype _ | Tempty_set | Trange _ -> Options.warning ~source:(fst tgt.term_loc) "Non-assignable term (skipped)@ (%a)" Printer.pp_term tgt (* -------------------------------------------------------------------------- *) (* --- Process Behaviors --- *) (* -------------------------------------------------------------------------- *) let context ~called ~kf ip = match called with | None -> Access.Prop ip | Some stmt -> Access.Call(stmt,kf,ip) let add_requires ~map ~called ~kf ~ki ~bhv ~formals ~result ip = let context = context ~called ~kf @@ Property.ip_of_requires kf ki bhv ip in add_ipred { map ; context ; formals ; result } ip let add_assumes ~map ~called ~kf ~ki ~bhv ~formals ~result ip = let context = context ~called ~kf @@ Property.ip_of_assumes kf ki bhv ip in add_ipred { map ; context ; formals ; result } ip let add_bassigns ~called ~map ~kf ~ki ~bhv ~formals ~result = function | WritesAny -> if called <> None then let loc = Kernel_function.get_location kf in Options.warning ~wkey ~source:(fst loc) "Precise assigns are required for calls" | Writes ws as asgn -> let bhv = Property.Id_contract (Datatype.String.Set.empty,bhv) in let ip = Option.get @@ Property.ip_of_assigns kf ki bhv asgn in let context = context ~called ~kf ip in let env = { map ; context ; formals ; result } in let iscalled = Option.map (fun _ -> ref false) called in List.iter (fun (t,from) -> add_assigns_from env ~iscalled ~from t.it_content) ws ; match iscalled with | None -> () | Some result -> if not !result && Ast_types.is_fun_or_ptr @@ Kernel_function.get_return_type kf then let loc = Access.location context in Options.warning ~wkey ~source:(fst loc) "Missing assigns \\result \\from for returned pointer" let add_allocation ~map ~called ~kf ~ki ~bhv ~formals ~result alloc = match alloc with | FreeAllocAny -> () | FreeAlloc _ -> ignore map ; ignore called ; ignore ki ; ignore bhv ; ignore formals ; ignore result ; let loc = Kernel_function.get_location kf in Options.not_yet_implemented ~source:(fst loc ) "Unsupported \\allocates and \\frees" (* | FreeAlloc (its1, its2) -> let bhv = Property.Id_contract (Datatype.String.Set.empty,bhv) in let clause = clause ~called @@ Option.get @@ Property.ip_of_allocation kf ki bhv alloc in let env = { map ; clause ; formals ; result } in (*TODO: FIX THIS, Cf. assigns *) let add_alloc env it1 it2 = let d1 = add_iterm env it1 in let d2 = add_iterm env it2 in ignore @@ merge_domain d1 d2 in List.iter2 (add_alloc env) its1 its2 *) let add_ensures ~map ~called ~kf ~ki ~bhv ~formals ~result ensures = List.iter (fun kp -> let ip = Property.ip_of_ensures kf ki bhv kp in let context = context ~called ~kf ip in add_ipred { map ; context ; formals ; result } (snd kp) ) ensures let rec add_extension ~map ~called ~kf ~ki ~formals ~result acsl = let eloc = match ki with | Kglobal -> Property.ELContract kf | Kstmt stmt -> Property.ELStmt (kf, stmt) in let context = context ~called ~kf @@ Property.ip_of_extended eloc acsl in match acsl.ext_kind with | Ext_id id -> if acsl.ext_plugin = "region" then match called with | None -> let env = { map ; context ; formals ; result } in List.iter (Logic.add_region env) (Spec.of_extid id) | Some stmt -> let loc = Cil_datatype.Stmt.loc stmt in Options.not_yet_implemented ~source:(fst loc) "Unsupported region specification for calls" else let loc = Access.location context in Options.not_yet_implemented ~source:(fst loc) "Unsupported \\%s:%s extensions" acsl.ext_plugin acsl.ext_name | Ext_terms ts -> let env = { map ; context ; formals ; result } in List.iter (iadd_term env) ts | Ext_preds ps -> let env = { map ; context ; formals ; result } in List.iter (add_predicate env) ps | Ext_annot (_,acsls) -> List.iter (add_extension ~map ~called ~kf ~ki ~formals ~result) acsls let add_behavior ~map ~called ~kf ~ki ~formals ~result bhv = begin List.iter (add_requires ~map ~called ~kf ~ki ~bhv ~formals ~result) bhv.b_requires ; List.iter (add_assumes ~map ~called ~kf ~ki ~bhv ~formals ~result) bhv.b_assumes ; add_ensures ~map ~called ~kf ~ki ~bhv ~formals ~result bhv.b_post_cond ; add_bassigns ~map ~called ~kf ~ki ~bhv ~formals ~result bhv.b_assigns ; add_allocation ~map ~called ~kf ~ki ~bhv ~formals ~result bhv.b_allocation ; List.iter (add_extension ~map ~called ~kf ~ki ~formals ~result) bhv.b_extended ; end (* -------------------------------------------------------------------------- *) (* --- Process Code Annotation --- *) (* -------------------------------------------------------------------------- *) let add_variant ~map ~called ~kf ~ki ~formals ~result variant = let context = context ~called ~kf @@ Property.ip_of_decreases kf ki variant in let env = { map ; context ; formals ; result } in ignore @@ add_term env @@ fst variant let add_terminates ~map ~called ~kf ~ki ~formals ~result spec condition = let ip = Property.ip_terminates_of_spec kf ki spec in let context = context ~called ~kf @@ Option.get ip in let env = { map ; context ; formals ; result } in add_ipred env condition let add_spec ~map ?called ~kf ?(ki=Kglobal) ?(formals=Vmap.empty) ~result s = begin Option.iter (add_variant ~map ~called ~kf ~ki ~formals ~result) s.spec_variant ; Option.iter (add_terminates ~map ~called ~kf ~ki ~formals ~result s) s.spec_terminates ; List.iter (add_behavior ~map ~called ~kf ~ki ~formals ~result) s.spec_behavior ; end (* -------------------------------------------------------------------------- *) (* --- Process Code Annotations --- *) (* -------------------------------------------------------------------------- *) let iprop ip = Access.Prop ip let add_code_annot ~map ~kf ~stmt ~result ca = let ki = Kstmt stmt in let formals = Vmap.empty in match ca.annot_content with | AAssert (_,{ tp_statement = p }) -> let context = iprop @@ Property.ip_of_code_annot_single kf stmt ca in let env = { map ; context ; formals ; result } in add_predicate env p | AStmtSpec (_,spec) -> add_spec ~map ~kf ~ki ~result spec | AInvariant (_,_,{ tp_statement = p }) -> let context = iprop @@ Property.ip_of_code_annot_single kf stmt ca in add_predicate { map ; context ; formals ; result } p | AVariant v -> add_variant ~map ~called:None ~kf ~ki ~formals ~result v | AAssigns (_,WritesAny) -> () | AAssigns (_,Writes ws) -> let context = iprop @@ Property.ip_of_code_annot_single kf stmt ca in let env = { map ; context ; formals ; result } in List.iter begin fun (tgt,_) -> add_assigns_from env ~iscalled:None tgt.it_content ~from:FromAny end ws | AAllocation (_,FreeAllocAny) -> () | AAllocation (_,FreeAlloc _) -> let loc = Cil_datatype.Stmt.loc stmt in Options.not_yet_implemented ~source:(fst loc) "Unsupported \\allocates and \\frees" ; (*TODO FIX THIS, Cf. assigns & add_allocates *) | AExtended (_,_, acsl) -> add_extension ~map ~called:None ~kf ~ki ~formals ~result acsl (* -------------------------------------------------------------------------- *)
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>