import IR.SymbolTable;
import IR.TypeDescriptor;
import IR.VarDescriptor;
-import IR.Flat.FlatMethod;
import IR.Tree.ArrayAccessNode;
import IR.Tree.AssignmentNode;
import IR.Tree.BlockExpressionNode;
// map a method descriptor to a method lattice
private Map<MethodDescriptor, SSJavaLattice<String>> md2lattice;
- // map a method descriptor to a lattice mapping
- private Map<MethodDescriptor, Map<VarDescriptor, String>> md2LatticeMapping;
-
- // map a method descriptor to a lattice mapping
- private Map<MethodDescriptor, Map<FieldDescriptor, String>> cd2LatticeMapping;
-
- // map a method descriptor to the set of hierarchy relations that are
- // contributed from the callee
- private Map<MethodDescriptor, Set<ParamIndexRelation>> mapMethodDescriptorToCalleeParamRelationSet;
-
// map a method descriptor to the set of method invocation nodes which are
// invoked by the method descriptor
private Map<MethodDescriptor, Set<MethodInvokeNode>> mapMethodDescriptorToMethodInvokeNodeSet;
private Map<MethodInvokeNode, Map<Integer, NTuple<Descriptor>>> mapMethodInvokeNodeToArgIdxMap;
+ private Map<MethodDescriptor, MethodLocationInfo> mapLatticeToMethodLocationInfo;
+
+ private Map<MethodDescriptor, Set<MethodDescriptor>> mapMethodDescToPossibleMethodDescSet;
+
boolean debug = true;
public LocationInference(SSJavaAnalysis ssjava, State state) {
this.cd2lattice = new HashMap<ClassDescriptor, SSJavaLattice<String>>();
this.md2lattice = new HashMap<MethodDescriptor, SSJavaLattice<String>>();
this.methodDescriptorsToVisitStack = new Stack<MethodDescriptor>();
- this.md2LatticeMapping = new HashMap<MethodDescriptor, Map<VarDescriptor, String>>();
- this.cd2LatticeMapping = new HashMap<MethodDescriptor, Map<FieldDescriptor, String>>();
- this.mapMethodDescriptorToCalleeParamRelationSet =
- new HashMap<MethodDescriptor, Set<ParamIndexRelation>>();
this.mapMethodDescriptorToMethodInvokeNodeSet =
new HashMap<MethodDescriptor, Set<MethodInvokeNode>>();
this.mapMethodInvokeNodeToArgIdxMap =
new HashMap<MethodInvokeNode, Map<Integer, NTuple<Descriptor>>>();
-
+ this.mapLatticeToMethodLocationInfo = new HashMap<MethodDescriptor, MethodLocationInfo>();
+ this.mapMethodDescToPossibleMethodDescSet =
+ new HashMap<MethodDescriptor, Set<MethodDescriptor>>();
}
public void setupToAnalyze() {
debug_writeLatticeDotFile();
+ // 3) check properties
+ checkLattices();
+
+ }
+
+ private void checkLattices() {
+
+ LinkedList<MethodDescriptor> descriptorListToAnalyze = ssjava.getSortedDescriptors();
+
+ // current descriptors to visit in fixed-point interprocedural analysis,
+ // prioritized by
+ // dependency in the call graph
+ methodDescriptorsToVisitStack.clear();
+
+ descriptorListToAnalyze.removeFirst();
+
+ Set<MethodDescriptor> methodDescriptorToVistSet = new HashSet<MethodDescriptor>();
+ methodDescriptorToVistSet.addAll(descriptorListToAnalyze);
+
+ while (!descriptorListToAnalyze.isEmpty()) {
+ MethodDescriptor md = descriptorListToAnalyze.removeFirst();
+ checkLatticesOfVirtualMethods(md);
+ }
+
}
private void debug_writeLatticeDotFile() {
// do fixed-point analysis
- // perform method READ/OVERWRITE analysis
LinkedList<MethodDescriptor> descriptorListToAnalyze = ssjava.getSortedDescriptors();
// current descriptors to visit in fixed-point interprocedural analysis,
MethodDescriptor md = methodDescriptorsToVisitStack.pop();
SSJavaLattice<String> methodLattice =
- new SSJavaLattice<String>(SSJavaLattice.TOP, SSJavaLattice.BOTTOM);
+ new SSJavaLattice<String>(SSJavaAnalysis.TOP, SSJavaAnalysis.BOTTOM);
System.out.println();
System.out.println("SSJAVA: Inferencing the lattice from " + md);
SSJavaLattice<String> prevMethodLattice = getMethodLattice(md);
if (!methodLattice.equals(prevMethodLattice)) {
- md2lattice.put(md, methodLattice);
+
+ setMethodLattice(md, methodLattice);
// results for callee changed, so enqueue dependents caller for
// further analysis
}
+ private void checkLatticesOfVirtualMethods(MethodDescriptor md) {
+
+ if (!md.isStatic()) {
+ Set<MethodDescriptor> setPossibleCallees = new HashSet<MethodDescriptor>();
+ setPossibleCallees.addAll(ssjava.getCallGraph().getMethods(md));
+
+ for (Iterator iterator = setPossibleCallees.iterator(); iterator.hasNext();) {
+ MethodDescriptor mdCallee = (MethodDescriptor) iterator.next();
+ if (!md.equals(mdCallee)) {
+ checkConsistency(md, mdCallee);
+ }
+ }
+
+ }
+
+ }
+
+ private void checkConsistency(MethodDescriptor md1, MethodDescriptor md2) {
+
+ // check that two lattice have the same relations between parameters(+PC
+ // LOC, RETURN LOC)
+
+ MethodLocationInfo methodInfo1 = getMethodLocationInfo(md1);
+
+ SSJavaLattice<String> lattice1 = getMethodLattice(md1);
+ SSJavaLattice<String> lattice2 = getMethodLattice(md2);
+
+ Set<String> paramLocNameSet1 = methodInfo1.getParameterLocNameSet();
+
+ for (Iterator iterator = paramLocNameSet1.iterator(); iterator.hasNext();) {
+ String locName1 = (String) iterator.next();
+ for (Iterator iterator2 = paramLocNameSet1.iterator(); iterator2.hasNext();) {
+ String locName2 = (String) iterator2.next();
+
+ // System.out.println("COMPARE " + locName1 + " - " + locName2 + " "
+ // + lattice1.isGreaterThan(locName1, locName2) + "-"
+ // + lattice2.isGreaterThan(locName1, locName2));
+
+ if (!locName1.equals(locName2)) {
+
+ boolean r1 = lattice1.isGreaterThan(locName1, locName2);
+ boolean r2 = lattice2.isGreaterThan(locName1, locName2);
+
+ if (r1 != r2) {
+ throw new Error("The method " + md1 + " is not consistent with the method " + md2
+ + ".:: They have a different ordering relation between parameters " + locName1
+ + " and " + locName2 + ".");
+ }
+ }
+
+ }
+ }
+
+ }
+
private String getSymbol(int idx, FlowNode node) {
Descriptor desc = node.getDescTuple().get(idx);
return desc.getSymbol();
private void analyzeMethodLattice(MethodDescriptor md, SSJavaLattice<String> methodLattice) {
+ MethodLocationInfo methodInfo = getMethodLocationInfo(md);
+
// first take a look at method invocation nodes to newly added relations
// from the callee
analyzeLatticeMethodInvocationNode(md);
// visit each node of method flow graph
-
FlowGraph fg = getFlowGraph(md);
Set<FlowNode> nodeSet = fg.getNodeSet();
for (Iterator iterator = nodeSet.iterator(); iterator.hasNext();) {
FlowNode srcNode = (FlowNode) iterator.next();
- // first, take a look at directly connected nodes
Set<FlowEdge> outEdgeSet = srcNode.getOutEdgeSet();
for (Iterator iterator2 = outEdgeSet.iterator(); iterator2.hasNext();) {
FlowEdge outEdge = (FlowEdge) iterator2.next();
FlowNode dstNode = outEdge.getDst();
- addRelationToLattice(md, methodLattice, srcNode, dstNode);
+ NTuple<Descriptor> srcNodeTuple = srcNode.getDescTuple();
+ NTuple<Descriptor> dstNodeTuple = dstNode.getDescTuple();
+
+ if (outEdge.getInitTuple().equals(srcNodeTuple)
+ && outEdge.getEndTuple().equals(dstNodeTuple)) {
+
+ if ((srcNodeTuple.size() > 1 && dstNodeTuple.size() > 1)
+ && srcNodeTuple.get(0).equals(dstNodeTuple.get(0))) {
+
+ // value flows between fields
+ VarDescriptor varDesc = (VarDescriptor) srcNodeTuple.get(0);
+ ClassDescriptor varClassDesc = varDesc.getType().getClassDesc();
+ extractRelationFromFieldFlows(varClassDesc, srcNode, dstNode, 1);
+
+ } else {
+ // in this case, take a look at connected nodes at the local level
+ addRelationToLattice(md, methodLattice, srcNode, dstNode);
+ }
+
+ }
}
}
+ // grab the this location if the method use the 'this' reference
+ String thisLocSymbol = md.getThis().getSymbol();
+ if (methodLattice.getKeySet().contains(thisLocSymbol)) {
+ methodInfo.setThisLocName(thisLocSymbol);
+ }
+
+ // calculate a return location
+ if (!md.getReturnType().isVoid()) {
+ Set<FlowNode> returnNodeSet = fg.getReturnNodeSet();
+ Set<String> returnVarSymbolSet = new HashSet<String>();
+
+ for (Iterator iterator = returnNodeSet.iterator(); iterator.hasNext();) {
+ FlowNode rtrNode = (FlowNode) iterator.next();
+ String localSymbol = rtrNode.getDescTuple().get(0).getSymbol();
+ returnVarSymbolSet.add(localSymbol);
+ }
+
+ String returnGLB = methodLattice.getGLB(returnVarSymbolSet);
+ if (returnGLB.equals(SSJavaAnalysis.BOTTOM)) {
+ // need to insert a new location in-between the bottom and all locations
+ // that is directly connected to the bottom
+ String returnNewLocationSymbol = "Loc" + (SSJavaLattice.seed++);
+ methodLattice.insertNewLocationAtOneLevelHigher(returnGLB, returnNewLocationSymbol);
+ methodInfo.setReturnLocName(returnNewLocationSymbol);
+ } else {
+ methodInfo.setReturnLocName(returnGLB);
+ }
+ }
+
}
private void analyzeLatticeMethodInvocationNode(MethodDescriptor mdCaller) {
String paramSymbol1 = getSymbol(0, paramFlowNode1);
String paramSymbol2 = getSymbol(0, paramFlowNode2);
- // if two parameters have relation, we need to propagate this relation
+ // if two parameters have a relation, we need to propagate this relation
// to the caller
- if (calleeLattice.isComparable(paramSymbol1, paramSymbol2)) {
+ if (!(paramSymbol1.equals(paramSymbol2))
+ && calleeLattice.isComparable(paramSymbol1, paramSymbol2)) {
int higherLocIdxCallee;
int lowerLocIdxCallee;
if (calleeLattice.isGreaterThan(paramSymbol1, paramSymbol2)) {
}
- private void addRelationToLattice(MethodDescriptor md, SSJavaLattice<String> methodLattice,
- FlowNode srcNode, FlowNode dstNode) {
- if ((srcNode.getDescTuple().size() > 1 && dstNode.getDescTuple().size() > 1)
- && srcNode.getDescTuple().get(0).equals(dstNode.getDescTuple().get(0))) {
- // value flow between fields: we don't need to add a binary relation
- // for this case
-
- VarDescriptor varDesc = (VarDescriptor) srcNode.getDescTuple().get(0);
- ClassDescriptor varClassDesc = varDesc.getType().getClassDesc();
+ private MethodLocationInfo getMethodLocationInfo(MethodDescriptor md) {
- extractRelationFromFieldFlows(varClassDesc, srcNode, dstNode, 1);
- return;
+ if (!mapLatticeToMethodLocationInfo.containsKey(md)) {
+ mapLatticeToMethodLocationInfo.put(md, new MethodLocationInfo(md));
}
- // add a new binary relation of dstNode < srcNode
+ return mapLatticeToMethodLocationInfo.get(md);
+
+ }
+ private void addRelationToLattice(MethodDescriptor md, SSJavaLattice<String> methodLattice,
+ FlowNode srcNode, FlowNode dstNode) {
+
+ // add a new binary relation of dstNode < srcNode
String srcSymbol = getSymbol(0, srcNode);
String dstSymbol = getSymbol(0, dstNode);
- methodLattice.addRelationHigherToLower(srcSymbol, dstSymbol);
+ FlowGraph flowGraph = getFlowGraph(md);
+ MethodLocationInfo methodInfo = getMethodLocationInfo(md);
+
+ if (srcNode.isParameter()) {
+ int paramIdx = flowGraph.getParamIdx(srcNode.getDescTuple());
+ methodInfo.addParameter(srcSymbol, srcNode, paramIdx);
+ }
+ if (dstNode.isParameter()) {
+ int paramIdx = flowGraph.getParamIdx(dstNode.getDescTuple());
+ methodInfo.addParameter(dstSymbol, dstNode, paramIdx);
+ }
+
+ if (!methodLattice.isGreaterThan(srcSymbol, dstSymbol)) {
+ // if the lattice does not have this relation, add it
+ methodLattice.addRelationHigherToLower(srcSymbol, dstSymbol);
+ }
}
private SSJavaLattice<String> getMethodLattice(MethodDescriptor md) {
-
if (!md2lattice.containsKey(md)) {
- md2lattice.put(md, new SSJavaLattice<String>(SSJavaLattice.TOP, SSJavaLattice.BOTTOM));
+ md2lattice.put(md, new SSJavaLattice<String>(SSJavaAnalysis.TOP, SSJavaAnalysis.BOTTOM));
}
return md2lattice.get(md);
}
+ private void setMethodLattice(MethodDescriptor md, SSJavaLattice<String> lattice) {
+ md2lattice.put(md, lattice);
+ }
+
private void extractRelationFromFieldFlows(ClassDescriptor cd, FlowNode srcNode,
FlowNode dstNode, int idx) {
- if (srcNode.getDescTuple().get(idx).equals(dstNode.getDescTuple().get(idx))) {
+ if (srcNode.getDescTuple().get(idx).equals(dstNode.getDescTuple().get(idx))
+ && srcNode.getDescTuple().size() > (idx + 1) && dstNode.getDescTuple().size() > (idx + 1)) {
// value flow between fields: we don't need to add a binary relation
// for this case
- VarDescriptor varDesc = (VarDescriptor) srcNode.getDescTuple().get(idx);
- ClassDescriptor varClassDesc = varDesc.getType().getClassDesc();
- extractRelationFromFieldFlows(varClassDesc, srcNode, dstNode, idx + 1);
+
+ Descriptor desc = srcNode.getDescTuple().get(idx);
+ ClassDescriptor classDesc;
+
+ if (idx == 0) {
+ classDesc = ((VarDescriptor) desc).getType().getClassDesc();
+ } else {
+ classDesc = ((FieldDescriptor) desc).getType().getClassDesc();
+ }
+
+ extractRelationFromFieldFlows(classDesc, srcNode, dstNode, idx + 1);
+
} else {
Descriptor srcFieldDesc = srcNode.getDescTuple().get(idx);
Descriptor dstFieldDesc = dstNode.getDescTuple().get(idx);
// add a new binary relation of dstNode < srcNode
-
SSJavaLattice<String> fieldLattice = getFieldLattice(cd);
- fieldLattice.addRelationHigherToLower(srcFieldDesc.getSymbol(), dstFieldDesc.getSymbol());
+
+ String srcSymbol = srcFieldDesc.getSymbol();
+ String dstSymbol = dstFieldDesc.getSymbol();
+
+ if (!fieldLattice.isGreaterThan(srcSymbol, dstSymbol)) {
+ fieldLattice.addRelationHigherToLower(srcSymbol, dstSymbol);
+ }
}
public SSJavaLattice<String> getFieldLattice(ClassDescriptor cd) {
if (!cd2lattice.containsKey(cd)) {
- cd2lattice.put(cd, new SSJavaLattice<String>(SSJavaLattice.TOP, SSJavaLattice.BOTTOM));
+ cd2lattice.put(cd, new SSJavaLattice<String>(SSJavaAnalysis.TOP, SSJavaAnalysis.BOTTOM));
}
return cd2lattice.get(cd);
}
MethodDescriptor md = toAnalyzeMethodNext();
if (ssjava.needTobeAnnotated(md)) {
if (state.SSJAVADEBUG) {
+ System.out.println();
System.out.println("SSJAVA: Constructing a flow graph: " + md);
}
- // creates a mapping from a parameter descriptor to its index
+ // creates a mapping from a method descriptor to virtual methods
+ Set<MethodDescriptor> setPossibleCallees = new HashSet<MethodDescriptor>();
+ if (md.isStatic()) {
+ setPossibleCallees.add(md);
+ } else {
+ setPossibleCallees.addAll(ssjava.getCallGraph().getMethods(md));
+ }
+ mapMethodDescToPossibleMethodDescSet.put(md, setPossibleCallees);
+ // creates a mapping from a parameter descriptor to its index
Map<Descriptor, Integer> mapParamDescToIdx = new HashMap<Descriptor, Integer>();
int offset = md.isStatic() ? 0 : 1;
for (int i = 0; i < md.numParameters(); i++) {
break;
case Kind.ReturnNode:
- analyzeReturnNode(md, nametable, (ReturnNode) bsn);
+ analyzeFlowReturnNode(md, nametable, (ReturnNode) bsn, implicitFlowTupleSet);
break;
case Kind.SubBlockNode:
analyzeFlowBlockNode(md, nametable, sbn.getBlockNode(), implicitFlowTupleSet);
}
- private void analyzeReturnNode(MethodDescriptor md, SymbolTable nametable, ReturnNode bsn) {
- // TODO Auto-generated method stub
+ private void analyzeFlowReturnNode(MethodDescriptor md, SymbolTable nametable, ReturnNode rn,
+ NodeTupleSet implicitFlowTupleSet) {
+
+ ExpressionNode returnExp = rn.getReturnExpression();
+
+ NodeTupleSet nodeSet = new NodeTupleSet();
+ analyzeFlowExpressionNode(md, nametable, returnExp, nodeSet, false);
+
+ FlowGraph fg = getFlowGraph(md);
+
+ // annotate the elements of the node set as the return location
+ for (Iterator iterator = nodeSet.iterator(); iterator.hasNext();) {
+ NTuple<Descriptor> returnDescTuple = (NTuple<Descriptor>) iterator.next();
+ fg.setReturnFlowNode(returnDescTuple);
+ for (Iterator iterator2 = implicitFlowTupleSet.iterator(); iterator2.hasNext();) {
+ NTuple<Descriptor> implicitFlowDescTuple = (NTuple<Descriptor>) iterator2.next();
+ fg.addValueFlowEdge(implicitFlowDescTuple, returnDescTuple);
+ }
+ }
}
// note that expression node can create more than one flow node
// nodeSet contains of flow nodes
- // base is always assigned to null except name node case!
+ // base is always assigned to null except the case of a name node!
NTuple<Descriptor> flowTuple;
private void analyzeFlowTertiaryNode(MethodDescriptor md, SymbolTable nametable, TertiaryNode tn,
NodeTupleSet nodeSet, NodeTupleSet implicitFlowTupleSet) {
- System.out.println("### analyzeFlowTertiaryNode=" + tn.printNode(0));
-
NodeTupleSet tertiaryTupleNode = new NodeTupleSet();
analyzeFlowExpressionNode(md, nametable, tn.getCond(), tertiaryTupleNode, null,
implicitFlowTupleSet, false);
// add edges from tertiaryTupleNode to all nodes of conditional nodes
tertiaryTupleNode.addTupleSet(implicitFlowTupleSet);
- System.out.println("### TertiarayNode's condition=" + tertiaryTupleNode);
analyzeFlowExpressionNode(md, nametable, tn.getTrueExpr(), tertiaryTupleNode, null,
implicitFlowTupleSet, false);
if (min.getExpression() != null) {
NodeTupleSet baseNodeSet = new NodeTupleSet();
- System.out.println("Analyzing base of method=" + min.getExpression());
analyzeFlowExpressionNode(calleeMD, nametable, min.getExpression(), baseNodeSet, null,
implicitFlowTupleSet, false);
NodeTupleSet rightOpSet = new NodeTupleSet();
// left operand
- System.out.println("Analyzing left op=" + on.getLeft().printNode(0) + "::"
- + on.getLeft().getClass());
analyzeFlowExpressionNode(md, nametable, on.getLeft(), leftOpSet, null, implicitFlowTupleSet,
false);
- System.out.println("leftOpSet=" + leftOpSet);
if (on.getRight() != null) {
// right operand
analyzeFlowExpressionNode(md, nametable, on.getRight(), rightOpSet, null,
implicitFlowTupleSet, false);
- System.out.println("rightOpSet=" + rightOpSet);
}
Operation op = on.getOp();
base.add(fd);
}
+ getFlowGraph(md).createNewFlowNode(base);
return base;
}
private void analyzeFlowAssignmentNode(MethodDescriptor md, SymbolTable nametable,
AssignmentNode an, NTuple<Descriptor> base, NodeTupleSet implicitFlowTupleSet) {
- System.out.println("analyzeFlowAssignmentNode=" + an);
-
NodeTupleSet nodeSetRHS = new NodeTupleSet();
NodeTupleSet nodeSetLHS = new NodeTupleSet();
// and its index value
analyzeFlowExpressionNode(md, nametable, an.getDest(), nodeSetLHS, null, implicitFlowTupleSet,
true);
- System.out.println("ASSIGNMENT NODE nodeSetLHS=" + nodeSetLHS);
if (!postinc) {
// analyze value flows of rhs expression
analyzeFlowExpressionNode(md, nametable, an.getSrc(), nodeSetRHS, null, implicitFlowTupleSet,
false);
- System.out.println("ASSIGNMENT NODE nodeSetRHS=" + nodeSetRHS);
// creates edges from RHS to LHS
for (Iterator<NTuple<Descriptor>> iter = nodeSetRHS.iterator(); iter.hasNext();) {
return mapMethodDescriptorToFlowGraph.get(md);
}
- public boolean addFlowGraphEdge(MethodDescriptor md, NTuple<Descriptor> from,
+ private boolean addFlowGraphEdge(MethodDescriptor md, NTuple<Descriptor> from,
NTuple<Descriptor> to) {
// TODO
// return true if it adds a new edge
}
}
-
-class ParamIndexRelation {
- private Integer higherIdx;
- private Integer lowerIdx;
-}
+++ /dev/null
-package Analysis.SSJava;
-
-import java.io.FileWriter;
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashSet;
-import java.util.Hashtable;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Set;
-
-import IR.ClassDescriptor;
-import IR.Descriptor;
-import IR.FieldDescriptor;
-import IR.MethodDescriptor;
-import IR.NameDescriptor;
-import IR.Operation;
-import IR.State;
-import IR.SymbolTable;
-import IR.VarDescriptor;
-import IR.Tree.ArrayAccessNode;
-import IR.Tree.AssignmentNode;
-import IR.Tree.BlockExpressionNode;
-import IR.Tree.BlockNode;
-import IR.Tree.BlockStatementNode;
-import IR.Tree.CastNode;
-import IR.Tree.DeclarationNode;
-import IR.Tree.ExpressionNode;
-import IR.Tree.IfStatementNode;
-import IR.Tree.Kind;
-import IR.Tree.LiteralNode;
-import IR.Tree.LoopNode;
-import IR.Tree.NameNode;
-import IR.Tree.OpNode;
-import IR.Tree.ReturnNode;
-import IR.Tree.SubBlockNode;
-import IR.Tree.SwitchStatementNode;
-import IR.Tree.SwitchBlockNode;
-
-public class SSJavaInferenceEngine {
-
- State state;
- static SSJavaAnalysis ssjava;
-
- Set<ClassDescriptor> toanalyze;
- List<ClassDescriptor> toanalyzeList;
-
- Set<MethodDescriptor> toanalyzeMethod;
- List<MethodDescriptor> toanalyzeMethodList;
-
- // mapping from 'descriptor' to 'composite location'
- Hashtable<Descriptor, CompositeLocation> d2loc;
-
- Hashtable<MethodDescriptor, CompositeLocation> md2ReturnLoc;
- Hashtable<MethodDescriptor, ReturnLocGenerator> md2ReturnLocGen;
-
- // mapping from 'locID' to 'class descriptor'
- Hashtable<String, ClassDescriptor> fieldLocName2cd;
-
- private Set<ImplicitTuple> implicitFlowSet; /*
- * should maybe be
- * hashtable<ExpressionNode
- * ,Set<VarID>>
- */
- private RelationSet rSet;
-
- boolean deterministic = true;
-
- public SSJavaInferenceEngine(SSJavaAnalysis ssjava, State state) {
- this.ssjava = ssjava;
- this.state = state;
- if (deterministic) {
- this.toanalyzeList = new ArrayList<ClassDescriptor>();
- } else {
- this.toanalyze = new HashSet<ClassDescriptor>();
- }
- if (deterministic) {
- this.toanalyzeMethodList = new ArrayList<MethodDescriptor>();
- } else {
- this.toanalyzeMethod = new HashSet<MethodDescriptor>();
- }
- this.d2loc = new Hashtable<Descriptor, CompositeLocation>();
- this.fieldLocName2cd = new Hashtable<String, ClassDescriptor>();
- this.md2ReturnLoc = new Hashtable<MethodDescriptor, CompositeLocation>();
- this.md2ReturnLocGen = new Hashtable<MethodDescriptor, ReturnLocGenerator>();
- this.implicitFlowSet = new HashSet<ImplicitTuple>();
- this.rSet = new RelationSet();
- }
-
- public void init() {
-
- // construct mapping from the location name to the class descriptor
- // assume that the location name is unique through the whole program
-
- Set<ClassDescriptor> cdSet = ssjava.getCd2lattice().keySet();
- for (Iterator iterator = cdSet.iterator(); iterator.hasNext();) {
- ClassDescriptor cd = (ClassDescriptor) iterator.next();
- SSJavaLattice<String> lattice = ssjava.getCd2lattice().get(cd);
- Set<String> fieldLocNameSet = lattice.getKeySet();
-
- for (Iterator iterator2 = fieldLocNameSet.iterator(); iterator2.hasNext();) {
- String fieldLocName = (String) iterator2.next();
- fieldLocName2cd.put(fieldLocName, cd);
- }
-
- }
-
- }
-
- public boolean toAnalyzeIsEmpty() {
- if (deterministic) {
- return toanalyzeList.isEmpty();
- } else {
- return toanalyze.isEmpty();
- }
- }
-
- public ClassDescriptor toAnalyzeNext() {
- if (deterministic) {
- return toanalyzeList.remove(0);
- } else {
- ClassDescriptor cd = toanalyze.iterator().next();
- toanalyze.remove(cd);
- return cd;
- }
- }
-
- public void setupToAnalyze() {
- SymbolTable classtable = state.getClassSymbolTable();
- if (deterministic) {
- toanalyzeList.clear();
- toanalyzeList.addAll(classtable.getValueSet());
- Collections.sort(toanalyzeList, new Comparator<ClassDescriptor>() {
- public int compare(ClassDescriptor o1, ClassDescriptor o2) {
- return o1.getClassName().compareTo(o2.getClassName());
- }
- });
- } else {
- toanalyze.clear();
- toanalyze.addAll(classtable.getValueSet());
- }
- }
-
- public void setupToAnalazeMethod(ClassDescriptor cd) {
-
- SymbolTable methodtable = cd.getMethodTable();
- if (deterministic) {
- toanalyzeMethodList.clear();
- toanalyzeMethodList.addAll(methodtable.getValueSet());
- Collections.sort(toanalyzeMethodList, new Comparator<MethodDescriptor>() {
- public int compare(MethodDescriptor o1, MethodDescriptor o2) {
- return o1.getSymbol().compareTo(o2.getSymbol());
- }
- });
- } else {
- toanalyzeMethod.clear();
- toanalyzeMethod.addAll(methodtable.getValueSet());
- }
- }
-
- public boolean toAnalyzeMethodIsEmpty() {
- if (deterministic) {
- return toanalyzeMethodList.isEmpty();
- } else {
- return toanalyzeMethod.isEmpty();
- }
- }
-
- public MethodDescriptor toAnalyzeMethodNext() {
- if (deterministic) {
- return toanalyzeMethodList.remove(0);
- } else {
- MethodDescriptor md = toanalyzeMethod.iterator().next();
- toanalyzeMethod.remove(md);
- return md;
- }
- }
-
- public void inference() {
- FileWriter latticeFile;
- PrintWriter latticeOut;
- setupToAnalyze();
-
- while (!toAnalyzeIsEmpty()) {
- ClassDescriptor cd = toAnalyzeNext();
- try {
- latticeFile = new FileWriter(cd.getClassName() + ".lat");
- } catch (IOException e) {
- System.out.println("File Fail");
- return;
- }
- latticeOut = new PrintWriter(latticeFile);
- if (ssjava.needToBeAnnoated(cd)) {
- setupToAnalazeMethod(cd);
- while (!toAnalyzeMethodIsEmpty()) {
- MethodDescriptor md = toAnalyzeMethodNext();
- if (ssjava.needTobeAnnotated(md)) {
- inferRelationsFromBlockNode(md, md.getParameterTable(), state.getMethodBody(md));
- latticeOut.println(md.getClassMethodName() + "\n");
- latticeOut.println(rSet.toString());
- rSet = new RelationSet();
- }
- }
- }
- latticeOut.flush();
- latticeOut.close();
- }
- }
-
- private void inferRelationsFromBlockNode(MethodDescriptor md, SymbolTable nametable, BlockNode bn) {
-
- bn.getVarTable().setParent(nametable);
- for (int i = 0; i < bn.size(); i++) {
- BlockStatementNode bsn = bn.get(i);
- inferRelationsFromBlockStatementNode(md, bn.getVarTable(), bsn);
- }
-
- }
-
- private void inferRelationsFromBlockStatementNode(MethodDescriptor md, SymbolTable nametable,
- BlockStatementNode bsn) {
-
- switch (bsn.kind()) {
- case Kind.BlockExpressionNode:
- inferRelationsFromBlockExpressionNode(md, nametable, (BlockExpressionNode) bsn);
- break;
-
- case Kind.DeclarationNode:
- inferRelationsFromDeclarationNode(md, nametable, (DeclarationNode) bsn);
- break;
-
- case Kind.IfStatementNode:
- inferRelationsFromIfStatementNode(md, nametable, (IfStatementNode) bsn);
- break;
-
- case Kind.LoopNode:
- inferRelationsFromLoopNode(md, nametable, (LoopNode) bsn);
- break;
-
- case Kind.ReturnNode:
- inferRelationsFromReturnNode(md, nametable, (ReturnNode) bsn);
- break;
-
- case Kind.SubBlockNode:
- inferRelationsFromSubBlockNode(md, nametable, (SubBlockNode) bsn);
- break;
-
- case Kind.SwitchStatementNode:
- inferRelationsFromSwitchStatementNode(md, nametable, (SwitchStatementNode) bsn);
- break;
-
- default:
- System.out.println(bsn.kind() + " not handled...");
- break;
- }
- }
-
- private void inferRelationsFromSwitchStatementNode(MethodDescriptor md,
- SymbolTable nametable, SwitchStatementNode ssn) {
-
- ClassDescriptor cd = md.getClassDesc();
- VarID condID =
- inferRelationsFromExpressionNode(md, nametable, ssn.getCondition(), null, (BlockStatementNode) ssn, false);
- BlockNode sbn = ssn.getSwitchBody();
-
- for (int i = 0; i < sbn.size(); i++) {
- inferRelationsFromSwitchBlockNode(md, nametable, (SwitchBlockNode) sbn.get(i));
- }
-
- for(ImplicitTuple tuple: implicitFlowSet){
- if(tuple.isFromBranch((BlockStatementNode) ssn)){
- implicitFlowSet.remove(tuple);
- }
- }
- }
-
- private void inferRelationsFromSwitchBlockNode(MethodDescriptor md,
- SymbolTable nametable, SwitchBlockNode sbn) {
- inferRelationsFromBlockNode(md, nametable, sbn.getSwitchBlockStatement());
- }
-
- private void inferRelationsFromReturnNode(MethodDescriptor md, SymbolTable nametable,
- ReturnNode rn) {
-
- ExpressionNode returnExp = rn.getReturnExpression();
-
- // interim fixes
- VarID returnID = new VarID(md);
- returnID.setReturn();
- if (returnExp != null) {
- inferRelationsFromExpressionNode(md, nametable, returnExp, returnID, null, false);
- }
- }
-
- private void inferRelationsFromLoopNode(MethodDescriptor md, SymbolTable nametable, LoopNode ln) {
-
- ClassDescriptor cd = md.getClassDesc();
- if (ln.getType() == LoopNode.WHILELOOP || ln.getType() == LoopNode.DOWHILELOOP) {
-
- inferRelationsFromExpressionNode(md, nametable, ln.getCondition(), null, ln, false);
-
- inferRelationsFromBlockNode(md, nametable, ln.getBody());
-
- for (ImplicitTuple tuple : implicitFlowSet) {
- if (tuple.isFromBranch(ln)) {
- implicitFlowSet.remove(tuple);
- }
- }
-
- } else {
- // check 'for loop' case
- BlockNode bn = ln.getInitializer();
- bn.getVarTable().setParent(nametable);
-
- inferRelationsFromBlockNode(md, nametable, bn);
- inferRelationsFromExpressionNode(md, bn.getVarTable(), ln.getCondition(), null, ln, false);
-
- inferRelationsFromBlockNode(md, bn.getVarTable(), ln.getUpdate());
- inferRelationsFromBlockNode(md, bn.getVarTable(), ln.getBody());
-
- for (ImplicitTuple tuple : implicitFlowSet) {
- if (tuple.isFromBranch(ln)) {
- implicitFlowSet.remove(tuple);
- }
- }
-
- }
-
- }
-
- private void inferRelationsFromSubBlockNode(MethodDescriptor md,
- SymbolTable nametable, SubBlockNode sbn) {
- inferRelationsFromBlockNode(md, nametable.getParent(), sbn.getBlockNode());
- }
-
- private void inferRelationsFromIfStatementNode(MethodDescriptor md, SymbolTable nametable,
- IfStatementNode isn) {
-
- inferRelationsFromExpressionNode(md, nametable, isn.getCondition(), null, isn, false);
-
- inferRelationsFromBlockNode(md, nametable, isn.getTrueBlock());
-
- if (isn.getFalseBlock() != null) {
- inferRelationsFromBlockNode(md, nametable, isn.getFalseBlock());
- }
-
- for (ImplicitTuple tuple : implicitFlowSet) {
- if (tuple.isFromBranch(isn)) {
- implicitFlowSet.remove(tuple);
- }
- }
- }
-
- private void inferRelationsFromDeclarationNode(MethodDescriptor md, SymbolTable nametable,
- DeclarationNode dn) {
- }
-
- private void inferRelationsFromBlockExpressionNode(MethodDescriptor md,
- SymbolTable nametable, BlockExpressionNode ben) {
- inferRelationsFromExpressionNode(md, nametable, ben.getExpression(), null, null, false);
- }
-
- private VarID inferRelationsFromExpressionNode(MethodDescriptor md, SymbolTable nametable,
- ExpressionNode en, VarID flowTo, BlockStatementNode implicitTag, boolean isLHS) {
-
- VarID var = null;
- switch (en.kind()) {
-
- case Kind.AssignmentNode:
- var =
- inferRelationsFromAssignmentNode(md, nametable, (AssignmentNode) en, flowTo, implicitTag);
- break;
-
- // case Kind.FieldAccessNode:
- // var =
- // inferRelationsFromFieldAccessNode(md, nametable, (FieldAccessNode) en,
- // flowTo);
- // break;
-
- case Kind.NameNode:
- var = inferRelationsFromNameNode(md, nametable, (NameNode) en, flowTo, implicitTag);
- break;
-
- case Kind.OpNode:
- var = inferRelationsFromOpNode(md, nametable, (OpNode) en, flowTo, implicitTag);
- break;
- /*
- * case Kind.CreateObjectNode: var = inferRelationsFromCreateObjectNode(md,
- * nametable, (CreateObjectNode) en); break;
- */
- case Kind.ArrayAccessNode:
- var = inferRelationsFromArrayAccessNode(md, nametable, (ArrayAccessNode) en, flowTo, implicitTag, isLHS);
- break;
-
- case Kind.LiteralNode:
- var = inferRelationsFromLiteralNode(md, nametable, (LiteralNode) en);
- break;
- /*
- * case Kind.MethodInvokeNode: var = inferRelationsFromMethodInvokeNode(md,
- * nametable, (MethodInvokeNode) en, flowTo); break;
- *
- * case Kind.TertiaryNode: var = inferRelationsFromTertiaryNode(md,
- * nametable, (TertiaryNode) en); break;
- */
- case Kind.CastNode:
- var = inferRelationsFromCastNode(md, nametable, (CastNode) en, flowTo, implicitTag);
- break;
-
- default:
- System.out.println("expressionnode not handled...");
- return null;
-
- }
- // addTypeLocation(en.getType(), compLoc);
- return var;
-
- }
-
-
- private VarID inferRelationsFromCastNode(MethodDescriptor md,
- SymbolTable nametable, CastNode cn, VarID flowTo, BlockStatementNode implicitTag) {
-
- ExpressionNode en = cn.getExpression();
- return inferRelationsFromExpressionNode(md, nametable, en, flowTo, implicitTag, false);
-
- }
- /*
- * private CompositeLocation inferRelationsFromTertiaryNode(MethodDescriptor
- * md, SymbolTable nametable, TertiaryNode tn, CompositeLocation constraint) {
- * ClassDescriptor cd = md.getClassDesc();
- *
- * CompositeLocation condLoc = inferRelationsFromExpressionNode(md, nametable,
- * tn.getCond(), new CompositeLocation(), constraint, false); //
- * addLocationType(tn.getCond().getType(), condLoc); CompositeLocation trueLoc
- * = inferRelationsFromExpressionNode(md, nametable, tn.getTrueExpr(), new
- * CompositeLocation(), constraint, false); //
- * addLocationType(tn.getTrueExpr().getType(), trueLoc); CompositeLocation
- * falseLoc = inferRelationsFromExpressionNode(md, nametable,
- * tn.getFalseExpr(), new CompositeLocation(), constraint, false); //
- * addLocationType(tn.getFalseExpr().getType(), falseLoc);
- *
- * // locations from true/false branches can be TOP when there are only
- * literal // values // in this case, we don't need to check flow down rule!
- *
- * // check if condLoc is higher than trueLoc & falseLoc if
- * (!trueLoc.get(0).isTop() && !CompositeLattice.isGreaterThan(condLoc,
- * trueLoc, generateErrorMessage(cd, tn))) { throw new Error(
- * "The location of the condition expression is lower than the true expression at "
- * + cd.getSourceFileName() + ":" + tn.getCond().getNumLine()); }
- *
- * if (!falseLoc.get(0).isTop() && !CompositeLattice.isGreaterThan(condLoc,
- * falseLoc, generateErrorMessage(cd, tn.getCond()))) { throw new Error(
- * "The location of the condition expression is lower than the true expression at "
- * + cd.getSourceFileName() + ":" + tn.getCond().getNumLine()); }
- *
- * // then, return glb of trueLoc & falseLoc Set<CompositeLocation>
- * glbInputSet = new HashSet<CompositeLocation>(); glbInputSet.add(trueLoc);
- * glbInputSet.add(falseLoc);
- *
- * return CompositeLattice.calculateGLB(glbInputSet, generateErrorMessage(cd,
- * tn)); }
- *
- * private CompositeLocation
- * inferRelationsFromMethodInvokeNode(MethodDescriptor md, SymbolTable
- * nametable, MethodInvokeNode min, CompositeLocation loc, CompositeLocation
- * constraint) {
- *
- * CompositeLocation baseLocation = null; if (min.getExpression() != null) {
- * baseLocation = inferRelationsFromExpressionNode(md, nametable,
- * min.getExpression(), new CompositeLocation(), constraint, false); } else {
- *
- * if (min.getMethod().isStatic()) { String globalLocId =
- * ssjava.getMethodLattice(md).getGlobalLoc(); if (globalLocId == null) {
- * throw new
- * Error("Method lattice does not define global variable location at " +
- * generateErrorMessage(md.getClassDesc(), min)); } baseLocation = new
- * CompositeLocation(new Location(md, globalLocId)); } else { String thisLocId
- * = ssjava.getMethodLattice(md).getThisLoc(); baseLocation = new
- * CompositeLocation(new Location(md, thisLocId)); } }
- *
- * checkCalleeConstraints(md, nametable, min, baseLocation, constraint);
- *
- * checkCallerArgumentLocationConstraints(md, nametable, min, baseLocation,
- * constraint);
- *
- * if (!min.getMethod().getReturnType().isVoid()) { // If method has a return
- * value, compute the highest possible return // location in the caller's
- * perspective CompositeLocation ceilingLoc =
- * computeCeilingLocationForCaller(md, nametable, min, baseLocation,
- * constraint); return ceilingLoc; }
- *
- * return new CompositeLocation();
- *
- * }
- *
- * private void checkCallerArgumentLocationConstraints(MethodDescriptor md,
- * SymbolTable nametable, MethodInvokeNode min, CompositeLocation
- * callerBaseLoc, CompositeLocation constraint) { // if parameter location
- * consists of THIS and FIELD location, // caller should pass an argument that
- * is comparable to the declared // parameter location // and is not lower
- * than the declared parameter location in the field // lattice.
- *
- * MethodDescriptor calleemd = min.getMethod();
- *
- * List<CompositeLocation> callerArgList = new ArrayList<CompositeLocation>();
- * List<CompositeLocation> calleeParamList = new
- * ArrayList<CompositeLocation>();
- *
- * MethodLattice<String> calleeLattice = ssjava.getMethodLattice(calleemd);
- * Location calleeThisLoc = new Location(calleemd,
- * calleeLattice.getThisLoc());
- *
- * for (int i = 0; i < min.numArgs(); i++) { ExpressionNode en =
- * min.getArg(i); CompositeLocation callerArgLoc =
- * inferRelationsFromExpressionNode(md, nametable, en, new
- * CompositeLocation(), constraint, false); callerArgList.add(callerArgLoc); }
- *
- * // setup callee params set for (int i = 0; i < calleemd.numParameters();
- * i++) { VarDescriptor calleevd = (VarDescriptor) calleemd.getParameter(i);
- * CompositeLocation calleeLoc = d2loc.get(calleevd);
- * calleeParamList.add(calleeLoc); }
- *
- * String errorMsg = generateErrorMessage(md.getClassDesc(), min);
- *
- * System.out.println("checkCallerArgumentLocationConstraints=" +
- * min.printNode(0)); System.out.println("base location=" + callerBaseLoc);
- *
- * for (int i = 0; i < calleeParamList.size(); i++) { CompositeLocation
- * calleeParamLoc = calleeParamList.get(i); if
- * (calleeParamLoc.get(0).equals(calleeThisLoc) && calleeParamLoc.getSize() >
- * 1) {
- *
- * // callee parameter location has field information CompositeLocation
- * callerArgLoc = callerArgList.get(i);
- *
- * CompositeLocation paramLocation = translateCalleeParamLocToCaller(md,
- * calleeParamLoc, callerBaseLoc, errorMsg);
- *
- * Set<CompositeLocation> inputGLBSet = new HashSet<CompositeLocation>(); if
- * (constraint != null) { inputGLBSet.add(callerArgLoc);
- * inputGLBSet.add(constraint); callerArgLoc =
- * CompositeLattice.calculateGLB(inputGLBSet,
- * generateErrorMessage(md.getClassDesc(), min)); }
- *
- * if (!CompositeLattice.isGreaterThan(callerArgLoc, paramLocation, errorMsg))
- * { throw new Error("Caller argument '" + min.getArg(i).printNode(0) + " : "
- * + callerArgLoc +
- * "' should be higher than corresponding callee's parameter : " +
- * paramLocation + " at " + errorMsg); }
- *
- * } }
- *
- * }
- *
- * private CompositeLocation translateCalleeParamLocToCaller(MethodDescriptor
- * md, CompositeLocation calleeParamLoc, CompositeLocation callerBaseLocation,
- * String errorMsg) {
- *
- * CompositeLocation translate = new CompositeLocation();
- *
- * for (int i = 0; i < callerBaseLocation.getSize(); i++) {
- * translate.addLocation(callerBaseLocation.get(i)); }
- *
- * for (int i = 1; i < calleeParamLoc.getSize(); i++) {
- * translate.addLocation(calleeParamLoc.get(i)); }
- *
- * System.out.println("TRANSLATED=" + translate + " from calleeParamLoc=" +
- * calleeParamLoc);
- *
- * return translate; }
- *
- * private CompositeLocation computeCeilingLocationForCaller(MethodDescriptor
- * md, SymbolTable nametable, MethodInvokeNode min, CompositeLocation
- * baseLocation, CompositeLocation constraint) { List<CompositeLocation>
- * argList = new ArrayList<CompositeLocation>();
- *
- * // by default, method has a THIS parameter argList.add(baseLocation);
- *
- * for (int i = 0; i < min.numArgs(); i++) { ExpressionNode en =
- * min.getArg(i); CompositeLocation callerArg =
- * inferRelationsFromExpressionNode(md, nametable, en, new
- * CompositeLocation(), constraint, false); argList.add(callerArg); }
- *
- * System.out.println("\n## computeReturnLocation=" + min.getMethod() +
- * " argList=" + argList); CompositeLocation compLoc =
- * md2ReturnLocGen.get(min.getMethod()).computeReturnLocation(argList);
- * DeltaLocation delta = new DeltaLocation(compLoc, 1);
- * System.out.println("##computeReturnLocation=" + delta);
- *
- * return delta;
- *
- * }
- *
- * private void checkCalleeConstraints(MethodDescriptor md, SymbolTable
- * nametable, MethodInvokeNode min, CompositeLocation callerBaseLoc,
- * CompositeLocation constraint) {
- *
- * System.out.println("checkCalleeConstraints="+min.printNode(0));
- *
- * MethodDescriptor calleemd = min.getMethod();
- *
- * MethodLattice<String> calleeLattice = ssjava.getMethodLattice(calleemd);
- * CompositeLocation calleeThisLoc = new CompositeLocation(new
- * Location(calleemd, calleeLattice.getThisLoc()));
- *
- * List<CompositeLocation> callerArgList = new ArrayList<CompositeLocation>();
- * List<CompositeLocation> calleeParamList = new
- * ArrayList<CompositeLocation>();
- *
- * if (min.numArgs() > 0) { // caller needs to guarantee that it passes
- * arguments in regarding to // callee's hierarchy
- *
- * // setup caller args set // first, add caller's base(this) location
- * callerArgList.add(callerBaseLoc); // second, add caller's arguments for
- * (int i = 0; i < min.numArgs(); i++) { ExpressionNode en = min.getArg(i);
- * CompositeLocation callerArgLoc = inferRelationsFromExpressionNode(md,
- * nametable, en, new CompositeLocation(), constraint, false);
- * callerArgList.add(callerArgLoc); }
- *
- * // setup callee params set // first, add callee's this location
- * calleeParamList.add(calleeThisLoc); // second, add callee's parameters for
- * (int i = 0; i < calleemd.numParameters(); i++) { VarDescriptor calleevd =
- * (VarDescriptor) calleemd.getParameter(i); CompositeLocation calleeLoc =
- * d2loc.get(calleevd);
- * System.out.println("calleevd="+calleevd+" loc="+calleeLoc);
- * calleeParamList.add(calleeLoc); }
- *
- * // here, check if ordering relations among caller's args respect //
- * ordering relations in-between callee's args CHECK: for (int i = 0; i <
- * calleeParamList.size(); i++) { CompositeLocation calleeLoc1 =
- * calleeParamList.get(i); CompositeLocation callerLoc1 =
- * callerArgList.get(i);
- *
- * for (int j = 0; j < calleeParamList.size(); j++) { if (i != j) {
- * CompositeLocation calleeLoc2 = calleeParamList.get(j); CompositeLocation
- * callerLoc2 = callerArgList.get(j);
- *
- * if (callerLoc1.get(callerLoc1.getSize() - 1).isTop() ||
- * callerLoc2.get(callerLoc2.getSize() - 1).isTop()) { continue CHECK; }
- *
- * System.out.println("calleeLoc1="+calleeLoc1);
- * System.out.println("calleeLoc2="
- * +calleeLoc2+"calleeParamList="+calleeParamList);
- *
- * int callerResult = CompositeLattice.compare(callerLoc1, callerLoc2, true,
- * generateErrorMessage(md.getClassDesc(), min)); int calleeResult =
- * CompositeLattice.compare(calleeLoc1, calleeLoc2, true,
- * generateErrorMessage(md.getClassDesc(), min));
- *
- * if (calleeResult == ComparisonResult.GREATER && callerResult !=
- * ComparisonResult.GREATER) { // If calleeLoc1 is higher than calleeLoc2 //
- * then, caller should have same ordering relation in-bet // callerLoc1 &
- * callerLoc2
- *
- * String paramName1, paramName2;
- *
- * if (i == 0) { paramName1 = "'THIS'"; } else { paramName1 = "'parameter " +
- * calleemd.getParamName(i - 1) + "'"; }
- *
- * if (j == 0) { paramName2 = "'THIS'"; } else { paramName2 = "'parameter " +
- * calleemd.getParamName(j - 1) + "'"; }
- *
- * throw new Error(
- * "Caller doesn't respect an ordering relation among method arguments: callee expects that "
- * + paramName1 + " should be higher than " + paramName2 + " in " + calleemd +
- * " at " + md.getClassDesc().getSourceFileName() + ":" + min.getNumLine()); }
- * }
- *
- * } }
- *
- * }
- *
- * }
- */
- private VarID inferRelationsFromArrayAccessNode(MethodDescriptor md, SymbolTable
- nametable, ArrayAccessNode aan, VarID flowTo, BlockStatementNode implicitTag, boolean isLHS) {
-
-
- VarID arrayID = inferRelationsFromExpressionNode(md, nametable, aan.getExpression(), flowTo, implicitTag, isLHS);
-
- if (isLHS) {
- VarID indexID = inferRelationsFromExpressionNode(md, nametable, aan.getIndex(), arrayID, implicitTag, isLHS);
- }
- else{
- VarID indexID = inferRelationsFromExpressionNode(md, nametable, aan.getIndex(), flowTo, implicitTag, isLHS);
- }
- return arrayID;
- }
-
- /*
- private CompositeLocation
- inferRelationsFromCreateObjectNode(MethodDescriptor md, SymbolTable
- nametable, CreateObjectNode con) {
-
- ClassDescriptor cd = md.getClassDesc();
-
- CompositeLocation compLoc = new CompositeLocation();
- compLoc.addLocation(Location.createTopLocation(md)); return compLoc;
-
- }
- */
- private VarID inferRelationsFromOpNode(MethodDescriptor md, SymbolTable nametable, OpNode on,
- VarID flowTo, BlockStatementNode implicitTag) {
-
- VarID var =
- inferRelationsFromExpressionNode(md, nametable, on.getLeft(), flowTo, implicitTag, false);
-
- if (on.getRight() != null) {
- inferRelationsFromExpressionNode(md, nametable, on.getRight(), flowTo, implicitTag, false);
- }
-
- Operation op = on.getOp();
-
- switch (op.getOp()) {
-
- case Operation.UNARYPLUS:
- case Operation.UNARYMINUS:
- case Operation.LOGIC_NOT:
- // single operand
- return var;
-
- case Operation.LOGIC_OR:
- case Operation.LOGIC_AND:
- case Operation.COMP:
- case Operation.BIT_OR:
- case Operation.BIT_XOR:
- case Operation.BIT_AND:
- case Operation.ISAVAILABLE:
- case Operation.EQUAL:
- case Operation.NOTEQUAL:
- case Operation.LT:
- case Operation.GT:
- case Operation.LTE:
- case Operation.GTE:
- case Operation.ADD:
- case Operation.SUB:
- case Operation.MULT:
- case Operation.DIV:
- case Operation.MOD:
- case Operation.LEFTSHIFT:
- case Operation.RIGHTSHIFT:
- case Operation.URIGHTSHIFT:
-
- return var;
-
- default:
- throw new Error(op.toString());
- }
-
- }
-
- private VarID inferRelationsFromLiteralNode(MethodDescriptor md, SymbolTable nametable,
- LiteralNode ln) {
- // literal data flow does not matter
- return null;
-
- }
-
- private VarID inferRelationsFromNameNode(MethodDescriptor md, SymbolTable nametable, NameNode nn,
- VarID flowTo, BlockStatementNode implicitTag) {
- VarID var = null;
- NameDescriptor nd = nn.getName();
- if (nd.getBase() != null) {
- var =
- inferRelationsFromExpressionNode(md, nametable, nn.getExpression(), flowTo, implicitTag,
- false);
- } else {
- String varname = nd.toString();
- if (varname.equals("this")) {
- var = new VarID(nd);
- if (flowTo != null) {
- rSet.addRelation(new BinaryRelation(var, flowTo));
- }
- if (implicitTag != null) {
- implicitFlowSet.add(new ImplicitTuple(var, implicitTag));
- }
- var.setThis();
- return var;
- }
-
- Descriptor d = (Descriptor) nametable.get(varname);
-
- if (d instanceof VarDescriptor) {
- var = new VarID(nd);
- if (flowTo != null) {
- rSet.addRelation(new BinaryRelation(var, flowTo));
- }
- if (implicitTag != null) {
- implicitFlowSet.add(new ImplicitTuple(var, implicitTag));
- }
- } else if (d instanceof FieldDescriptor) {
- FieldDescriptor fd = (FieldDescriptor) d;
- if (fd.isStatic()) {
- if (fd.isFinal()) {
- var = new VarID(nd);
- if (flowTo != null) {
- rSet.addRelation(new BinaryRelation(var, flowTo));
- }
- if (implicitTag != null) {
- implicitFlowSet.add(new ImplicitTuple(var, implicitTag));
- }
- var.setTop();
- return var;
- } else {
- var = new VarID(nd);
- if (flowTo != null) {
- rSet.addRelation(new BinaryRelation(var, flowTo));
- }
- if (implicitTag != null) {
- implicitFlowSet.add(new ImplicitTuple(var, implicitTag));
- }
- var.setGlobal();
- }
- } else {
- var = new VarID(nd);
- if (flowTo != null) {
- rSet.addRelation(new BinaryRelation(var, flowTo));
- }
- if (implicitTag != null) {
- implicitFlowSet.add(new ImplicitTuple(var, implicitTag));
- }
- var.setThis();
- }
- } else if (d == null) {
- var = new VarID(nd);
- if (flowTo != null) {
- rSet.addRelation(new BinaryRelation(var, flowTo));
- }
- if (implicitTag != null) {
- implicitFlowSet.add(new ImplicitTuple(var, implicitTag));
- }
- var.setGlobal();
- return var;
- }
- }
- return var;
- }
-
- /*
- * private CompositeLocation
- * inferRelationsFromFieldAccessNode(MethodDescriptor md, SymbolTable
- * nametable, FieldAccessNode fan, CompositeLocation loc, CompositeLocation
- * constraint) {
- *
- * ExpressionNode left = fan.getExpression(); TypeDescriptor ltd =
- * left.getType();
- *
- * FieldDescriptor fd = fan.getField();
- *
- * String varName = null; if (left.kind() == Kind.NameNode) { NameDescriptor
- * nd = ((NameNode) left).getName(); varName = nd.toString(); }
- *
- * if (ltd.isClassNameRef() || (varName != null && varName.equals("this"))) {
- * // using a class name directly or access using this if (fd.isStatic() &&
- * fd.isFinal()) { loc.addLocation(Location.createTopLocation(md)); return
- * loc; } }
- *
- * loc = inferRelationsFromExpressionNode(md, nametable, left, loc,
- * constraint, false);
- * System.out.println("### inferRelationsFromFieldAccessNode=" +
- * fan.printNode(0)); System.out.println("### left=" + left.printNode(0)); if
- * (!left.getType().isPrimitive()) { Location fieldLoc = getFieldLocation(fd);
- * loc.addLocation(fieldLoc); }
- *
- * return loc; }
- *
- * private Location getFieldLocation(FieldDescriptor fd) {
- *
- * System.out.println("### getFieldLocation=" + fd);
- * System.out.println("### fd.getType().getExtension()=" +
- * fd.getType().getExtension());
- *
- * Location fieldLoc = (Location) fd.getType().getExtension();
- *
- * // handle the case that method annotation checking skips checking field //
- * declaration if (fieldLoc == null) { fieldLoc =
- * checkFieldDeclaration(fd.getClassDescriptor(), fd); }
- *
- * return fieldLoc;
- *
- * }
- */
-
- private VarID inferRelationsFromAssignmentNode(MethodDescriptor md, SymbolTable nametable,
- AssignmentNode an, VarID flowTo, BlockStatementNode implicitTag) {
- ClassDescriptor cd = md.getClassDesc();
- boolean postinc = true;
-
- if (an.getOperation().getBaseOp() == null
- || (an.getOperation().getBaseOp().getOp() != Operation.POSTINC && an.getOperation()
- .getBaseOp().getOp() != Operation.POSTDEC))
- postinc = false;
- // get ID for leftside
- VarID destID =
- inferRelationsFromExpressionNode(md, nametable, an.getDest(), flowTo, implicitTag, true);
-
- if (!postinc) {
- // recursively add relations from RHS to LHS
- inferRelationsFromExpressionNode(md, nametable, an.getSrc(), destID, null, false);
-
- } else {
- // add relation to self
- destID = inferRelationsFromExpressionNode(md, nametable, an.getDest(), destID, null, false);
- }
-
- // checks if flow to anythin and adds relation
- if (flowTo != null) {
- rSet.addRelation(new BinaryRelation(destID, flowTo));
- }
-
- // add relations for implicit flow
- for (ImplicitTuple it : implicitFlowSet) {
- rSet.addRelation(new BinaryRelation(it.getVar(), destID));
- }
-
- return destID;
- }
-}
\ No newline at end of file