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
74c9f998
Commit
74c9f998
authored
4 years ago
by
Allan Blanchard
Browse files
Options
Downloads
Patches
Plain Diff
[wp] Improves assigns checking in RefUsage
parent
f534007f
No related branches found
Branches containing commit
No related tags found
Tags containing commit
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
src/plugins/wp/RefUsage.ml
+96
-22
96 additions, 22 deletions
src/plugins/wp/RefUsage.ml
with
96 additions
and
22 deletions
src/plugins/wp/RefUsage.ml
+
96
−
22
View file @
74c9f998
...
@@ -572,6 +572,101 @@ and v_body (env:ctx) = (* locals of the logical function are removed *)
...
@@ -572,6 +572,101 @@ and v_body (env:ctx) = (* locals of the logical function are removed *)
|
LBpred
(
p
)
->
vglob
(
pred
env
p
)
|
LBpred
(
p
)
->
vglob
(
pred
env
p
)
|
LBinductive
(
inds
)
->
E
.
fcup
(
fun
(
_
,_,_,
p
)
->
vglob
(
pred
env
p
))
inds
|
LBinductive
(
inds
)
->
E
.
fcup
(
fun
(
_
,_,_,
p
)
->
vglob
(
pred
env
p
))
inds
(* ---------------------------------------------------------------------- *)
(* --- Assigns checking --- *)
(* ---------------------------------------------------------------------- *)
module
AssignsCompleteness
:
sig
val
check
:
kernel_function
->
unit
end
=
struct
exception
Incomplete_assigns
of
(
string
list
*
string
)
let
dkey_verbose
=
Wp_parameters
.
register_category
"verbose-assigns-warning"
(* Warn on any function without assigns *)
let
wkey_pedantic
=
Wp_parameters
.
register_warn_category
"pedantic-assigns"
let
()
=
Wp_parameters
.
set_warn_status
wkey_pedantic
Log
.
Winactive
let
collect_assigns
kf
=
let
opt_try
f
p
=
function
None
->
f
p
|
Some
x
->
Some
x
in
let
fold_assigns
bhv
=
let
folder
_
a
acc
=
match
a
,
acc
with
|
WritesAny
,
_
->
None
|
_
,
None
->
Some
a
|
_
,
Some
acc
->
Some
(
Logic_utils
.
concat_assigns
acc
a
)
in
Annotations
.
fold_assigns
folder
kf
bhv
None
in
let
find_default
()
=
match
fold_assigns
Cil
.
default_behavior_name
with
|
None
->
if
Wp_parameters
.
has_dkey
dkey_verbose
then
Wp_parameters
.
warning
"No default assigns for '%a'.@ Trying complete behaviors if any."
Kernel_function
.
pretty
kf
;
None
|
Some
x
->
Some
[
x
]
in
let
find_complete
()
=
let
fold_behaviors
names
=
let
folder
l
name
=
match
(
fold_assigns
name
)
with
|
None
->
raise
(
Incomplete_assigns
(
names
,
name
))
|
Some
a
->
a
::
l
in
try
Some
(
List
.
fold_left
folder
[]
names
)
with
Incomplete_assigns
(
bhv_l
,
b
)
->
if
Wp_parameters
.
has_dkey
dkey_verbose
then
Wp_parameters
.
warning
"Complete behaviors: %a.@ No assigns for %s"
(
Pretty_utils
.
pp_list
~
pre
:
"{"
~
last
:
"}"
~
sep
:
", "
Format
.
pp_print_string
)
bhv_l
b
;
None
in
Annotations
.
fold_complete
(
fun
_
->
opt_try
fold_behaviors
)
kf
None
in
(* First:
- try to find default behavior assigns, if we cannot get it
- try to find a "complete behaviors" set where each behavior has assigns
As assigns and froms are over-approximations, the result (if it exists)
must cover all assigned memory locations and all data dependencies.
*)
opt_try
find_complete
()
(
opt_try
find_default
()
None
)
let
check_assigns
kf
assigns
=
let
vassigns
a
=
let
res_t
=
Kernel_function
.
get_return_type
kf
in
let
assigns_result
({
it_content
=
t
}
,
_
)
=
Logic_utils
.
is_result
t
in
let
froms
=
match
a
with
WritesAny
->
[]
|
Writes
l
->
l
in
if
Cil
.
isPointerType
res_t
&&
not
(
List
.
exists
assigns_result
froms
)
then
Wp_parameters
.
warning
~
once
:
true
~
source
:
(
fst
(
Kernel_function
.
get_location
kf
))
"No 'assigns
\\
result
\\
from ...' specification for function '%a', \
returning pointer type.@ Callers assumptions might be imprecise."
Kernel_function
.
pretty
kf
;
let
vfrom
=
function
|
t
,
FromAny
when
Logic_typing
.
is_pointer_type
t
.
it_content
.
term_type
->
Wp_parameters
.
warning
~
once
:
true
~
source
:
(
fst
t
.
it_content
.
term_loc
)
"No
\\
from specification for assigned pointer '%a'.@ \
Callers assumptions might be imprecise."
Cil_printer
.
pp_identified_term
t
|
_
->
()
in
List
.
iter
vfrom
froms
in
match
assigns
with
|
None
->
Wp_parameters
.
warning
~
wkey
:
wkey_pedantic
~
once
:
true
~
source
:
(
fst
(
Kernel_function
.
get_location
kf
))
"No 'assigns' specification for function '%a'.@ \
Callers assumptions might be imprecise."
Kernel_function
.
pretty
kf
|
Some
l
->
List
.
iter
vassigns
l
let
check
kf
=
check_assigns
kf
(
collect_assigns
kf
)
end
(* ---------------------------------------------------------------------- *)
(* ---------------------------------------------------------------------- *)
(* --- Compilation of C Function --- *)
(* --- Compilation of C Function --- *)
(* ---------------------------------------------------------------------- *)
(* ---------------------------------------------------------------------- *)
...
@@ -668,33 +763,12 @@ let cfun_spec env kf =
...
@@ -668,33 +763,12 @@ let cfun_spec env kf =
let
update_spec_env
v
=
env
.
local
.
spec
<-
E
.
cup
env
.
local
.
spec
v
;
let
update_spec_env
v
=
env
.
local
.
spec
<-
E
.
cup
env
.
local
.
spec
v
;
Cil
.
SkipChildren
Cil
.
SkipChildren
in
in
let
res_type
=
Kernel_function
.
get_return_type
kf
in
let
is_from_result
({
it_content
=
t
}
,
_
)
=
Logic_utils
.
is_result
t
in
let
visitor
=
object
let
visitor
=
object
inherit
Cil
.
nopCilVisitor
inherit
Cil
.
nopCilVisitor
method
!
vpredicate
p
=
update_spec_env
(
pred
env
p
)
method
!
vpredicate
p
=
update_spec_env
(
pred
env
p
)
method
!
vterm
t
=
update_spec_env
(
vterm
env
t
)
method
!
vterm
t
=
update_spec_env
(
vterm
env
t
)
method
!
vassigns
=
function
|
WritesAny
->
Cil
.
SkipChildren
|
Writes
l
when
Cil
.
isPointerType
res_type
&&
not
(
List
.
exists
is_from_result
l
)
->
Wp_parameters
.
warning
~
once
:
true
"No 'assigns
\\
result
\\
from ...' specification for function '%a', \
returning pointer type.@ Callers assumptions might be imprecise."
Kernel_function
.
pretty
kf
;
Cil
.
DoChildren
|
_
->
Cil
.
DoChildren
method
!
vfrom
=
function
|
it
,
FromAny
when
Logic_typing
.
is_pointer_type
it
.
it_content
.
term_type
->
Wp_parameters
.
warning
~
once
:
true
"No
\\
from specification for assigned pointer '%a'.@ \
Callers assumptions might be imprecise."
Cil_printer
.
pp_identified_term
it
;
Cil
.
DoChildren
|
_
->
Cil
.
DoChildren
end
in
end
in
AssignsCompleteness
.
check
kf
;
let
spec
=
Annotations
.
funspec
kf
in
let
spec
=
Annotations
.
funspec
kf
in
ignore
(
Cil
.
visitCilFunspec
(
visitor
:>
Cil
.
cilVisitor
)
spec
)
;
ignore
(
Cil
.
visitCilFunspec
(
visitor
:>
Cil
.
cilVisitor
)
spec
)
;
(* Partitioning the accesses of the spec for formals vs globals *)
(* Partitioning the accesses of the spec for formals vs globals *)
...
...
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