Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
F
frama-c
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Deploy
Releases
Container Registry
Model registry
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
pub
frama-c
Commits
d628c429
Commit
d628c429
authored
4 years ago
by
Loïc Correnson
Browse files
Options
Downloads
Patches
Plain Diff
[wp] beautify MemoryContext
parent
f3ae1e7b
No related branches found
No related tags found
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
src/plugins/wp/MemoryContext.ml
+69
-57
69 additions, 57 deletions
src/plugins/wp/MemoryContext.ml
with
69 additions
and
57 deletions
src/plugins/wp/MemoryContext.ml
+
69
−
57
View file @
d628c429
...
@@ -50,7 +50,7 @@ type partition = {
...
@@ -50,7 +50,7 @@ type partition = {
globals
:
zone
list
;
(* [ &G , G[...], ... ] *)
globals
:
zone
list
;
(* [ &G , G[...], ... ] *)
to_heap
:
zone
list
;
(* [ p, ... ] *)
to_heap
:
zone
list
;
(* [ p, ... ] *)
context
:
zone
list
;
(* [ p+(..), ... ] *)
context
:
zone
list
;
(* [ p+(..), ... ] *)
by_addr
:
zone
list
;
by_addr
:
zone
list
;
(* [ &(x + ..), ... ] *)
}
}
(* -------------------------------------------------------------------------- *)
(* -------------------------------------------------------------------------- *)
...
@@ -87,12 +87,11 @@ let set x p w =
...
@@ -87,12 +87,11 @@ let set x p w =
else
w
else
w
(* -------------------------------------------------------------------------- *)
(* -------------------------------------------------------------------------- *)
(*
ANNOTS
*)
(*
--- Building Annotations
---
*)
(* -------------------------------------------------------------------------- *)
(* -------------------------------------------------------------------------- *)
open
Logic_const
open
Logic_const
let
rec
ptr_of
=
function
let
rec
ptr_of
=
function
|
Ctype
t
->
Ctype
(
TPtr
(
t
,
[]
))
|
Ctype
t
->
Ctype
(
TPtr
(
t
,
[]
))
|
t
when
Logic_typing
.
is_set_type
t
->
|
t
when
Logic_typing
.
is_set_type
t
->
...
@@ -188,24 +187,19 @@ let valid_region loc r =
...
@@ -188,24 +187,19 @@ let valid_region loc r =
let
t
=
region_to_term
loc
r
in
let
t
=
region_to_term
loc
r
in
pvalid
~
loc
(
here_label
,
t
)
pvalid
~
loc
(
here_label
,
t
)
let
global_zones
partition
=
let
simplify
ps
=
List
.
map
(
fun
z
->
[
z
])
partition
.
globals
List
.
sort_uniq
Logic_utils
.
compare_predicate
(
List
.
filter
(
fun
p
->
not
(
Logic_utils
.
is_trivially_true
p
))
ps
)
let
context_zones
partition
=
List
.
map
(
fun
z
->
[
z
])
partition
.
context
let
addr_of_zones
partition
=
let
ptrset
{
term_type
=
t
}
=
let
comp
a
b
=
Cil_datatype
.
Typ
.
compare
(
type_of_zone
a
)
(
type_of_zone
b
)
in
let
open
Logic_typing
in
L
is
t
.
sort
comp
partition
.
by_addr
is
_pointer_type
t
||
(
is_set_type
t
&&
is_pointer_type
(
type_of_element
t
))
let
heap_zones
partition
=
(* -------------------------------------------------------------------------- *)
let
comp
a
b
=
Cil_datatype
.
Typ
.
compare
(
type_of_zone
a
)
(
type_of_zone
b
)
in
(* --- Partition Helpers --- *)
List
.
sort
comp
partition
.
to_heap
(* -------------------------------------------------------------------------- *)
(* Note that this function does not return separated zone lists, but well-typed
let
welltyped
zones
=
zone lists.
*)
let
well_type_zones
zone_function
partition
=
let
rec
partition_by_type
t
acc
l
=
let
rec
partition_by_type
t
acc
l
=
match
l
,
acc
with
match
l
,
acc
with
|
[]
,
_
->
|
[]
,
_
->
...
@@ -217,10 +211,24 @@ let well_type_zones zone_function partition =
...
@@ -217,10 +211,24 @@ let well_type_zones zone_function partition =
|
x
::
l
,
acc
->
|
x
::
l
,
acc
->
partition_by_type
(
type_of_zone
x
)
([
x
]
::
acc
)
l
partition_by_type
(
type_of_zone
x
)
([
x
]
::
acc
)
l
in
in
partition_by_type
Cil
.
voidType
[]
(
zone_function
partition
)
let
compare_zone
a
b
=
Cil_datatype
.
Typ
.
compare
(
type_of_zone
a
)
(
type_of_zone
b
)
in
partition_by_type
Cil
.
voidType
[]
(
List
.
sort
compare_zone
zones
)
let
global_zones
partition
=
List
.
map
(
fun
z
->
[
z
])
partition
.
globals
let
context_zones
partition
=
List
.
map
(
fun
z
->
[
z
])
partition
.
context
let
heaps
partition
=
welltyped
partition
.
to_heap
let
addr_of_vars
partition
=
welltyped
partition
.
by_addr
let
heaps
=
well_type_zones
heap_zones
(* -------------------------------------------------------------------------- *)
(* --- Computing Separation --- *)
(* -------------------------------------------------------------------------- *)
(* Memory regions shall be separated with each others *)
let
main_separation
loc
globals
context
heaps
=
let
main_separation
loc
globals
context
heaps
=
match
heaps
,
context
with
match
heaps
,
context
with
|
[]
,
[]
->
|
[]
,
[]
->
...
@@ -236,6 +244,7 @@ let main_separation loc globals context heaps =
...
@@ -236,6 +244,7 @@ let main_separation loc globals context heaps =
in
in
List
.
map
for_typed_heap
heaps
List
.
map
for_typed_heap
heaps
(* Filter assigns *)
let
assigned_locations
kf
filter
=
let
assigned_locations
kf
filter
=
let
add_from
l
(
e
,
_ds
)
=
let
add_from
l
(
e
,
_ds
)
=
if
filter
e
.
it_content
then
e
::
l
else
l
if
filter
e
.
it_content
then
e
::
l
else
l
...
@@ -246,6 +255,7 @@ let assigned_locations kf filter =
...
@@ -246,6 +255,7 @@ let assigned_locations kf filter =
in
in
Annotations
.
fold_assigns
add_assign
kf
Cil
.
default_behavior_name
[]
Annotations
.
fold_assigns
add_assign
kf
Cil
.
default_behavior_name
[]
(* Locations assigned by pointer from a call *)
let
assigned_via_pointers
kf
=
let
assigned_via_pointers
kf
=
let
rec
assigned_via_pointer
t
=
let
rec
assigned_via_pointer
t
=
match
t
.
term_node
with
match
t
.
term_node
with
...
@@ -263,12 +273,13 @@ let assigned_via_pointers kf =
...
@@ -263,12 +273,13 @@ let assigned_via_pointers kf =
in
in
assigned_locations
kf
assigned_via_pointer
assigned_locations
kf
assigned_via_pointer
(* Checks whether a term refers to Post *)
let
post_term
t
=
let
post_term
t
=
let
exception
Post_value
in
let
exception
Post_value
in
let
v
=
object
let
v
=
object
inherit
Cil
.
nopCilVisitor
inherit
Cil
.
nopCilVisitor
method
!
vlogic_label
=
function
method
!
vlogic_label
=
function
|
BuiltinLabel
(
Post
)
->
raise
Post_value
|
BuiltinLabel
Post
->
raise
Post_value
|
_
->
Cil
.
SkipChildren
|
_
->
Cil
.
SkipChildren
method
!
vterm_lval
=
function
method
!
vterm_lval
=
function
|
TResult
_
,
_
->
raise
Post_value
|
TResult
_
,
_
->
raise
Post_value
...
@@ -277,6 +288,7 @@ let post_term t =
...
@@ -277,6 +288,7 @@ let post_term t =
try
ignore
(
Cil
.
visitCilTerm
v
t
)
;
false
try
ignore
(
Cil
.
visitCilTerm
v
t
)
;
false
with
Post_value
->
true
with
Post_value
->
true
(* Computes conditions from call assigns *)
let
assigned_separation
kf
loc
globals
=
let
assigned_separation
kf
loc
globals
=
let
addr_of
t
=
addr_of_lval
~
loc
t
.
it_content
in
let
addr_of
t
=
addr_of_lval
~
loc
t
.
it_content
in
let
asgnd_ptrs
=
List
.
map
addr_of
(
assigned_via_pointers
kf
)
in
let
asgnd_ptrs
=
List
.
map
addr_of
(
assigned_via_pointers
kf
)
in
...
@@ -286,28 +298,18 @@ let assigned_separation kf loc globals =
...
@@ -286,28 +298,18 @@ let assigned_separation kf loc globals =
in
in
List
.
fold_left
folder
([]
,
[]
)
asgnd_ptrs
List
.
fold_left
folder
([]
,
[]
)
asgnd_ptrs
let
simpl_pred_list
l
=
(* Computes conditions from partition *)
List
.
sort_uniq
Logic_utils
.
compare_predicate
(
List
.
filter
(
fun
p
->
not
(
Logic_utils
.
is_trivially_true
p
))
l
)
let
clauses_of_partition
kf
loc
p
=
let
clauses_of_partition
kf
loc
p
=
let
globals
=
global_zones
p
in
let
globals
=
global_zones
p
in
let
main_sep
=
let
main_sep
=
main_separation
loc
globals
(
context_zones
p
)
(
heaps
p
)
in
main_separation
loc
globals
(
context_zones
p
)
(
heaps
p
)
in
let
assigns_sep_req
,
assigns_sep_ens
=
assigned_separation
kf
loc
globals
in
let
assigns_sep_req
,
assigns_sep_ens
=
assigned_separation
kf
loc
globals
in
let
context_validity
=
List
.
map
(
valid_region
loc
)
(
context_zones
p
)
in
let
context_validity
=
List
.
map
(
valid_region
loc
)
(
context_zones
p
)
in
let
reqs
=
main_sep
@
assigns_sep_req
@
context_validity
in
let
reqs
=
main_sep
@
assigns_sep_req
@
context_validity
in
let
reqs
=
simpl
_pred_list
reqs
in
let
reqs
=
simpl
ify
reqs
in
let
ens
=
simpl
_pred_list
assigns_sep_ens
in
let
ens
=
simpl
ify
assigns_sep_ens
in
reqs
,
ens
reqs
,
ens
let
addr_of_vars
=
well_type_zones
addr_of_zones
(* Computes conditions from return *)
let
ptr_or_ptr_set
{
term_type
=
t
}
=
let
open
Logic_typing
in
is_pointer_type
t
||
(
is_set_type
t
&&
is_pointer_type
(
type_of_element
t
))
let
out_pointers_separation
kf
loc
p
=
let
out_pointers_separation
kf
loc
p
=
let
ret_t
=
Kernel_function
.
get_return_type
kf
in
let
ret_t
=
Kernel_function
.
get_return_type
kf
in
let
addr_of
t
=
addr_of_lval
~
loc
t
.
it_content
in
let
addr_of
t
=
addr_of_lval
~
loc
t
.
it_content
in
...
@@ -315,7 +317,7 @@ let out_pointers_separation kf loc p =
...
@@ -315,7 +317,7 @@ let out_pointers_separation kf loc p =
Extlib
.
filter_map
Extlib
.
filter_map
(* Search assigned pointers via a pointer,
(* Search assigned pointers via a pointer,
e.g. 'assigns *p ;' with '*p' of type pointer or set of pointers *)
e.g. 'assigns *p ;' with '*p' of type pointer or set of pointers *)
(
fun
t
->
ptr
_or_ptr_
set
t
.
it_content
)
addr_of
(
assigned_via_pointers
kf
)
(
fun
t
->
ptrset
t
.
it_content
)
addr_of
(
assigned_via_pointers
kf
)
in
in
let
asgnd_ptrs
=
let
asgnd_ptrs
=
if
Cil
.
isPointerType
ret_t
then
tresult
~
loc
ret_t
::
asgnd_ptrs
if
Cil
.
isPointerType
ret_t
then
tresult
~
loc
ret_t
::
asgnd_ptrs
...
@@ -333,19 +335,9 @@ let out_pointers_separation kf loc p =
...
@@ -333,19 +335,9 @@ let out_pointers_separation kf loc p =
let
globals
=
global_zones
p
in
let
globals
=
global_zones
p
in
List
.
map
(
fun
t
->
term_separated_from_regions
loc
t
globals
)
asgnd_ptrs
List
.
map
(
fun
t
->
term_separated_from_regions
loc
t
globals
)
asgnd_ptrs
in
in
simpl_pred_list
(
formals_separation
@
globals_separation
)
simplify
(
formals_separation
@
globals_separation
)
module
Table
=
State_builder
.
Hashtbl
(
Cil_datatype
.
Kf
.
Hashtbl
)
(
Datatype
.
Option
(
Cil_datatype
.
Funbehavior
))
(
struct
let
name
=
"MemoryContext.Table"
let
size
=
17
let
dependencies
=
[
Ast
.
self
]
end
)
(* Computes all conditions from behavior *)
let
compute_behavior
kf
name
hypotheses_computer
=
let
compute_behavior
kf
name
hypotheses_computer
=
let
partition
=
hypotheses_computer
kf
in
let
partition
=
hypotheses_computer
kf
in
let
loc
=
Kernel_function
.
get_location
kf
in
let
loc
=
Kernel_function
.
get_location
kf
in
...
@@ -366,6 +358,28 @@ let compute_behavior kf name hypotheses_computer =
...
@@ -366,6 +358,28 @@ let compute_behavior kf name hypotheses_computer =
b_extended
=
[]
b_extended
=
[]
}
}
(* -------------------------------------------------------------------------- *)
(* --- Memoization --- *)
(* -------------------------------------------------------------------------- *)
module
Table
=
State_builder
.
Hashtbl
(
Cil_datatype
.
Kf
.
Hashtbl
)
(
Datatype
.
Option
(
Cil_datatype
.
Funbehavior
))
(
struct
let
name
=
"MemoryContext.Table"
let
size
=
17
let
dependencies
=
[
Ast
.
self
]
end
)
module
RegisteredHypotheses
=
State_builder
.
Set_ref
(
Cil_datatype
.
Kf
.
Set
)
(
struct
let
name
=
"Wp.MemoryContext.RegisteredHypotheses"
let
dependencies
=
[
Ast
.
self
]
end
)
let
compute
name
hypotheses_computer
=
let
compute
name
hypotheses_computer
=
Globals
.
Functions
.
iter
Globals
.
Functions
.
iter
(
fun
kf
->
ignore
(
compute_behavior
kf
name
hypotheses_computer
))
(
fun
kf
->
ignore
(
compute_behavior
kf
name
hypotheses_computer
))
...
@@ -378,6 +392,10 @@ let get_behavior kf name hypotheses_computer =
...
@@ -378,6 +392,10 @@ let get_behavior kf name hypotheses_computer =
end
end
kf
kf
(* -------------------------------------------------------------------------- *)
(* --- External API --- *)
(* -------------------------------------------------------------------------- *)
let
print_memory_context
kf
bhv
fmt
=
let
print_memory_context
kf
bhv
fmt
=
begin
begin
let
printer
=
new
Printer
.
extensible_printer
()
in
let
printer
=
new
Printer
.
extensible_printer
()
in
...
@@ -401,14 +419,6 @@ let warn kf name hyp_computer =
...
@@ -401,14 +419,6 @@ let warn kf name hyp_computer =
let
emitter
=
let
emitter
=
Emitter
.(
create
"Wp.Hypotheses"
[
Funspec
]
~
correctness
:
[]
~
tuning
:
[]
)
Emitter
.(
create
"Wp.Hypotheses"
[
Funspec
]
~
correctness
:
[]
~
tuning
:
[]
)
module
RegisteredHypotheses
=
State_builder
.
Set_ref
(
Cil_datatype
.
Kf
.
Set
)
(
struct
let
name
=
"Wp.MemoryContext.RegisteredHypotheses"
let
dependencies
=
[
Ast
.
self
]
end
)
let
add_behavior
kf
name
hypotheses_computer
=
let
add_behavior
kf
name
hypotheses_computer
=
if
RegisteredHypotheses
.
mem
kf
then
()
if
RegisteredHypotheses
.
mem
kf
then
()
else
begin
else
begin
...
@@ -418,3 +428,5 @@ let add_behavior kf name hypotheses_computer =
...
@@ -418,3 +428,5 @@ let add_behavior kf name hypotheses_computer =
end
;
end
;
RegisteredHypotheses
.
add
kf
RegisteredHypotheses
.
add
kf
end
end
(* -------------------------------------------------------------------------- *)
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment