WALA/com.ibm.wala.core.tests/src/com/ibm/wala/core/tests/slicer/SlicerTest.java

1136 lines
48 KiB
Java

/*******************************************************************************
* Copyright (c) 2006 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package com.ibm.wala.core.tests.slicer;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Collection;
import java.util.Collections;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.Test;
import com.ibm.wala.classLoader.Language;
import com.ibm.wala.core.tests.callGraph.CallGraphTestUtil;
import com.ibm.wala.core.tests.util.TestConstants;
import com.ibm.wala.examples.drivers.PDFSlice;
import com.ibm.wala.ipa.callgraph.AnalysisCacheImpl;
import com.ibm.wala.ipa.callgraph.AnalysisOptions;
import com.ibm.wala.ipa.callgraph.AnalysisScope;
import com.ibm.wala.ipa.callgraph.CGNode;
import com.ibm.wala.ipa.callgraph.CallGraph;
import com.ibm.wala.ipa.callgraph.CallGraphBuilder;
import com.ibm.wala.ipa.callgraph.ContextSelector;
import com.ibm.wala.ipa.callgraph.Entrypoint;
import com.ibm.wala.ipa.callgraph.IAnalysisCacheView;
import com.ibm.wala.ipa.callgraph.impl.PartialCallGraph;
import com.ibm.wala.ipa.callgraph.impl.Util;
import com.ibm.wala.ipa.callgraph.propagation.InstanceKey;
import com.ibm.wala.ipa.callgraph.propagation.PointerAnalysis;
import com.ibm.wala.ipa.callgraph.propagation.SSAContextInterpreter;
import com.ibm.wala.ipa.callgraph.propagation.SSAPropagationCallGraphBuilder;
import com.ibm.wala.ipa.callgraph.propagation.cfa.ZeroXInstanceKeys;
import com.ibm.wala.ipa.callgraph.propagation.cfa.nCFABuilder;
import com.ibm.wala.ipa.cha.ClassHierarchyException;
import com.ibm.wala.ipa.cha.ClassHierarchyFactory;
import com.ibm.wala.ipa.cha.IClassHierarchy;
import com.ibm.wala.ipa.slicer.MethodEntryStatement;
import com.ibm.wala.ipa.slicer.NormalStatement;
import com.ibm.wala.ipa.slicer.SDG;
import com.ibm.wala.ipa.slicer.Slicer;
import com.ibm.wala.ipa.slicer.Slicer.ControlDependenceOptions;
import com.ibm.wala.ipa.slicer.Slicer.DataDependenceOptions;
import com.ibm.wala.ipa.slicer.Statement;
import com.ibm.wala.ipa.slicer.thin.ThinSlicer;
import com.ibm.wala.ssa.IR;
import com.ibm.wala.ssa.SSAAbstractInvokeInstruction;
import com.ibm.wala.ssa.SSAAbstractThrowInstruction;
import com.ibm.wala.ssa.SSAArrayLoadInstruction;
import com.ibm.wala.ssa.SSAConditionalBranchInstruction;
import com.ibm.wala.ssa.SSAGetInstruction;
import com.ibm.wala.ssa.SSAInstruction;
import com.ibm.wala.ssa.SSAInvokeInstruction;
import com.ibm.wala.ssa.SSANewInstruction;
import com.ibm.wala.ssa.SSAPutInstruction;
import com.ibm.wala.ssa.SSAReturnInstruction;
import com.ibm.wala.types.ClassLoaderReference;
import com.ibm.wala.types.Descriptor;
import com.ibm.wala.util.CancelException;
import com.ibm.wala.util.collections.Iterator2Iterable;
import com.ibm.wala.util.config.AnalysisScopeReader;
import com.ibm.wala.util.config.FileOfClasses;
import com.ibm.wala.util.debug.Assertions;
import com.ibm.wala.util.graph.GraphIntegrity;
import com.ibm.wala.util.graph.GraphIntegrity.UnsoundGraphException;
import com.ibm.wala.util.intset.IntSet;
import com.ibm.wala.util.strings.Atom;
public class SlicerTest {
private static AnalysisScope cachedScope;
// more aggressive exclusions to avoid library blowup
// in interprocedural tests
private static final String EXCLUSIONS = "java\\/awt\\/.*\n" +
"javax\\/swing\\/.*\n" +
"sun\\/awt\\/.*\n" +
"sun\\/swing\\/.*\n" +
"com\\/sun\\/.*\n" +
"sun\\/.*\n" +
"org\\/netbeans\\/.*\n" +
"org\\/openide\\/.*\n" +
"com\\/ibm\\/crypto\\/.*\n" +
"com\\/ibm\\/security\\/.*\n" +
"org\\/apache\\/xerces\\/.*\n" +
"java\\/security\\/.*\n" +
"";
private static AnalysisScope findOrCreateAnalysisScope() throws IOException {
if (cachedScope == null) {
cachedScope = AnalysisScopeReader.readJavaScope(TestConstants.WALA_TESTDATA, null, SlicerTest.class.getClassLoader());
cachedScope.setExclusions(new FileOfClasses(new ByteArrayInputStream(EXCLUSIONS.getBytes("UTF-8"))));
}
return cachedScope;
}
private static IClassHierarchy cachedCHA;
private static IClassHierarchy findOrCreateCHA(AnalysisScope scope) throws ClassHierarchyException {
if (cachedCHA == null) {
cachedCHA = ClassHierarchyFactory.make(scope);
}
return cachedCHA;
}
@AfterClass
public static void afterClass() {
cachedCHA = null;
cachedScope = null;
}
@Test
public void testSlice1() throws ClassHierarchyException, IllegalArgumentException, CancelException, IOException {
AnalysisScope scope = findOrCreateAnalysisScope();
IClassHierarchy cha = findOrCreateCHA(scope);
Iterable<Entrypoint> entrypoints = com.ibm.wala.ipa.callgraph.impl.Util.makeMainEntrypoints(scope, cha,
TestConstants.SLICE1_MAIN);
AnalysisOptions options = CallGraphTestUtil.makeAnalysisOptions(scope, entrypoints);
CallGraphBuilder<InstanceKey> builder = Util.makeZeroOneCFABuilder(Language.JAVA, options, new AnalysisCacheImpl(), cha, scope);
CallGraph cg = builder.makeCallGraph(options, null);
CGNode main = findMainMethod(cg);
Statement s = findCallTo(main, "println");
System.err.println("Statement: " + s);
// compute a data slice
final PointerAnalysis<InstanceKey> pointerAnalysis = builder.getPointerAnalysis();
Collection<Statement> computeBackwardSlice = Slicer.computeBackwardSlice(s, cg, pointerAnalysis,
DataDependenceOptions.FULL, ControlDependenceOptions.NONE);
Collection<Statement> slice = computeBackwardSlice;
dumpSlice(slice);
int i = 0;
for (Statement st : slice) {
if (st.getNode().getMethod().getDeclaringClass().getClassLoader().getReference().equals(ClassLoaderReference.Application)) {
i++;
}
}
Assert.assertEquals(16, i);
}
@Test
public void testSlice2() throws ClassHierarchyException, IllegalArgumentException, CancelException, IOException {
AnalysisScope scope = findOrCreateAnalysisScope();
IClassHierarchy cha = findOrCreateCHA(scope);
Iterable<Entrypoint> entrypoints = com.ibm.wala.ipa.callgraph.impl.Util.makeMainEntrypoints(scope, cha,
TestConstants.SLICE2_MAIN);
AnalysisOptions options = CallGraphTestUtil.makeAnalysisOptions(scope, entrypoints);
CallGraphBuilder<InstanceKey> builder = Util.makeZeroOneCFABuilder(Language.JAVA, options, new AnalysisCacheImpl(), cha, scope);
CallGraph cg = builder.makeCallGraph(options, null);
CGNode main = findMethod(cg, "baz");
Statement s = findCallTo(main, "println");
System.err.println("Statement: " + s);
// compute a data slice
final PointerAnalysis<InstanceKey> pointerAnalysis = builder.getPointerAnalysis();
Collection<Statement> computeBackwardSlice = Slicer.computeBackwardSlice(s, cg, pointerAnalysis,
DataDependenceOptions.FULL, ControlDependenceOptions.NONE);
Collection<Statement> slice = computeBackwardSlice;
dumpSlice(slice);
Assert.assertEquals(slice.toString(), 9, countNormals(slice));
}
@Test
public void testSlice3() throws ClassHierarchyException, IllegalArgumentException, CancelException, IOException {
AnalysisScope scope = findOrCreateAnalysisScope();
IClassHierarchy cha = findOrCreateCHA(scope);
Iterable<Entrypoint> entrypoints = com.ibm.wala.ipa.callgraph.impl.Util.makeMainEntrypoints(scope, cha,
TestConstants.SLICE3_MAIN);
AnalysisOptions options = CallGraphTestUtil.makeAnalysisOptions(scope, entrypoints);
CallGraphBuilder<InstanceKey> builder = Util.makeZeroOneCFABuilder(Language.JAVA, options, new AnalysisCacheImpl(), cha, scope);
CallGraph cg = builder.makeCallGraph(options, null);
CGNode main = findMethod(cg, "main");
Statement s = findCallTo(main, "doNothing");
System.err.println("Statement: " + s);
// compute a data slice
final PointerAnalysis<InstanceKey> pointerAnalysis = builder.getPointerAnalysis();
Collection<Statement> slice = Slicer.computeBackwardSlice(s, cg, pointerAnalysis, DataDependenceOptions.FULL,
ControlDependenceOptions.NONE);
dumpSlice(slice);
Assert.assertEquals(slice.toString(), 1, countAllocations(slice));
}
@Test
public void testSlice4() throws ClassHierarchyException, IllegalArgumentException, CancelException, IOException {
AnalysisScope scope = findOrCreateAnalysisScope();
IClassHierarchy cha = findOrCreateCHA(scope);
Iterable<Entrypoint> entrypoints = com.ibm.wala.ipa.callgraph.impl.Util.makeMainEntrypoints(scope, cha,
TestConstants.SLICE4_MAIN);
AnalysisOptions options = CallGraphTestUtil.makeAnalysisOptions(scope, entrypoints);
CallGraphBuilder<InstanceKey> builder = Util.makeZeroOneCFABuilder(Language.JAVA, options, new AnalysisCacheImpl(), cha, scope);
CallGraph cg = builder.makeCallGraph(options, null);
CGNode main = findMainMethod(cg);
Statement s = findCallTo(main, "foo");
s = PDFSlice.getReturnStatementForCall(s);
System.err.println("Statement: " + s);
// compute a data slice
final PointerAnalysis<InstanceKey> pointerAnalysis = builder.getPointerAnalysis();
Collection<Statement> slice = Slicer.computeForwardSlice(s, cg, pointerAnalysis, DataDependenceOptions.FULL,
ControlDependenceOptions.NONE);
dumpSlice(slice);
Assert.assertEquals(slice.toString(), 4, slice.size());
}
@Test
public void testSlice5() throws ClassHierarchyException, IllegalArgumentException, CancelException, IOException {
AnalysisScope scope = findOrCreateAnalysisScope();
IClassHierarchy cha = findOrCreateCHA(scope);
Iterable<Entrypoint> entrypoints = com.ibm.wala.ipa.callgraph.impl.Util.makeMainEntrypoints(scope, cha,
TestConstants.SLICE5_MAIN);
AnalysisOptions options = CallGraphTestUtil.makeAnalysisOptions(scope, entrypoints);
CallGraphBuilder<InstanceKey> builder = Util.makeZeroOneCFABuilder(Language.JAVA, options, new AnalysisCacheImpl(), cha, scope);
CallGraph cg = builder.makeCallGraph(options, null);
CGNode n = findMethod(cg, "baz");
Statement s = findCallTo(n, "foo");
s = PDFSlice.getReturnStatementForCall(s);
System.err.println("Statement: " + s);
// compute a data slice
final PointerAnalysis<InstanceKey> pointerAnalysis = builder.getPointerAnalysis();
Collection<Statement> slice = Slicer.computeForwardSlice(s, cg, pointerAnalysis,
DataDependenceOptions.FULL, ControlDependenceOptions.NONE);
dumpSlice(slice);
Assert.assertEquals(slice.toString(), 7, slice.size());
}
/**
* test unreproduced bug reported on mailing list by Sameer Madan, 7/3/2007
*
* @throws CancelException
* @throws IllegalArgumentException
* @throws IOException
*/
@Test
public void testSlice7() throws ClassHierarchyException, IllegalArgumentException, CancelException, IOException {
AnalysisScope scope = findOrCreateAnalysisScope();
IClassHierarchy cha = findOrCreateCHA(scope);
Iterable<Entrypoint> entrypoints = com.ibm.wala.ipa.callgraph.impl.Util.makeMainEntrypoints(scope, cha,
TestConstants.SLICE7_MAIN);
AnalysisOptions options = CallGraphTestUtil.makeAnalysisOptions(scope, entrypoints);
CallGraphBuilder<InstanceKey> builder = Util.makeZeroOneContainerCFABuilder(options, new AnalysisCacheImpl(), cha, scope);
CallGraph cg = builder.makeCallGraph(options, null);
CGNode main = findMainMethod(cg);
Statement s = findFirstAllocation(main);
System.err.println("Statement: " + s);
// compute a data slice
final PointerAnalysis<InstanceKey> pointerAnalysis = builder.getPointerAnalysis();
Collection<Statement> slice = Slicer.computeForwardSlice(s, cg, pointerAnalysis,
DataDependenceOptions.FULL, ControlDependenceOptions.NONE);
dumpSlice(slice);
}
/**
* test bug reported on mailing list by Ravi Chandhran, 4/16/2010
*
* @throws CancelException
* @throws IllegalArgumentException
* @throws IOException
*/
@Test
public void testSlice8() throws ClassHierarchyException, IllegalArgumentException, CancelException, IOException {
AnalysisScope scope = findOrCreateAnalysisScope();
IClassHierarchy cha = findOrCreateCHA(scope);
Iterable<Entrypoint> entrypoints = com.ibm.wala.ipa.callgraph.impl.Util.makeMainEntrypoints(scope, cha,
TestConstants.SLICE8_MAIN);
AnalysisOptions options = CallGraphTestUtil.makeAnalysisOptions(scope, entrypoints);
CallGraphBuilder<InstanceKey> builder = Util.makeZeroOneCFABuilder(Language.JAVA, options, new AnalysisCacheImpl(), cha, scope);
CallGraph cg = builder.makeCallGraph(options, null);
CGNode process = findMethod(cg, Descriptor.findOrCreateUTF8("()V"), Atom.findOrCreateUnicodeAtom("process"));
Statement s = findCallToDoNothing(process);
System.err.println("Statement: " + s);
// compute a backward slice, with data dependence and no exceptional control dependence
final PointerAnalysis<InstanceKey> pointerAnalysis = builder.getPointerAnalysis();
Collection<Statement> slice = Slicer.computeBackwardSlice(s, cg, pointerAnalysis, DataDependenceOptions.FULL,
ControlDependenceOptions.NO_EXCEPTIONAL_EDGES);
dumpSlice(slice);
Assert.assertEquals(4, countInvokes(slice));
// should only get 4 statements total when ignoring control dependences completely
slice = Slicer.computeBackwardSlice(s, cg, pointerAnalysis, DataDependenceOptions.FULL,
ControlDependenceOptions.NONE);
Assert.assertEquals(slice.toString(), 4, slice.size());
}
@Test
public void testSlice9() throws ClassHierarchyException, IllegalArgumentException, CancelException, IOException {
AnalysisScope scope = findOrCreateAnalysisScope();
IClassHierarchy cha = findOrCreateCHA(scope);
Iterable<Entrypoint> entrypoints = com.ibm.wala.ipa.callgraph.impl.Util.makeMainEntrypoints(scope, cha,
TestConstants.SLICE9_MAIN);
AnalysisOptions options = CallGraphTestUtil.makeAnalysisOptions(scope, entrypoints);
CallGraphBuilder<InstanceKey> builder = Util.makeZeroOneCFABuilder(Language.JAVA, options, new AnalysisCacheImpl(), cha, scope);
CallGraph cg = builder.makeCallGraph(options, null);
CGNode main = findMainMethod(cg);
Statement s = findCallToDoNothing(main);
System.err.println("Statement: " + s);
// compute a backward slice, with data dependence and no exceptional control dependence
final PointerAnalysis<InstanceKey> pointerAnalysis = builder.getPointerAnalysis();
Collection<Statement> slice = Slicer.computeBackwardSlice(s, cg, pointerAnalysis, DataDependenceOptions.FULL,
ControlDependenceOptions.NO_EXCEPTIONAL_EDGES);
//dumpSlice(slice);
Assert.assertEquals(/*slice.toString(), */5, countApplicationNormals(slice));
}
@Test
public void testTestCD1() throws ClassHierarchyException, IllegalArgumentException, CancelException, IOException {
AnalysisScope scope = findOrCreateAnalysisScope();
IClassHierarchy cha = findOrCreateCHA(scope);
Iterable<Entrypoint> entrypoints = com.ibm.wala.ipa.callgraph.impl.Util.makeMainEntrypoints(scope, cha,
TestConstants.SLICE_TESTCD1);
AnalysisOptions options = CallGraphTestUtil.makeAnalysisOptions(scope, entrypoints);
CallGraphBuilder<InstanceKey> builder = Util.makeZeroOneCFABuilder(Language.JAVA, options, new AnalysisCacheImpl(), cha, scope);
CallGraph cg = builder.makeCallGraph(options, null);
CGNode main = findMainMethod(cg);
Statement s = findCallToDoNothing(main);
System.err.println("Statement: " + s);
// compute a data slice
final PointerAnalysis<InstanceKey> pointerAnalysis = builder.getPointerAnalysis();
Collection<Statement> slice = Slicer.computeBackwardSlice(s, cg, pointerAnalysis, DataDependenceOptions.NONE,
ControlDependenceOptions.FULL);
dumpSlice(slice);
Assert.assertEquals(slice.toString(), 2, countConditionals(slice));
}
@Test
public void testTestCD2() throws ClassHierarchyException, IllegalArgumentException, CancelException, IOException {
AnalysisScope scope = findOrCreateAnalysisScope();
IClassHierarchy cha = findOrCreateCHA(scope);
Iterable<Entrypoint> entrypoints = com.ibm.wala.ipa.callgraph.impl.Util.makeMainEntrypoints(scope, cha,
TestConstants.SLICE_TESTCD2);
AnalysisOptions options = CallGraphTestUtil.makeAnalysisOptions(scope, entrypoints);
CallGraphBuilder<InstanceKey> builder = Util.makeZeroOneCFABuilder(Language.JAVA, options, new AnalysisCacheImpl(), cha, scope);
CallGraph cg = builder.makeCallGraph(options, null);
CGNode main = findMainMethod(cg);
Statement s = findCallToDoNothing(main);
System.err.println("Statement: " + s);
// compute a data slice
final PointerAnalysis<InstanceKey> pointerAnalysis = builder.getPointerAnalysis();
Collection<Statement> slice = Slicer.computeBackwardSlice(s, cg, pointerAnalysis, DataDependenceOptions.NONE,
ControlDependenceOptions.FULL);
dumpSlice(slice);
Assert.assertEquals(slice.toString(), 1, countConditionals(slice));
}
@Test
public void testTestCD3() throws ClassHierarchyException, IllegalArgumentException, CancelException, IOException {
AnalysisScope scope = findOrCreateAnalysisScope();
IClassHierarchy cha = findOrCreateCHA(scope);
Iterable<Entrypoint> entrypoints = com.ibm.wala.ipa.callgraph.impl.Util.makeMainEntrypoints(scope, cha,
TestConstants.SLICE_TESTCD3);
AnalysisOptions options = CallGraphTestUtil.makeAnalysisOptions(scope, entrypoints);
CallGraphBuilder<InstanceKey> builder = Util.makeZeroOneCFABuilder(Language.JAVA, options, new AnalysisCacheImpl(), cha, scope);
CallGraph cg = builder.makeCallGraph(options, null);
CGNode main = findMainMethod(cg);
Statement s = findCallToDoNothing(main);
System.err.println("Statement: " + s);
// compute a data slice
final PointerAnalysis<InstanceKey> pointerAnalysis = builder.getPointerAnalysis();
Collection<Statement> slice = Slicer.computeBackwardSlice(s, cg, pointerAnalysis, DataDependenceOptions.NONE,
ControlDependenceOptions.FULL);
dumpSlice(slice);
Assert.assertEquals(slice.toString(), 0, countConditionals(slice));
}
@Test
public void testTestCD4() throws ClassHierarchyException, IllegalArgumentException, CancelException, IOException {
AnalysisScope scope = findOrCreateAnalysisScope();
IClassHierarchy cha = findOrCreateCHA(scope);
Iterable<Entrypoint> entrypoints = com.ibm.wala.ipa.callgraph.impl.Util.makeMainEntrypoints(scope, cha,
TestConstants.SLICE_TESTCD4);
AnalysisOptions options = CallGraphTestUtil.makeAnalysisOptions(scope, entrypoints);
CallGraphBuilder<InstanceKey> builder = Util.makeZeroOneCFABuilder(Language.JAVA, options, new AnalysisCacheImpl(), cha, scope);
CallGraph cg = builder.makeCallGraph(options, null);
CGNode main = findMainMethod(cg);
Statement s = findCallToDoNothing(main);
System.err.println("Statement: " + s);
// compute a no-data slice
final PointerAnalysis<InstanceKey> pointerAnalysis = builder.getPointerAnalysis();
Collection<Statement> slice = Slicer.computeBackwardSlice(s, cg, pointerAnalysis, DataDependenceOptions.NONE,
ControlDependenceOptions.FULL);
dumpSlice(slice);
Assert.assertEquals(0, countConditionals(slice));
// compute a full slice
slice = Slicer.computeBackwardSlice(s, cg, pointerAnalysis,
DataDependenceOptions.FULL, ControlDependenceOptions.FULL);
dumpSlice(slice);
Assert.assertEquals(slice.toString(), 1, countConditionals(slice));
}
@Test
public void testTestCD5() throws ClassHierarchyException, IllegalArgumentException, CancelException, IOException {
AnalysisScope scope = findOrCreateAnalysisScope();
IClassHierarchy cha = findOrCreateCHA(scope);
Iterable<Entrypoint> entrypoints = com.ibm.wala.ipa.callgraph.impl.Util.makeMainEntrypoints(scope, cha,
TestConstants.SLICE_TESTCD5);
AnalysisOptions options = CallGraphTestUtil.makeAnalysisOptions(scope, entrypoints);
CallGraphBuilder<InstanceKey> builder = Util.makeZeroOneCFABuilder(Language.JAVA, options, new AnalysisCacheImpl(), cha, scope);
CallGraph cg = builder.makeCallGraph(options, null);
CGNode main = findMainMethod(cg);
Statement s = new MethodEntryStatement(main);
System.err.println("Statement: " + s);
// compute a no-data slice
final PointerAnalysis<InstanceKey> pointerAnalysis = builder.getPointerAnalysis();
Collection<Statement> slice = Slicer.computeForwardSlice(s, cg, pointerAnalysis,
DataDependenceOptions.NONE, ControlDependenceOptions.NO_EXCEPTIONAL_EDGES);
dumpSlice(slice);
Assert.assertEquals(10, slice.size());
Assert.assertEquals(3, countReturns(slice));
}
@Test
public void testTestCD5NoInterproc() throws ClassHierarchyException, IllegalArgumentException, CancelException, IOException {
AnalysisScope scope = findOrCreateAnalysisScope();
IClassHierarchy cha = findOrCreateCHA(scope);
Iterable<Entrypoint> entrypoints = com.ibm.wala.ipa.callgraph.impl.Util.makeMainEntrypoints(scope, cha,
TestConstants.SLICE_TESTCD5);
AnalysisOptions options = CallGraphTestUtil.makeAnalysisOptions(scope, entrypoints);
CallGraphBuilder<InstanceKey> builder = Util.makeZeroOneCFABuilder(Language.JAVA, options, new AnalysisCacheImpl(), cha, scope);
CallGraph cg = builder.makeCallGraph(options, null);
CGNode main = findMainMethod(cg);
Statement s = new MethodEntryStatement(main);
System.err.println("Statement: " + s);
// compute a no-data slice
final PointerAnalysis<InstanceKey> pointerAnalysis = builder.getPointerAnalysis();
Collection<Statement> slice = Slicer.computeForwardSlice(s, cg, pointerAnalysis,
DataDependenceOptions.NONE, ControlDependenceOptions.NO_INTERPROC_NO_EXCEPTION);
dumpSlice(slice);
Assert.assertEquals(8, slice.size());
Assert.assertEquals(2, countReturns(slice));
}
@Test
public void testTestCD6() throws ClassHierarchyException, IllegalArgumentException, CancelException, IOException {
AnalysisScope scope = findOrCreateAnalysisScope();
IClassHierarchy cha = findOrCreateCHA(scope);
Iterable<Entrypoint> entrypoints = com.ibm.wala.ipa.callgraph.impl.Util.makeMainEntrypoints(scope, cha,
TestConstants.SLICE_TESTCD6);
AnalysisOptions options = CallGraphTestUtil.makeAnalysisOptions(scope, entrypoints);
CallGraphBuilder<InstanceKey> builder = Util.makeZeroOneCFABuilder(Language.JAVA, options, new AnalysisCacheImpl(), cha, scope);
CallGraph cg = builder.makeCallGraph(options, null);
CGNode main = findMainMethod(cg);
Statement s = new MethodEntryStatement(main);
System.err.println("Statement: " + s);
// compute a no-data slice
final PointerAnalysis<InstanceKey> pointerAnalysis = builder.getPointerAnalysis();
Collection<Statement> slice = Slicer.computeForwardSlice(s, cg, pointerAnalysis,
DataDependenceOptions.NONE, ControlDependenceOptions.NO_EXCEPTIONAL_EDGES);
dumpSlice(slice);
Assert.assertEquals(slice.toString(), 2, countInvokes(slice));
}
@Test
public void testTestId() throws ClassHierarchyException, IllegalArgumentException, CancelException, IOException {
AnalysisScope scope = findOrCreateAnalysisScope();
IClassHierarchy cha = findOrCreateCHA(scope);
Iterable<Entrypoint> entrypoints = com.ibm.wala.ipa.callgraph.impl.Util.makeMainEntrypoints(scope, cha,
TestConstants.SLICE_TESTID);
AnalysisOptions options = CallGraphTestUtil.makeAnalysisOptions(scope, entrypoints);
CallGraphBuilder<InstanceKey> builder = Util.makeZeroOneCFABuilder(Language.JAVA, options, new AnalysisCacheImpl(), cha, scope);
CallGraph cg = builder.makeCallGraph(options, null);
CGNode main = findMainMethod(cg);
Statement s = findCallToDoNothing(main);
System.err.println("Statement: " + s);
// compute a data slice
final PointerAnalysis<InstanceKey> pointerAnalysis = builder.getPointerAnalysis();
Collection<Statement> slice = Slicer.computeBackwardSlice(s, cg, pointerAnalysis, DataDependenceOptions.FULL,
ControlDependenceOptions.NONE);
dumpSlice(slice);
Assert.assertEquals(slice.toString(), 1, countAllocations(slice));
}
@Test
public void testTestArrays() throws ClassHierarchyException, IllegalArgumentException, CancelException, IOException {
AnalysisScope scope = findOrCreateAnalysisScope();
IClassHierarchy cha = findOrCreateCHA(scope);
Iterable<Entrypoint> entrypoints = com.ibm.wala.ipa.callgraph.impl.Util.makeMainEntrypoints(scope, cha,
TestConstants.SLICE_TESTARRAYS);
AnalysisOptions options = CallGraphTestUtil.makeAnalysisOptions(scope, entrypoints);
CallGraphBuilder<InstanceKey> builder = Util.makeZeroOneCFABuilder(Language.JAVA, options, new AnalysisCacheImpl(), cha, scope);
CallGraph cg = builder.makeCallGraph(options, null);
CGNode main = findMainMethod(cg);
Statement s = findCallToDoNothing(main);
System.err.println("Statement: " + s);
// compute a data slice
final PointerAnalysis<InstanceKey> pointerAnalysis = builder.getPointerAnalysis();
Collection<Statement> slice = Slicer.computeBackwardSlice(s, cg, pointerAnalysis, DataDependenceOptions.FULL,
ControlDependenceOptions.NONE);
dumpSlice(slice);
Assert.assertEquals(slice.toString(), 2, countAllocations(slice));
Assert.assertEquals(slice.toString(), 1, countAloads(slice));
}
@Test
public void testTestFields() throws ClassHierarchyException, IllegalArgumentException, CancelException, IOException {
AnalysisScope scope = findOrCreateAnalysisScope();
IClassHierarchy cha = findOrCreateCHA(scope);
Iterable<Entrypoint> entrypoints = com.ibm.wala.ipa.callgraph.impl.Util.makeMainEntrypoints(scope, cha,
TestConstants.SLICE_TESTFIELDS);
AnalysisOptions options = CallGraphTestUtil.makeAnalysisOptions(scope, entrypoints);
CallGraphBuilder<InstanceKey> builder = Util.makeZeroOneCFABuilder(Language.JAVA, options, new AnalysisCacheImpl(), cha, scope);
CallGraph cg = builder.makeCallGraph(options, null);
CGNode main = findMainMethod(cg);
Statement s = findCallToDoNothing(main);
System.err.println("Statement: " + s);
// compute a data slice
final PointerAnalysis<InstanceKey> pointerAnalysis = builder.getPointerAnalysis();
Collection<Statement> slice = Slicer.computeBackwardSlice(s, cg, pointerAnalysis, DataDependenceOptions.FULL,
ControlDependenceOptions.NONE);
dumpSlice(slice);
Assert.assertEquals(slice.toString(), 2, countAllocations(slice));
Assert.assertEquals(slice.toString(), 1, countPutfields(slice));
}
@Test
public void testThin1() throws ClassHierarchyException, IllegalArgumentException, CancelException, IOException {
AnalysisScope scope = findOrCreateAnalysisScope();
IClassHierarchy cha = findOrCreateCHA(scope);
Iterable<Entrypoint> entrypoints = com.ibm.wala.ipa.callgraph.impl.Util.makeMainEntrypoints(scope, cha,
TestConstants.SLICE_TESTTHIN1);
AnalysisOptions options = CallGraphTestUtil.makeAnalysisOptions(scope, entrypoints);
CallGraphBuilder<InstanceKey> builder = Util.makeZeroOneCFABuilder(Language.JAVA, options, new AnalysisCacheImpl(), cha, scope);
CallGraph cg = builder.makeCallGraph(options, null);
CGNode main = findMainMethod(cg);
Statement s = findCallToDoNothing(main);
System.err.println("Statement: " + s);
// compute normal data slice
// compute a data slice
final PointerAnalysis<InstanceKey> pointerAnalysis = builder.getPointerAnalysis();
Collection<Statement> slice = Slicer.computeBackwardSlice(s, cg, pointerAnalysis, DataDependenceOptions.FULL,
ControlDependenceOptions.NONE);
dumpSlice(slice);
Assert.assertEquals(3, countAllocations(slice));
Assert.assertEquals(2, countPutfields(slice));
// compute thin slice .. ignore base pointers
Collection<Statement> computeBackwardSlice = Slicer.computeBackwardSlice(s, cg, pointerAnalysis,
DataDependenceOptions.NO_BASE_PTRS, ControlDependenceOptions.NONE);
slice = computeBackwardSlice;
dumpSlice(slice);
Assert.assertEquals(slice.toString(), 2, countAllocations(slice));
Assert.assertEquals(slice.toString(), 1, countPutfields(slice));
}
@Test
public void testTestGlobal() throws ClassHierarchyException, IllegalArgumentException, CancelException, IOException {
AnalysisScope scope = findOrCreateAnalysisScope();
IClassHierarchy cha = findOrCreateCHA(scope);
Iterable<Entrypoint> entrypoints = com.ibm.wala.ipa.callgraph.impl.Util.makeMainEntrypoints(scope, cha,
TestConstants.SLICE_TESTGLOBAL);
AnalysisOptions options = CallGraphTestUtil.makeAnalysisOptions(scope, entrypoints);
CallGraphBuilder<InstanceKey> builder = Util.makeZeroOneCFABuilder(Language.JAVA, options, new AnalysisCacheImpl(), cha, scope);
CallGraph cg = builder.makeCallGraph(options, null);
CGNode main = findMainMethod(cg);
Statement s = findCallToDoNothing(main);
System.err.println("Statement: " + s);
// compute a data slice
final PointerAnalysis<InstanceKey> pointerAnalysis = builder.getPointerAnalysis();
Collection<Statement> slice = Slicer.computeBackwardSlice(s, cg, pointerAnalysis, DataDependenceOptions.FULL,
ControlDependenceOptions.NONE);
dumpSlice(slice);
Assert.assertEquals(slice.toString(), 1, countAllocations(slice));
Assert.assertEquals(slice.toString(), 2, countPutstatics(slice));
Assert.assertEquals(slice.toString(), 2, countGetstatics(slice));
}
@Test
public void testTestMultiTarget() throws ClassHierarchyException, IllegalArgumentException, CancelException, IOException {
AnalysisScope scope = findOrCreateAnalysisScope();
IClassHierarchy cha = findOrCreateCHA(scope);
Iterable<Entrypoint> entrypoints = com.ibm.wala.ipa.callgraph.impl.Util.makeMainEntrypoints(scope, cha,
TestConstants.SLICE_TESTMULTITARGET);
AnalysisOptions options = CallGraphTestUtil.makeAnalysisOptions(scope, entrypoints);
CallGraphBuilder<InstanceKey> builder = Util.makeZeroOneCFABuilder(Language.JAVA, options, new AnalysisCacheImpl(), cha, scope);
CallGraph cg = builder.makeCallGraph(options, null);
CGNode main = findMainMethod(cg);
Statement s = findCallToDoNothing(main);
System.err.println("Statement: " + s);
// compute a data slice
final PointerAnalysis<InstanceKey> pointerAnalysis = builder.getPointerAnalysis();
Collection<Statement> slice = Slicer.computeBackwardSlice(s, cg, pointerAnalysis, DataDependenceOptions.FULL,
ControlDependenceOptions.NONE);
dumpSlice(slice);
Assert.assertEquals(slice.toString(), 2, countAllocations(slice));
}
@Test
public void testTestRecursion() throws ClassHierarchyException, IllegalArgumentException, CancelException, IOException {
AnalysisScope scope = findOrCreateAnalysisScope();
IClassHierarchy cha = findOrCreateCHA(scope);
Iterable<Entrypoint> entrypoints = com.ibm.wala.ipa.callgraph.impl.Util.makeMainEntrypoints(scope, cha,
TestConstants.SLICE_TESTRECURSION);
AnalysisOptions options = CallGraphTestUtil.makeAnalysisOptions(scope, entrypoints);
CallGraphBuilder<InstanceKey> builder = Util.makeZeroOneCFABuilder(Language.JAVA, options, new AnalysisCacheImpl(), cha, scope);
CallGraph cg = builder.makeCallGraph(options, null);
CGNode main = findMainMethod(cg);
Statement s = findCallToDoNothing(main);
System.err.println("Statement: " + s);
// compute a data slice
final PointerAnalysis<InstanceKey> pointerAnalysis = builder.getPointerAnalysis();
Collection<Statement> slice = Slicer.computeBackwardSlice(s, cg, pointerAnalysis, DataDependenceOptions.FULL,
ControlDependenceOptions.NONE);
dumpSlice(slice);
Assert.assertEquals(slice.toString(), 3, countAllocations(slice));
Assert.assertEquals(slice.toString(), 2, countPutfields(slice));
}
@Test
public void testPrimGetterSetter() throws ClassHierarchyException, IllegalArgumentException, CancelException, IOException {
AnalysisScope scope = findOrCreateAnalysisScope();
IClassHierarchy cha = findOrCreateCHA(scope);
Iterable<Entrypoint> entrypoints = com.ibm.wala.ipa.callgraph.impl.Util.makeMainEntrypoints(scope, cha,
TestConstants.SLICE_TEST_PRIM_GETTER_SETTER);
AnalysisOptions options = CallGraphTestUtil.makeAnalysisOptions(scope, entrypoints);
CallGraphBuilder<InstanceKey> builder = Util.makeZeroOneCFABuilder(Language.JAVA, options, new AnalysisCacheImpl(), cha, scope);
CallGraph cg = builder.makeCallGraph(options, null);
CGNode test = findMethod(cg, "test");
PartialCallGraph pcg = PartialCallGraph.make(cg, Collections.singleton(test));
Statement s = findCallToDoNothing(test);
System.err.println("Statement: " + s);
// compute full slice
final PointerAnalysis<InstanceKey> pointerAnalysis = builder.getPointerAnalysis();
Collection<Statement> slice = Slicer.computeBackwardSlice(s, pcg, pointerAnalysis,
DataDependenceOptions.FULL, ControlDependenceOptions.FULL);
dumpSlice(slice);
Assert.assertEquals(slice.toString(), 0, countAllocations(slice));
Assert.assertEquals(slice.toString(), 1, countPutfields(slice));
}
/**
* Test of using N-CFA builder to distinguish receiver objects for two calls
* to a getter method. Also tests disabling SMUSH_PRIMITIVE_HOLDERS to ensure
* we get distinct abstract objects for two different primitive holders.
*/
@Test
public void testPrimGetterSetter2() throws ClassHierarchyException, IllegalArgumentException, CancelException, IOException {
AnalysisScope scope = findOrCreateAnalysisScope();
IClassHierarchy cha = findOrCreateCHA(scope);
Iterable<Entrypoint> entrypoints = com.ibm.wala.ipa.callgraph.impl.Util.makeMainEntrypoints(scope, cha,
TestConstants.SLICE_TEST_PRIM_GETTER_SETTER2);
AnalysisOptions options = CallGraphTestUtil.makeAnalysisOptions(scope, entrypoints);
Util.addDefaultSelectors(options, cha);
Util.addDefaultBypassLogic(options, scope, Util.class.getClassLoader(), cha);
ContextSelector appSelector = null;
SSAContextInterpreter appInterpreter = null;
IAnalysisCacheView cache = new AnalysisCacheImpl();
SSAPropagationCallGraphBuilder builder = new nCFABuilder(1, Language.JAVA.getFakeRootMethod(cha, options, cache), options, cache, appSelector, appInterpreter);
// nCFABuilder uses type-based heap abstraction by default, but we want allocation sites
// NOTE: we disable ZeroXInstanceKeys.SMUSH_PRIMITIVE_HOLDERS for this test, since IntWrapper
// is a primitive holder
builder.setInstanceKeys(new ZeroXInstanceKeys(options, cha, builder.getContextInterpreter(), ZeroXInstanceKeys.ALLOCATIONS
| ZeroXInstanceKeys.SMUSH_MANY /* | ZeroXInstanceKeys.SMUSH_PRIMITIVE_HOLDERS */ | ZeroXInstanceKeys.SMUSH_STRINGS
| ZeroXInstanceKeys.SMUSH_THROWABLES));
CallGraph cg = builder.makeCallGraph(options, null);
CGNode test = findMainMethod(cg);
PartialCallGraph pcg = PartialCallGraph.make(cg, Collections.singleton(test));
Statement s = findCallToDoNothing(test);
System.err.println("Statement: " + s);
final PointerAnalysis<InstanceKey> pointerAnalysis = builder.getPointerAnalysis();
Collection<Statement> slice = Slicer.computeBackwardSlice(s, pcg, pointerAnalysis,
DataDependenceOptions.FULL, ControlDependenceOptions.NONE);
dumpSlice(slice);
Assert.assertEquals(slice.toString(), 1, countAllocations(slice));
Assert.assertEquals(slice.toString(), 1, countPutfields(slice));
}
@Test
public void testTestThrowCatch() throws ClassHierarchyException, IllegalArgumentException, CancelException, IOException {
AnalysisScope scope = findOrCreateAnalysisScope();
IClassHierarchy cha = findOrCreateCHA(scope);
Iterable<Entrypoint> entrypoints = com.ibm.wala.ipa.callgraph.impl.Util.makeMainEntrypoints(scope, cha,
TestConstants.SLICE_TESTTHROWCATCH);
AnalysisOptions options = CallGraphTestUtil.makeAnalysisOptions(scope, entrypoints);
CallGraphBuilder<InstanceKey> builder = Util.makeZeroOneCFABuilder(Language.JAVA, options, new AnalysisCacheImpl(), cha, scope);
CallGraph cg = builder.makeCallGraph(options, null);
CGNode main = findMainMethod(cg);
Statement s = findCallToDoNothing(main);
System.err.println("Statement: " + s);
// compute a data slice
final PointerAnalysis<InstanceKey> pointerAnalysis = builder.getPointerAnalysis();
Collection<Statement> slice = Slicer.computeBackwardSlice(s, cg, pointerAnalysis, DataDependenceOptions.FULL,
ControlDependenceOptions.NONE);
dumpSlice(slice);
Assert.assertEquals(slice.toString(), 1, countApplicationAllocations(slice));
Assert.assertEquals(slice.toString(), 1, countThrows(slice));
Assert.assertEquals(slice.toString(), 1, countGetfields(slice));
}
@Test
public void testTestMessageFormat() throws ClassHierarchyException, IllegalArgumentException, CancelException, IOException {
AnalysisScope scope = findOrCreateAnalysisScope();
IClassHierarchy cha = findOrCreateCHA(scope);
Iterable<Entrypoint> entrypoints = com.ibm.wala.ipa.callgraph.impl.Util.makeMainEntrypoints(scope, cha,
TestConstants.SLICE_TESTMESSAGEFORMAT);
AnalysisOptions options = CallGraphTestUtil.makeAnalysisOptions(scope, entrypoints);
CallGraphBuilder<InstanceKey> builder = Util.makeZeroCFABuilder(Language.JAVA, options, new AnalysisCacheImpl(), cha, scope);
CallGraph cg = builder.makeCallGraph(options, null);
CGNode main = findMainMethod(cg);
Statement seed = new NormalStatement(main, 2);
System.err.println("Statement: " + seed);
// compute a backwards thin slice
ThinSlicer ts = new ThinSlicer(cg, builder.getPointerAnalysis());
Collection<Statement> slice = ts.computeBackwardThinSlice(seed);
dumpSlice(slice);
}
/**
* test for bug reported on mailing list by Joshua Garcia, 5/16/2010
*/
@Test
public void testTestInetAddr() 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_TESTINETADDR);
AnalysisOptions options = CallGraphTestUtil.makeAnalysisOptions(scope, entrypoints);
CallGraphBuilder<InstanceKey> builder = Util.makeZeroOneCFABuilder(Language.JAVA, options, new AnalysisCacheImpl(), cha, scope);
CallGraph cg = builder.makeCallGraph(options, null);
SDG<?> sdg = new SDG<>(cg, builder.getPointerAnalysis(), DataDependenceOptions.NO_BASE_NO_HEAP, ControlDependenceOptions.FULL);
GraphIntegrity.check(sdg);
}
@Test
public void testJustThrow() throws ClassHierarchyException, IllegalArgumentException, CancelException, IOException {
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<InstanceKey> builder = Util.makeZeroOneCFABuilder(Language.JAVA, options, new AnalysisCacheImpl(), cha, scope);
CallGraph cg = builder.makeCallGraph(options, null);
CGNode main = findMainMethod(cg);
Statement s = findCallToDoNothing(main);
System.err.println("Statement: " + s);
final PointerAnalysis<InstanceKey> pointerAnalysis = builder.getPointerAnalysis();
Collection<Statement> slice = Slicer.computeBackwardSlice(s, cg, pointerAnalysis, DataDependenceOptions.FULL,
ControlDependenceOptions.NO_EXCEPTIONAL_EDGES);
dumpSlice(slice);
}
public static int countAllocations(Collection<Statement> slice) {
int count = 0;
for (Statement s : slice) {
if (s.getKind().equals(Statement.Kind.NORMAL)) {
NormalStatement ns = (NormalStatement) s;
if (ns.getInstruction() instanceof SSANewInstruction) {
count++;
}
}
}
return count;
}
public static int countApplicationAllocations(Collection<Statement> slice) {
int count = 0;
for (Statement s : slice) {
if (s.getKind().equals(Statement.Kind.NORMAL)) {
NormalStatement ns = (NormalStatement) s;
if (ns.getInstruction() instanceof SSANewInstruction) {
AnalysisScope scope = s.getNode().getClassHierarchy().getScope();
if (scope.isApplicationLoader(s.getNode().getMethod().getDeclaringClass().getClassLoader())) {
count++;
}
}
}
}
return count;
}
public static int countThrows(Collection<Statement> slice) {
int count = 0;
for (Statement s : slice) {
if (s.getKind().equals(Statement.Kind.NORMAL)) {
NormalStatement ns = (NormalStatement) s;
if (ns.getInstruction() instanceof SSAAbstractThrowInstruction) {
count++;
}
}
}
return count;
}
public static int countAloads(Collection<Statement> slice) {
int count = 0;
for (Statement s : slice) {
if (s.getKind().equals(Statement.Kind.NORMAL)) {
NormalStatement ns = (NormalStatement) s;
if (ns.getInstruction() instanceof SSAArrayLoadInstruction) {
count++;
}
}
}
return count;
}
public static int countNormals(Collection<Statement> slice) {
int count = 0;
for (Statement s : slice) {
if (s.getKind().equals(Statement.Kind.NORMAL)) {
count++;
}
}
return count;
}
public static int countApplicationNormals(Collection<Statement> slice) {
int count = 0;
for (Statement s : slice) {
if (s.getKind().equals(Statement.Kind.NORMAL)) {
AnalysisScope scope = s.getNode().getClassHierarchy().getScope();
if (scope.isApplicationLoader(s.getNode().getMethod().getDeclaringClass().getClassLoader())) {
count++;
}
}
}
return count;
}
public static int countConditionals(Collection<Statement> slice) {
int count = 0;
for (Statement s : slice) {
if (s.getKind().equals(Statement.Kind.NORMAL)) {
NormalStatement ns = (NormalStatement) s;
if (ns.getInstruction() instanceof SSAConditionalBranchInstruction) {
count++;
}
}
}
return count;
}
public static int countInvokes(Collection<Statement> slice) {
int count = 0;
for (Statement s : slice) {
if (s.getKind().equals(Statement.Kind.NORMAL)) {
NormalStatement ns = (NormalStatement) s;
if (ns.getInstruction() instanceof SSAAbstractInvokeInstruction) {
count++;
}
}
}
return count;
}
public static int countPutfields(Collection<Statement> slice) {
int count = 0;
for (Statement s : slice) {
if (s.getKind().equals(Statement.Kind.NORMAL)) {
NormalStatement ns = (NormalStatement) s;
if (ns.getInstruction() instanceof SSAPutInstruction) {
SSAPutInstruction p = (SSAPutInstruction) ns.getInstruction();
if (!p.isStatic()) {
count++;
}
}
}
}
return count;
}
public static int countReturns(Collection<Statement> slice) {
int count = 0;
for (Statement s: slice) {
if (s.getKind().equals(Statement.Kind.NORMAL)) {
NormalStatement ns = (NormalStatement) s;
if (ns.getInstruction() instanceof SSAReturnInstruction) {
count++;
}
}
}
return count;
}
public static int countGetfields(Collection<Statement> slice) {
int count = 0;
for (Statement s : slice) {
if (s.getKind().equals(Statement.Kind.NORMAL)) {
NormalStatement ns = (NormalStatement) s;
if (ns.getInstruction() instanceof SSAGetInstruction) {
SSAGetInstruction p = (SSAGetInstruction) ns.getInstruction();
if (!p.isStatic()) {
count++;
}
}
}
}
return count;
}
public static int countPutstatics(Collection<Statement> slice) {
int count = 0;
for (Statement s : slice) {
if (s.getKind().equals(Statement.Kind.NORMAL)) {
NormalStatement ns = (NormalStatement) s;
if (ns.getInstruction() instanceof SSAPutInstruction) {
SSAPutInstruction p = (SSAPutInstruction) ns.getInstruction();
if (p.isStatic()) {
count++;
}
}
}
}
return count;
}
public static int countGetstatics(Collection<Statement> slice) {
int count = 0;
for (Statement s : slice) {
if (s.getKind().equals(Statement.Kind.NORMAL)) {
NormalStatement ns = (NormalStatement) s;
if (ns.getInstruction() instanceof SSAGetInstruction) {
SSAGetInstruction p = (SSAGetInstruction) ns.getInstruction();
if (p.isStatic()) {
count++;
}
}
}
}
return count;
}
public static void dumpSlice(Collection<Statement> slice) {
dumpSlice(slice, new PrintWriter(System.err));
}
public static void dumpSlice(Collection<Statement> slice, PrintWriter w) {
w.println("SLICE:\n");
int i = 1;
for (Statement s : slice) {
String line = (i++) + " " + s;
w.println(line);
w.flush();
}
}
public static void dumpSliceToFile(Collection<Statement> slice, String fileName) throws FileNotFoundException {
File f = new File(fileName);
FileOutputStream fo = new FileOutputStream(f);
try (final PrintWriter w = new PrintWriter(fo)) {
dumpSlice(slice, w);
}
}
public static CGNode findMainMethod(CallGraph cg) {
Descriptor d = Descriptor.findOrCreateUTF8("([Ljava/lang/String;)V");
Atom name = Atom.findOrCreateUnicodeAtom("main");
return findMethod(cg, d, name);
}
/**
* @param cg
* @param d
* @param name
*/
private static CGNode findMethod(CallGraph cg, Descriptor d, Atom name) {
for (CGNode n : Iterator2Iterable.make(cg.getSuccNodes(cg.getFakeRootNode()))) {
if (n.getMethod().getName().equals(name) && n.getMethod().getDescriptor().equals(d)) {
return n;
}
}
// if it's not a successor of fake root, just iterate over everything
for (CGNode n : cg) {
if (n.getMethod().getName().equals(name) && n.getMethod().getDescriptor().equals(d)) {
return n;
}
}
Assertions.UNREACHABLE("failed to find method " + name);
return null;
}
public static CGNode findMethod(CallGraph cg, String name) {
Atom a = Atom.findOrCreateUnicodeAtom(name);
for (CGNode n : cg) {
if (n.getMethod().getName().equals(a)) {
return n;
}
}
System.err.println("call graph " + cg);
Assertions.UNREACHABLE("failed to find method " + name);
return null;
}
public static Statement findCallTo(CGNode n, String methodName) {
IR ir = n.getIR();
for (SSAInstruction s : Iterator2Iterable.make(ir.iterateAllInstructions())) {
if (s instanceof SSAInvokeInstruction) {
SSAInvokeInstruction call = (SSAInvokeInstruction) s;
if (call.getCallSite().getDeclaredTarget().getName().toString().equals(methodName)) {
IntSet indices = ir.getCallInstructionIndices(((SSAInvokeInstruction) s).getCallSite());
Assertions.productionAssertion(indices.size() == 1, "expected 1 but got " + indices.size());
return new NormalStatement(n, indices.intIterator().next());
}
}
}
Assertions.UNREACHABLE("failed to find call to " + methodName + " in " + n);
return null;
}
public static Statement findFirstAllocation(CGNode n) {
IR ir = n.getIR();
for (int i = 0; i < ir.getInstructions().length; i++) {
SSAInstruction s = ir.getInstructions()[i];
if (s instanceof SSANewInstruction) {
return new NormalStatement(n, i);
}
}
Assertions.UNREACHABLE("failed to find allocation in " + n);
return null;
}
private static Statement findCallToDoNothing(CGNode n) {
return findCallTo(n, "doNothing");
}
}