fix for handling of static methods in ContainerContextSelector

This commit is contained in:
Manu Sridharan 2013-05-14 14:17:26 -07:00
parent 0b557ac685
commit c0e3cb9831
3 changed files with 76 additions and 20 deletions

View File

@ -0,0 +1,27 @@
/*******************************************************************************
* Copyright (c) 2008 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 demandpa;
import java.util.Arrays;
public class TestArraysCopyOf {
public static void main(String[] args) {
Object[] o1 = new Object[1];
Object[] o2 = new Object[1];
o1[0] = new A();
o2[0] = new B();
Object[] o3 = Arrays.copyOf(o1, 1, Object[].class);
Arrays.copyOf(o2, 1, Object[].class);
Object x = o3[0];
DemandPATestUtil.testThisVar(x);
}
}

View File

@ -20,6 +20,7 @@ import org.junit.Test;
import com.ibm.wala.classLoader.IClass;
import com.ibm.wala.classLoader.IMethod;
import com.ibm.wala.core.tests.demandpa.AbstractPtrTest;
import com.ibm.wala.core.tests.util.TestConstants;
import com.ibm.wala.core.tests.util.WalaTestCase;
import com.ibm.wala.ipa.callgraph.AnalysisCache;
@ -27,11 +28,15 @@ 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.CallGraphStats;
import com.ibm.wala.ipa.callgraph.Entrypoint;
import com.ibm.wala.ipa.callgraph.impl.AllApplicationEntrypoints;
import com.ibm.wala.ipa.callgraph.impl.DefaultEntrypoint;
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.PointerKey;
import com.ibm.wala.ipa.callgraph.propagation.SSAPropagationCallGraphBuilder;
import com.ibm.wala.ipa.cfg.BasicBlockInContext;
import com.ibm.wala.ipa.cfg.InterproceduralCFG;
@ -48,6 +53,7 @@ import com.ibm.wala.util.debug.Assertions;
import com.ibm.wala.util.graph.Graph;
import com.ibm.wala.util.graph.GraphIntegrity;
import com.ibm.wala.util.graph.GraphIntegrity.UnsoundGraphException;
import com.ibm.wala.util.intset.OrdinalSet;
import com.ibm.wala.util.strings.Atom;
import com.ibm.wala.util.warnings.Warnings;
@ -235,6 +241,23 @@ public class CallGraphTest extends WalaTestCase {
CallGraphTestUtil.buildZeroCFA(options, new AnalysisCache(), cha, scope, false);
}
@Test
public void testZeroOneContainerCopyOf() throws IOException, ClassHierarchyException, IllegalArgumentException, CancelException {
AnalysisScope scope = CallGraphTestUtil.makeJ2SEAnalysisScope(TestConstants.WALA_TESTDATA,
CallGraphTestUtil.REGRESSION_EXCLUSIONS);
ClassHierarchy cha = ClassHierarchy.make(scope);
Iterable<Entrypoint> entrypoints = Util.makeMainEntrypoints(scope, cha, "Ldemandpa/TestArraysCopyOf");
AnalysisOptions options = CallGraphTestUtil.makeAnalysisOptions(scope, entrypoints);
AnalysisCache cache = new AnalysisCache();
CallGraphBuilder builder = Util.makeZeroOneContainerCFABuilder(options, cache, cha, scope);
CallGraph cg = builder.makeCallGraph(options, null);
PointerAnalysis pa = builder.getPointerAnalysis();
CGNode mainMethod = AbstractPtrTest.findMainMethod(cg);
PointerKey keyToQuery = AbstractPtrTest.getParam(mainMethod, "testThisVar", pa.getHeapModel());
OrdinalSet<InstanceKey> pointsToSet = pa.getPointsToSet(keyToQuery);
Assert.assertEquals(1, pointsToSet.size());
}
/**
* make main entrypoints, even in the primordial loader.
*/

View File

@ -112,7 +112,7 @@ public class ContainerContextSelector implements ContextSelector {
if (keys != null && keys.length > 0 && keys[0] != null) {
receiver = keys[0];
}
if (receiver != null && mayUnderstand(caller, site, callee, receiver)) {
if (mayUnderstand(caller, site, callee, receiver)) {
if (DEBUG) {
System.err.println("May Understand: " + callee + " recv " + receiver);
}
@ -280,6 +280,9 @@ public class ContainerContextSelector implements ContextSelector {
if (site.isStatic()) {
return false;
}
if (receiver == null) {
return false;
}
if (targetMethod.getDeclaringClass().getReference().equals(TypeReference.JavaLangObject)) {
// ramp down context: assuming methods on java.lang.Object don't cause pollution
// important for containers that invoke reflection
@ -289,25 +292,28 @@ public class ContainerContextSelector implements ContextSelector {
return true;
}
if (receiver == null) {
// any possible receiver. However, we will only handle this call
// if the concrete receiver type is interesting.
IClass klass = targetMethod.getDeclaringClass();
int n = cha.getNumberOfImmediateSubclasses(klass);
if (n > 0) {
// the receiver is not "effectively final".
// give up and assume we might see an interesting subclass.
return true;
}
// only one possible receiver class
if (delegate.isInteresting(klass)) {
// we may create a receiver instance context for this call
return true;
} else {
// we will never create a receiver instance context for this call
return false;
}
}
// TODO MS disabling logic below; it has been disabled anyway
// for a while since we were avoiding calling this method with
// receiver == null. Should we delete it?
// if (receiver == null) {
// // any possible receiver. However, we will only handle this call
// // if the concrete receiver type is interesting.
// IClass klass = targetMethod.getDeclaringClass();
// int n = cha.getNumberOfImmediateSubclasses(klass);
// if (n > 0) {
// // the receiver is not "effectively final".
// // give up and assume we might see an interesting subclass.
// return true;
// }
// // only one possible receiver class
// if (delegate.isInteresting(klass)) {
// // we may create a receiver instance context for this call
// return true;
// } else {
// // we will never create a receiver instance context for this call
// return false;
// }
// }
if (!delegate.isInteresting(receiver.getConcreteType())) {
return false;
}