2007-06-03 21:54:49 +00:00
|
|
|
/******************************************************************************
|
|
|
|
* Copyright (c) 2002 - 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.cast.test;
|
|
|
|
|
2007-07-05 03:04:43 +00:00
|
|
|
import java.util.Collection;
|
|
|
|
import java.util.Iterator;
|
2007-06-03 21:54:49 +00:00
|
|
|
|
2017-03-18 02:04:17 +00:00
|
|
|
import org.junit.Assert;
|
|
|
|
|
2011-04-04 15:29:53 +00:00
|
|
|
import com.ibm.wala.cast.loader.AstMethod;
|
|
|
|
import com.ibm.wala.cast.tree.CAstSourcePositionMap.Position;
|
2007-07-05 03:04:43 +00:00
|
|
|
import com.ibm.wala.classLoader.CallSiteReference;
|
2007-06-03 21:54:49 +00:00
|
|
|
import com.ibm.wala.core.tests.util.WalaTestCase;
|
2007-07-05 03:04:43 +00:00
|
|
|
import com.ibm.wala.ipa.callgraph.CGNode;
|
|
|
|
import com.ibm.wala.ipa.callgraph.CallGraph;
|
|
|
|
import com.ibm.wala.ssa.IR;
|
2014-07-08 18:44:06 +00:00
|
|
|
import com.ibm.wala.ssa.SSACFG;
|
2011-04-04 15:29:53 +00:00
|
|
|
import com.ibm.wala.ssa.SSAInstruction;
|
2007-07-05 03:04:43 +00:00
|
|
|
import com.ibm.wala.util.collections.NonNullSingletonIterator;
|
2007-06-03 21:54:49 +00:00
|
|
|
|
|
|
|
public abstract class TestCallGraphShape extends WalaTestCase {
|
|
|
|
|
2014-07-08 18:44:06 +00:00
|
|
|
protected void verifyCFGAssertions(CallGraph CG, Object[][] assertionData) {
|
|
|
|
for(Object[] dat : assertionData) {
|
|
|
|
String function = (String) dat[0];
|
|
|
|
for(CGNode N : getNodes(CG, function)) {
|
|
|
|
int[][] edges = (int[][]) dat[1];
|
|
|
|
SSACFG cfg = N.getIR().getControlFlowGraph();
|
|
|
|
for (int i = 0; i < edges.length; i++) {
|
|
|
|
SSACFG.BasicBlock bb = cfg.getNode(i);
|
|
|
|
Assert.assertEquals("basic block " + i, edges[i].length, cfg.getSuccNodeCount(bb));
|
|
|
|
for (int j = 0; j < edges[i].length; j++) {
|
|
|
|
Assert.assertTrue(cfg.hasEdge(bb, cfg.getNode(edges[i][j])));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-04-04 15:29:53 +00:00
|
|
|
protected void verifySourceAssertions(CallGraph CG, Object[][] assertionData) {
|
|
|
|
for(Object[] dat : assertionData) {
|
|
|
|
String function = (String) dat[0];
|
|
|
|
for(CGNode N : getNodes(CG, function)) {
|
|
|
|
if (N.getMethod() instanceof AstMethod) {
|
|
|
|
AstMethod M = (AstMethod) N.getMethod();
|
|
|
|
SSAInstruction[] insts = N.getIR().getInstructions();
|
|
|
|
insts: for(int i = 0; i < insts.length; i++) {
|
|
|
|
SSAInstruction inst = insts[i];
|
|
|
|
if (inst != null) {
|
|
|
|
Position pos = M.getSourcePosition(i);
|
|
|
|
if (pos != null) {
|
|
|
|
String fileName = pos.getURL().toString();
|
|
|
|
if (fileName.lastIndexOf('/') >= 0) {
|
|
|
|
fileName = fileName.substring(fileName.lastIndexOf('/')+1);
|
|
|
|
}
|
|
|
|
for(int j = 0; j < assertionData.length; j++) {
|
|
|
|
String file = (String) assertionData[j][1];
|
|
|
|
if (file.indexOf('/') >= 0) {
|
|
|
|
file = file.substring(file.lastIndexOf('/') + 1);
|
|
|
|
}
|
|
|
|
if (file.equalsIgnoreCase(fileName)) {
|
|
|
|
if (pos.getFirstLine() >= (Integer) assertionData[j][2]
|
|
|
|
&&
|
2012-05-08 17:17:01 +00:00
|
|
|
(pos.getLastLine() != -1? pos.getLastLine(): pos.getFirstLine()) <= (Integer) assertionData[j][3]) {
|
2011-04-04 15:29:53 +00:00
|
|
|
System.err.println("found " + inst + " of " + M + " at expected position " + pos);
|
|
|
|
continue insts;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-05-08 17:17:01 +00:00
|
|
|
Assert.assertTrue("unexpected location " + pos + " for " + inst + " of " + M + "\n" + N.getIR(), false);
|
2011-04-04 15:29:53 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-06-03 21:54:49 +00:00
|
|
|
protected static class Name {
|
|
|
|
String name;
|
|
|
|
|
|
|
|
int instructionIndex;
|
|
|
|
|
|
|
|
int vn;
|
|
|
|
|
2007-06-03 23:35:43 +00:00
|
|
|
public Name(int vn, int instructionIndex, String name) {
|
2007-06-03 21:54:49 +00:00
|
|
|
this.vn = vn;
|
|
|
|
this.name = name;
|
|
|
|
this.instructionIndex = instructionIndex;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
protected void verifyNameAssertions(CallGraph CG, Object[][] assertionData) {
|
2017-11-28 20:26:09 +00:00
|
|
|
for (Object[] element : assertionData) {
|
|
|
|
Iterator<CGNode> NS = getNodes(CG, (String) element[0]).iterator();
|
2007-06-03 21:54:49 +00:00
|
|
|
while (NS.hasNext()) {
|
Fix nearly all Eclipse warnings about using raw types
Along the way, I also converted many "for (;;)" loops into modern
"for (:)" loops. I didn't systematically look for all opportunities
to do this, though. I merely made this change where I was already
converting raw Iterator uses into modern Iterator<...> uses.
Better use of generics also allowed many casts to become statically
redundant. I have removed all such redundant casts.
Only three raw-types warnings remain after this batch of fixes. All
three involve raw uses of CallGraphBuilder. I've tried to fix these
too, but it quickly snowballs into a cascade of changes that may or
may not eventually reach a statically-type-save fixed point. I may
give these last few problem areas another go in the future. For now,
though, the hundreds of other fixes seem worth keeping even if there
are a few stragglers.
This commit may change some public APIs, but only by making weaker
type signatures stronger by replacing raw types with generic types.
For example, we may change something like "Set" into "Set<String>",
but we're not adding new arguments, changing any
underlying (post-generics-erasure) types, etc.
2017-07-09 18:38:35 +00:00
|
|
|
CGNode N = NS.next();
|
2007-07-06 22:08:39 +00:00
|
|
|
IR ir = N.getIR();
|
2017-11-28 20:26:09 +00:00
|
|
|
Name[] names = (Name[]) element[1];
|
|
|
|
for (Name name : names) {
|
2007-06-03 21:54:49 +00:00
|
|
|
|
2017-11-28 20:26:09 +00:00
|
|
|
System.err.println("looking for " + name.name + ", " + name.vn + " in " + N);
|
2007-06-03 21:54:49 +00:00
|
|
|
|
2017-11-28 20:26:09 +00:00
|
|
|
String[] localNames = ir.getLocalNames(name.instructionIndex, name.vn);
|
2007-06-03 21:54:49 +00:00
|
|
|
|
|
|
|
boolean found = false;
|
2017-11-28 20:26:09 +00:00
|
|
|
for (String localName : localNames) {
|
|
|
|
if (localName.equals(name.name)) {
|
2007-06-03 21:54:49 +00:00
|
|
|
found = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-11-28 20:26:09 +00:00
|
|
|
Assert.assertTrue("no name " + name.name + " for " + N + "\n" + ir, found);
|
2007-06-03 21:54:49 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
protected void verifyGraphAssertions(CallGraph CG, Object[][] assertionData) {
|
2009-06-03 18:27:39 +00:00
|
|
|
// System.err.println(CG);
|
2007-06-03 21:54:49 +00:00
|
|
|
|
2009-01-19 15:12:39 +00:00
|
|
|
if (assertionData == null) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2007-06-03 21:54:49 +00:00
|
|
|
for (int i = 0; i < assertionData.length; i++) {
|
|
|
|
|
|
|
|
check_target: for (int j = 0; j < ((String[]) assertionData[i][1]).length; j++) {
|
Fix nearly all Eclipse warnings about using raw types
Along the way, I also converted many "for (;;)" loops into modern
"for (:)" loops. I didn't systematically look for all opportunities
to do this, though. I merely made this change where I was already
converting raw Iterator uses into modern Iterator<...> uses.
Better use of generics also allowed many casts to become statically
redundant. I have removed all such redundant casts.
Only three raw-types warnings remain after this batch of fixes. All
three involve raw uses of CallGraphBuilder. I've tried to fix these
too, but it quickly snowballs into a cascade of changes that may or
may not eventually reach a statically-type-save fixed point. I may
give these last few problem areas another go in the future. For now,
though, the hundreds of other fixes seem worth keeping even if there
are a few stragglers.
This commit may change some public APIs, but only by making weaker
type signatures stronger by replacing raw types with generic types.
For example, we may change something like "Set" into "Set<String>",
but we're not adding new arguments, changing any
underlying (post-generics-erasure) types, etc.
2017-07-09 18:38:35 +00:00
|
|
|
Iterator<CGNode> srcs = (assertionData[i][0] instanceof String) ? getNodes(CG, (String) assertionData[i][0]).iterator()
|
2017-03-12 03:20:51 +00:00
|
|
|
: new NonNullSingletonIterator<>(CG.getFakeRootNode());
|
2007-06-03 21:54:49 +00:00
|
|
|
|
|
|
|
Assert.assertTrue("cannot find " + assertionData[i][0], srcs.hasNext());
|
|
|
|
|
2011-04-27 13:58:56 +00:00
|
|
|
boolean checkAbsence = false;
|
|
|
|
String targetName = ((String[]) assertionData[i][1])[j];
|
|
|
|
if (targetName.startsWith("!")) {
|
|
|
|
checkAbsence = true;
|
|
|
|
targetName = targetName.substring(1);
|
|
|
|
}
|
|
|
|
|
2012-02-21 13:47:01 +00:00
|
|
|
while (srcs.hasNext()) {
|
Fix nearly all Eclipse warnings about using raw types
Along the way, I also converted many "for (;;)" loops into modern
"for (:)" loops. I didn't systematically look for all opportunities
to do this, though. I merely made this change where I was already
converting raw Iterator uses into modern Iterator<...> uses.
Better use of generics also allowed many casts to become statically
redundant. I have removed all such redundant casts.
Only three raw-types warnings remain after this batch of fixes. All
three involve raw uses of CallGraphBuilder. I've tried to fix these
too, but it quickly snowballs into a cascade of changes that may or
may not eventually reach a statically-type-save fixed point. I may
give these last few problem areas another go in the future. For now,
though, the hundreds of other fixes seem worth keeping even if there
are a few stragglers.
This commit may change some public APIs, but only by making weaker
type signatures stronger by replacing raw types with generic types.
For example, we may change something like "Set" into "Set<String>",
but we're not adding new arguments, changing any
underlying (post-generics-erasure) types, etc.
2017-07-09 18:38:35 +00:00
|
|
|
CGNode src = srcs.next();
|
|
|
|
for (Iterator<CallSiteReference> sites = src.iterateCallSites(); sites.hasNext();) {
|
|
|
|
CallSiteReference sr = sites.next();
|
2011-04-27 13:58:56 +00:00
|
|
|
|
Fix nearly all Eclipse warnings about using raw types
Along the way, I also converted many "for (;;)" loops into modern
"for (:)" loops. I didn't systematically look for all opportunities
to do this, though. I merely made this change where I was already
converting raw Iterator uses into modern Iterator<...> uses.
Better use of generics also allowed many casts to become statically
redundant. I have removed all such redundant casts.
Only three raw-types warnings remain after this batch of fixes. All
three involve raw uses of CallGraphBuilder. I've tried to fix these
too, but it quickly snowballs into a cascade of changes that may or
may not eventually reach a statically-type-save fixed point. I may
give these last few problem areas another go in the future. For now,
though, the hundreds of other fixes seem worth keeping even if there
are a few stragglers.
This commit may change some public APIs, but only by making weaker
type signatures stronger by replacing raw types with generic types.
For example, we may change something like "Set" into "Set<String>",
but we're not adding new arguments, changing any
underlying (post-generics-erasure) types, etc.
2017-07-09 18:38:35 +00:00
|
|
|
Iterator<CGNode> dsts = getNodes(CG, targetName).iterator();
|
2012-02-23 18:15:05 +00:00
|
|
|
if (! checkAbsence) {
|
|
|
|
Assert.assertTrue("cannot find " + targetName, dsts.hasNext());
|
|
|
|
}
|
|
|
|
|
2007-06-03 21:54:49 +00:00
|
|
|
while (dsts.hasNext()) {
|
Fix nearly all Eclipse warnings about using raw types
Along the way, I also converted many "for (;;)" loops into modern
"for (:)" loops. I didn't systematically look for all opportunities
to do this, though. I merely made this change where I was already
converting raw Iterator uses into modern Iterator<...> uses.
Better use of generics also allowed many casts to become statically
redundant. I have removed all such redundant casts.
Only three raw-types warnings remain after this batch of fixes. All
three involve raw uses of CallGraphBuilder. I've tried to fix these
too, but it quickly snowballs into a cascade of changes that may or
may not eventually reach a statically-type-save fixed point. I may
give these last few problem areas another go in the future. For now,
though, the hundreds of other fixes seem worth keeping even if there
are a few stragglers.
This commit may change some public APIs, but only by making weaker
type signatures stronger by replacing raw types with generic types.
For example, we may change something like "Set" into "Set<String>",
but we're not adding new arguments, changing any
underlying (post-generics-erasure) types, etc.
2017-07-09 18:38:35 +00:00
|
|
|
CGNode dst = dsts.next();
|
2017-11-28 20:26:09 +00:00
|
|
|
for (CGNode cgNode : CG.getPossibleTargets(src, sr)) {
|
|
|
|
if (cgNode.equals(dst)) {
|
2011-04-27 13:58:56 +00:00
|
|
|
if (checkAbsence) {
|
|
|
|
System.err.println(("found unexpected " + src + " --> " + dst + " at " + sr));
|
|
|
|
Assert.assertTrue("found edge " + assertionData[i][0] + " ---> " + targetName, false);
|
|
|
|
} else {
|
|
|
|
System.err.println(("found expected " + src + " --> " + dst + " at " + sr));
|
|
|
|
continue check_target;
|
|
|
|
}
|
2007-06-03 21:54:49 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-04-27 13:58:56 +00:00
|
|
|
System.err.println("cannot find edge " + assertionData[i][0] + " ---> " + targetName);
|
|
|
|
Assert.assertTrue("cannot find edge " + assertionData[i][0] + " ---> " + targetName, checkAbsence);
|
2007-06-03 21:54:49 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-10-02 19:30:03 +00:00
|
|
|
|
|
|
|
/**
|
2011-04-04 15:29:53 +00:00
|
|
|
* Verifies that none of the nodes that match the source description has an edge to any of the nodes that match the destination
|
2010-10-02 19:30:03 +00:00
|
|
|
* description. (Used for checking for false connections in the callgraph)
|
|
|
|
*
|
|
|
|
* @param CG
|
|
|
|
* @param sourceDescription
|
|
|
|
* @param destDescription
|
|
|
|
*/
|
|
|
|
protected void verifyNoEdges(CallGraph CG, String sourceDescription, String destDescription) {
|
Fix nearly all Eclipse warnings about using raw types
Along the way, I also converted many "for (;;)" loops into modern
"for (:)" loops. I didn't systematically look for all opportunities
to do this, though. I merely made this change where I was already
converting raw Iterator uses into modern Iterator<...> uses.
Better use of generics also allowed many casts to become statically
redundant. I have removed all such redundant casts.
Only three raw-types warnings remain after this batch of fixes. All
three involve raw uses of CallGraphBuilder. I've tried to fix these
too, but it quickly snowballs into a cascade of changes that may or
may not eventually reach a statically-type-save fixed point. I may
give these last few problem areas another go in the future. For now,
though, the hundreds of other fixes seem worth keeping even if there
are a few stragglers.
This commit may change some public APIs, but only by making weaker
type signatures stronger by replacing raw types with generic types.
For example, we may change something like "Set" into "Set<String>",
but we're not adding new arguments, changing any
underlying (post-generics-erasure) types, etc.
2017-07-09 18:38:35 +00:00
|
|
|
Collection<CGNode> sources = getNodes(CG, sourceDescription);
|
|
|
|
Collection<CGNode> dests = getNodes(CG, destDescription);
|
2010-10-02 19:30:03 +00:00
|
|
|
for (Object source : sources) {
|
|
|
|
for (Object dest : dests) {
|
|
|
|
for (Iterator<CGNode> i = CG.getSuccNodes((CGNode) source); i.hasNext();) {
|
|
|
|
if (i.next().equals(dest)) {
|
|
|
|
Assert.fail("Found a link from " + source + " to " + dest);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-04-04 15:29:53 +00:00
|
|
|
protected static final Object ROOT = new Object() {
|
|
|
|
@Override
|
|
|
|
public String toString() {
|
|
|
|
return "CallGraphRoot";
|
|
|
|
}
|
|
|
|
};
|
2007-06-03 21:54:49 +00:00
|
|
|
|
2011-04-04 15:29:53 +00:00
|
|
|
protected abstract Collection<CGNode> getNodes(CallGraph CG, String functionIdentifier);
|
2007-06-03 21:54:49 +00:00
|
|
|
|
|
|
|
}
|