Package it.unive.lisa.program.cfg
Class CFG
- java.lang.Object
-
- it.unive.lisa.util.datastructures.graph.Graph<CFG,Statement,Edge>
-
- it.unive.lisa.program.cfg.CFG
-
- All Implemented Interfaces:
CodeMember
- Direct Known Subclasses:
CFGWithAnalysisResults
public class CFG extends Graph<CFG,Statement,Edge> implements CodeMember
-
-
Field Summary
-
Fields inherited from class it.unive.lisa.util.datastructures.graph.Graph
adjacencyMatrix, entrypoints
-
-
Constructor Summary
Constructors Modifier Constructor Description protectedCFG(CFG other)Clones the given control flow graph.CFG(CFGDescriptor descriptor)Builds the control flow graph.CFG(CFGDescriptor descriptor, java.util.Collection<Statement> entrypoints, AdjacencyMatrix<Statement,Edge,CFG> adjacencyMatrix)Builds the control flow graph.
-
Method Summary
All Methods Instance Methods Concrete Methods Modifier and Type Method Description voidaddControlFlowStructure(ControlFlowStructure cf)Adds the givenControlFlowStructureto the ones contained in this cfg.<A extends AbstractState<A,H,V>,H extends HeapDomain<H>,V extends ValueDomain<V>>
CFGWithAnalysisResults<A,H,V>fixpoint(AnalysisState<A,H,V> entryState, InterproceduralAnalysis<A,H,V> interprocedural, WorkingSet<Statement> ws, int widenAfter)Computes a fixpoint over this control flow graph.<A extends AbstractState<A,H,V>,H extends HeapDomain<H>,V extends ValueDomain<V>>
CFGWithAnalysisResults<A,H,V>fixpoint(AnalysisState<A,H,V> singleton, java.util.Map<Statement,AnalysisState<A,H,V>> startingPoints, InterproceduralAnalysis<A,H,V> interprocedural, WorkingSet<Statement> ws, int widenAfter)Computes a fixpoint over this control flow graph.<A extends AbstractState<A,H,V>,H extends HeapDomain<H>,V extends ValueDomain<V>>
CFGWithAnalysisResults<A,H,V>fixpoint(java.util.Collection<Statement> entrypoints, AnalysisState<A,H,V> entryState, InterproceduralAnalysis<A,H,V> interprocedural, WorkingSet<Statement> ws, int widenAfter)Computes a fixpoint over this control flow graph.java.util.Collection<Statement>getAllExitpoints()Yields the statements of this control flow graph that are normal exitpoints, that is, that normally ends the execution of this cfg, returning the control to the caller, or throwing an error (i.e., all such statements on which eitherStatement.stopsExecution()orStatement.throwsError()hold).java.util.Collection<ControlFlowStructure>getControlFlowStructures()Yields the collection ofControlFlowStructures contained in this cfg.
Note that if no control flow structures have been provided by frontends, and no attempt at extracting them has been made yet, invoking this method will cause aControlFlowExtractorto try to extract them.CFGDescriptorgetDescriptor()Yields the name of this control flow graph.ProgramPointgetGenericProgramPoint()Yields a genericProgramPointhappening inside this cfg.java.util.Collection<Statement>getGuards(ProgramPoint pp)Yields the guard of all theControlFlowStructures, regardless of their type, containing the given program point.java.util.Collection<Statement>getIfThenElseGuards(ProgramPoint pp)Yields the guard of all theIfThenElsecontaining the given program point.java.util.Collection<Statement>getLoopGuards(ProgramPoint pp)Yields the guard of allLoops containing the given program point.StatementgetMostRecentGuard(ProgramPoint pp)Yields the guard of the most recentControlFlowStructure, regardless of its type, containing the given program point.StatementgetMostRecentIfThenElseGuard(ProgramPoint pp)Yields the guard of the most recentIfThenElsecontaining the given program point.StatementgetMostRecentLoopGuard(ProgramPoint pp)Yields the guard of the most recentLoopcontaining the given program point.java.util.Collection<Statement>getNormalExitpoints()Yields the statements of this control flow graph that are normal exitpoints, that is, that normally ends the execution of this cfg, returning the control to the caller without throwing an error (i.e., all such statements on whichStatement.stopsExecution()holds butStatement.throwsError()does not).booleanisGuarded(ProgramPoint pp)Yieldstrueif and only if the given program point is inside the body of aControlFlowStructure, regardless of its type.
Note that if no control flow structures have been provided by frontends, and no attempt at extracting them has been made yet, invoking this method will cause aControlFlowExtractorto try to extract them.booleanisInsideIfThenElse(ProgramPoint pp)Yieldstrueif and only if the given program point is inside one of the branches of anIfThenElse.
Note that if no control flow structures have been provided by frontends, and no attempt at extracting them has been made yet, invoking this method will cause aControlFlowExtractorto try to extract them.booleanisInsideLoop(ProgramPoint pp)Yieldstrueif and only if the given program point is inside the body of aLoop.
Note that if no control flow structures have been provided by frontends, and no attempt at extracting them has been made yet, invoking this method will cause aControlFlowExtractorto try to extract them.protected voidpreSimplify(Statement node)Callback that is invoked on a node before simplifying it.voidsimplify()Simplifies this cfg, removing allNoOps and rewriting the edge set accordingly.protected DotCFGtoDot(java.util.function.Function<Statement,java.lang.String> labelGenerator)Converts this graph to aDotGraphinstance.java.lang.StringtoString()voidvalidate()Validates this cfg, ensuring that the code contained in it is well formed.-
Methods inherited from class it.unive.lisa.util.datastructures.graph.Graph
accept, addEdge, addNode, addNode, dump, dump, followersOf, getAdjacencyMatrix, getEdgeConnecting, getEdges, getEdgesCount, getEntrypoints, getIngoingEdges, getNodes, getNodesCount, getOutgoingEdges, isEqualTo, predecessorsOf, simplify
-
-
-
-
Constructor Detail
-
CFG
public CFG(CFGDescriptor descriptor)
Builds the control flow graph.- Parameters:
descriptor- the descriptor of this cfg
-
CFG
public CFG(CFGDescriptor descriptor, java.util.Collection<Statement> entrypoints, AdjacencyMatrix<Statement,Edge,CFG> adjacencyMatrix)
Builds the control flow graph.- Parameters:
descriptor- the descriptor of this cfgentrypoints- the statements of this cfg that will be reachable from other cfgsadjacencyMatrix- the matrix containing all the statements and the edges that will be part of this cfg
-
CFG
protected CFG(CFG other)
Clones the given control flow graph.- Parameters:
other- the original cfg
-
-
Method Detail
-
getDescriptor
public final CFGDescriptor getDescriptor()
Yields the name of this control flow graph.- Specified by:
getDescriptorin interfaceCodeMember- Returns:
- the name
-
getNormalExitpoints
public final java.util.Collection<Statement> getNormalExitpoints()
Yields the statements of this control flow graph that are normal exitpoints, that is, that normally ends the execution of this cfg, returning the control to the caller without throwing an error (i.e., all such statements on whichStatement.stopsExecution()holds butStatement.throwsError()does not).- Returns:
- the normal exitpoints of this cfg.
-
getAllExitpoints
public final java.util.Collection<Statement> getAllExitpoints()
Yields the statements of this control flow graph that are normal exitpoints, that is, that normally ends the execution of this cfg, returning the control to the caller, or throwing an error (i.e., all such statements on which eitherStatement.stopsExecution()orStatement.throwsError()hold).- Returns:
- the exitpoints of this cfg.
-
addControlFlowStructure
public final void addControlFlowStructure(ControlFlowStructure cf)
Adds the givenControlFlowStructureto the ones contained in this cfg.- Parameters:
cf- the control flow structure to add- Throws:
java.lang.IllegalArgumentException- if a control flow structure for the same condition already exists
-
getControlFlowStructures
public java.util.Collection<ControlFlowStructure> getControlFlowStructures()
Yields the collection ofControlFlowStructures contained in this cfg.
Note that if no control flow structures have been provided by frontends, and no attempt at extracting them has been made yet, invoking this method will cause aControlFlowExtractorto try to extract them.- Returns:
- the collection, either provided by frontends or extracted, of the control flow structures of this method
-
toString
public java.lang.String toString()
-
simplify
public void simplify()
Simplifies this cfg, removing allNoOps and rewriting the edge set accordingly. This method will throw anUnsupportedOperationExceptionif one of theNoOps has an outgoing edge that is not aSequentialEdge, since such statement is expected to always be sequential.- Throws:
java.lang.UnsupportedOperationException- if there exists at least oneNoOpwith an outgoing non-sequential edge.
-
fixpoint
public final <A extends AbstractState<A,H,V>,H extends HeapDomain<H>,V extends ValueDomain<V>> CFGWithAnalysisResults<A,H,V> fixpoint(AnalysisState<A,H,V> entryState, InterproceduralAnalysis<A,H,V> interprocedural, WorkingSet<Statement> ws, int widenAfter) throws FixpointException
Computes a fixpoint over this control flow graph. This method returns aCFGWithAnalysisResultsinstance mapping eachStatementto theAnalysisStatecomputed by this method. The computation usesLattice.lub(Lattice)to compose results obtained at different iterations, up towidenAfter * predecessors_numbertimes, wherepredecessors_numberis the number of expressions that are predecessors of the one being processed. After overcoming that threshold,Lattice.widening(Lattice)is used. The computation starts at the statements returned byGraph.getEntrypoints(), usingentryStateas entry state for all of them.interproceduralwill be invoked to get the approximation of all invoked cfgs, whilewsis used as working set for the statements to process.- Type Parameters:
A- the type ofAbstractStatecontained into the analysis stateH- the type ofHeapDomaincontained into the computed abstract stateV- the type ofValueDomaincontained into the computed abstract state- Parameters:
entryState- the entry states to apply to eachStatementreturned byGraph.getEntrypoints()interprocedural- the interprocedural analysis that can be queried when a call towards an other cfg is encounteredws- theWorkingSetinstance to use for this computationwidenAfter- the number of times after which theLattice.lub(Lattice)invocation gets replaced by theLattice.widening(Lattice)call. Use0to always useLattice.lub(Lattice)- Returns:
- a
CFGWithAnalysisResultsinstance that is equivalent to this control flow graph, and that stores for eachStatementthe result of the fixpoint computation - Throws:
FixpointException- if an error occurs during the semantic computation of a statement, or if some unknown/invalid statement ends up in the working set
-
fixpoint
public final <A extends AbstractState<A,H,V>,H extends HeapDomain<H>,V extends ValueDomain<V>> CFGWithAnalysisResults<A,H,V> fixpoint(java.util.Collection<Statement> entrypoints, AnalysisState<A,H,V> entryState, InterproceduralAnalysis<A,H,V> interprocedural, WorkingSet<Statement> ws, int widenAfter) throws FixpointException
Computes a fixpoint over this control flow graph. This method returns aCFGWithAnalysisResultsinstance mapping eachStatementto theAnalysisStatecomputed by this method. The computation usesLattice.lub(Lattice)to compose results obtained at different iterations, up towidenAfter * predecessors_numbertimes, wherepredecessors_numberis the number of expressions that are predecessors of the one being processed. After overcoming that threshold,Lattice.widening(Lattice)is used. The computation starts at the statements inentrypoints, usingentryStateas entry state for all of them.interproceduralwill be invoked to get the approximation of all invoked cfgs, whilewsis used as working set for the statements to process.- Type Parameters:
A- the type ofAbstractStatecontained into the analysis stateH- the type ofHeapDomaincontained into the computed abstract stateV- the type ofValueDomaincontained into the computed abstract state- Parameters:
entrypoints- the collection ofStatements that to use as a starting point of the computation (that must be nodes of this cfg)entryState- the entry states to apply to eachStatementinentrypointsinterprocedural- the callgraph that can be queried when a call towards an other cfg is encounteredws- theWorkingSetinstance to use for this computationwidenAfter- the number of times after which theLattice.lub(Lattice)invocation gets replaced by theLattice.widening(Lattice)call. Use0to always useLattice.lub(Lattice)- Returns:
- a
CFGWithAnalysisResultsinstance that is equivalent to this control flow graph, and that stores for eachStatementthe result of the fixpoint computation - Throws:
FixpointException- if an error occurs during the semantic computation of a statement, or if some unknown/invalid statement ends up in the working set
-
fixpoint
public final <A extends AbstractState<A,H,V>,H extends HeapDomain<H>,V extends ValueDomain<V>> CFGWithAnalysisResults<A,H,V> fixpoint(AnalysisState<A,H,V> singleton, java.util.Map<Statement,AnalysisState<A,H,V>> startingPoints, InterproceduralAnalysis<A,H,V> interprocedural, WorkingSet<Statement> ws, int widenAfter) throws FixpointException
Computes a fixpoint over this control flow graph. This method returns aCFGWithAnalysisResultsinstance mapping eachStatementto theAnalysisStatecomputed by this method. The computation usesLattice.lub(Lattice)to compose results obtained at different iterations, up towidenAfter * predecessors_numbertimes, wherepredecessors_numberis the number of expressions that are predecessors of the one being processed. After overcoming that threshold,Lattice.widening(Lattice)is used. The computation starts at the statements instartingPoints, using as its entry state their respective value.interproceduralwill be invoked to get the approximation of all invoked cfgs, whilewsis used as working set for the statements to process.- Type Parameters:
A- the type ofAbstractStatecontained into the analysis stateH- the type ofHeapDomaincontained into the computed abstract stateV- the type ofValueDomaincontained into the computed abstract state- Parameters:
singleton- an instance of theAnalysisStatecontaining the abstract state of the analysis to run, used to retrieve top and bottom valuesstartingPoints- a map betweenStatements that to use as a starting point of the computation (that must be nodes of this cfg) and the entry states to apply on itinterprocedural- the callgraph that can be queried when a call towards an other cfg is encounteredws- theWorkingSetinstance to use for this computationwidenAfter- the number of times after which theLattice.lub(Lattice)invocation gets replaced by theLattice.widening(Lattice)call. Use0to always useLattice.lub(Lattice)- Returns:
- a
CFGWithAnalysisResultsinstance that is equivalent to this control flow graph, and that stores for eachStatementthe result of the fixpoint computation - Throws:
FixpointException- if an error occurs during the semantic computation of a statement, or if some unknown/invalid statement ends up in the working set
-
toDot
protected DotCFG toDot(java.util.function.Function<Statement,java.lang.String> labelGenerator)
Description copied from class:GraphConverts this graph to aDotGraphinstance.
-
preSimplify
protected void preSimplify(Statement node)
Description copied from class:GraphCallback that is invoked on a node before simplifying it.- Overrides:
preSimplifyin classGraph<CFG,Statement,Edge>- Parameters:
node- the node about to be simplified
-
getGenericProgramPoint
public ProgramPoint getGenericProgramPoint()
Yields a genericProgramPointhappening inside this cfg. A generic program point can be used for semantic evaluations of instrumentedStatements, that are not tied to any concrete statement.- Returns:
- a generic program point happening in this cfg
-
validate
public void validate() throws ProgramValidationExceptionValidates this cfg, ensuring that the code contained in it is well formed. This method checks that:- the underlying adjacency matrix is valid, through
AdjacencyMatrix.validate(Collection) - all
ControlFlowStructures of this cfg contains node effectively in the cfg - all
Statements that stop the execution (according toStatement.stopsExecution()) do not have outgoing edges - all entrypoints are effectively part of this cfg
- Throws:
ProgramValidationException- if one of the aforementioned checks fail
- the underlying adjacency matrix is valid, through
-
isGuarded
public boolean isGuarded(ProgramPoint pp)
Yieldstrueif and only if the given program point is inside the body of aControlFlowStructure, regardless of its type.
Note that if no control flow structures have been provided by frontends, and no attempt at extracting them has been made yet, invoking this method will cause aControlFlowExtractorto try to extract them.- Parameters:
pp- the program point- Returns:
trueifppis inside a control flow structure
-
isInsideLoop
public boolean isInsideLoop(ProgramPoint pp)
Yieldstrueif and only if the given program point is inside the body of aLoop.
Note that if no control flow structures have been provided by frontends, and no attempt at extracting them has been made yet, invoking this method will cause aControlFlowExtractorto try to extract them.- Parameters:
pp- the program point- Returns:
trueifppis inside a loop
-
isInsideIfThenElse
public boolean isInsideIfThenElse(ProgramPoint pp)
Yieldstrueif and only if the given program point is inside one of the branches of anIfThenElse.
Note that if no control flow structures have been provided by frontends, and no attempt at extracting them has been made yet, invoking this method will cause aControlFlowExtractorto try to extract them.- Parameters:
pp- the program point- Returns:
trueifppis inside an if-then-else
-
getGuards
public java.util.Collection<Statement> getGuards(ProgramPoint pp)
Yields the guard of all theControlFlowStructures, regardless of their type, containing the given program point. If the program point is not part of the body of a control structure, this method returns an empty collection.
Note that if no control flow structures have been provided by frontends, and no attempt at extracting them has been made yet, invoking this method will cause aControlFlowExtractorto try to extract them.- Parameters:
pp- the program point- Returns:
- the collection of the guards of all structures containing
pp
-
getLoopGuards
public java.util.Collection<Statement> getLoopGuards(ProgramPoint pp)
Yields the guard of allLoops containing the given program point. If the program point is not part of the body of a loop, this method returns an empty collection.
Note that if no control flow structures have been provided by frontends, and no attempt at extracting them has been made yet, invoking this method will cause aControlFlowExtractorto try to extract them.- Parameters:
pp- the program point- Returns:
- the collection of the guards of all loops containing
pp
-
getIfThenElseGuards
public java.util.Collection<Statement> getIfThenElseGuards(ProgramPoint pp)
Yields the guard of all theIfThenElsecontaining the given program point. If the program point is not part of a branch of an if-then-else, this method returns an empty collection.
Note that if no control flow structures have been provided by frontends, and no attempt at extracting them has been made yet, invoking this method will cause aControlFlowExtractorto try to extract them.- Parameters:
pp- the program point- Returns:
- the collection of the guards of all if-then-elses containing
pp
-
getMostRecentGuard
public Statement getMostRecentGuard(ProgramPoint pp)
Yields the guard of the most recentControlFlowStructure, regardless of its type, containing the given program point. If the program point is not part of the body of a control structure, this method returnsnull.
Note that if no control flow structures have been provided by frontends, and no attempt at extracting them has been made yet, invoking this method will cause aControlFlowExtractorto try to extract them.- Parameters:
pp- the program point- Returns:
- the most recent if-then-else guard, or
null
-
getMostRecentLoopGuard
public Statement getMostRecentLoopGuard(ProgramPoint pp)
Yields the guard of the most recentLoopcontaining the given program point. If the program point is not part of the body of a loop, this method returnsnull.
Note that if no control flow structures have been provided by frontends, and no attempt at extracting them has been made yet, invoking this method will cause aControlFlowExtractorto try to extract them.- Parameters:
pp- the program point- Returns:
- the most recent loop guard, or
null
-
getMostRecentIfThenElseGuard
public Statement getMostRecentIfThenElseGuard(ProgramPoint pp)
Yields the guard of the most recentIfThenElsecontaining the given program point. If the program point is not part of a branch of an if-then-else, this method returnsnull.
Note that if no control flow structures have been provided by frontends, and no attempt at extracting them has been made yet, invoking this method will cause aControlFlowExtractorto try to extract them.- Parameters:
pp- the program point- Returns:
- the most recent if-then-else guard, or
null
-
-