Class ArrayBoundsGraph
As it is written The paper describes, that the distance is equal to the shortest hyper path. But what if we don't know anything about a variable (i.e. it is returned by a method)? There will be no path at all, the distance should be unlimited.
Initializing all nodes with -infinity instead of infinity, seems to work at first glance, as we also have hyper edges with more than one source, which cause the maximum to be propagated instead of minimum. However, this will not work, as loops will not get updated properly.
We need to make sure, that only nodes, which are not connected to the source of shortest path computation are set to infinity. To do so, it is enough to set nodes, which don't have a predecessor to infinity. (Nodes in cycles will always have an ancestor, which is not part of the cycle. So all nodes are either connected to the source, or a node with no predecessor.)
In this implementation this is done, by adding an infinity node and connect all lose ends to
it (see ArrayBoundsGraphBuilder.bundleDeadEnds(ArrayBoundsGraph)
). Note, that array
length and the zero node are dead ends, if they are not the source of a shortest path
computation. To prevent changing the inequality graph, depending on which source is used, a kind
of trap door construct is used (See createSourceVar(Integer)
).
There are some variations, but these are minor changes to improve results:
- handling of constants (see
addConstant(Integer, Integer)
) - pi nodes (see
addPhi(Integer)
) - array length nodes (see
arrayLength
)
- Author:
- Stephan Gocht
<stephan@gobro.de>
-
Field Summary
-
Constructor Summary
-
Method Summary
Modifier and TypeMethodDescriptionvoid
addAdditionEdge
(Integer src, Integer dst, Integer value) void
void
addConstant
(Integer variable, Integer value) Add variable as constant with value value.void
void
void
void
createSourceVar
(Integer var) Adds var as source var.getArrayNode
(Integer array) getPhis()
getVariableWeight
(Integer variable) void
markAsArrayAccess
(Integer array, Integer index) void
markAsArrayLength
(Integer array, Integer variable) Mark variable as length for array.void
markAsDeadEnd
(Integer variable) void
void
reset()
Resets the weight of all nodes.Methods inherited from class com.ibm.wala.analysis.arraybounds.hypergraph.DirectedHyperGraph
getEdges, getNodes, toString, updateNodeEdges
-
Field Details
-
ZERO
We need a ssa variable representing zero. So we just use an integer, which is never produced by ssa generation -
ZERO_HELPER
-
UNLIMITED
We need a ssa variable representing unlimited (values we don't know anything about). So we just use an integer, which is never produced by ssa generation
-
-
Constructor Details
-
ArrayBoundsGraph
public ArrayBoundsGraph()
-
-
Method Details
-
postProcessConstants
public void postProcessConstants() -
addAdditionEdge
-
addArray
-
addConstant
Add variable as constant with value value.This will create the following construct: [zero] -(value)-> [h1] -0- > [variable] -(-value)-> [h2] -0-> [zero].
The bidirectional linking, allows things like
int[] a = new int[2](); a[0] = 1;
to work properly. h1, h2 are helper nodes: [zero] and [variable] may have other predecessors, this will cause their in edges to be merged to a single hyper edge with weight zero. The helper nodes are inserted to keep the proper distance from [zero]. -
addEdge
-
addNode
-
addPhi
-
addPi
-
createSourceVar
Adds var as source var. A source var is a variable, which can be used as source for shortest path computation.This will create the following construct: [unlimited] -> [var] -> [var] -(unlimited)-> [unlimited]
This is a trap door construct: if [var] is not set to 0 it will get the value unlimited, if [var] is set to 0 it will stay 0.
-
generateNewVar
-
getArrayAccess
-
getArrayLength
-
getArrayNode
-
getPhis
-
markAsArrayAccess
-
markAsArrayLength
-
markAsDeadEnd
-
getVariableWeight
-
reset
public void reset()Description copied from class:DirectedHyperGraph
Resets the weight of all nodes.- Overrides:
reset
in classDirectedHyperGraph<Integer>
-