diff --git a/com.ibm.wala.cast.java.test.data/.classpath b/com.ibm.wala.cast.java.test.data/.classpath
index e8ea977a6..4f83b2397 100644
--- a/com.ibm.wala.cast.java.test.data/.classpath
+++ b/com.ibm.wala.cast.java.test.data/.classpath
@@ -2,6 +2,6 @@
-
+
diff --git a/com.ibm.wala.cast.java.test.data/.settings/org.eclipse.jdt.core.prefs b/com.ibm.wala.cast.java.test.data/.settings/org.eclipse.jdt.core.prefs
index 4c8bbd5ba..d5a912066 100644
--- a/com.ibm.wala.cast.java.test.data/.settings/org.eclipse.jdt.core.prefs
+++ b/com.ibm.wala.cast.java.test.data/.settings/org.eclipse.jdt.core.prefs
@@ -7,9 +7,9 @@ org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nul
org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate
-org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
-org.eclipse.jdt.core.compiler.compliance=1.7
+org.eclipse.jdt.core.compiler.compliance=1.8
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
@@ -106,7 +106,7 @@ org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disa
org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
-org.eclipse.jdt.core.compiler.source=1.7
+org.eclipse.jdt.core.compiler.source=1.8
org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0
diff --git a/com.ibm.wala.core.testdata/src/dynamicCG/CallbacksMainClass.java b/com.ibm.wala.core.testdata/src/dynamicCG/CallbacksMainClass.java
new file mode 100644
index 000000000..ad61873f6
--- /dev/null
+++ b/com.ibm.wala.core.testdata/src/dynamicCG/CallbacksMainClass.java
@@ -0,0 +1,33 @@
+package dynamicCG;
+
+import java.util.HashSet;
+import java.util.Set;
+
+public class CallbacksMainClass {
+
+ private static CallbacksMainClass instance;
+
+ static {
+ callSomethingStatic();
+ }
+
+ public static void main(String[] args) {
+ Set junk = new HashSet();
+ junk.add(instance);
+ System.err.println(junk.iterator().next().toString());
+ }
+
+ private static void callSomethingStatic() {
+ instance = new CallbacksMainClass();
+ }
+
+ @Override
+ public String toString() {
+ return callSomething();
+ }
+
+ private String callSomething() {
+ return "string";
+ }
+
+}
diff --git a/com.ibm.wala.core.tests/dat/Java60RegressionExclusions.txt b/com.ibm.wala.core.tests/dat/Java60RegressionExclusions.txt
index f2bc72dea..0a868f5a8 100644
--- a/com.ibm.wala.core.tests/dat/Java60RegressionExclusions.txt
+++ b/com.ibm.wala.core.tests/dat/Java60RegressionExclusions.txt
@@ -1,5 +1,3 @@
-apple\/.*
-com\/apple\/.*
java\/awt\/.*
javax\/swing\/.*
sun\/awt\/.*
@@ -13,6 +11,8 @@ com\/ibm\/security\/.*
org\/apache\/xerces\/.*
dalvik\/.*
java\/io\/ObjectStreamClass*
+apple\/.*
+com\/apple\/.*
jdk\/.*
org\/omg\/.*
org\/w3c\/.*
diff --git a/com.ibm.wala.core.tests/src/com/ibm/wala/core/tests/shrike/DynamicCallGraphTest.java b/com.ibm.wala.core.tests/src/com/ibm/wala/core/tests/shrike/DynamicCallGraphTest.java
index 559615a66..94fd48710 100644
--- a/com.ibm.wala.core.tests/src/com/ibm/wala/core/tests/shrike/DynamicCallGraphTest.java
+++ b/com.ibm.wala.core.tests/src/com/ibm/wala/core/tests/shrike/DynamicCallGraphTest.java
@@ -32,13 +32,11 @@ import com.ibm.wala.util.CancelException;
public class DynamicCallGraphTest extends DynamicCallGraphTestBase {
private static String testJarLocation = getClasspathEntry("com.ibm.wala.core.testdata");
-
- private static String testMain = "dynamicCG.MainClass";
-
- private CallGraph staticCG(String exclusionsFile) throws IOException, ClassHierarchyException, IllegalArgumentException, CancelException {
+
+ private CallGraph staticCG(String mainClass, String exclusionsFile) throws IOException, ClassHierarchyException, IllegalArgumentException, CancelException {
AnalysisScope scope = CallGraphTestUtil.makeJ2SEAnalysisScope(TestConstants.WALA_TESTDATA, exclusionsFile != null? exclusionsFile: CallGraphTestUtil.REGRESSION_EXCLUSIONS);
ClassHierarchy cha = ClassHierarchy.make(scope);
- Iterable entrypoints = com.ibm.wala.ipa.callgraph.impl.Util.makeMainEntrypoints(scope, cha, "LdynamicCG/MainClass");
+ Iterable entrypoints = com.ibm.wala.ipa.callgraph.impl.Util.makeMainEntrypoints(scope, cha, mainClass);
AnalysisOptions options = CallGraphTestUtil.makeAnalysisOptions(scope, entrypoints);
return CallGraphTestUtil.buildZeroOneCFA(options, new AnalysisCache(), cha, scope, false);
}
@@ -46,16 +44,24 @@ public class DynamicCallGraphTest extends DynamicCallGraphTestBase {
@Test
public void testGraph() throws IOException, ClassNotFoundException, InvalidClassFileException, FailureException, SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException, ClassHierarchyException, CancelException, InterruptedException {
instrument(testJarLocation);
- run(testMain, null);
- CallGraph staticCG = staticCG(null);
+ run("dynamicCG.MainClass", null);
+ CallGraph staticCG = staticCG("LdynamicCG/MainClass", null);
+ checkEdges(staticCG);
+ }
+
+ @Test
+ public void testCallbacks() throws IOException, ClassNotFoundException, InvalidClassFileException, FailureException, SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException, ClassHierarchyException, CancelException, InterruptedException {
+ instrument(testJarLocation);
+ run("dynamicCG.CallbacksMainClass", null);
+ CallGraph staticCG = staticCG("LdynamicCG/CallbacksMainClass", null);
checkEdges(staticCG);
}
@Test
public void testExclusions() throws IOException, ClassNotFoundException, InvalidClassFileException, FailureException, SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException, ClassHierarchyException, CancelException, InterruptedException {
instrument(testJarLocation);
- run(testMain, "ShrikeTestExclusions.txt");
- CallGraph staticCG = staticCG("ShrikeTestExclusions.txt");
+ run("dynamicCG.MainClass", "ShrikeTestExclusions.txt");
+ CallGraph staticCG = staticCG("LdynamicCG/MainClass", "ShrikeTestExclusions.txt");
checkEdges(staticCG);
}
diff --git a/com.ibm.wala.core.tests/src/com/ibm/wala/core/tests/shrike/DynamicCallGraphTestBase.java b/com.ibm.wala.core.tests/src/com/ibm/wala/core/tests/shrike/DynamicCallGraphTestBase.java
index 8dbcb8c61..038e0505c 100644
--- a/com.ibm.wala.core.tests/src/com/ibm/wala/core/tests/shrike/DynamicCallGraphTestBase.java
+++ b/com.ibm.wala.core.tests/src/com/ibm/wala/core/tests/shrike/DynamicCallGraphTestBase.java
@@ -61,9 +61,9 @@ public abstract class DynamicCallGraphTestBase extends WalaTestCase {
private boolean instrumentedJarBuilt = false;
- private static String instrumentedJarLocation = System.getProperty("java.io.tmpdir") + File.separator + "test.jar";
+ private String instrumentedJarLocation = System.getProperty("java.io.tmpdir") + File.separator + "test.jar";
- private static String cgLocation = System.getProperty("java.io.tmpdir") + File.separator + "cg.txt";
+ private String cgLocation = System.getProperty("java.io.tmpdir") + File.separator + "cg.txt";
protected void instrument(String testJarLocation) throws IOException, ClassNotFoundException, InvalidClassFileException, FailureException {
if (! instrumentedJarBuilt) {
@@ -116,8 +116,14 @@ public abstract class DynamicCallGraphTestBase extends WalaTestCase {
childJvm.setFailonerror(true);
childJvm.setFork(true);
+ if (new File(cgLocation).exists()) {
+ new File(cgLocation).delete();
+ }
+
childJvm.init();
- Process x = Runtime.getRuntime().exec(childJvm.getCommandLine().toString());
+ String commandLine = childJvm.getCommandLine().toString();
+ System.err.println(commandLine);
+ Process x = Runtime.getRuntime().exec(commandLine);
x.waitFor();
Assert.assertTrue("expected to create call graph", new File(cgLocation).exists());
@@ -149,7 +155,7 @@ public abstract class DynamicCallGraphTestBase extends WalaTestCase {
Pair x = Pair.make(caller, callee);
if (! edges.contains(x)) {
edges.add(x);
- System.err.println("found expected edge" + caller + " --> " + callee);
+ System.err.println("found expected edge " + caller + " --> " + callee);
}
}
}
@@ -189,6 +195,8 @@ public abstract class DynamicCallGraphTestBase extends WalaTestCase {
String callerClass = edge.nextToken();
if ("root".equals(callerClass)) {
caller = staticCG.getFakeRootNode();
+ } else if ("callbacks".equals(callerClass)) {
+ continue loop;
} else {
String callerMethod = edge.nextToken();
MethodReference callerRef = MethodReference.findOrCreate(TypeReference.findOrCreate(ClassLoaderReference.Application, "L" + callerClass), Selector.make(callerMethod));
diff --git a/com.ibm.wala.core/src/com/ibm/wala/analysis/reflection/java7/MethodHandles.java b/com.ibm.wala.core/src/com/ibm/wala/analysis/reflection/java7/MethodHandles.java
index e4139f823..293e4697b 100644
--- a/com.ibm.wala.core/src/com/ibm/wala/analysis/reflection/java7/MethodHandles.java
+++ b/com.ibm.wala.core/src/com/ibm/wala/analysis/reflection/java7/MethodHandles.java
@@ -51,7 +51,6 @@ import com.ibm.wala.util.functions.Function;
import com.ibm.wala.util.intset.IntSet;
import com.ibm.wala.util.intset.IntSetUtil;
-@SuppressWarnings("deprecation")
public class MethodHandles {
private static final IntSet self = IntSetUtil.make(new int[0]);
diff --git a/com.ibm.wala.core/src/com/ibm/wala/ipa/callgraph/cha/CHACallGraph.java b/com.ibm.wala.core/src/com/ibm/wala/ipa/callgraph/cha/CHACallGraph.java
index 7cd857cde..2e8287cc9 100644
--- a/com.ibm.wala.core/src/com/ibm/wala/ipa/callgraph/cha/CHACallGraph.java
+++ b/com.ibm.wala.core/src/com/ibm/wala/ipa/callgraph/cha/CHACallGraph.java
@@ -14,6 +14,7 @@ import java.lang.ref.SoftReference;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
+import java.util.Stack;
import com.ibm.wala.classLoader.CallSiteReference;
import com.ibm.wala.classLoader.IMethod;
@@ -32,9 +33,9 @@ import com.ibm.wala.shrikeBT.IInvokeInstruction;
import com.ibm.wala.ssa.DefUse;
import com.ibm.wala.ssa.IR;
import com.ibm.wala.util.CancelException;
+import com.ibm.wala.util.Predicate;
import com.ibm.wala.util.collections.ComposedIterator;
import com.ibm.wala.util.collections.EmptyIterator;
-import com.ibm.wala.util.Predicate;
import com.ibm.wala.util.collections.FilterIterator;
import com.ibm.wala.util.collections.HashMapFactory;
import com.ibm.wala.util.collections.HashSetFactory;
@@ -116,7 +117,8 @@ public class CHACallGraph extends BasicCallGraph {
for(Entrypoint e : entrypoints) {
root.addTarget(e.makeSite(programCounter++), null);
}
- closure(root, true);
+ newNodes.push(root);
+ closure();
isInitialized = true;
}
@@ -206,24 +208,6 @@ public class CHACallGraph extends BasicCallGraph {
protected CGNode makeFakeWorldClinitNode() throws CancelException {
return new CHARootNode(new FakeWorldClinitMethod(cha, options, cache), Everywhere.EVERYWHERE);
}
-
- private void closure(CGNode n, boolean fromRoot) throws CancelException {
- for(Iterator sites = n.iterateCallSites(); sites.hasNext(); ) {
- Iterator methods = getPossibleTargets(sites.next());
- while (methods.hasNext()) {
- IMethod target = methods.next();
- if (!target.isAbstract()) {
- CGNode callee = getNode(target, Everywhere.EVERYWHERE);
- if (callee == null) {
- callee = findOrCreateNode(target, Everywhere.EVERYWHERE);
- if (fromRoot) {
- registerEntrypoint(callee);
- }
- }
- }
- }
- }
- }
private int clinitPC = 0;
@@ -247,12 +231,35 @@ public class CHACallGraph extends BasicCallGraph {
return n;
}
+ private Stack newNodes = new Stack();
+
+ private void closure() throws CancelException {
+ while (! newNodes.isEmpty()) {
+ CGNode n = newNodes.pop();
+ for(Iterator sites = n.iterateCallSites(); sites.hasNext(); ) {
+ Iterator methods = getPossibleTargets(sites.next());
+ while (methods.hasNext()) {
+ IMethod target = methods.next();
+ if (!target.isAbstract()) {
+ CGNode callee = getNode(target, Everywhere.EVERYWHERE);
+ if (callee == null) {
+ callee = findOrCreateNode(target, Everywhere.EVERYWHERE);
+ if (n == getFakeRootNode()) {
+ registerEntrypoint(callee);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
private CGNode makeNewNode(IMethod method, Context C) throws CancelException {
CGNode n;
Key k = new Key(method, C);
n = new CHANode(method, C);
registerNode(k, n);
- closure(n, false);
+ newNodes.push(n);
return n;
}
diff --git a/com.ibm.wala.core/src/com/ibm/wala/ipa/callgraph/propagation/PropagationCallGraphBuilder.java b/com.ibm.wala.core/src/com/ibm/wala/ipa/callgraph/propagation/PropagationCallGraphBuilder.java
index 369cdd8c6..0ff3b85da 100644
--- a/com.ibm.wala.core/src/com/ibm/wala/ipa/callgraph/propagation/PropagationCallGraphBuilder.java
+++ b/com.ibm.wala.core/src/com/ibm/wala/ipa/callgraph/propagation/PropagationCallGraphBuilder.java
@@ -260,11 +260,8 @@ public abstract class PropagationCallGraphBuilder implements CallGraphBuilder {
/** BEGIN Custom change: throw exception on empty entry points. This is a severe issue that should not go undetected! */
if (entrypointCallSites.isEmpty()) {
- throw new IllegalStateException("Could not create a entrypoint callsites."
- + " This happens when some parameters of the method can not be generated automatically "
- + "(e.g. when they refer to an interface or an abstract class).");
- }
-
+ throw new IllegalStateException("Could not create a entrypoint callsites: " + Warnings.asString());
+ }
/** END Custom change: throw exception on empty entry points. This is a severe issue that should not go undetected! */
customInit();
diff --git a/com.ibm.wala.dalvik.test/source/com/ibm/wala/dalvik/test/callGraph/DroidBenchCGTest.java b/com.ibm.wala.dalvik.test/source/com/ibm/wala/dalvik/test/callGraph/DroidBenchCGTest.java
index bbb75e388..a59d36f5d 100644
--- a/com.ibm.wala.dalvik.test/source/com/ibm/wala/dalvik/test/callGraph/DroidBenchCGTest.java
+++ b/com.ibm.wala.dalvik.test/source/com/ibm/wala/dalvik/test/callGraph/DroidBenchCGTest.java
@@ -146,17 +146,19 @@ public abstract class DroidBenchCGTest extends DalvikCallGraphTestBase {
skipTests.add("Button2.apk");
}
- public static Collection