PrunedCFG had been changed to always include an entry and exit node.
The logic for detecting an "empty" ExceptionPrunedCFG inside the PDG
construction code had not been updated appropriately.
This commit is contained in:
Manu Sridharan 2015-08-06 11:08:27 -07:00
parent cb77169101
commit 13a46d8ea3
7 changed files with 59 additions and 8 deletions

1
.gitignore vendored
View File

@ -26,6 +26,7 @@ com.ibm.wala.cast.js/lib/
com.ibm.wala.core.testdata/*.jar
com.ibm.wala.core.testdata/@dot/
com.ibm.wala.core.testdata/lib/
com.ibm.wala.core.testdata/ocaml/
com.ibm.wala.core.tests/dat/wala.examples.properties
com.ibm.wala.core.tests/report
com.ibm.wala.core/@dot

View File

@ -0,0 +1,18 @@
package slice;
import java.io.IOException;
public class JustThrow {
private static int throwException() {
throw new RuntimeException();
}
public static void main(String[] argv) throws IOException{
doNothing(throwException());
}
private static void doNothing(int x) {
}
}

View File

@ -692,6 +692,28 @@ public class SlicerTest {
GraphIntegrity.check(sdg);
}
@Test
public void testJustThrow() throws ClassHierarchyException, IllegalArgumentException, CancelException, IOException, UnsoundGraphException {
AnalysisScope scope = findOrCreateAnalysisScope();
IClassHierarchy cha = findOrCreateCHA(scope);
Iterable<Entrypoint> entrypoints = com.ibm.wala.ipa.callgraph.impl.Util.makeMainEntrypoints(scope, cha,
TestConstants.SLICE_JUSTTHROW);
AnalysisOptions options = CallGraphTestUtil.makeAnalysisOptions(scope, entrypoints);
CallGraphBuilder builder = Util.makeZeroOneCFABuilder(options, new AnalysisCache(), cha, scope);
CallGraph cg = builder.makeCallGraph(options, null);
CGNode main = findMainMethod(cg);
Statement s = findCallToDoNothing(main);
System.err.println("Statement: " + s);
Collection<Statement> slice = Slicer.computeBackwardSlice(s, cg, builder.getPointerAnalysis(), DataDependenceOptions.FULL,
ControlDependenceOptions.NO_EXCEPTIONAL_EDGES);
dumpSlice(slice);
}
public static int countAllocations(Collection<Statement> slice) {
int count = 0;
for (Statement s : slice) {

View File

@ -139,4 +139,6 @@ public interface TestConstants {
public final static String SLICE_TESTINETADDR = "Lslice/TestInetAddr";
public final static String SLICE_JUSTTHROW = "Lslice/JustThrow";
}

View File

@ -289,10 +289,8 @@ public class PrunedCFG<I, T extends IBasicBlock<I>> extends AbstractNumberedGrap
Set<T> reachable = DFS.getReachableNodes(temp, Collections.singleton(cfg.entry()));
Set<T> back = DFS.getReachableNodes(GraphInverter.invert(temp), Collections.singleton(cfg.exit()));
reachable.retainAll(back);
/** BEGIN Custom change: entry and exit in every cfg */
reachable.add(cfg.entry());
reachable.add(cfg.exit());
/** END Custom change: entry and exit in every cfg */
this.nodes = new FilteredNodes<T>(cfg, reachable);
this.edges = new FilteredCFGEdges<I, T>(cfg, nodes, filter);

View File

@ -28,6 +28,7 @@ import com.ibm.wala.ipa.callgraph.propagation.InstanceKey;
import com.ibm.wala.ipa.callgraph.propagation.PointerAnalysis;
import com.ibm.wala.ipa.callgraph.propagation.PointerKey;
import com.ibm.wala.ipa.cfg.ExceptionPrunedCFG;
import com.ibm.wala.ipa.cfg.PrunedCFG;
import com.ibm.wala.ipa.modref.DelegatingExtendedHeapModel;
import com.ibm.wala.ipa.modref.ExtendedHeapModel;
import com.ibm.wala.ipa.modref.ModRef;
@ -62,6 +63,7 @@ import com.ibm.wala.util.collections.MapUtil;
import com.ibm.wala.util.config.SetOfClasses;
import com.ibm.wala.util.debug.Assertions;
import com.ibm.wala.util.debug.UnimplementedError;
import com.ibm.wala.util.graph.GraphUtil;
import com.ibm.wala.util.graph.NumberedGraph;
import com.ibm.wala.util.graph.dominators.Dominators;
import com.ibm.wala.util.graph.labeled.SlowSparseNumberedLabeledGraph;
@ -233,14 +235,18 @@ public class PDG implements NumberedGraph<Statement> {
}
ControlFlowGraph<SSAInstruction, ISSABasicBlock> controlFlowGraph = ir.getControlFlowGraph();
if (cOptions.equals(ControlDependenceOptions.NO_EXCEPTIONAL_EDGES)) {
controlFlowGraph = ExceptionPrunedCFG.make(controlFlowGraph);
// In case the CFG has no nodes left because the only control dependencies
// were
// exceptional, simply return because at this point there are no nodes.
PrunedCFG<SSAInstruction, ISSABasicBlock> prunedCFG = ExceptionPrunedCFG.make(controlFlowGraph);
// In case the CFG has only the entry and exit nodes left
// and no edges because the only control dependencies
// were exceptional, simply return because at this point there are no nodes.
// Otherwise, later this may raise an Exception.
if (controlFlowGraph.getNumberOfNodes() == 0) {
if (prunedCFG.getNumberOfNodes() == 2
&& prunedCFG.containsNode(controlFlowGraph.entry())
&& prunedCFG.containsNode(controlFlowGraph.exit())
&& GraphUtil.countEdges(prunedCFG) == 0) {
return;
}
controlFlowGraph = prunedCFG;
} else {
Assertions.productionAssertion(cOptions.equals(ControlDependenceOptions.FULL));
}

View File

@ -47,7 +47,11 @@ public class DominanceFrontiers<T> {
}
public Iterator<T> getDominanceFrontier(T n) {
return DF.get(n).iterator();
Set<T> frontier = DF.get(n);
if (frontier == null) {
throw new IllegalArgumentException("no dominance frontier for node " + n);
}
return frontier.iterator();
}
public boolean isDominatedBy(T node, T master) {