diff --git a/src/kernel_services/ast_data/annotations.ml b/src/kernel_services/ast_data/annotations.ml index cc6c5221d3e88a2f0f0cf893a453e9cc80869625..90690303633e5645a68168a2d13dcf4a7c9cab9c 100644 --- a/src/kernel_services/ast_data/annotations.ml +++ b/src/kernel_services/ast_data/annotations.ml @@ -1001,6 +1001,19 @@ let add_disjoint e kf ?stmt ?active l = Property_status.register (Property.ip_of_disjoint kf (kinstr stmt) active l) end +let add_spec ?register_children e kf ?stmt ?active spec = + add_behaviors ?register_children e kf ?stmt ?active spec.spec_behavior; + Option.iter (fun variant -> add_decreases e kf variant) spec.spec_variant; + Option.iter + (fun terminates -> add_terminates e kf ?stmt ?active terminates) + spec.spec_terminates; + List.iter + (fun complete -> add_complete e kf ?stmt ?active complete) + spec.spec_complete_behaviors; + List.iter + (fun disjoint -> add_disjoint e kf ?stmt ?active disjoint) + spec.spec_disjoint_behaviors + let extend_behavior e kf ?stmt ?active ?(behavior=Cil.default_behavior_name) set_bhv = (* Kernel.feedback "Function %a, behavior %s" Kf.pretty kf bhv_name;*) diff --git a/src/kernel_services/ast_data/annotations.mli b/src/kernel_services/ast_data/annotations.mli index c6b8e7d3f81dcf518e58918404d31c93da63d1af..1b7e315613ec5e5bd32073bb0b8eef9424d1218f 100644 --- a/src/kernel_services/ast_data/annotations.mli +++ b/src/kernel_services/ast_data/annotations.mli @@ -334,6 +334,14 @@ type 'a behavior_component_addition = @since Aluminium-20160501 *) +val add_spec: ?register_children:bool -> spec contract_component_addition +(** Add new spec into the given contract. + + [register_children] is directly given to the function [add_behaviors]. + + @since Frama-C+dev +*) + val add_behaviors: ?register_children:bool -> funbehavior list contract_component_addition (** Add new behaviors into the given contract. diff --git a/src/plugins/e-acsl/share/e-acsl/observation_model/e_acsl_observation_model.h b/src/plugins/e-acsl/share/e-acsl/observation_model/e_acsl_observation_model.h index f55417402c009ae4e15f44fb747d6d3be9a0f62e..4a5a8204afda7fc9457a9b68a8c7712c5290ee09 100644 --- a/src/plugins/e-acsl/share/e-acsl/observation_model/e_acsl_observation_model.h +++ b/src/plugins/e-acsl/share/e-acsl/observation_model/e_acsl_observation_model.h @@ -36,6 +36,19 @@ #include "../internals/e_acsl_alias.h" #include "e_acsl_heap.h" +/*@ ghost extern int __fc_heap_status; */ + +/*@ axiomatic dynamic_allocation { + @ predicate is_allocable{L}(integer n) // Can a block of n bytes be allocated? + @ reads __fc_heap_status; + @ // The logic label L is not used, but it must be present because the + @ // predicate depends on the memory state + @ axiom never_allocable{L}: + @ \forall integer i; + @ i < 0 || i > __FC_SIZE_MAX ==> !is_allocable(i); + @ } +*/ + /************************************************************************/ /*** API Prefixes {{{ ***/ /************************************************************************/ @@ -83,8 +96,16 @@ * behaviour is as if the size were some non-zero value, except that the * returned pointer shall not be used to access an object." */ /*@ - assigns __e_acsl_heap_allocation_size \from size, __e_acsl_heap_allocation_size; - assigns __e_acsl_heap_allocated_blocks \from size, __e_acsl_heap_allocated_blocks; + assigns __e_acsl_heap_allocation_size \from indirect:size, __e_acsl_heap_allocation_size; + assigns __e_acsl_heap_allocated_blocks \from indirect:size, __e_acsl_heap_allocated_blocks; + behavior allocation: + assumes can_allocate: is_allocable(size); + assigns __e_acsl_heap_allocation_size \from indirect:size, __e_acsl_heap_allocation_size; + assigns __e_acsl_heap_allocated_blocks \from indirect:size, __e_acsl_heap_allocated_blocks; + behavior no_allocation: + assumes cannot_allocate: !is_allocable(size); + assigns __e_acsl_heap_allocation_size \from indirect:size, __e_acsl_heap_allocation_size; + assigns __e_acsl_heap_allocated_blocks \from size, __e_acsl_heap_allocated_blocks; */ void * malloc(size_t size) __attribute__((FC_BUILTIN)); @@ -94,6 +115,14 @@ void * malloc(size_t size) /*@ assigns __e_acsl_heap_allocation_size \from indirect:nbr_elt, indirect:size_elt, __e_acsl_heap_allocation_size; assigns __e_acsl_heap_allocated_blocks \from indirect:nbr_elt, indirect:size_elt, __e_acsl_heap_allocated_blocks; + behavior allocation: + assumes can_allocate: is_allocable(nbr_elt * size_elt); + assigns __e_acsl_heap_allocation_size \from indirect:nbr_elt, indirect:size_elt, __e_acsl_heap_allocation_size; + assigns __e_acsl_heap_allocated_blocks \from indirect:nbr_elt, indirect:size_elt, __e_acsl_heap_allocated_blocks; + behavior no_allocation: + assumes cannot_allocate: !is_allocable(nbr_elt * size_elt); + assigns __e_acsl_heap_allocation_size \from indirect:nbr_elt, indirect:size_elt, __e_acsl_heap_allocation_size; + assigns __e_acsl_heap_allocated_blocks \from indirect:nbr_elt, indirect:size_elt, __e_acsl_heap_allocated_blocks; */ void * calloc(size_t nbr_elt, size_t size_elt) __attribute__((FC_BUILTIN)); @@ -103,6 +132,19 @@ void * calloc(size_t nbr_elt, size_t size_elt) /*@ assigns __e_acsl_heap_allocation_size \from __e_acsl_heap_allocation_size; assigns __e_acsl_heap_allocated_blocks \from __e_acsl_heap_allocated_blocks; + behavior allocation: + assumes can_allocate: is_allocable(size); + assigns __e_acsl_heap_allocation_size \from __e_acsl_heap_allocation_size; + assigns __e_acsl_heap_allocated_blocks \from __e_acsl_heap_allocated_blocks; + behavior deallocation: + assumes nonnull_ptr: ptr != \null; + assumes can_allocate: is_allocable(size); + assigns __e_acsl_heap_allocation_size \from __e_acsl_heap_allocation_size; + assigns __e_acsl_heap_allocated_blocks \from __e_acsl_heap_allocated_blocks; + behavior fail: + assumes cannot_allocate: !is_allocable(size); + assigns __e_acsl_heap_allocation_size \from __e_acsl_heap_allocation_size; + assigns __e_acsl_heap_allocated_blocks \from __e_acsl_heap_allocated_blocks; */ void * realloc(void * ptr, size_t size) __attribute__((FC_BUILTIN)); @@ -112,6 +154,14 @@ void * realloc(void * ptr, size_t size) /*@ assigns __e_acsl_heap_allocation_size \from __e_acsl_heap_allocation_size; assigns __e_acsl_heap_allocated_blocks \from __e_acsl_heap_allocated_blocks; + behavior deallocation: + assumes nonnull_p: ptr != \null; + assigns __e_acsl_heap_allocation_size \from __e_acsl_heap_allocation_size; + assigns __e_acsl_heap_allocated_blocks \from __e_acsl_heap_allocated_blocks; + behavior no_deallocation: + assumes null_p: ptr == \null; + assigns __e_acsl_heap_allocation_size \from __e_acsl_heap_allocation_size; + assigns __e_acsl_heap_allocated_blocks \from __e_acsl_heap_allocated_blocks; */ void free(void * ptr) __attribute__((FC_BUILTIN)); @@ -137,6 +187,14 @@ void *aligned_alloc(size_t alignment, size_t size) /*@ assigns __e_acsl_heap_allocation_size \from indirect:alignment, size, __e_acsl_heap_allocation_size; assigns __e_acsl_heap_allocated_blocks \from indirect:alignment, size, __e_acsl_heap_allocated_blocks; + behavior allocation: + assumes can_allocate: is_allocable(size); + assigns __e_acsl_heap_allocation_size \from indirect:alignment, size, __e_acsl_heap_allocation_size; + assigns __e_acsl_heap_allocated_blocks \from indirect:alignment, size, __e_acsl_heap_allocated_blocks; + behavior no_allocation: + assumes cannot_allocate: !is_allocable(size); + assigns __e_acsl_heap_allocation_size \from indirect:alignment, size, __e_acsl_heap_allocation_size; + assigns __e_acsl_heap_allocated_blocks \from indirect:alignment, size, __e_acsl_heap_allocated_blocks; */ int posix_memalign(void **memptr, size_t alignment, size_t size) __attribute__((FC_BUILTIN)); diff --git a/src/plugins/e-acsl/src/project_initializer/rtl.ml b/src/plugins/e-acsl/src/project_initializer/rtl.ml index 07be50d1a64fb1cfbebc38c5a8351b25e03b7204..8c96f04f908c620773f0a2cb0bf2ca75df2d489d 100644 --- a/src/plugins/e-acsl/src/project_initializer/rtl.ml +++ b/src/plugins/e-acsl/src/project_initializer/rtl.ml @@ -100,6 +100,71 @@ end = struct *) end +(* Internal module to store the associations between symbols in the RTL project + and their corresponding symbols in the user's project. *) +module Assocs: sig + val clear: unit -> unit + (** Clear stored associations. *) + + val add_kf: global -> kernel_function -> unit + (** Add an association between a global in the RTL project and the + corresponding kernel function in the user's project. *) + + val mem_kf: global -> bool + (** Returns true if the given global from the RTL project has a corresponding + kernel function in the user's project. *) + + val get_kf: global -> kernel_function + (** Returns the corresponding kernel function from the user's project for the + given global in the RTL project. *) + + val add_vi: varinfo -> varinfo -> unit + (** [add_vi rtl_vi user_vi] adds an association between a [varinfo] in the + RTL project and the corresponding [varinfo] in the user's project. *) + + val find_vi: varinfo -> varinfo + (** [find_vi rtl_vi] returns the corresponding [varinfo] from the user's + project for the given [varinfo] in the RTL project if it exists, or raise + [Not_found] otherwise. *) + + val add_li: logic_info -> logic_info -> unit + (** [add_li rtl_li user_li] adds an association between a [logic_info] in the + RTL project and the corresponding [logic_info] in the user's project. *) + + val find_li: logic_info -> logic_info + (** [find_li rtl_li] returns the corresponding [logic_info] from the user's + project for the given [logic_info] in the RTL project if it exists, + or raise [Not_found] otherwise. *) + +end = struct + let kfs: kernel_function Global.Hashtbl.t = Global.Hashtbl.create 17 + let vars: varinfo Varinfo.Hashtbl.t = Varinfo.Hashtbl.create 17 + let logic_vars: logic_info Logic_info.Hashtbl.t = Logic_info.Hashtbl.create 17 + + let clear () = + Global.Hashtbl.clear kfs; + Varinfo.Hashtbl.clear vars; + Logic_info.Hashtbl.clear logic_vars + + let add_kf rtl_g user_kf = Global.Hashtbl.replace kfs rtl_g user_kf + let mem_kf rtl_g = Global.Hashtbl.mem kfs rtl_g + let get_kf rtl_g = + try + Global.Hashtbl.find kfs rtl_g + with Not_found -> + Options.fatal + "Unable to find user kf corresponding to %a. Assocs.mem_kf should be \ + used before calling Assocs.get_kf" + Printer.pp_global rtl_g + + let add_vi rtl_vi user_vi = Varinfo.Hashtbl.replace vars rtl_vi user_vi + let find_vi rtl_vi = Varinfo.Hashtbl.find vars rtl_vi + + let add_li rtl_li user_li = Logic_info.Hashtbl.replace logic_vars rtl_li user_li + let find_li rtl_li = Logic_info.Hashtbl.find logic_vars rtl_li +end + + (* NOTE: do not use [Mergecil.merge] since all [ast]'s symbols must be kept unchanged: so do it ourselves. Thanksfully, we merge in a particular setting because we know what the RTL is. Therefore merging is far from being @@ -109,11 +174,15 @@ end tables. @return the list of globals to be inserted into [ast], in reverse order. *) let lookup_rtl_globals rtl_ast = - (* [do_it ~add mem acc l g] checks whether the global does exist in the user's - AST. If not, add it to the corresponding symbol table(s). *) - let rec do_it ?(add=fun _g -> ()) mem acc l g = - if mem g then do_globals (g :: acc) l - else begin + (* [do_it ~add ~assoc mem acc l g] checks whether the global does exist in the + user's AST. If not, add it to the corresponding symbol table(s). If yes, + save the association between the global in the user's AST and the global in + the RTL. *) + let rec do_it ?(add=fun _g -> ()) ?(assoc=fun _g -> ()) mem acc l g = + if mem g then begin + assoc g; + do_globals (g :: acc) l + end else begin add g; Symbols.add_global g; do_globals (g :: acc) l @@ -134,8 +203,11 @@ let lookup_rtl_globals rtl_ast = do_ty acc l g Logic_typing.Enum ei.ename | GVarDecl(vi, (pos, _)) | GVar(vi, _, (pos, _)) as g :: l -> let tunit = Translation_unit pos.Filepath.pos_path in + let get_old_vi_opt vi = + Globals.Syntactic_search.find_in_scope vi.vorig_name tunit + in let mem _g = - let g = Globals.Syntactic_search.find_in_scope vi.vorig_name tunit in + let g = get_old_vi_opt vi in Option.is_some g in let add g = @@ -145,16 +217,95 @@ let lookup_rtl_globals rtl_ast = | GVar(_, ii, _) -> Globals.Vars.add vi ii | _ -> assert false in - do_it ~add mem acc l g + let assoc _g = + (* [assoc] is called if [mem] returns true, so the option returned by + [get_old_vi_opt] is [Some] by construction. *) + let old_vi = get_old_vi_opt vi in + Assocs.add_vi vi (Option.get old_vi) + in + do_it ~add ~assoc mem acc l g | GFunDecl(_, vi, _loc) | GFun({ svar = vi }, _loc) as g :: l -> let add _g = Symbols.add_vi vi.vname vi; (* functions will be registered in kernel's table after substitution of RTL's symbols inside them *) in - do_it ~add (fun _ -> Globals.Functions.mem_name vi.vname) acc l g + let assoc g = + let kf = Globals.Functions.find_by_name vi.vname in + Assocs.add_kf g kf + in + do_it ~add ~assoc (fun _ -> Globals.Functions.mem_name vi.vname) acc l g + | GAnnot (Daxiomatic (name, galist, _, _), _) as g :: l -> + (* processing axiomatics *) + let fun_or_preds = + (* extract the functions and predicates from the axiomatic *) + List.filter_map + (fun ga -> + match ga with + | Dfun_or_pred (li, _) -> Some li + | _ -> None) + galist + in + let mem _ = + (* check if some function or predicate of the axiomatic [exists] in the + user's project, if all the functions and predicates are in the user's + project ([forall]), and store which function and predicate are in the + user's project in [conflicting_lis]. *) + let exists, forall, conflicting_lis = + List.fold_left + (fun (exists, forall, conflicting_lis) li -> + let lv_name = li.l_var_info.lv_name in + let li_exists = Logic_env.Logic_info.mem lv_name in + let conflicting_lis = + if li_exists then li :: conflicting_lis else conflicting_lis + in + exists || li_exists, forall && li_exists, conflicting_lis) + (false, true, []) + fun_or_preds + in + (* The axiomatic is considered "in the user's project" if and only if + all its functions and predicates are in the user's project. If only + some of them are in it then it is an error, and if none of them are + then the axiomatic is not in the user's project. *) + if exists && not forall then + Options.abort + "@[The following logic functions or predicates@ \ + are in conflict with logic functions or predicates from the@ \ + axiomatic '%s' in the E-ACSL runtime library, please rename@ \ + them:@ %a@]" + name + (Pretty_utils.pp_list + ~sep:",@ " + Printer.pp_logic_info) + conflicting_lis + else + forall + in + let assoc _g = + List.iter + (fun li -> + let lv_name = li.l_var_info.lv_name in + let old_lis = Logic_env.Logic_info.find lv_name in + let old_li = + try + List.find + (fun old_li -> Logic_utils.is_same_logic_info li old_li) + old_lis + with Not_found -> + Options.fatal + "Unable to find the logic_info in the user's AST \ + corresponding to the logic_info %a in the RTL's AST. This \ + most likely comes from a mismatch between the axiomatic %s \ + in the RTL that is supposed to mirror one from the stdlib." + Printer.pp_logic_info li + name + in + Assocs.add_li li old_li) + fun_or_preds + in + do_it ~assoc mem acc l g | GAnnot _ :: l -> - (* ignoring annotations from the AST *) + (* ignoring other annotations from the AST *) do_globals acc l | GPragma _ as g :: l -> do_it Symbols.mem_global acc l g @@ -163,34 +314,86 @@ let lookup_rtl_globals rtl_ast = in do_globals [] rtl_ast.globals +(** [get_kf vi] returns the kernel function corresponding to the given varinfo + in the current project. The varinfo must correspond to a kernel function. *) +let get_kf vi = + try + Globals.Functions.get vi + with Not_found -> + Options.fatal "unknown function %s in project %a" + vi.vname + Project.pretty (Project.current ()) + +(** [get_formals_and_spec prj vi] returns a couple with the formals and function + specification of the function corresponding to the varinfo [vi] in the + project [prj]. The varinfo must correspond to a function of the given + project. *) +let get_formals_and_spec prj vi = + let selection = + State_selection.of_list + [ Globals.Functions.self; Annotations.funspec_state ] + in + Project.on + prj + ~selection + (fun vi -> + let kf = get_kf vi in + Kernel_function.get_formals kf, + Annotations.funspec ~populate:false kf) + vi + +(** Visitor to replace [varinfo] and [logic_info] leaves of an AST with + corresponding values from the [Assocs] tables. + If the visitor is created with the [formals] associating the [varinfo] of + the RTL formals with the [varinfo] of the user formals, then replace the + corresponding [varinfo] leaves. *) +class vis_replace_leaves ?formals () = + object + (* Since we are already working on a copied project, we can use an inplace + visitor. *) + inherit Visitor.frama_c_inplace + + val formals: varinfo Varinfo.Hashtbl.t = + match formals with + | None -> Varinfo.Hashtbl.create 7 + | Some formals -> formals + + (* Since the RTL project will be deleted at the end of the AST + merge, we can temporarily violate the Frama-C invariant that says + that a varinfo or logic_info must be in a single project and directly + replace the varinfo/logic_info of the RTL in the specification with the + logic_info/varinfo of the user's AST. *) + + method! vlogic_info_use rtl_li = + try + (* Replace the logic_info if it is a logic_info from the RTL project. *) + let user_li = Assocs.find_li rtl_li in + Cil.ChangeTo user_li + with Not_found -> + Cil.SkipChildren + + method! vvrbl rtl_vi = + try + (* Replace the varinfo if it is a global from the RTL project.*) + let user_vi = Assocs.find_vi rtl_vi in + Cil.ChangeTo user_vi + with Not_found -> + try + (* Replace the varinfo if it is a formal. *) + let user_vi = Varinfo.Hashtbl.find formals rtl_vi in + Cil.ChangeTo user_vi + with Not_found -> + (* Otherwise do nothing. *) + Cil.SkipChildren + end + (* [substitute_rtl_symbols] registers the correct symbols for RTL's functions *) let substitute_rtl_symbols rtl_prj = function | GVarDecl _ | GVar _ as g -> g | GFunDecl(_, vi, loc) | GFun({ svar = vi }, loc) as g -> - let get_kf vi = - try - Globals.Functions.get vi - with Not_found -> - Options.fatal "unknown function %s in project %a" - vi.vname - Project.pretty (Project.current ()) - in - let selection = - State_selection.of_list - [ Globals.Functions.self; Annotations.funspec_state ] - in (* get the RTL's formals and spec *) - let formals, spec = - Project.on - rtl_prj - ~selection - (fun vi -> - let kf = get_kf vi in - Kernel_function.get_formals kf, - Annotations.funspec ~populate:false kf) - vi - in + let formals, spec = get_formals_and_spec rtl_prj vi in (match g with | GFunDecl _ -> Globals.Functions.replace_by_declaration spec vi loc @@ -209,10 +412,47 @@ let substitute_rtl_symbols rtl_prj = function Annotations.register_funspec ~emitter:Options.emitter kf; Symbols.add_kf kf; g + | GAnnot (Daxiomatic _ as ga, loc) -> + let vis_replace_leaves = new vis_replace_leaves () in + let ga = Visitor.visitFramacAnnotation vis_replace_leaves ga in + Annotations.add_global Options.emitter ga; + GAnnot (ga, loc) | GType _ | GCompTag _ | GCompTagDecl _ | GEnumTag _ | GEnumTagDecl _ | GAnnot _ | GAsm _ | GPragma _ | GText _ -> assert false +(* [merge_rtl_spec rtl_prj rtl_global] adds the spec of the given global + function from the RTL project to the corresponding function in the current + project. Before adding the spec, the varinfos of the global variables and + formals in the spec are replaced with their corresponding varinfos in the + current project. *) +let merge_rtl_spec rtl_prj rtl_global = + match rtl_global with + | GFunDecl(_, vi, _loc) | GFun({ svar = vi }, _loc) as g -> + (* get the RTL's formals and spec *) + let rtl_formals, spec = get_formals_and_spec rtl_prj vi in + (* if the spec is not empty, then merge it with the user's spec *) + if not (Cil.is_empty_funspec spec) then begin + (* get the user's kf *) + let user_kf = Assocs.get_kf g in + (* get the user's formals *) + let user_formals = Kernel_function.get_formals user_kf in + (* replace all the formals and global variables in the spec with the + formals and globals from the user's project. *) + let formals_assoc: varinfo Varinfo.Hashtbl.t = Varinfo.Hashtbl.create 7 in + List.iter2 + (fun rtl_vi user_vi -> Varinfo.Hashtbl.add formals_assoc rtl_vi user_vi) + rtl_formals + user_formals; + let vis_replace_formals = new vis_replace_leaves ~formals:formals_assoc () in + let spec = Visitor.visitFramacFunspec vis_replace_formals spec in + (* Add the updated spec to the user's kf *) + Annotations.add_spec Options.emitter user_kf spec + end + | GVarDecl _ | GVar _ | GType _ | GCompTag _ | GCompTagDecl _ | GEnumTag _ + | GEnumTagDecl _ | GAnnot _ | GAsm _ | GPragma _ | GText _ -> + assert false + (* [insert_rtl_globals] adds the rtl symbols into the user's AST *) let insert_rtl_globals rtl_prj rtl_globals ast = let add_ty acc old_g new_g = @@ -238,12 +478,21 @@ let insert_rtl_globals rtl_prj rtl_globals ast = only declared *) let acc = add_ty acc g (GEnumTagDecl(ei, loc)) in add acc l - | GVarDecl _ | GVar _ | GFunDecl _ | GFun _ as g :: l -> + | GVarDecl _ | GVar _ | GFunDecl _ | GFun _ + | GAnnot (Daxiomatic _, _) as g :: l -> let acc = if Symbols.mem_global g then + (* The symbol is in the RTL project, but not in the user's project. + Perform the symbols substitution and add the global to the user's + project. *) let g = substitute_rtl_symbols rtl_prj g in g :: acc - else + else if Assocs.mem_kf g then begin + (* The symbol is in the RTL project and associated with a kf in the + user's project. Merge both contracts. *) + merge_rtl_spec rtl_prj g; + acc + end else acc in add acc l @@ -261,6 +510,7 @@ let link rtl_prj = let rtl_globals = lookup_rtl_globals rtl_ast in (* Symbols.debug ();*) insert_rtl_globals rtl_prj rtl_globals ast; + Assocs.clear (); Ast.mark_as_grown () (* diff --git a/src/plugins/e-acsl/tests/memory/memsize.c b/src/plugins/e-acsl/tests/memory/memsize.c index c214b60ebd4dcbb33a07b64bf3fddf3e7aec9a8e..2260a306878d6dfd4943d73ccbddc6436c2ec2f5 100644 --- a/src/plugins/e-acsl/tests/memory/memsize.c +++ b/src/plugins/e-acsl/tests/memory/memsize.c @@ -1,5 +1,6 @@ -/* run.config +/* run.config_ci COMMENT: Checking heap memory size + STDOPT: +"-eva-no-builtins-auto" */ #include <stdlib.h> diff --git a/src/plugins/e-acsl/tests/memory/oracle_ci/gen_memalign.c b/src/plugins/e-acsl/tests/memory/oracle_ci/gen_memalign.c index 594eb809025228428f8d77a55c247c7157cab650..86b350d6bcd47ce810e3942357482c1a1697e052 100644 --- a/src/plugins/e-acsl/tests/memory/oracle_ci/gen_memalign.c +++ b/src/plugins/e-acsl/tests/memory/oracle_ci/gen_memalign.c @@ -40,6 +40,12 @@ extern int __e_acsl_sound_verdict; */ int __gen_e_acsl_posix_memalign(void **memptr, size_t alignment, size_t size); +/*@ assigns __e_acsl_heap_allocation_size, __e_acsl_heap_allocated_blocks; + assigns __e_acsl_heap_allocation_size + \from (indirect: alignment), size, __e_acsl_heap_allocation_size; + assigns __e_acsl_heap_allocated_blocks + \from (indirect: alignment), size, __e_acsl_heap_allocated_blocks; + */ void *aligned_alloc(size_t alignment, size_t size); int main(int argc, char const **argv) diff --git a/src/plugins/e-acsl/tests/memory/oracle_ci/gen_memsize.c b/src/plugins/e-acsl/tests/memory/oracle_ci/gen_memsize.c index 134e80f8dafed2dc211d27d63cf0ed3076a9c401..d31fa69d2a5df24b8d9189086ba15157c57864a5 100644 --- a/src/plugins/e-acsl/tests/memory/oracle_ci/gen_memsize.c +++ b/src/plugins/e-acsl/tests/memory/oracle_ci/gen_memsize.c @@ -11,73 +11,73 @@ int main(int argc, char **argv) char *a = malloc((unsigned long)7); __e_acsl_assert(__e_acsl_heap_allocation_size == 7UL,"Assertion","main", "__e_acsl_heap_allocation_size == 7", - "tests/memory/memsize.c",14); + "tests/memory/memsize.c",15); /*@ assert __e_acsl_heap_allocation_size ≡ 7; */ ; char *b = malloc((unsigned long)14); __e_acsl_assert(__e_acsl_heap_allocation_size == 21UL,"Assertion","main", "__e_acsl_heap_allocation_size == 21", - "tests/memory/memsize.c",16); + "tests/memory/memsize.c",17); /*@ assert __e_acsl_heap_allocation_size ≡ 21; */ ; free((void *)a); __e_acsl_assert(__e_acsl_heap_allocation_size == 14UL,"Assertion","main", "__e_acsl_heap_allocation_size == 14", - "tests/memory/memsize.c",20); + "tests/memory/memsize.c",21); /*@ assert __e_acsl_heap_allocation_size ≡ 14; */ ; a = (char *)0; free((void *)a); __e_acsl_assert(__e_acsl_heap_allocation_size == 14UL,"Assertion","main", "__e_acsl_heap_allocation_size == 14", - "tests/memory/memsize.c",25); + "tests/memory/memsize.c",26); /*@ assert __e_acsl_heap_allocation_size ≡ 14; */ ; b = (char *)realloc((void *)b,(unsigned long)9); __e_acsl_assert(__e_acsl_heap_allocation_size == 9UL,"Assertion","main", "__e_acsl_heap_allocation_size == 9", - "tests/memory/memsize.c",29); + "tests/memory/memsize.c",30); /*@ assert __e_acsl_heap_allocation_size ≡ 9; */ ; b = (char *)realloc((void *)b,(unsigned long)18); __e_acsl_assert(__e_acsl_heap_allocation_size == 18UL,"Assertion","main", "__e_acsl_heap_allocation_size == 18", - "tests/memory/memsize.c",33); + "tests/memory/memsize.c",34); /*@ assert __e_acsl_heap_allocation_size ≡ 18; */ ; b = (char *)realloc((void *)b,(unsigned long)0); b = (char *)0; __e_acsl_assert(__e_acsl_heap_allocation_size == 0UL,"Assertion","main", "__e_acsl_heap_allocation_size == 0", - "tests/memory/memsize.c",38); + "tests/memory/memsize.c",39); /*@ assert __e_acsl_heap_allocation_size ≡ 0; */ ; b = (char *)realloc((void *)b,(unsigned long)8); __e_acsl_assert(__e_acsl_heap_allocation_size == 8UL,"Assertion","main", "__e_acsl_heap_allocation_size == 8", - "tests/memory/memsize.c",42); + "tests/memory/memsize.c",43); /*@ assert __e_acsl_heap_allocation_size ≡ 8; */ ; b = (char *)realloc((void *)0,(unsigned long)8); __e_acsl_assert(__e_acsl_heap_allocation_size == 16UL,"Assertion","main", "__e_acsl_heap_allocation_size == 16", - "tests/memory/memsize.c",46); + "tests/memory/memsize.c",47); /*@ assert __e_acsl_heap_allocation_size ≡ 16; */ ; b = (char *)realloc((void *)0,18446744073709551615UL); __e_acsl_assert(__e_acsl_heap_allocation_size == 16UL,"Assertion","main", "__e_acsl_heap_allocation_size == 16", - "tests/memory/memsize.c",50); + "tests/memory/memsize.c",51); /*@ assert __e_acsl_heap_allocation_size ≡ 16; */ ; __e_acsl_assert(b == (char *)0,"Assertion","main","b == (char *)0", - "tests/memory/memsize.c",51); + "tests/memory/memsize.c",52); /*@ assert b ≡ (char *)0; */ ; b = (char *)calloc(18446744073709551615UL,18446744073709551615UL); __e_acsl_assert(__e_acsl_heap_allocation_size == 16UL,"Assertion","main", "__e_acsl_heap_allocation_size == 16", - "tests/memory/memsize.c",55); + "tests/memory/memsize.c",56); /*@ assert __e_acsl_heap_allocation_size ≡ 16; */ ; __e_acsl_assert(b == (char *)0,"Assertion","main","b == (char *)0", - "tests/memory/memsize.c",56); + "tests/memory/memsize.c",57); /*@ assert b ≡ (char *)0; */ ; b = (char *)malloc(18446744073709551615UL); __e_acsl_assert(__e_acsl_heap_allocation_size == 16UL,"Assertion","main", "__e_acsl_heap_allocation_size == 16", - "tests/memory/memsize.c",60); + "tests/memory/memsize.c",61); /*@ assert __e_acsl_heap_allocation_size ≡ 16; */ ; __e_acsl_assert(b == (char *)0,"Assertion","main","b == (char *)0", - "tests/memory/memsize.c",61); + "tests/memory/memsize.c",62); /*@ assert b ≡ (char *)0; */ ; __retres = 0; __e_acsl_memory_clean(); diff --git a/src/plugins/e-acsl/tests/memory/oracle_ci/memsize.res.oracle b/src/plugins/e-acsl/tests/memory/oracle_ci/memsize.res.oracle index 2db55f248cb6caa7f38d1c46c8c93f5bdc964f5e..68e3cc47739f873c790ec413966607107df9a811 100644 --- a/src/plugins/e-acsl/tests/memory/oracle_ci/memsize.res.oracle +++ b/src/plugins/e-acsl/tests/memory/oracle_ci/memsize.res.oracle @@ -1,7 +1,66 @@ [e-acsl] beginning translation. [e-acsl] translation done in project "e-acsl". -[eva:alarm] tests/memory/memsize.c:14: Warning: +[eva] tests/memory/memsize.c:14: Warning: ignoring unsupported \allocates clause +[eva:alarm] tests/memory/memsize.c:15: Warning: + function __e_acsl_assert: precondition got status unknown. +[eva:alarm] tests/memory/memsize.c:15: Warning: assertion got status unknown. +[eva] tests/memory/memsize.c:16: Warning: ignoring unsupported \allocates clause +[eva:alarm] tests/memory/memsize.c:17: Warning: + function __e_acsl_assert: precondition got status unknown. +[eva:alarm] tests/memory/memsize.c:17: Warning: assertion got status unknown. +[eva] tests/memory/memsize.c:20: Warning: ignoring unsupported \allocates clause +[eva:alarm] tests/memory/memsize.c:20: Warning: + function free: precondition 'freeable' got status unknown. +[eva:alarm] tests/memory/memsize.c:21: Warning: + function __e_acsl_assert: precondition got status unknown. +[eva:alarm] tests/memory/memsize.c:21: Warning: assertion got status unknown. +[eva] tests/memory/memsize.c:25: Warning: ignoring unsupported \allocates clause +[eva:alarm] tests/memory/memsize.c:26: Warning: + function __e_acsl_assert: precondition got status unknown. +[eva:alarm] tests/memory/memsize.c:26: Warning: assertion got status unknown. +[eva] FRAMAC_SHARE/libc/stdlib.h:452: Warning: + no 'assigns \result \from ...' clause specified for function realloc +[eva] tests/memory/memsize.c:29: Warning: ignoring unsupported \allocates clause +[eva:alarm] tests/memory/memsize.c:29: Warning: + function realloc: precondition 'freeable' got status unknown. +[eva:alarm] tests/memory/memsize.c:30: Warning: + function __e_acsl_assert: precondition got status unknown. +[eva:alarm] tests/memory/memsize.c:30: Warning: assertion got status unknown. +[eva] tests/memory/memsize.c:33: Warning: ignoring unsupported \allocates clause +[eva:alarm] tests/memory/memsize.c:33: Warning: + function realloc: precondition 'freeable' got status unknown. +[eva:alarm] tests/memory/memsize.c:34: Warning: + function __e_acsl_assert: precondition got status unknown. +[eva:alarm] tests/memory/memsize.c:34: Warning: assertion got status unknown. +[eva] tests/memory/memsize.c:37: Warning: ignoring unsupported \allocates clause +[eva:alarm] tests/memory/memsize.c:37: Warning: + function realloc: precondition 'freeable' got status unknown. +[eva:alarm] tests/memory/memsize.c:39: Warning: + function __e_acsl_assert: precondition got status unknown. +[eva:alarm] tests/memory/memsize.c:39: Warning: assertion got status unknown. +[eva] tests/memory/memsize.c:42: Warning: ignoring unsupported \allocates clause +[eva:alarm] tests/memory/memsize.c:43: Warning: + function __e_acsl_assert: precondition got status unknown. +[eva:alarm] tests/memory/memsize.c:43: Warning: assertion got status unknown. +[eva] tests/memory/memsize.c:46: Warning: ignoring unsupported \allocates clause +[eva:alarm] tests/memory/memsize.c:47: Warning: + function __e_acsl_assert: precondition got status unknown. +[eva:alarm] tests/memory/memsize.c:47: Warning: assertion got status unknown. +[eva] tests/memory/memsize.c:50: Warning: ignoring unsupported \allocates clause +[eva:alarm] tests/memory/memsize.c:51: Warning: + function __e_acsl_assert: precondition got status unknown. +[eva:alarm] tests/memory/memsize.c:51: Warning: assertion got status unknown. +[eva:alarm] tests/memory/memsize.c:52: Warning: + function __e_acsl_assert: precondition got status unknown. +[eva] FRAMAC_SHARE/libc/stdlib.h:385: Warning: + no 'assigns \result \from ...' clause specified for function calloc +[eva] tests/memory/memsize.c:55: Warning: ignoring unsupported \allocates clause +[eva:alarm] tests/memory/memsize.c:56: Warning: + function __e_acsl_assert: precondition got status unknown. +[eva:alarm] tests/memory/memsize.c:56: Warning: assertion got status unknown. +[eva] tests/memory/memsize.c:60: Warning: ignoring unsupported \allocates clause +[eva:alarm] tests/memory/memsize.c:61: Warning: + function __e_acsl_assert: precondition got status unknown. +[eva:alarm] tests/memory/memsize.c:61: Warning: assertion got status unknown. +[eva:alarm] tests/memory/memsize.c:62: Warning: function __e_acsl_assert: precondition got status unknown. -[eva:alarm] tests/memory/memsize.c:14: Warning: assertion got status unknown. -[eva:alarm] tests/memory/memsize.c:16: Warning: - function __e_acsl_assert: precondition got status invalid.