Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
C
cwe_checker
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
fact-depend
cwe_checker
Commits
7b6c6f4a
Unverified
Commit
7b6c6f4a
authored
Dec 24, 2021
by
Enkelmann
Committed by
GitHub
Dec 24, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fix handling of default values for fixpoint computations (#273)
parent
9981d746
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
31 additions
and
14 deletions
+31
-14
fixpoint.rs
src/cwe_checker_lib/src/analysis/fixpoint.rs
+28
-11
interprocedural_fixpoint_generic.rs
...cker_lib/src/analysis/interprocedural_fixpoint_generic.rs
+3
-3
No files found.
src/cwe_checker_lib/src/analysis/fixpoint.rs
View file @
7b6c6f4a
...
...
@@ -20,6 +20,7 @@
//!
//! In the current implementation edge transition functions are also allowed to return `None`
//! to indicate that no information flows through the edge.
//! In such a case the value at the target node of the edge will not get updated.
//! For example, an analysis can use this to indicate edges that are never taken
//! and thus prevent dead code to affect the analysis.
//!
...
...
@@ -49,7 +50,7 @@ pub trait Context {
type
NodeLabel
;
/// The type of the value that gets assigned to each node.
/// The values should form a partially ordered set.
type
NodeValue
:
PartialEq
+
Eq
;
type
NodeValue
:
PartialEq
+
Eq
+
Clone
;
/// Get the graph on which the fixpoint computation operates.
fn
get_graph
(
&
self
)
->
&
DiGraph
<
Self
::
NodeLabel
,
Self
::
EdgeLabel
>
;
...
...
@@ -91,8 +92,6 @@ pub struct Computation<T: Context> {
priority_to_node_list
:
Vec
<
NodeIndex
>
,
/// The worklist contains the priority numbers (not the node indices!) of nodes marked as not yet stabilized.
worklist
:
BTreeSet
<
usize
>
,
/// The (optional) default value assigned to nodes without an explicit value.
default_value
:
Option
<
T
::
NodeValue
>
,
/// The internal map containing all known node values.
node_values
:
FnvHashMap
<
NodeIndex
,
T
::
NodeValue
>
,
}
...
...
@@ -126,9 +125,11 @@ impl<T: Context> Computation<T> {
let
node_priority_list
:
Vec
<
usize
>
=
node_to_index
.values
()
.copied
()
.collect
();
let
mut
worklist
=
BTreeSet
::
new
();
// If a default value exists, all nodes are added to the worklist. If not, the worklist is empty
if
default_value
.is_some
()
{
let
mut
node_values
:
FnvHashMap
<
NodeIndex
,
T
::
NodeValue
>
=
FnvHashMap
::
default
();
if
let
Some
(
default
)
=
default_value
{
for
i
in
0
..
priority_sorted_nodes
.len
()
{
worklist
.insert
(
i
);
node_values
.insert
(
NodeIndex
::
new
(
i
),
default
.clone
());
}
}
Computation
{
...
...
@@ -136,8 +137,7 @@ impl<T: Context> Computation<T> {
node_priority_list
,
priority_to_node_list
:
priority_sorted_nodes
,
worklist
,
default_value
,
node_values
:
FnvHashMap
::
default
(),
node_values
,
}
}
...
...
@@ -169,11 +169,7 @@ impl<T: Context> Computation<T> {
/// Get the value of a node.
pub
fn
get_node_value
(
&
self
,
node
:
NodeIndex
)
->
Option
<&
T
::
NodeValue
>
{
if
let
Some
(
value
)
=
self
.node_values
.get
(
&
node
)
{
Some
(
value
)
}
else
{
self
.default_value
.as_ref
()
}
self
.node_values
.get
(
&
node
)
}
/// Set the value of a node and mark the node as not yet stabilized.
...
...
@@ -337,6 +333,27 @@ mod tests {
}
#[test]
fn
fixpoint_with_default_value
()
{
let
mut
graph
:
DiGraph
<
(),
u64
>
=
DiGraph
::
new
();
for
_i
in
0
..
101
{
graph
.add_node
(());
}
for
i
in
0
..
100
{
graph
.add_edge
(
NodeIndex
::
new
(
i
),
NodeIndex
::
new
(
i
+
1
),
i
as
u64
%
10
+
1
);
}
for
i
in
0
..
10
{
graph
.add_edge
(
NodeIndex
::
new
(
i
*
10
),
NodeIndex
::
new
(
i
*
10
+
5
),
0
);
}
let
mut
solution
=
Computation
::
new
(
FPContext
{
graph
},
Some
(
100
));
solution
.set_node_value
(
NodeIndex
::
new
(
10
),
0
);
solution
.compute_with_max_steps
(
20
);
assert_eq!
(
100
,
*
solution
.get_node_value
(
NodeIndex
::
new
(
0
))
.unwrap
());
assert_eq!
(
3
,
*
solution
.get_node_value
(
NodeIndex
::
new
(
12
))
.unwrap
());
}
#[test]
fn
worklist_node_order
()
{
let
mut
graph
:
DiGraph
<
(),
u64
>
=
DiGraph
::
new
();
for
_i
in
0
..
21
{
...
...
src/cwe_checker_lib/src/analysis/interprocedural_fixpoint_generic.rs
View file @
7b6c6f4a
...
...
@@ -14,8 +14,8 @@ use crate::prelude::*;
/// The interprocedural_flow value will either be transferred from the end of the called subroutine
/// to the return site in case of a forward analysis or from the beginning of the called subroutine
/// to the callsite in a backward analysis.
#[derive(PartialEq,
Eq,
Serialize,
Deserialize)]
pub
enum
NodeValue
<
T
:
PartialEq
+
Eq
>
{
#[derive(PartialEq,
Eq,
Serialize,
Deserialize
,
Clone
)]
pub
enum
NodeValue
<
T
:
PartialEq
+
Eq
+
Clone
>
{
/// A single abstract value
Value
(
T
),
/// The value saved at artificial combinator nodes.
...
...
@@ -29,7 +29,7 @@ pub enum NodeValue<T: PartialEq + Eq> {
},
}
impl
<
T
:
PartialEq
+
Eq
>
NodeValue
<
T
>
{
impl
<
T
:
PartialEq
+
Eq
+
Clone
>
NodeValue
<
T
>
{
/// Unwraps the contained value for non-combinator nodes.
/// Panics if given a combinator value of an artificial node.
pub
fn
unwrap_value
(
&
self
)
->
&
T
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment