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
cfe2a65d
Commit
cfe2a65d
authored
4 years ago
by
Allan Blanchard
Browse files
Options
Downloads
Patches
Plain Diff
[wp] Hypotheses to validate at post
parent
dda13ade
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
+76
-28
76 additions, 28 deletions
src/plugins/wp/MemoryContext.ml
with
76 additions
and
28 deletions
src/plugins/wp/MemoryContext.ml
+
76
−
28
View file @
cfe2a65d
...
@@ -50,6 +50,7 @@ type partition = {
...
@@ -50,6 +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
;
}
}
(* -------------------------------------------------------------------------- *)
(* -------------------------------------------------------------------------- *)
...
@@ -60,12 +61,13 @@ let empty = {
...
@@ -60,12 +61,13 @@ let empty = {
globals
=
[]
;
globals
=
[]
;
context
=
[]
;
context
=
[]
;
to_heap
=
[]
;
to_heap
=
[]
;
by_addr
=
[]
;
}
}
let
set
x
p
w
=
let
set
x
p
w
=
match
p
with
match
p
with
|
NotUsed
->
w
|
NotUsed
->
w
|
ByAddr
->
w
|
ByAddr
->
{
w
with
by_addr
=
Var
x
::
w
.
by_addr
}
|
ByRef
|
InContext
->
|
ByRef
|
InContext
->
if
Cil
.
isFunctionType
x
.
vtype
then
w
else
if
Cil
.
isFunctionType
x
.
vtype
then
w
else
{
w
with
context
=
Ptr
x
::
w
.
context
}
{
w
with
context
=
Ptr
x
::
w
.
context
}
...
@@ -192,6 +194,10 @@ let global_zones partition =
...
@@ -192,6 +194,10 @@ let global_zones partition =
let
context_zones
partition
=
let
context_zones
partition
=
List
.
map
(
fun
z
->
[
z
])
partition
.
context
List
.
map
(
fun
z
->
[
z
])
partition
.
context
let
addr_of_zones
partition
=
let
comp
a
b
=
Cil_datatype
.
Typ
.
compare
(
type_of_zone
a
)
(
type_of_zone
b
)
in
List
.
sort
comp
partition
.
by_addr
let
heap_zones
partition
=
let
heap_zones
partition
=
let
comp
a
b
=
Cil_datatype
.
Typ
.
compare
(
type_of_zone
a
)
(
type_of_zone
b
)
in
let
comp
a
b
=
Cil_datatype
.
Typ
.
compare
(
type_of_zone
a
)
(
type_of_zone
b
)
in
List
.
sort
comp
partition
.
to_heap
List
.
sort
comp
partition
.
to_heap
...
@@ -199,7 +205,7 @@ let heap_zones partition =
...
@@ -199,7 +205,7 @@ let heap_zones partition =
(* Note that this function does not return separated zone lists, but well-typed
(* Note that this function does not return separated zone lists, but well-typed
zone lists.
zone lists.
*)
*)
let
heaps
partition
=
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
|
[]
,
_
->
|
[]
,
_
->
...
@@ -211,7 +217,9 @@ let heaps partition =
...
@@ -211,7 +217,9 @@ let heaps 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
[]
(
heap_zones
partition
)
partition_by_type
Cil
.
voidType
[]
(
zone_function
partition
)
let
heaps
=
well_type_zones
heap_zones
let
main_separation
loc
globals
context
heaps
=
let
main_separation
loc
globals
context
heaps
=
match
heaps
,
context
with
match
heaps
,
context
with
...
@@ -232,16 +240,11 @@ let assigned_locations kf filter =
...
@@ -232,16 +240,11 @@ 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
in
in
let
add_assign
kf
_emitter
assigns
l
=
match
assigns
with
let
add_assign
_emitter
assigns
l
=
match
assigns
with
|
WritesAny
->
|
WritesAny
->
l
Wp_parameters
.
warning
~
wkey
:
Wp_parameters
.
wkey_imprecise_hypotheses_assigns
~
once
:
true
"No assigns for function '%a', model hypotheses will be imprecise"
Kernel_function
.
pretty
kf
;
l
|
Writes
froms
->
List
.
fold_left
add_from
l
froms
|
Writes
froms
->
List
.
fold_left
add_from
l
froms
in
in
Annotations
.
fold_assigns
(
add_assign
kf
)
kf
Cil
.
default_behavior_name
[]
Annotations
.
fold_assigns
add_assign
kf
Cil
.
default_behavior_name
[]
let
assigned_via_pointers
kf
=
let
assigned_via_pointers
kf
=
let
rec
assigned_via_pointer
t
=
let
rec
assigned_via_pointer
t
=
...
@@ -260,24 +263,67 @@ let assigned_via_pointers kf =
...
@@ -260,24 +263,67 @@ let assigned_via_pointers kf =
in
in
assigned_locations
kf
assigned_via_pointer
assigned_locations
kf
assigned_via_pointer
let
post_term
t
=
let
exception
Post_value
in
let
v
=
object
inherit
Cil
.
nopCilVisitor
method
!
vlogic_label
=
function
|
BuiltinLabel
(
Post
)
->
raise
Post_value
|
_
->
Cil
.
SkipChildren
method
!
vterm_lval
=
function
|
TResult
_
,
_
->
raise
Post_value
|
_
->
Cil
.
DoChildren
end
in
try
ignore
(
Cil
.
visitCilTerm
v
t
)
;
false
with
Post_value
->
true
let
simpl_pred_list
l
=
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
)
main_separation
loc
globals
(
context_zones
p
)
(
heaps
p
)
in
in
let
assigns_sep
=
let
assigns_sep
_req
,
assigns_sep_ens
=
let
addr_of
t
=
addr_of_lval
~
loc
t
.
it_content
in
let
addr_of
t
=
addr_of_lval
~
loc
t
.
it_content
in
List
.
map
let
folder
(
req
,
ens
)
t
=
(
fun
t
->
term_separated_from_regions
loc
(
addr_of
t
)
globals
)
let
sep
=
term_separated_from_regions
loc
(
addr_of
t
)
globals
in
(
assigned_via_pointers
kf
)
if
post_term
t
.
it_content
then
(
req
,
sep
::
ens
)
else
(
sep
::
req
,
ens
)
in
List
.
fold_left
folder
([]
,
[]
)
(
assigned_via_pointers
kf
)
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
=
simpl_pred_list
reqs
in
let
ens
=
simpl_pred_list
assigns_sep_ens
in
reqs
,
ens
let
addr_of_vars
=
well_type_zones
addr_of_zones
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
escaping_formals
kf
loc
p
=
let
ret_t
=
Kernel_function
.
get_return_type
kf
in
let
addr_of
t
=
addr_of_lval
~
loc
t
.
it_content
in
let
asgnd_ptrs
=
Extlib
.
filter_map
(* Search assigned pointers via a pointer,
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
)
in
in
let
context_validity
=
let
asgnd_ptrs
=
List
.
map
(
valid_region
loc
)
(
context_zones
p
)
if
Cil
.
isPointerType
ret_t
then
tresult
~
loc
ret_t
::
asgnd_ptrs
else
asgnd_ptrs
in
in
let
reqs
=
main_sep
@
assigns_sep
@
context_validity
in
let
local_zone
=
function
Var
v
->
v
.
vformal
|
_
->
false
in
let
reqs
=
List
.
filter
(
fun
p
->
not
(
Logic_utils
.
is_trivially_true
p
))
reqs
in
let
local_partition
=
{
p
with
by_addr
=
List
.
filter
local_zone
p
.
by_addr
}
in
let
reqs
=
List
.
sort_uniq
Logic_utils
.
compare_predicate
reqs
in
let
locals
=
addr_of_vars
local_partition
in
reqs
simpl_pred_list
(
List
.
map
(
fun
t
->
term_separated_from_regions
loc
t
locals
)
asgnd_ptrs
)
module
Table
=
module
Table
=
State_builder
.
Hashtbl
State_builder
.
Hashtbl
...
@@ -292,16 +338,18 @@ module Table =
...
@@ -292,16 +338,18 @@ module Table =
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
let
reqs
=
clauses_of_partition
kf
loc
partition
in
let
reqs
,
ens
=
clauses_of_partition
kf
loc
partition
in
let
reqs
=
List
.
map
Logic_const
.
new_predicate
reqs
in
let
ens
=
escaping_formals
kf
loc
partition
@
ens
in
match
reqs
with
let
reqs
=
List
.
map
new_predicate
reqs
in
|
[]
->
None
let
ens
=
List
.
map
(
fun
p
->
Normal
,
new_predicate
p
)
ens
in
|
l1
->
match
reqs
,
ens
with
|
[]
,
[]
->
None
|
reqs
,
ens
->
Some
{
Some
{
b_name
=
name
;
b_name
=
name
;
b_requires
=
l1
;
b_requires
=
reqs
;
b_assumes
=
[]
;
b_assumes
=
[]
;
b_post_cond
=
[]
;
b_post_cond
=
ens
;
b_assigns
=
WritesAny
;
b_assigns
=
WritesAny
;
b_allocation
=
FreeAllocAny
;
b_allocation
=
FreeAllocAny
;
b_extended
=
[]
b_extended
=
[]
...
...
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