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
0bc431da
"src/plugins/e-acsl/dup_functions.ml" did not exist on "99f261fe1c42f75ebb5d4067189aa71d031ad9a0"
Commit
0bc431da
authored
5 years ago
by
Allan Blanchard
Committed by
Virgile Prevosto
5 years ago
Browse files
Options
Downloads
Patches
Plain Diff
[ghost] Ghost CFG, no more references
parent
2b0e4954
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/kernel_internals/typing/ghost_cfg.ml
+70
-69
70 additions, 69 deletions
src/kernel_internals/typing/ghost_cfg.ml
with
70 additions
and
69 deletions
src/kernel_internals/typing/ghost_cfg.ml
+
70
−
69
View file @
0bc431da
...
@@ -54,89 +54,88 @@ let noGhostBlock b =
...
@@ -54,89 +54,88 @@ let noGhostBlock b =
end
in
end
in
(
visitCilBlock
(
noGhostVisitor
:>
cilVisitor
)
b
)
,
(
noGhostVisitor
#
getBehavior
()
)
(
visitCilBlock
(
noGhostVisitor
:>
cilVisitor
)
b
)
,
(
noGhostVisitor
#
getBehavior
()
)
let
isSkip
stmt
=
match
stmt
.
skind
with
(* We ignore blocks: their successors are their 1st stmt so we visit them *)
|
Instr
(
Skip
(
_
))
|
Block
(
_
)
|
Continue
(
_
)
|
Break
(
_
)
->
true
|
_
->
false
type
follower
=
type
follower
=
(* For a stmt, an "Infinite" follower means that following skip instructions
(* For a stmt, an "Infinite" follower means that following skip instructions
we just go back to this stmt. *)
we just go back to this stmt. *)
|
Infinite
|
Exit
|
Stmt
of
stmt
|
Infinite
|
Exit
|
Stmt
of
stmt
let
rec
skipSkip
?
(
visited
=
StmtSet
.
empty
)
s
=
let
sync
stmt
=
if
StmtSet
.
mem
s
visited
then
Infinite
match
stmt
.
skind
with
else
match
isSkip
s
with
(* We ignore blocks: their successors are their 1st stmt so we visit them *)
|
false
->
Stmt
s
|
Instr
(
Skip
(
_
))
|
Block
(
_
)
|
Continue
(
_
)
|
Break
(
_
)
->
false
|
true
when
s
.
succs
=
[]
->
Exit
|
_
->
true
|
_
->
skipSkip
~
visited
:
(
StmtSet
.
add
s
visited
)
(
Extlib
.
as_singleton
s
.
succs
)
let
nextSync
stmt
=
let
rec
aux
visited
s
=
let
firstNonSkipNonGhosts
stmt
=
if
StmtSet
.
mem
s
visited
then
Infinite
let
rec
do_find
~
visited
stmt
=
else
match
sync
s
with
if
List
.
mem
stmt
!
visited
then
[]
|
true
->
Stmt
s
|
false
when
s
.
succs
=
[]
->
Exit
|
_
->
aux
(
StmtSet
.
add
s
visited
)
(
Extlib
.
as_singleton
s
.
succs
)
in
aux
StmtSet
.
empty
stmt
let
nextNonGhostSync
stmt
=
let
rec
do_find
(
res
,
visited
)
stmt
=
if
StmtSet
.
mem
stmt
visited
then
res
,
visited
else
begin
else
begin
visited
:=
stmt
::
!
visited
;
let
visited
=
StmtSet
.
add
stmt
visited
in
if
isSkip
stmt
then
do_find
~
visited
(
Extlib
.
as_singleton
stmt
.
succs
)
if
not
(
sync
stmt
)
then
else
if
not
(
stmt
.
ghost
)
then
[
stmt
]
do_find
(
res
,
visited
)
(
Extlib
.
as_singleton
stmt
.
succs
)
else
List
.
flatten
(
List
.
map
(
do_find
~
visited
)
stmt
.
succs
)
else
if
not
(
stmt
.
ghost
)
then
StmtSet
.
add
stmt
res
,
visited
else
List
.
fold_left
do_find
(
res
,
visited
)
stmt
.
succs
end
end
in
in
do_find
~
visited
:
(
ref
[]
)
stmt
fst
(
do_find
(
StmtSet
.
empty
,
StmtSet
.
empty
)
stmt
)
let
alteredCFG
stmt
=
let
alteredCFG
stmt
=
error
~
source
:
(
fst
(
Stmt
.
loc
stmt
))
"Ghost code breaks CFG starting at:@.%a"
error
~
source
:
(
fst
(
Stmt
.
loc
stmt
))
"Ghost code breaks CFG starting at:@.%a"
Cil_printer
.
pp_stmt
stmt
Cil_printer
.
pp_stmt
stmt
let
rec
checkGhostCFG
bhv
?
(
visited
=
ref
StmtSet
.
empty
)
withGhostStart
noGhost
=
let
checkGhostCFG
bhv
withGhostStart
noGhost
=
match
(
skipSkip
withGhostStart
)
,
(
skipSkip
noGhost
)
with
let
rec
do_check
visited
withGhostStart
noGhostStart
=
|
Stmt
withGhost
,
Stmt
noGhost
->
begin
match
(
nextSync
withGhostStart
)
,
(
nextSync
noGhostStart
)
with
if
StmtSet
.
mem
withGhost
!
visited
then
()
|
Stmt
withGhost
,
Stmt
_
when
StmtSet
.
mem
withGhost
visited
->
visited
else
begin
|
Stmt
withGhost
,
Stmt
noGhost
->
visited
:=
StmtSet
.
add
withGhost
!
visited
;
let
visited
=
StmtSet
.
add
withGhost
visited
in
let
withGhost
=
List
.
sort_uniq
Stmt
.
compare
(
firstNonSkipNonGhosts
withGhost
)
in
let
withGhost
=
match
withGhost
,
noGhost
with
StmtSet
.
contains_single_elt
(
nextNonGhostSync
withGhost
)
|
[
s1
]
,
s2
when
not
(
Stmt
.
equal
s1
(
Get_orig
.
stmt
bhv
s2
))
->
in
alteredCFG
withGhostStart
begin
match
withGhost
,
noGhost
with
|
[
{
skind
=
If
(
_
)
}
as
s1
]
,
s2
->
|
Some
s1
,
s2
when
not
(
Stmt
.
equal
s1
(
Get_orig
.
stmt
bhv
s2
))
->
checkIf
bhv
~
visited
s1
s2
alteredCFG
withGhostStart
;
visited
|
[
{
skind
=
Switch
(
_
)
}
as
s1
]
,
s2
->
checkSwitch
bhv
~
visited
s1
s2
|
Some
({
skind
=
If
(
_
)
}
as
withGhost
)
,
noGhost
->
|
[
{
skind
=
Loop
(
_
)
}
as
s1
]
,
s2
->
let
wgThen
,
wgElse
=
Cil
.
separate_if_succs
withGhost
in
checkLoop
bhv
~
visited
s1
s2
let
ngThen
,
ngElse
=
Cil
.
separate_if_succs
noGhost
in
|
[
{
succs
=
[
next_s1
]
}
]
,
{
succs
=
[
next_s2
]
}
->
let
visited
=
do_check
visited
wgThen
ngThen
in
checkGhostCFG
bhv
~
visited
next_s1
next_s2
do_check
visited
wgElse
ngElse
|
[
{
succs
=
[]
}
]
,
{
succs
=
[]
}
->
()
|
_
,
_
->
|
Some
({
skind
=
Switch
(
_
)
}
as
withGhost
)
,
noGhost
->
alteredCFG
withGhostStart
let
ngSuccs
,
ngDef
=
Cil
.
separate_switch_succs
noGhost
in
let
wgAllSuccs
,
wgDef
=
Cil
.
separate_switch_succs
withGhost
in
let
wgSuccsG
,
wgSuccsNG
=
List
.
partition
(
fun
s
->
s
.
ghost
)
wgAllSuccs
in
let
mustDefault
=
wgDef
::
wgSuccsG
in
assert
(
List
.
length
ngSuccs
=
List
.
length
wgSuccsNG
)
;
let
visited
=
List
.
fold_left2
do_check
visited
wgSuccsNG
ngSuccs
in
List
.
fold_left
(
fun
v
s
->
do_check
v
s
ngDef
)
visited
mustDefault
|
Some
({
skind
=
Loop
(
_
,
wgb
,_,_,_
)
})
,
{
skind
=
Loop
(
_
,
ngb
,_,_,_
)
}
->
begin
match
wgb
.
bstmts
,
ngb
.
bstmts
with
|
s1
::
_
,
s2
::
_
->
do_check
visited
s1
s2
|
_
,
_
->
visited
end
|
Some
{
succs
=
[
wg
]
}
,
{
succs
=
[
ng
]
}
->
do_check
visited
wg
ng
|
Some
{
succs
=
[]
}
,
{
succs
=
[]
}
->
visited
|
_
,
_
->
alteredCFG
withGhostStart
;
visited
end
end
end
;
|
Exit
,
Exit
|
Infinite
,
Infinite
->
visited
|
Exit
,
Exit
|
Infinite
,
Infinite
->
()
|
_
,
_
->
alteredCFG
withGhostStart
;
visited
|
_
,
_
->
alteredCFG
withGhostStart
and
checkIf
bhv
~
visited
withGhost
noGhost
=
let
withGhostThen
,
withGhostElse
=
Cil
.
separate_if_succs
withGhost
in
let
noGhostThen
,
noGhostElse
=
Cil
.
separate_if_succs
noGhost
in
checkGhostCFG
bhv
~
visited
withGhostThen
noGhostThen
;
checkGhostCFG
bhv
~
visited
withGhostElse
noGhostElse
and
checkLoop
bhv
~
visited
withGhost
noGhost
=
let
withGhostBlock
,
noGhostBlock
=
match
withGhost
.
skind
,
noGhost
.
skind
with
|
Loop
(
_
,
b1
,
_
,
_
,
_
)
,
Loop
(
_
,
b2
,
_
,
_
,
_
)
->
b1
,
b2
|
_
->
assert
false
in
match
withGhostBlock
.
bstmts
,
noGhostBlock
.
bstmts
with
|
s1
::
_
,
s2
::
_
->
checkGhostCFG
bhv
~
visited
s1
s2
|
_
,
_
->
()
and
checkSwitch
bhv
~
visited
withGhost
noGhost
=
let
noGhostSuccs
,
noGhostDef
=
Cil
.
separate_switch_succs
noGhost
in
let
withGhostAllSuccs
,
withGhostDef
=
Cil
.
separate_switch_succs
withGhost
in
let
withGhostSuccsGhost
,
withGhostSuccsNonGhost
=
List
.
partition
(
fun
s
->
s
.
ghost
)
withGhostAllSuccs
in
in
let
mustDefault
=
withGhostDef
::
withGhostSuccsGhost
in
ignore
(
do_check
StmtSet
.
empty
withGhostStart
noGhost
)
assert
(
List
.
length
noGhostSuccs
=
List
.
length
withGhostSuccsNonGhost
)
;
List
.
iter2
(
checkGhostCFG
bhv
~
visited
)
withGhostSuccsNonGhost
noGhostSuccs
;
List
.
iter
(
fun
s
->
checkGhostCFG
bhv
~
visited
s
noGhostDef
)
mustDefault
let
checkGhostCFGInFun
(
fd
:
fundec
)
=
let
checkGhostCFGInFun
(
fd
:
fundec
)
=
if
fd
.
svar
.
vghost
then
()
if
fd
.
svar
.
vghost
then
()
...
@@ -155,7 +154,9 @@ let checkGhostCFGInFun (fd : fundec) =
...
@@ -155,7 +154,9 @@ let checkGhostCFGInFun (fd : fundec) =
end
end
let
checkGhostCFGInFile
(
f
:
file
)
=
let
checkGhostCFGInFile
(
f
:
file
)
=
Cil
.
iterGlobals
f
(
function
GFun
(
fd
,_
)
->
checkGhostCFGInFun
fd
|
_
->
()
)
Cil
.
iterGlobals
f
(
function
|
GFun
(
fd
,
_
)
->
checkGhostCFGInFun
fd
|
_
->
()
)
let
transform_category
=
let
transform_category
=
File
.
register_code_transformation_category
"Ghost CFG checking"
File
.
register_code_transformation_category
"Ghost CFG checking"
...
...
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