Skip to content
Snippets Groups Projects
Commit ef99c7f4 authored by Basile Desloges's avatar Basile Desloges
Browse files

[eacsl] Fix generated `__e_acsl_globals_clean()`

The `__eacsl_globals_clean()` global function is only created if there
are globals variables. A `return;` statement is added at the end of the
function to satisfy Frama-C invariants.
parent 4e99ef53
No related branches found
No related tags found
No related merge requests found
...@@ -187,20 +187,24 @@ let mk_init_function () = ...@@ -187,20 +187,24 @@ let mk_init_function () =
vi, fundec vi, fundec
let mk_clean_function () = let mk_clean_function () =
(* Create and register [__e_acsl_globals_clean] function with definition if Varinfo.Hashtbl.length tbl = 0 then
for de-allocation of global variables *) None
let vi, fundec, _kf = mk_function function_clean_name in else
(* Generate delete statements and add them to the function body *) (* Create and register [__e_acsl_globals_clean] function with definition
let stmts = for de-allocation of global variables *)
Varinfo.Hashtbl.fold_sorted let vi, fundec, _kf = mk_function function_clean_name in
(fun vi _l acc -> (* Generate delete statements and add them to the function body *)
if Misc.is_fc_or_compiler_builtin vi then acc let return = Cil.mkStmt ~valid_sid:true (Return (None, Location.unknown)) in
else Smart_stmt.delete_stmt vi :: acc) let stmts =
tbl Varinfo.Hashtbl.fold_sorted
[] (fun vi _l acc ->
in if Misc.is_fc_or_compiler_builtin vi then acc
fundec.sbody.bstmts <- stmts; else Smart_stmt.delete_stmt vi :: acc)
vi, fundec tbl
[return]
in
fundec.sbody.bstmts <- stmts;
Some (vi, fundec)
(* (*
Local Variables: Local Variables:
......
...@@ -44,9 +44,9 @@ val mk_init_function: unit -> varinfo * fundec ...@@ -44,9 +44,9 @@ val mk_init_function: unit -> varinfo * fundec
(** Generate a new C function containing the observers for global variable (** Generate a new C function containing the observers for global variable
declarations and initializations. *) declarations and initializations. *)
val mk_clean_function: unit -> varinfo * fundec val mk_clean_function: unit -> (varinfo * fundec) option
(** Generate a new C function containing the observers for global variable (** Generate a new C function containing the observers for global variable
de-allocations. *) de-allocations if there are global variables. *)
(* (*
Local Variables: Local Variables:
......
...@@ -710,8 +710,12 @@ let inject_global_handler file main = ...@@ -710,8 +710,12 @@ let inject_global_handler file main =
let vi_init, fundec_init = Global_observer.mk_init_function () in let vi_init, fundec_init = Global_observer.mk_init_function () in
let cil_fct_init = GFun(fundec_init, Location.unknown) in let cil_fct_init = GFun(fundec_init, Location.unknown) in
(* Create [__e_acsl_globals_delete] function *) (* Create [__e_acsl_globals_delete] function *)
let vi_clean, fundec_clean = Global_observer.mk_clean_function () in let vi_and_fundec_clean_opt = Global_observer.mk_clean_function () in
let cil_fct_clean = GFun(fundec_clean, Location.unknown) in let cil_fct_clean_opt =
Option.map
(fun (_, fundec_clean) -> GFun(fundec_clean, Location.unknown))
vi_and_fundec_clean_opt
in
match main with match main with
| Some main -> | Some main ->
let mk_fct_call vi = let mk_fct_call vi =
...@@ -730,14 +734,14 @@ let inject_global_handler file main = ...@@ -730,14 +734,14 @@ let inject_global_handler file main =
(* Create [__e_acsl_globals_init();] call *) (* Create [__e_acsl_globals_init();] call *)
let stmt_init = mk_fct_call vi_init in let stmt_init = mk_fct_call vi_init in
(* Create [__e_acsl_globals_delete();] call *) (* Create [__e_acsl_globals_delete();] call *)
let stmt_clean = let stmt_clean_opt =
match fundec_clean.sbody.bstmts with Option.map
| [] -> None (fun (vi_clean, _) -> mk_fct_call vi_clean)
| _ -> Some (mk_fct_call vi_clean) vi_and_fundec_clean_opt
in in
(* Surround the content of main with the calls to (* Surround the content of main with the calls to
[__e_acsl_globals_init();] and [__e_acsl_globals_delete();] *) [__e_acsl_globals_init();] and [__e_acsl_globals_delete();] *)
surround_function_with main main_fundec stmt_init stmt_clean; surround_function_with main main_fundec stmt_init stmt_clean_opt;
(* Retrieve all globals except main *) (* Retrieve all globals except main *)
let main_vi = Globals.Functions.get_vi main in let main_vi = Globals.Functions.get_vi main in
let new_globals = let new_globals =
...@@ -758,9 +762,10 @@ let inject_global_handler file main = ...@@ -758,9 +762,10 @@ let inject_global_handler file main =
let globals_to_add = [ GFun(main_fundec, Location.unknown) ] in let globals_to_add = [ GFun(main_fundec, Location.unknown) ] in
(* Prepend [__e_acsl_globals_clean] if not empty *) (* Prepend [__e_acsl_globals_clean] if not empty *)
let globals_to_add = let globals_to_add =
match fundec_clean.sbody.bstmts with Option.fold
| [] -> globals_to_add ~none:globals_to_add
| _ -> cil_fct_clean :: globals_to_add ~some:(fun cil_fct_clean -> cil_fct_clean :: globals_to_add)
cil_fct_clean_opt
in in
(* Prepend [__e_acsl_globals_init] *) (* Prepend [__e_acsl_globals_init] *)
let globals_to_add = cil_fct_init :: globals_to_add in let globals_to_add = cil_fct_init :: globals_to_add in
...@@ -782,9 +787,10 @@ let inject_global_handler file main = ...@@ -782,9 +787,10 @@ let inject_global_handler file main =
Global_observer.function_init_name Global_observer.function_init_name
Global_observer.function_clean_name; Global_observer.function_clean_name;
let globals_func = let globals_func =
match fundec_clean.sbody.bstmts with Option.fold
| [] -> [ cil_fct_init ] ~none:[ cil_fct_init ]
| _ -> [ cil_fct_init; cil_fct_clean ] ~some:(fun cil_fct_clean -> [ cil_fct_init; cil_fct_clean ])
cil_fct_clean_opt
in in
file.globals <- file.globals @ globals_func file.globals <- file.globals @ globals_func
......
/* run.config_ci
COMMENT: frama-c/e-acsl#145, test for validity of globals_init and
globals_clean.
STDOPT: +"-verbose 1 -eva-print"
*/
int G = 0;
int main(void) {
/*@ assert \valid(&G); */
int a = G;
return 0;
}
/* Generated by Frama-C */
#include "stddef.h"
#include "stdio.h"
int G = 0;
void __e_acsl_globals_init(void)
{
static char __e_acsl_already_run = 0;
if (! __e_acsl_already_run) {
__e_acsl_already_run = 1;
__e_acsl_store_block((void *)(& G),(size_t)4);
__e_acsl_full_init((void *)(& G));
}
return;
}
void __e_acsl_globals_clean(void)
{
__e_acsl_delete_block((void *)(& G));
return;
}
int main(void)
{
int __retres;
__e_acsl_memory_init((int *)0,(char ***)0,(size_t)8);
__e_acsl_globals_init();
{
int __gen_e_acsl_valid;
__gen_e_acsl_valid = __e_acsl_valid((void *)(& G),sizeof(int),
(void *)(& G),(void *)0);
__e_acsl_assert(__gen_e_acsl_valid,"Assertion","main","\\valid(&G)",
"tests/bts/issue-eacsl-145.c",9);
}
/*@ assert \valid(&G); */ ;
int a = G;
__retres = 0;
__e_acsl_globals_clean();
__e_acsl_memory_clean();
return __retres;
}
[kernel] Parsing tests/bts/issue-eacsl-145.c (with preprocessing)
[e-acsl] beginning translation.
[kernel] Parsing FRAMAC_SHARE/e-acsl/e_acsl.h (with preprocessing)
[e-acsl] translation done in project "e-acsl".
[eva] Analyzing a complete application starting at main
[eva] Computing initial state
[eva] Initial state computed
[eva:initial-state] Values of globals at initialization
G ∈ {0}
__e_acsl_heap_allocation_size ∈ [--..--]
__e_acsl_heap_allocated_blocks ∈ [--..--]
__fc_heap_status ∈ [--..--]
__e_acsl_math_HUGE_VAL ∈ [-1.79769313486e+308 .. 1.79769313486e+308]
__e_acsl_math_HUGE_VALF ∈ [-3.40282346639e+38 .. 3.40282346639e+38]
__e_acsl_math_INFINITY ∈ [-1.79769313486e+308 .. 1.79769313486e+308]
__e_acsl_init ∈ [--..--]
[eva] using specification for function __e_acsl_memory_init
[eva] using specification for function __e_acsl_store_block
[eva] using specification for function __e_acsl_full_init
[eva] using specification for function __e_acsl_valid
[eva] using specification for function __e_acsl_assert
[eva] using specification for function __e_acsl_delete_block
[eva] using specification for function __e_acsl_memory_clean
[eva] done for function main
[eva] ====== VALUES COMPUTED ======
[eva:summary] ====== ANALYSIS SUMMARY ======
----------------------------------------------------------------------------
5 functions analyzed (out of 5): 100% coverage.
In these functions, 27 statements reached (out of 27): 100% coverage.
----------------------------------------------------------------------------
No errors or warnings raised during the analysis.
----------------------------------------------------------------------------
0 alarms generated by the analysis.
----------------------------------------------------------------------------
Evaluation of the logical properties reached by the analysis:
Assertions 1 valid 0 unknown 0 invalid 1 total
Preconditions 1 valid 0 unknown 0 invalid 1 total
100% of the logical properties reached have been proven.
----------------------------------------------------------------------------
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment