package Analysis.SSJava;
import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Iterator;
State state;
static SSJavaAnalysis ssjava;
- HashSet toanalyze;
+ Set<ClassDescriptor> toanalyze;
+ List<ClassDescriptor> toanalyzeList;
+
+ Set<MethodDescriptor> toanalyzeMethod;
+ List<MethodDescriptor> toanalyzeMethodList;
// mapping from 'descriptor' to 'composite location'
Hashtable<Descriptor, CompositeLocation> d2loc;
// mapping from 'locID' to 'class descriptor'
Hashtable<String, ClassDescriptor> fieldLocName2cd;
+ boolean deterministic = true;
+
public FlowDownCheck(SSJavaAnalysis ssjava, State state) {
this.ssjava = ssjava;
this.state = state;
- this.toanalyze = new HashSet();
+ 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>();
}
- public void flowDownCheck() {
+ 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 flowDownCheck() {
// phase 1 : checking declaration node and creating mapping of 'type
// desciptor' & 'location'
- toanalyze.addAll(classtable.getValueSet());
- toanalyze.addAll(state.getTaskSymbolTable().getValueSet());
+ setupToAnalyze();
- while (!toanalyze.isEmpty()) {
- Object obj = toanalyze.iterator().next();
- ClassDescriptor cd = (ClassDescriptor) obj;
- toanalyze.remove(cd);
+ while (!toAnalyzeIsEmpty()) {
+ ClassDescriptor cd = toAnalyzeNext();
if (ssjava.needToBeAnnoated(cd)) {
}
checkDeclarationInClass(cd);
- for (Iterator method_it = cd.getMethods(); method_it.hasNext();) {
- MethodDescriptor md = (MethodDescriptor) method_it.next();
+
+ setupToAnalazeMethod(cd);
+ while (!toAnalyzeMethodIsEmpty()) {
+ MethodDescriptor md = toAnalyzeMethodNext();
if (ssjava.needTobeAnnotated(md)) {
checkDeclarationInMethodBody(cd, md);
}
}
+
}
}
// phase2 : checking assignments
- toanalyze.addAll(classtable.getValueSet());
- toanalyze.addAll(state.getTaskSymbolTable().getValueSet());
- while (!toanalyze.isEmpty()) {
- Object obj = toanalyze.iterator().next();
- ClassDescriptor cd = (ClassDescriptor) obj;
- toanalyze.remove(cd);
+ setupToAnalyze();
+
+ while (!toAnalyzeIsEmpty()) {
+ ClassDescriptor cd = toAnalyzeNext();
- for (Iterator method_it = cd.getMethods(); method_it.hasNext();) {
- MethodDescriptor md = (MethodDescriptor) method_it.next();
+ setupToAnalazeMethod(cd);
+ while (!toAnalyzeMethodIsEmpty()) {
+ MethodDescriptor md = toAnalyzeMethodNext();
if (ssjava.needTobeAnnotated(md)) {
+ System.out.println("SSJAVA: Checking assignments: " + md);
checkMethodBody(cd, md);
}
}
private void checkDeclarationInMethodBody(ClassDescriptor cd, MethodDescriptor md) {
BlockNode bn = state.getMethodBody(md);
- if (ssjava.needTobeAnnotated(md)) {
- // first, check annotations on method declaration
-
- // parsing returnloc annotation
- Vector<AnnotationDescriptor> methodAnnotations = md.getModifiers().getAnnotations();
- if (methodAnnotations != null) {
- for (int i = 0; i < methodAnnotations.size(); i++) {
- AnnotationDescriptor an = methodAnnotations.elementAt(i);
- if (an.getMarker().equals(ssjava.RETURNLOC)) {
- // developer explicitly defines method lattice
- String returnLocDeclaration = an.getValue();
- CompositeLocation returnLocComp =
- parseLocationDeclaration(md, null, returnLocDeclaration);
- md2ReturnLoc.put(md, returnLocComp);
- }
- }
- if (!md.getReturnType().isVoid() && !md2ReturnLoc.containsKey(md)) {
- throw new Error("Return location is not specified for the method " + md + " at "
- + cd.getSourceFileName());
- }
- }
+ // first, check annotations on method parameters
+ List<CompositeLocation> paramList = new ArrayList<CompositeLocation>();
+ for (int i = 0; i < md.numParameters(); i++) {
+ // process annotations on method parameters
+ VarDescriptor vd = (VarDescriptor) md.getParameter(i);
+ assignLocationOfVarDescriptor(vd, md, md.getParameterTable(), bn);
+ paramList.add(d2loc.get(vd));
+ }
+ Vector<AnnotationDescriptor> methodAnnotations = md.getModifiers().getAnnotations();
- List<CompositeLocation> paramList = new ArrayList<CompositeLocation>();
+ // second, check return location annotation
+ if (!md.getReturnType().isVoid()) {
+ CompositeLocation returnLocComp = null;
- boolean hasReturnValue = (!md.getReturnType().isVoid());
- if (hasReturnValue) {
- MethodLattice<String> methodLattice = ssjava.getMethodLattice(md);
- String thisLocId = methodLattice.getThisLoc();
- if (thisLocId == null) {
- throw new Error("Method '" + md + "' does not have the definition of 'this' location at "
- + md.getClassDesc().getSourceFileName());
+ String rtrStr = ssjava.getMethodLattice(md).getReturnLoc();
+ if (rtrStr != null) {
+ returnLocComp = new CompositeLocation(new Location(md, rtrStr));
+ } else {
+ if (methodAnnotations != null) {
+ for (int i = 0; i < methodAnnotations.size(); i++) {
+ AnnotationDescriptor an = methodAnnotations.elementAt(i);
+ if (an.getMarker().equals(ssjava.RETURNLOC)) {
+ // this case, developer explicitly defines method lattice
+ String returnLocDeclaration = an.getValue();
+ returnLocComp = parseLocationDeclaration(md, null, returnLocDeclaration);
+ }
+ }
+ } else {
+ // if developer does not define method lattice
+ // search return location in the method default lattice
+ if (returnLocComp == null) {
+ MethodLattice<String> methodDefaultLattice = ssjava.getMethodDefaultLattice(cd);
+ if (methodDefaultLattice.getReturnLoc() != null) {
+ returnLocComp =
+ parseLocationDeclaration(md, null, methodDefaultLattice.getReturnLoc());
+ }
+ }
}
- CompositeLocation thisLoc = new CompositeLocation(new Location(md, thisLocId));
- paramList.add(thisLoc);
}
- for (int i = 0; i < md.numParameters(); i++) {
- // process annotations on method parameters
- VarDescriptor vd = (VarDescriptor) md.getParameter(i);
- assignLocationOfVarDescriptor(vd, md, md.getParameterTable(), bn);
- if (hasReturnValue) {
- paramList.add(d2loc.get(vd));
- }
+ if (returnLocComp == null) {
+ throw new Error("Return location is not specified for the method " + md + " at "
+ + cd.getSourceFileName());
}
- if (hasReturnValue) {
- md2ReturnLocGen.put(md, new ReturnLocGenerator(md2ReturnLoc.get(md), paramList,
- generateErrorMessage(cd, null)));
+ md2ReturnLoc.put(md, returnLocComp);
+
+ // check this location
+ MethodLattice<String> methodLattice = ssjava.getMethodLattice(md);
+ String thisLocId = methodLattice.getThisLoc();
+ if (thisLocId == null) {
+ throw new Error("Method '" + md + "' does not have the definition of 'this' location at "
+ + md.getClassDesc().getSourceFileName());
}
- checkDeclarationInBlockNode(md, md.getParameterTable(), bn);
+ CompositeLocation thisLoc = new CompositeLocation(new Location(md, thisLocId));
+ paramList.add(0, thisLoc);
+
+ System.out.println("### ReturnLocGenerator=" + md);
+ System.out.println("### md2ReturnLoc.get(md)=" + md2ReturnLoc.get(md));
+ md2ReturnLocGen.put(md, new ReturnLocGenerator(md2ReturnLoc.get(md), paramList, md + " of "
+ + cd.getSourceFileName()));
}
+ // fourth, check declarations inside of method
+
+ checkDeclarationInBlockNode(md, md.getParameterTable(), bn);
+
}
private void checkDeclarationInBlockNode(MethodDescriptor md, SymbolTable nametable, BlockNode bn) {
constraint, false);
BlockNode sbn = ssn.getSwitchBody();
- Set<CompositeLocation> blockLocSet = new HashSet<CompositeLocation>();
- for (int i = 0; i < sbn.size(); i++) {
- CompositeLocation blockLoc =
- checkLocationFromSwitchBlockNode(md, nametable, (SwitchBlockNode) sbn.get(i), constraint);
- if (!CompositeLattice.isGreaterThan(condLoc, blockLoc,
- generateErrorMessage(cd, ssn.getCondition()))) {
- throw new Error(
- "The location of the switch-condition statement is lower than the conditional body at "
- + cd.getSourceFileName() + ":" + ssn.getCondition().getNumLine());
- }
+ constraint = generateNewConstraint(constraint, condLoc);
- blockLocSet.add(blockLoc);
+ for (int i = 0; i < sbn.size(); i++) {
+ checkLocationFromSwitchBlockNode(md, nametable, (SwitchBlockNode) sbn.get(i), constraint);
}
- return CompositeLattice.calculateGLB(blockLocSet);
+ return new CompositeLocation();
}
private CompositeLocation checkLocationFromSwitchBlockNode(MethodDescriptor md,
checkLocationFromExpressionNode(md, nametable, returnExp, new CompositeLocation(),
constraint, false);
+ // if this return statement is inside branch, return value has an implicit
+ // flow from conditional location
+ if (constraint != null) {
+ Set<CompositeLocation> inputGLB = new HashSet<CompositeLocation>();
+ inputGLB.add(returnValueLoc);
+ inputGLB.add(constraint);
+ returnValueLoc =
+ CompositeLattice.calculateGLB(inputGLB, generateErrorMessage(md.getClassDesc(), rn));
+ }
+
// check if return value is equal or higher than RETRUNLOC of method
// declaration annotation
CompositeLocation declaredReturnLoc = md2ReturnLoc.get(md);
int compareResult =
- CompositeLattice.compare(returnValueLoc, declaredReturnLoc,
+ CompositeLattice.compare(returnValueLoc, declaredReturnLoc, false,
generateErrorMessage(md.getClassDesc(), rn));
if (compareResult == ComparisonResult.LESS || compareResult == ComparisonResult.INCOMPARABLE) {
Set<CompositeLocation> inputSet = new HashSet<CompositeLocation>();
inputSet.add(currentCon);
inputSet.add(newCon);
- return CompositeLattice.calculateGLB(inputSet);
+ return CompositeLattice.calculateGLB(inputSet, "");
}
}
glbInputSet.add(trueLoc);
glbInputSet.add(falseLoc);
- return CompositeLattice.calculateGLB(glbInputSet);
+ return CompositeLattice.calculateGLB(glbInputSet, generateErrorMessage(cd, tn));
}
private CompositeLocation checkLocationFromMethodInvokeNode(MethodDescriptor md,
SymbolTable nametable, MethodInvokeNode min, CompositeLocation loc,
CompositeLocation constraint) {
- checkCalleeConstraints(md, nametable, min, constraint);
-
CompositeLocation baseLocation = null;
if (min.getExpression() != null) {
baseLocation =
baseLocation = new CompositeLocation(new Location(md, thisLocId));
}
+ checkCalleeConstraints(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
}
private void checkCalleeConstraints(MethodDescriptor md, SymbolTable nametable,
- MethodInvokeNode min, CompositeLocation constraint) {
+ MethodInvokeNode min, CompositeLocation callerBaseLoc, CompositeLocation constraint) {
+
+ MethodDescriptor calleemd = min.getMethod();
- if (min.numArgs() > 1) {
+ 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 callerArg1 =
+ CompositeLocation callerArgLoc =
checkLocationFromExpressionNode(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);
+ 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;
+ }
- VarDescriptor calleevd = (VarDescriptor) min.getMethod().getParameter(i);
- CompositeLocation calleeLoc1 = d2loc.get(calleevd);
-
- if (!callerArg1.get(0).isTop()) {
- // here, check if ordering relations among caller's args respect
- // ordering relations in-between callee's args
- for (int currentIdx = 0; currentIdx < min.numArgs(); currentIdx++) {
- if (currentIdx != i) { // skip itself
- ExpressionNode argExp = min.getArg(currentIdx);
-
- CompositeLocation callerArg2 =
- checkLocationFromExpressionNode(md, nametable, argExp, new CompositeLocation(),
- constraint, false);
-
- VarDescriptor calleevd2 = (VarDescriptor) min.getMethod().getParameter(currentIdx);
- CompositeLocation calleeLoc2 = d2loc.get(calleevd2);
-
- int callerResult =
- CompositeLattice.compare(callerArg1, callerArg2,
- generateErrorMessage(md.getClassDesc(), min));
- int calleeResult =
- CompositeLattice.compare(calleeLoc1, calleeLoc2,
- 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
-
- throw new Error("Caller doesn't respect ordering relations among method arguments:"
- + md.getClassDesc().getSourceFileName() + ":" + min.getNumLine());
+ 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());
}
}
- }
+ }
}
}
Set<CompositeLocation> inputGLB = new HashSet<CompositeLocation>();
inputGLB.add(arrayLoc);
inputGLB.add(indexLoc);
- return CompositeLattice.calculateGLB(inputGLB);
+ return CompositeLattice.calculateGLB(inputGLB, generateErrorMessage(cd, aan));
}
}
// addTypeLocation(on.getRight().getType(), rightLoc);
}
- System.out.println("checking op node=" + on.printNode(0)
- + generateErrorMessage(md.getClassDesc(), on));
- System.out.println("# op node=" + on.printNode(0));
- System.out.println("left loc=" + leftLoc + " from " + on.getLeft().getClass());
+ System.out.println("\n# OP NODE=" + on.printNode(0));
+ System.out.println("# left loc=" + leftLoc + " from " + on.getLeft().getClass());
if (on.getRight() != null) {
- System.out.println("right loc=" + rightLoc + " from " + on.getRight().kind());
+ System.out.println("# right loc=" + rightLoc + " from " + on.getRight().getClass());
}
Operation op = on.getOp();
Set<CompositeLocation> inputSet = new HashSet<CompositeLocation>();
inputSet.add(leftLoc);
inputSet.add(rightLoc);
- CompositeLocation glbCompLoc = CompositeLattice.calculateGLB(inputSet);
+ CompositeLocation glbCompLoc =
+ CompositeLattice.calculateGLB(inputSet, generateErrorMessage(cd, on));
+ System.out.println("# glbCompLoc=" + glbCompLoc);
return glbCompLoc;
default:
Location locElement = new Location(md, thisLocId);
loc.addLocation(locElement);
return loc;
+
}
Descriptor d = (Descriptor) nametable.get(varname);
System.out.println("rhsLocation=" + rhsLocation);
System.out.println("constraint=" + constraint);
- if (constraint != null) {
- inputGLBSet.add(rhsLocation);
- inputGLBSet.add(constraint);
- srcLocation = CompositeLattice.calculateGLB(inputGLBSet);
- } else {
- srcLocation = rhsLocation;
+ srcLocation = rhsLocation;
+
+ if (!rhsLocation.get(rhsLocation.getSize() - 1).isTop()) {
+ if (constraint != null) {
+ inputGLBSet.add(rhsLocation);
+ inputGLBSet.add(constraint);
+ srcLocation = CompositeLattice.calculateGLB(inputGLBSet, generateErrorMessage(cd, an));
+ }
}
if (!CompositeLattice.isGreaterThan(srcLocation, destLocation, generateErrorMessage(cd, an))) {
if (constraint != null) {
inputGLBSet.add(rhsLocation);
inputGLBSet.add(constraint);
- srcLocation = CompositeLattice.calculateGLB(inputGLBSet);
+ srcLocation = CompositeLattice.calculateGLB(inputGLBSet, generateErrorMessage(cd, an));
} else {
srcLocation = rhsLocation;
}
+ System.out.println("srcLocation=" + srcLocation);
+ System.out.println("rhsLocation=" + rhsLocation);
+ System.out.println("constraint=" + constraint);
+
if (!CompositeLattice.isGreaterThan(srcLocation, destLocation, generateErrorMessage(cd, an))) {
throw new Error("Location " + destLocation
+ " is not allowed to have the value flow that moves within the same location at "
return deltaLoc;
}
- private Location parseFieldLocDeclaraton(String decl, String msg) {
+ private Location parseFieldLocDeclaraton(String decl, String msg) throws Exception {
int idx = decl.indexOf(".");
+
String className = decl.substring(0, idx);
String fieldName = decl.substring(idx + 1);
Descriptor d = state.getClassSymbolTable().get(className);
if (d == null) {
+ System.out.println("state.getClassSymbolTable()=" + state.getClassSymbolTable());
throw new Error("The class in the location declaration '" + decl + "' does not exist at "
+ msg);
}
SSJavaLattice<String> localLattice = CompositeLattice.getLatticeByDescriptor(md);
Location localLoc = new Location(md, localLocId);
if (localLattice == null || (!localLattice.containsKey(localLocId))) {
+ System.out.println("locDec=" + locDec);
throw new Error("Location " + localLocId
+ " is not defined in the local variable lattice at "
- + md.getClassDesc().getSourceFileName() + "::" + (n != null ? n.getNumLine() : "") + ".");
+ + md.getClassDesc().getSourceFileName() + "::" + (n != null ? n.getNumLine() : md) + ".");
}
compLoc.addLocation(localLoc);
for (int i = 1; i < locIdList.size(); i++) {
String locName = locIdList.get(i);
-
- Location fieldLoc =
- parseFieldLocDeclaraton(locName, generateErrorMessage(md.getClassDesc(), n));
- // ClassDescriptor cd = fieldLocName2cd.get(locName);
- // SSJavaLattice<String> fieldLattice =
- // CompositeLattice.getLatticeByDescriptor(cd);
- //
- // if (fieldLattice == null || (!fieldLattice.containsKey(locName))) {
- // throw new Error("Location " + locName +
- // " is not defined in the field lattice at "
- // + cd.getSourceFileName() + ".");
- // }
- // Location fieldLoc = new Location(cd, locName);
- compLoc.addLocation(fieldLoc);
+ try {
+ Location fieldLoc =
+ parseFieldLocDeclaraton(locName, generateErrorMessage(md.getClassDesc(), n));
+ compLoc.addLocation(fieldLoc);
+ } catch (Exception e) {
+ throw new Error("The location declaration '" + locName + "' is wrong at "
+ + generateErrorMessage(md.getClassDesc(), n));
+ }
}
return compLoc;
public static boolean isGreaterThan(CompositeLocation loc1, CompositeLocation loc2, String msg) {
- System.out.println("isGreaterThan=" + loc1 + " " + loc2 + " msg=" + msg);
- int baseCompareResult = compareBaseLocationSet(loc1, loc2, true, msg);
+ System.out.println("\nisGreaterThan=" + loc1 + " " + loc2 + " msg=" + msg);
+ int baseCompareResult = compareBaseLocationSet(loc1, loc2, true, false, msg);
if (baseCompareResult == ComparisonResult.EQUAL) {
if (compareDelta(loc1, loc2) == ComparisonResult.GREATER) {
return true;
}
- public static int compare(CompositeLocation loc1, CompositeLocation loc2, String msg) {
+ public static int compare(CompositeLocation loc1, CompositeLocation loc2, boolean ignore,
+ String msg) {
System.out.println("compare=" + loc1 + " " + loc2);
- int baseCompareResult = compareBaseLocationSet(loc1, loc2, false, msg);
+ int baseCompareResult = compareBaseLocationSet(loc1, loc2, false, ignore, msg);
if (baseCompareResult == ComparisonResult.EQUAL) {
return compareDelta(loc1, loc2);
}
private static int compareBaseLocationSet(CompositeLocation compLoc1,
- CompositeLocation compLoc2, boolean awareSharedLoc, String msg) {
+ CompositeLocation compLoc2, boolean awareSharedLoc, boolean ignore, String msg) {
// if compLoc1 is greater than compLoc2, return true
// else return false;
for (int i = 0; i < compLoc1.getSize(); i++) {
Location loc1 = compLoc1.get(i);
if (i >= compLoc2.getSize()) {
- throw new Error("Failed to compare two locations of " + compLoc1 + " and " + compLoc2
- + " because they are not comparable.");
- }
- Location loc2 = compLoc2.get(i);
-
- Descriptor d1 = loc1.getDescriptor();
- Descriptor d2 = loc2.getDescriptor();
-
- Descriptor descriptor;
-
- if (d1 instanceof ClassDescriptor && d2 instanceof ClassDescriptor) {
-
- if (d1.equals(d2)) {
- descriptor = d1;
- } else {
- // identifying which one is parent class
- Set<Descriptor> d1SubClassesSet = ssjava.tu.getSubClasses((ClassDescriptor) d1);
- Set<Descriptor> d2SubClassesSet = ssjava.tu.getSubClasses((ClassDescriptor) d2);
-
- if (d1 == null && d2 == null) {
- throw new Error("Failed to compare two locations of " + compLoc1 + " and " + compLoc2
- + " because they are not comparable at " + msg);
- } else if (d1SubClassesSet != null && d1SubClassesSet.contains(d2)) {
- descriptor = d1;
- } else if (d2SubClassesSet != null && d2SubClassesSet.contains(d1)) {
- descriptor = d2;
- } else {
- throw new Error("Failed to compare two locations of " + compLoc1 + " and " + compLoc2
- + " because they are not comparable at " + msg);
- }
- }
-
- } else if (d1 instanceof MethodDescriptor && d2 instanceof MethodDescriptor) {
-
- if (d1.equals(d2)) {
- descriptor = d1;
+ if (ignore) {
+ return ComparisonResult.INCOMPARABLE;
} else {
-
- // identifying which one is parent class
- MethodDescriptor md1 = (MethodDescriptor) d1;
- MethodDescriptor md2 = (MethodDescriptor) d2;
-
- if (!md1.matches(md2)) {
- throw new Error("Failed to compare two locations of " + compLoc1 + " and " + compLoc2
- + " because they are not comparable at " + msg);
- }
-
- Set<Descriptor> d1SubClassesSet =
- ssjava.tu.getSubClasses(((MethodDescriptor) d1).getClassDesc());
- Set<Descriptor> d2SubClassesSet =
- ssjava.tu.getSubClasses(((MethodDescriptor) d2).getClassDesc());
-
- if (d1 == null && d2 == null) {
- throw new Error("Failed to compare two locations of " + compLoc1 + " and " + compLoc2
- + " because they are not comparable at " + msg);
- } else if (d1 != null && d1SubClassesSet.contains(d2)) {
- descriptor = d1;
- } else if (d2 != null && d2SubClassesSet.contains(d1)) {
- descriptor = d2;
- } else {
- throw new Error("Failed to compare two locations of " + compLoc1 + " and " + compLoc2
- + " because they are not comparable at " + msg);
- }
+ throw new Error("Failed to compare two locations of " + compLoc1 + " and " + compLoc2
+ + " because they are not comparable at " + msg);
}
-
- } else {
- throw new Error("Failed to compare two locations of " + compLoc1 + " and " + compLoc2
- + " because they are not comparable at " + msg);
}
+ Location loc2 = compLoc2.get(i);
- // SSJavaLattice<String> lattice1 = getLatticeByDescriptor(d1);
- // SSJavaLattice<String> lattice2 = getLatticeByDescriptor(d2);
-
+ Descriptor descriptor = getCommonParentDescriptor(loc1, loc2, msg);
SSJavaLattice<String> lattice = getLatticeByDescriptor(descriptor);
- // check if the spin location is appeared only at the end of the
+ // check if the shared location is appeared only at the end of the
// composite location
- if (lattice.getSpinLocSet().contains(loc1.getLocIdentifier())) {
+ if (lattice.getSharedLocSet().contains(loc1.getLocIdentifier())) {
if (i != (compLoc1.getSize() - 1)) {
throw new Error("The shared location " + loc1.getLocIdentifier()
+ " cannot be appeared in the middle of composite location at" + msg);
}
}
- if (lattice.getSpinLocSet().contains(loc2.getLocIdentifier())) {
+ if (lattice.getSharedLocSet().contains(loc2.getLocIdentifier())) {
if (i != (compLoc2.getSize() - 1)) {
- throw new Error("The spin location " + loc2.getLocIdentifier()
+ throw new Error("The shared location " + loc2.getLocIdentifier()
+ " cannot be appeared in the middle of composite location at " + msg);
}
}
// note that the spinning location only can be appeared in the last
// part of the composite location
if (awareSharedLoc && numOfTie == compLoc1.getSize()
- && lattice.getSpinLocSet().contains(loc1.getLocIdentifier())) {
+ && lattice.getSharedLocSet().contains(loc1.getLocIdentifier())) {
return ComparisonResult.GREATER;
}
continue;
if (numOfTie == compLoc1.getSize()) {
if (numOfTie != compLoc2.getSize()) {
- throw new Error("Failed to compare two locations of " + compLoc1 + " and " + compLoc2
- + " because they are not comparable at " + msg);
+
+ if (ignore) {
+ return ComparisonResult.INCOMPARABLE;
+ } else {
+ throw new Error("Failed to compare two locations of " + compLoc1 + " and " + compLoc2
+ + " because they are not comparable at " + msg);
+ }
+
}
return ComparisonResult.EQUAL;
}
- public static CompositeLocation calculateGLB(Set<CompositeLocation> inputSet) {
+ public static CompositeLocation calculateGLB(Set<CompositeLocation> inputSet, String errMsg) {
- // System.out.println("Calculating GLB=" + inputSet);
+ System.out.println("Calculating GLB=" + inputSet);
CompositeLocation glbCompLoc = new CompositeLocation();
// calculate GLB of the first(priority) element
int maxTupleSize = 0;
CompositeLocation maxCompLoc = null;
+ Location prevPriorityLoc = null;
for (Iterator iterator = inputSet.iterator(); iterator.hasNext();) {
CompositeLocation compLoc = (CompositeLocation) iterator.next();
if (compLoc.getSize() > maxTupleSize) {
// check if priority location are coming from the same lattice
if (priorityDescriptor == null) {
priorityDescriptor = priorityLoc.getDescriptor();
- } else if (!priorityDescriptor.equals(priorityLoc.getDescriptor())) {
- throw new Error("Failed to calculate GLB of " + inputSet
- + " because they are from different lattices.");
+ } else {
+ priorityDescriptor = getCommonParentDescriptor(priorityLoc, prevPriorityLoc, errMsg);
}
+ prevPriorityLoc = priorityLoc;
+ // else if (!priorityDescriptor.equals(priorityLoc.getDescriptor())) {
+ // throw new Error("Failed to calculate GLB of " + inputSet
+ // + " because they are from different lattices.");
+ // }
}
SSJavaLattice<String> locOrder = getLatticeByDescriptor(priorityDescriptor);
}
if (compSet.size() == 1) {
-
// if GLB(x1,x2)==x1 or x2 : GLB case 2,3
CompositeLocation comp = compSet.iterator().next();
for (int i = 1; i < comp.getSize(); i++) {
// if more than one location shares the same priority GLB
// need to calculate the rest of GLB loc
- // int compositeLocSize = compSet.iterator().next().getSize();
- int compositeLocSize = maxFromCompSet.getSize();
-
- Set<String> glbInputSet = new HashSet<String>();
- Descriptor currentD = null;
- for (int i = 1; i < compositeLocSize; i++) {
- for (Iterator iterator = compSet.iterator(); iterator.hasNext();) {
- CompositeLocation compositeLocation = (CompositeLocation) iterator.next();
- if (compositeLocation.getSize() > i) {
- Location currentLoc = compositeLocation.get(i);
- currentD = currentLoc.getDescriptor();
- // making set of the current location sharing the same idx
- glbInputSet.add(currentLoc.getLocIdentifier());
- }
+ // setup input set starting from the second tuple item
+ Set<CompositeLocation> innerGLBInput = new HashSet<CompositeLocation>();
+ for (Iterator iterator = compSet.iterator(); iterator.hasNext();) {
+ CompositeLocation compLoc = (CompositeLocation) iterator.next();
+ CompositeLocation innerCompLoc = new CompositeLocation();
+ for (int idx = 1; idx < compLoc.getSize(); idx++) {
+ innerCompLoc.addLocation(compLoc.get(idx));
+ }
+ if (innerCompLoc.getSize() > 0) {
+ innerGLBInput.add(innerCompLoc);
}
- // calculate glb for the current lattice
+ }
- SSJavaLattice<String> currentLattice = getLatticeByDescriptor(currentD);
- String currentGLBLocId = currentLattice.getGLB(glbInputSet);
- glbCompLoc.addLocation(new Location(currentD, currentGLBLocId));
+ if (innerGLBInput.size() > 0) {
+ CompositeLocation innerGLB = CompositeLattice.calculateGLB(innerGLBInput, errMsg);
+ for (int idx = 0; idx < innerGLB.getSize(); idx++) {
+ glbCompLoc.addLocation(innerGLB.get(idx));
+ }
}
// if input location corresponding to glb is a delta, need to apply
}
}
+ System.out.println("GLB=" + glbCompLoc);
return glbCompLoc;
}
return lattice;
}
+ static Descriptor getCommonParentDescriptor(Location loc1, Location loc2, String msg) {
+
+ Descriptor d1 = loc1.getDescriptor();
+ Descriptor d2 = loc2.getDescriptor();
+
+ Descriptor descriptor;
+
+ if (d1 instanceof ClassDescriptor && d2 instanceof ClassDescriptor) {
+
+ if (d1.equals(d2)) {
+ descriptor = d1;
+ } else {
+ // identifying which one is parent class
+ Set<Descriptor> d1SubClassesSet = ssjava.tu.getSubClasses((ClassDescriptor) d1);
+ Set<Descriptor> d2SubClassesSet = ssjava.tu.getSubClasses((ClassDescriptor) d2);
+
+ if (d1 == null && d2 == null) {
+ throw new Error("Failed to compare two locations of " + loc1 + " and " + loc2
+ + " because they are not comparable at " + msg);
+ } else if (d1SubClassesSet != null && d1SubClassesSet.contains(d2)) {
+ descriptor = d1;
+ } else if (d2SubClassesSet != null && d2SubClassesSet.contains(d1)) {
+ descriptor = d2;
+ } else {
+ throw new Error("Failed to compare two locations of " + loc1 + " and " + loc2
+ + " because they are not comparable at " + msg);
+ }
+ }
+
+ } else if (d1 instanceof MethodDescriptor && d2 instanceof MethodDescriptor) {
+
+ if (d1.equals(d2)) {
+ descriptor = d1;
+ } else {
+
+ // identifying which one is parent class
+ MethodDescriptor md1 = (MethodDescriptor) d1;
+ MethodDescriptor md2 = (MethodDescriptor) d2;
+
+ if (!md1.matches(md2)) {
+ throw new Error("Failed to compare two locations of " + loc1 + " and " + loc2
+ + " because they are not comparable at " + msg);
+ }
+
+ Set<Descriptor> d1SubClassesSet =
+ ssjava.tu.getSubClasses(((MethodDescriptor) d1).getClassDesc());
+ Set<Descriptor> d2SubClassesSet =
+ ssjava.tu.getSubClasses(((MethodDescriptor) d2).getClassDesc());
+
+ if (d1 == null && d2 == null) {
+ throw new Error("Failed to compare two locations of " + loc1 + " and " + loc2
+ + " because they are not comparable at " + msg);
+ } else if (d1 != null && d1SubClassesSet.contains(d2)) {
+ descriptor = d1;
+ } else if (d2 != null && d2SubClassesSet.contains(d1)) {
+ descriptor = d2;
+ } else {
+ throw new Error("Failed to compare two locations of " + loc1 + " and " + loc2
+ + " because they are not comparable at " + msg);
+ }
+ }
+
+ } else {
+ throw new Error("Failed to compare two locations of " + loc1 + " and " + loc2
+ + " because they are not comparable at " + msg);
+ }
+
+ return descriptor;
+
+ }
+
}
class ComparisonResult {
paramIdx2paramType = new Hashtable<Integer, Integer>();
for (int i = 0; i < params.size(); i++) {
CompositeLocation param = params.get(i);
- int compareResult = CompositeLattice.compare(param, returnLoc, msg);
+ int compareResult = CompositeLattice.compare(param, returnLoc, true, msg);
int type;
if (compareResult == ComparisonResult.GREATER) {
// compute GLB of arguments subset that are same or higher than return
// location
- CompositeLocation glb = CompositeLattice.calculateGLB(inputGLB);
+ CompositeLocation glb = CompositeLattice.calculateGLB(inputGLB, "");
return glb;
}
}