(&self, env: &GlobalEnv, targets: &mut FunctionTargetsHolder)
| 227 | } |
| 228 | |
| 229 | fn initialize(&self, env: &GlobalEnv, targets: &mut FunctionTargetsHolder) { |
| 230 | let options = ProverOptions::get(env); |
| 231 | |
| 232 | // If we are verifying only one function or module, check that this indeed exists. |
| 233 | match &options.verify_scope { |
| 234 | VerificationScope::Only(name) | VerificationScope::OnlyModule(name) => { |
| 235 | let for_module = matches!(&options.verify_scope, VerificationScope::OnlyModule(_)); |
| 236 | let mut target_exists = false; |
| 237 | for module in env.get_modules() { |
| 238 | if module.is_target() { |
| 239 | if for_module { |
| 240 | target_exists = module.matches_name(name) |
| 241 | } else { |
| 242 | target_exists = module.get_functions().any(|f| f.matches_name(name)); |
| 243 | } |
| 244 | if target_exists { |
| 245 | break; |
| 246 | } |
| 247 | } |
| 248 | } |
| 249 | if !target_exists { |
| 250 | env.error( |
| 251 | &env.unknown_loc(), |
| 252 | &format!( |
| 253 | "{} target {} does not exist in target modules", |
| 254 | if for_module { "module" } else { "function" }, |
| 255 | name |
| 256 | ), |
| 257 | ) |
| 258 | } |
| 259 | } |
| 260 | _ => {} |
| 261 | } |
| 262 | |
| 263 | // Collect information for global invariant instrumentation |
| 264 | |
| 265 | // probe how global invariants will be evaluated in the functions |
| 266 | let (fun_set_with_inv_check_on_exit, fun_set_with_no_inv_check) = |
| 267 | Self::probe_invariant_status_in_functions(env); |
| 268 | |
| 269 | // get a map on how invariants are applicable in functions |
| 270 | let fun_to_inv_map = Self::build_function_to_invariants_map(env, targets); |
| 271 | |
| 272 | // error checking, this needs to be done after the invariant applicability map because some |
| 273 | // rules depends on information in that map. |
| 274 | for fun_id in &fun_set_with_no_inv_check { |
| 275 | let fun_env = env.get_function(*fun_id); |
| 276 | |
| 277 | // Rule 1: external-facing functions are not allowed in the N set (i.e., have invariant |
| 278 | // checking completely turned-off), UNLESS they don't modify any memory that are checked |
| 279 | // in any suspendable invariant. |
| 280 | if fun_env.has_unknown_callers() { |
| 281 | let relevance = fun_to_inv_map.get(fun_id).unwrap(); |
| 282 | let num_suspendable_inv_modified = relevance |
| 283 | .modified |
| 284 | .iter() |
| 285 | .filter(|inv_id| is_invariant_suspendable(env, **inv_id)) |
| 286 | .count(); |
nothing calls this directly
no test coverage detected