X-Git-Url: http://plrg.eecs.uci.edu/git/?p=IRC.git;a=blobdiff_plain;f=Robust%2Fsrc%2FAnalysis%2FSSJava%2FFlowDownCheck.java;h=5bce89cc1d66caa7c03194173f6a3bdcd1e1d178;hp=9cbe54bde105816425298b208b1552548405de42;hb=d45bb251bdc1196d7848094fa2ccd566b39e021c;hpb=a8b64832616c39013fa76a9d38c7e7affaa7cb2f diff --git a/Robust/src/Analysis/SSJava/FlowDownCheck.java b/Robust/src/Analysis/SSJava/FlowDownCheck.java index 9cbe54bd..5bce89cc 100644 --- a/Robust/src/Analysis/SSJava/FlowDownCheck.java +++ b/Robust/src/Analysis/SSJava/FlowDownCheck.java @@ -226,7 +226,8 @@ public class FlowDownCheck { if (state.SSJAVADEBUG) { System.out.println("SSJAVA: Checking Flow-down Rules: " + md); } - checkMethodBody(cd, md, null); + CompositeLocation calleePCLOC = ssjava.getPCLocation(md); + checkMethodBody(cd, md, calleePCLOC); } } } @@ -306,23 +307,32 @@ public class FlowDownCheck { } Vector methodAnnotations = md.getModifiers().getAnnotations(); - // second, check return location annotation - if (!md.getReturnType().isVoid()) { - CompositeLocation returnLocComp = null; - - boolean hasReturnLocDeclaration = false; - 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); - hasReturnLocDeclaration = true; - } + CompositeLocation returnLocComp = null; + + boolean hasReturnLocDeclaration = false; + 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); + hasReturnLocDeclaration = true; + } else if (an.getMarker().equals(ssjava.THISLOC)) { + String thisLoc = an.getValue(); + ssjava.getMethodLattice(md).setThisLoc(thisLoc); + } else if (an.getMarker().equals(ssjava.GLOBALLOC)) { + String globalLoc = an.getValue(); + ssjava.getMethodLattice(md).setGlobalLoc(globalLoc); + } else if (an.getMarker().equals(ssjava.PCLOC)) { + String pcLocDeclaration = an.getValue(); + ssjava.setPCLocation(md, parseLocationDeclaration(md, null, pcLocDeclaration)); } } + } + // second, check return location annotation + if (!md.getReturnType().isVoid() && !ssjava.getMethodContainingSSJavaLoop().equals(md)) { if (!hasReturnLocDeclaration) { // if developer does not define method lattice // search return location in the method default lattice @@ -339,21 +349,26 @@ public class FlowDownCheck { md2ReturnLoc.put(md, returnLocComp); - // check this location + } + + if (!md.getReturnType().isVoid() && !ssjava.getMethodContainingSSJavaLoop().equals(md)) { MethodLattice 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()); - } - CompositeLocation thisLoc = new CompositeLocation(new Location(md, thisLocId)); - paramList.add(0, thisLoc); + if ((!md.isStatic())) { - // System.out.println("### ReturnLocGenerator=" + md); - // System.out.println("### md2ReturnLoc.get(md)=" + md2ReturnLoc.get(md)); + if (thisLocId == null) { + throw new Error("Method '" + md + "' does not have the definition of 'this' location at " + + md.getClassDesc().getSourceFileName()); + } + + CompositeLocation thisLoc = new CompositeLocation(new Location(md, thisLocId)); + paramList.add(0, thisLoc); + + } md2ReturnLocGen.put(md, new ReturnLocGenerator(md2ReturnLoc.get(md), md, paramList, md + " of " + cd.getSourceFileName())); + } // fourth, check declarations inside of method @@ -537,8 +552,14 @@ public class FlowDownCheck { private CompositeLocation checkLocationFromReturnNode(MethodDescriptor md, SymbolTable nametable, ReturnNode rn, CompositeLocation constraint) { + if (ssjava.getMethodContainingSSJavaLoop().equals(md)) { + return new CompositeLocation(); + } + ExpressionNode returnExp = rn.getReturnExpression(); + CompositeLocation declaredReturnLoc = md2ReturnLoc.get(md); + CompositeLocation returnValueLoc; if (returnExp != null) { returnValueLoc = @@ -560,9 +581,40 @@ public class FlowDownCheck { // generateErrorMessage(md.getClassDesc(), rn)); // } + if (constraint != null) { + + // Set inputGLB = new HashSet(); + // inputGLB.add(returnValueLoc); + // inputGLB.add(constraint); + // returnValueLoc = + // CompositeLattice.calculateGLB(inputGLB, + // generateErrorMessage(md.getClassDesc(), rn)); + + // if (!returnValueLoc.get(returnValueLoc.getSize() - 1).isTop()) { + // if (!CompositeLattice.isGreaterThan(constraint, returnValueLoc, + // generateErrorMessage(md.getClassDesc(), rn))) { + // System.out.println("returnValueLoc.get(returnValueLoc.getSize() - 1).isTop()=" + // + returnValueLoc.get(returnValueLoc.getSize() - 1).isTop()); + // throw new Error("The value flow from " + constraint + " to " + + // returnValueLoc + // + " does not respect location hierarchy on the assignment " + + // rn.printNode(0) + // + " at " + md.getClassDesc().getSourceFileName() + "::" + + // rn.getNumLine()); + // } + // } + + if (!CompositeLattice.isGreaterThan(constraint, declaredReturnLoc, + generateErrorMessage(md.getClassDesc(), rn))) { + throw new Error("The value flow from " + constraint + " to " + declaredReturnLoc + + " does not respect location hierarchy on the assignment " + rn.printNode(0) + + " at " + md.getClassDesc().getSourceFileName() + "::" + rn.getNumLine()); + } + + } + // 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, false, @@ -606,6 +658,12 @@ public class FlowDownCheck { // check 'for loop' case BlockNode bn = ln.getInitializer(); bn.getVarTable().setParent(nametable); + // need to check initialization node + // checkLocationFromBlockNode(md, bn.getVarTable(), bn, constraint); + for (int i = 0; i < bn.size(); i++) { + BlockStatementNode bsn = bn.get(i); + checkLocationFromBlockStatementNode(md, bn.getVarTable(), bsn, constraint); + } // calculate glb location of condition and update statements CompositeLocation condLoc = @@ -649,13 +707,14 @@ public class FlowDownCheck { private CompositeLocation checkLocationFromIfStatementNode(MethodDescriptor md, SymbolTable nametable, IfStatementNode isn, CompositeLocation constraint) { + System.out.println("\n\ncheckLocationFromIfStatementNode=" + isn.printNode(0)); CompositeLocation condLoc = checkLocationFromExpressionNode(md, nametable, isn.getCondition(), new CompositeLocation(), constraint, false); - // addLocationType(isn.getCondition().getType(), condLoc); - + System.out.println("-######old constraint=" + constraint); constraint = generateNewConstraint(constraint, condLoc); + System.out.println("-######new constraint=" + constraint); checkLocationFromBlockNode(md, nametable, isn.getTrueBlock(), constraint); if (isn.getFalseBlock() != null) { @@ -682,7 +741,7 @@ public class FlowDownCheck { } if (!isOwned) { throw new Error( - "It is now allowed to create the reference alias from the reference not owned by the method at " + "It is not allowed to create the reference alias from the reference not owned by the method at " + generateErrorMessage(md.getClassDesc(), tn)); } @@ -729,11 +788,12 @@ public class FlowDownCheck { private void checkDeclarationInSubBlockNode(MethodDescriptor md, SymbolTable nametable, SubBlockNode sbn) { - checkDeclarationInBlockNode(md, nametable.getParent(), sbn.getBlockNode()); + checkDeclarationInBlockNode(md, nametable, sbn.getBlockNode()); } private CompositeLocation checkLocationFromBlockExpressionNode(MethodDescriptor md, SymbolTable nametable, BlockExpressionNode ben, CompositeLocation constraint) { + CompositeLocation compLoc = checkLocationFromExpressionNode(md, nametable, ben.getExpression(), null, constraint, false); // addTypeLocation(ben.getExpression().getType(), compLoc); @@ -854,24 +914,25 @@ public class FlowDownCheck { // System.out.println("# false=" + tn.getFalseExpr().printNode(0) + " Loc=" // + falseLoc); - // 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 false expression at " - + cd.getSourceFileName() + ":" + tn.getCond().getNumLine()); - } + // we don't need to check that 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 false expression at " + // + cd.getSourceFileName() + ":" + tn.getCond().getNumLine()); + // } // then, return glb of trueLoc & falseLoc Set glbInputSet = new HashSet(); + glbInputSet.add(condLoc); glbInputSet.add(trueLoc); glbInputSet.add(falseLoc); @@ -888,7 +949,7 @@ public class FlowDownCheck { CompositeLocation constraint) { ClassDescriptor cd = md.getClassDesc(); - MethodDescriptor calleeMD = min.getMethod(); + MethodDescriptor calleeMethodDesc = min.getMethod(); NameDescriptor baseName = min.getBaseName(); boolean isSystemout = false; @@ -896,8 +957,9 @@ public class FlowDownCheck { isSystemout = baseName.getSymbol().equals("System.out"); } - if (!ssjava.isSSJavaUtil(calleeMD.getClassDesc()) && !ssjava.isTrustMethod(calleeMD) - && !calleeMD.getModifiers().isNative() && !isSystemout) { + if (!ssjava.isSSJavaUtil(calleeMethodDesc.getClassDesc()) + && !ssjava.isTrustMethod(calleeMethodDesc) && !calleeMethodDesc.getModifiers().isNative() + && !isSystemout) { CompositeLocation baseLocation = null; if (min.getExpression() != null) { @@ -922,31 +984,109 @@ public class FlowDownCheck { // min.printNode(0) // + " baseLocation=" + baseLocation + " constraint=" + constraint); + // setup the location list of caller's arguments + List callerArgList = new ArrayList(); + + // setup the location list of callee's parameters + MethodLattice calleeLattice = ssjava.getMethodLattice(calleeMethodDesc); + List calleeParamList = new ArrayList(); + + if (min.numArgs() > 0) { + if (!calleeMethodDesc.isStatic()) { + callerArgList.add(baseLocation); + } + for (int i = 0; i < min.numArgs(); i++) { + ExpressionNode en = min.getArg(i); + CompositeLocation callerArgLoc = + checkLocationFromExpressionNode(md, nametable, en, new CompositeLocation(), + constraint, false); + callerArgList.add(callerArgLoc); + } + + if (!calleeMethodDesc.isStatic()) { + CompositeLocation calleeThisLoc = + new CompositeLocation(new Location(calleeMethodDesc, calleeLattice.getThisLoc())); + calleeParamList.add(calleeThisLoc); + } + + for (int i = 0; i < calleeMethodDesc.numParameters(); i++) { + VarDescriptor calleevd = (VarDescriptor) calleeMethodDesc.getParameter(i); + CompositeLocation calleeLoc = d2loc.get(calleevd); + calleeParamList.add(calleeLoc); + } + } + if (constraint != null) { - int compareResult = - CompositeLattice.compare(constraint, baseLocation, true, generateErrorMessage(cd, min)); - if (compareResult != ComparisonResult.GREATER) { - // if the current constraint is higher than method's THIS location - // no need to check constraints! - CompositeLocation calleeConstraint = - translateCallerLocToCalleeLoc(calleeMD, baseLocation, constraint); - // System.out.println("check method body for constraint:" + calleeMD + - // " calleeConstraint=" - // + calleeConstraint); - checkMethodBody(calleeMD.getClassDesc(), calleeMD, calleeConstraint); + // check whether the PC location is lower than one of the + // argument locations. If it is lower, the callee has to have @PCLOC + // annotation that declares the program counter that is higher than + // corresponding parameter + + CompositeLocation calleePCLOC = ssjava.getPCLocation(calleeMethodDesc); + + for (int idx = 0; idx < callerArgList.size(); idx++) { + CompositeLocation argLocation = callerArgList.get(idx); + + // if the PC location is lower than an argument location + // then, need to check that the callee's the initial location for the PC is also lower + // than the corresponding parameter location + + if (!argLocation.get(0).isTop() + && CompositeLattice.compare(argLocation, constraint, true, + generateErrorMessage(cd, min)) == ComparisonResult.GREATER) { + + CompositeLocation paramLocation = calleeParamList.get(idx); + + int paramCompareResult = + CompositeLattice.compare(paramLocation, calleePCLOC, true, + generateErrorMessage(cd, min)); + // CompositeLattice.compare(calleePCLOC, paramLocation, true, + // generateErrorMessage(cd, min)); + + System.out.println("-CHECKPCLOC:"); + System.out.println("---ARG LOC=" + + argLocation + + " callerPCLOC=" + + constraint + + " result=" + + CompositeLattice.compare(argLocation, constraint, true, + generateErrorMessage(cd, min))); + System.out.println("---PARAM LOC=" + paramLocation + " calleePCLOC=" + calleePCLOC + + " paramCompareResult=" + paramCompareResult); + + if (!(paramLocation.get(0).equals(calleePCLOC.get(0)) && calleePCLOC.getSize() > 1) + && paramCompareResult == ComparisonResult.LESS) { + throw new Error( + "The argument(idx=" + + idx + + ") location " + + argLocation + + "is higher than the caller program counter location " + + constraint + + ". Need to specify that the initial PC location of the callee, which is currently set to " + + calleePCLOC + ", is not higher than " + paramLocation + " in the method " + + calleeMethodDesc.getSymbol() + ":" + min.getNumLine()); + } + + } + } + } checkCalleeConstraints(md, nametable, min, baseLocation, constraint); - // checkCallerArgumentLocationConstraints(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); + + if (ceilingLoc == null) { + return new CompositeLocation(Location.createTopLocation(md)); + } return ceilingLoc; } } @@ -983,6 +1123,10 @@ public class FlowDownCheck { MethodDescriptor calleemd = min.getMethod(); + if (calleemd.isStatic()) { + return; + } + List callerArgList = new ArrayList(); List calleeParamList = new ArrayList(); @@ -1011,7 +1155,12 @@ public class FlowDownCheck { // System.out.println("base location=" + callerBaseLoc + " constraint=" + // constraint); - for (int i = 0; i < calleeParamList.size(); i++) { + System.out.println("calleeParamList=" + calleeParamList); + int offset = 0; + if (!md.isStatic()) { + offset = 1; + } + for (int i = offset; i < calleeParamList.size(); i++) { CompositeLocation calleeParamLoc = calleeParamList.get(i); if (calleeParamLoc.get(0).equals(calleeThisLoc) && calleeParamLoc.getSize() > 1) { @@ -1030,7 +1179,18 @@ public class FlowDownCheck { generateErrorMessage(md.getClassDesc(), min)); } - if (!CompositeLattice.isGreaterThan(callerArgLoc, paramLocation, errorMsg)) { + Location argLastLoc = callerArgLoc.get(callerArgLoc.getSize() - 1); + Location paramLastLoc = paramLocation.get(paramLocation.getSize() - 1); + + if (argLastLoc.equals(paramLastLoc) && ssjava.isSharedLocation(argLastLoc) + && ssjava.isSharedLocation(paramLastLoc)) { + continue; + } + + System.out.println("---idx=" + i + " callerArgLoc=" + callerArgLoc + " paramLocation=" + + paramLocation); + // if (!CompositeLattice.isGreaterThan(callerArgLoc, paramLocation, errorMsg)) { + if (CompositeLattice.compare(callerArgLoc, paramLocation, true, errorMsg) == ComparisonResult.LESS) { throw new Error("Caller argument '" + min.getArg(i).printNode(0) + " : " + callerArgLoc + "' should be higher than corresponding callee's parameter : " + paramLocation + " at " + errorMsg); @@ -1066,7 +1226,9 @@ public class FlowDownCheck { List argList = new ArrayList(); // by default, method has a THIS parameter - argList.add(baseLocation); + if (!min.getMethod().isStatic()) { + argList.add(baseLocation); + } for (int i = 0; i < min.numArgs(); i++) { ExpressionNode en = min.getArg(i); @@ -1076,8 +1238,7 @@ public class FlowDownCheck { argList.add(callerArg); } - // System.out.println("\n## computeReturnLocation=" + min.getMethod() + - // " argList=" + argList); + // System.out.println("\n## computeReturnLocation=" + min.getMethod() + " argList=" + argList); CompositeLocation ceilLoc = md2ReturnLocGen.get(min.getMethod()).computeReturnLocation(argList); // System.out.println("## ReturnLocation=" + ceilLoc); @@ -1088,13 +1249,12 @@ public class FlowDownCheck { 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 calleeLattice = ssjava.getMethodLattice(calleemd); - CompositeLocation calleeThisLoc = - new CompositeLocation(new Location(calleemd, calleeLattice.getThisLoc())); + + System.out.println("checkCalleeConstraints=" + calleemd + " calleeLattice.getThisLoc()=" + + calleeLattice.getThisLoc()); List callerArgList = new ArrayList(); List calleeParamList = new ArrayList(); @@ -1105,7 +1265,8 @@ public class FlowDownCheck { // setup caller args set // first, add caller's base(this) location - callerArgList.add(callerBaseLoc); + if (!calleemd.isStatic()) + callerArgList.add(callerBaseLoc); // second, add caller's arguments for (int i = 0; i < min.numArgs(); i++) { ExpressionNode en = min.getArg(i); @@ -1117,7 +1278,11 @@ public class FlowDownCheck { // setup callee params set // first, add callee's this location - calleeParamList.add(calleeThisLoc); + if (!calleemd.isStatic()) { + CompositeLocation calleeThisLoc = + new CompositeLocation(new Location(calleemd, calleeLattice.getThisLoc())); + calleeParamList.add(calleeThisLoc); + } // second, add callee's parameters for (int i = 0; i < calleemd.numParameters(); i++) { VarDescriptor calleevd = (VarDescriptor) calleemd.getParameter(i); @@ -1172,16 +1337,24 @@ public class FlowDownCheck { String paramName1, paramName2; - if (i == 0) { - paramName1 = "'THIS'"; + if (!calleemd.isStatic()) { + if (i == 0) { + paramName1 = "'THIS'"; + } else { + paramName1 = "'parameter " + calleemd.getParamName(i - 1) + "'"; + } } else { - paramName1 = "'parameter " + calleemd.getParamName(i - 1) + "'"; + paramName1 = "'parameter " + calleemd.getParamName(i) + "'"; } - if (j == 0) { - paramName2 = "'THIS'"; + if (!calleemd.isStatic()) { + if (j == 0 && !calleemd.isStatic()) { + paramName2 = "'THIS'"; + } else { + paramName2 = "'parameter " + calleemd.getParamName(j - 1) + "'"; + } } else { - paramName2 = "'parameter " + calleemd.getParamName(j - 1) + "'"; + paramName2 = "'parameter " + calleemd.getParamName(j) + "'"; } throw new Error( @@ -1200,18 +1373,19 @@ public class FlowDownCheck { private CompositeLocation checkLocationFromArrayAccessNode(MethodDescriptor md, SymbolTable nametable, ArrayAccessNode aan, CompositeLocation constraint, boolean isLHS) { - + System.out.println("aan=" + aan.printNode(0) + " line#=" + aan.getNumLine()); ClassDescriptor cd = md.getClassDesc(); - + System.out.println("aan.getExpression()=" + aan.getExpression().getClass()); CompositeLocation arrayLoc = checkLocationFromExpressionNode(md, nametable, aan.getExpression(), new CompositeLocation(), constraint, isLHS); - + System.out.println("HERE?"); // addTypeLocation(aan.getExpression().getType(), arrayLoc); CompositeLocation indexLoc = checkLocationFromExpressionNode(md, nametable, aan.getIndex(), new CompositeLocation(), constraint, isLHS); // addTypeLocation(aan.getIndex().getType(), indexLoc); + System.out.println("HERE2?"); if (isLHS) { if (!CompositeLattice.isGreaterThan(indexLoc, arrayLoc, generateErrorMessage(cd, aan))) { @@ -1223,7 +1397,11 @@ public class FlowDownCheck { Set inputGLB = new HashSet(); inputGLB.add(arrayLoc); inputGLB.add(indexLoc); - return CompositeLattice.calculateGLB(inputGLB, generateErrorMessage(cd, aan)); + System.out.println("arrayLoc=" + arrayLoc + " indexLoc=" + indexLoc); + CompositeLocation comp = + CompositeLattice.calculateGLB(inputGLB, generateErrorMessage(cd, aan)); + System.out.println("---aan=" + aan.printNode(0) + " compLoc=" + comp); + return comp; } } @@ -1255,12 +1433,9 @@ public class FlowDownCheck { // addTypeLocation(on.getRight().getType(), rightLoc); } - // System.out.println("\n# OP NODE=" + on.printNode(0)); - // System.out.println("# left loc=" + leftLoc + " from " + - // on.getLeft().getClass()); + // System.out.println("# left loc=" + leftLoc + " from " + on.getLeft().getClass()); // if (on.getRight() != null) { - // System.out.println("# right loc=" + rightLoc + " from " + - // on.getRight().getClass()); + // System.out.println("# right loc=" + rightLoc + " from " + on.getRight().getClass()); // } Operation op = on.getOp(); @@ -1322,6 +1497,7 @@ public class FlowDownCheck { private CompositeLocation checkLocationFromNameNode(MethodDescriptor md, SymbolTable nametable, NameNode nn, CompositeLocation loc, CompositeLocation constraint) { + // System.out.println("checkLocationFromNameNode nn=" + nn.printNode(0)); NameDescriptor nd = nn.getName(); if (nd.getBase() != null) { loc = @@ -1353,6 +1529,7 @@ public class FlowDownCheck { } else if (d instanceof FieldDescriptor) { // the type of field descriptor has a location! FieldDescriptor fd = (FieldDescriptor) d; + // System.out.println("fd=" + fd); if (fd.isStatic()) { if (fd.isFinal()) { // if it is 'static final', the location has TOP since no one can @@ -1360,6 +1537,7 @@ public class FlowDownCheck { loc.addLocation(Location.createTopLocation(md)); return loc; } else { + // if 'static', the location has pre-assigned global loc MethodLattice localLattice = ssjava.getMethodLattice(md); String globalLocId = localLattice.getGlobalLoc(); @@ -1367,7 +1545,7 @@ public class FlowDownCheck { throw new Error("Global location element is not defined in the method " + md); } Location globalLoc = new Location(md, globalLocId); - + System.out.println("static=" + globalLoc); loc.addLocation(globalLoc); } } else { @@ -1399,6 +1577,7 @@ public class FlowDownCheck { } } + return loc; } @@ -1425,26 +1604,29 @@ public class FlowDownCheck { } } + Set inputGLB = new HashSet(); if (left instanceof ArrayAccessNode) { ArrayAccessNode aan = (ArrayAccessNode) left; - left = aan.getExpression(); + CompositeLocation indexLoc = + checkLocationFromExpressionNode(md, nametable, aan.getIndex(), loc, constraint, false); + inputGLB.add(indexLoc); } loc = checkLocationFromExpressionNode(md, nametable, left, loc, constraint, false); - // System.out.println("### checkLocationFromFieldAccessNode=" + - // fan.printNode(0)); - // System.out.println("### left=" + left.printNode(0)); if (!left.getType().isPrimitive()) { - if (fd.getSymbol().equals("length")) { + if (!fd.getSymbol().equals("length")) { // array.length access, return the location of the array - return loc; + Location fieldLoc = getFieldLocation(fd); + loc.addLocation(fieldLoc); } - Location fieldLoc = getFieldLocation(fd); - loc.addLocation(fieldLoc); } + + inputGLB.add(loc); + loc = CompositeLattice.calculateGLB(inputGLB, generateErrorMessage(md.getClassDesc(), fan)); + return loc; } @@ -1489,7 +1671,7 @@ public class FlowDownCheck { private CompositeLocation checkLocationFromAssignmentNode(MethodDescriptor md, SymbolTable nametable, AssignmentNode an, CompositeLocation loc, CompositeLocation constraint) { - // System.out.println("\n# ASSIGNMENTNODE=" + an.printNode(0)); + System.out.println("\n\ncheckLocationFromAssignmentNode=" + an.printNode(0)); ClassDescriptor cd = md.getClassDesc(); @@ -1518,20 +1700,31 @@ public class FlowDownCheck { checkLocationFromExpressionNode(md, nametable, an.getSrc(), new CompositeLocation(), constraint, false); - srcLocation = rhsLocation; + if (an.getOperation().getOp() >= 2 && an.getOperation().getOp() <= 12) { + // if assignment contains OP+EQ operator, need to merge location types + // of LHS & RHS into the RHS + Set srcGLBSet = new HashSet(); + srcGLBSet.add(rhsLocation); + srcGLBSet.add(destLocation); + srcLocation = CompositeLattice.calculateGLB(srcGLBSet, generateErrorMessage(cd, an)); + } else { + 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(constraint, destLocation, generateErrorMessage(cd, an))) { + throw new Error("The value flow from " + constraint + " to " + destLocation + + " does not respect location hierarchy on the assignment " + an.printNode(0) + + " at " + cd.getSourceFileName() + "::" + an.getNumLine()); + } + // inputGLBSet.add(srcLocation); + // inputGLBSet.add(constraint); + // srcLocation = CompositeLattice.calculateGLB(inputGLBSet, + // generateErrorMessage(cd, an)); } - // } - // System.out.println("dstLocation=" + destLocation); - // System.out.println("rhsLocation=" + rhsLocation); - // System.out.println("srcLocation=" + srcLocation); - // System.out.println("constraint=" + constraint); + System.out.println("src=" + srcLocation + " dest=" + destLocation + " const=" + constraint); if (!CompositeLattice.isGreaterThan(srcLocation, destLocation, generateErrorMessage(cd, an))) { @@ -1553,7 +1746,7 @@ public class FlowDownCheck { ssjava.addSameHeightWriteFlatNode(fn); } - } + } } else { destLocation = @@ -1562,17 +1755,21 @@ public class FlowDownCheck { constraint, false); if (constraint != null) { - inputGLBSet.add(rhsLocation); - inputGLBSet.add(constraint); - srcLocation = CompositeLattice.calculateGLB(inputGLBSet, generateErrorMessage(cd, an)); + + if (!CompositeLattice.isGreaterThan(constraint, destLocation, generateErrorMessage(cd, an))) { + throw new Error("The value flow from " + constraint + " to " + destLocation + + " does not respect location hierarchy on the assignment " + an.printNode(0) + + " at " + cd.getSourceFileName() + "::" + an.getNumLine()); + } + // inputGLBSet.add(rhsLocation); + // inputGLBSet.add(constraint); + // srcLocation = CompositeLattice.calculateGLB(inputGLBSet, + // generateErrorMessage(cd, an)); + srcLocation = rhsLocation; } 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))) { if (srcLocation.equals(destLocation)) { @@ -1795,6 +1992,9 @@ public class FlowDownCheck { addLocationType(fd.getType(), loc); + if (ssjava.isSharedLocation(loc)) { + ssjava.addSharedDesc(loc, fd); + } } } @@ -1935,7 +2135,11 @@ public class FlowDownCheck { } else if (lattice.isGreaterThan(loc1.getLocIdentifier(), loc2.getLocIdentifier())) { return ComparisonResult.GREATER; } else { - return ComparisonResult.LESS; + if (lattice.isComparable(loc1.getLocIdentifier(), loc2.getLocIdentifier())) { + return ComparisonResult.LESS; + } else { + return ComparisonResult.INCOMPARABLE; + } } } @@ -1962,7 +2166,7 @@ public class FlowDownCheck { public static CompositeLocation calculateGLB(Set 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 @@ -1975,6 +2179,7 @@ public class FlowDownCheck { // composite location int maxTupleSize = 0; + int minTupleSize = 0; CompositeLocation maxCompLoc = null; Location prevPriorityLoc = null; @@ -1984,6 +2189,9 @@ public class FlowDownCheck { maxTupleSize = compLoc.getSize(); maxCompLoc = compLoc; } + if (minTupleSize == 0 || compLoc.getSize() < minTupleSize) { + minTupleSize = compLoc.getSize(); + } Location priorityLoc = compLoc.get(0); String priorityLocId = priorityLoc.getLocIdentifier(); priorityLocIdentifierSet.add(priorityLocId); @@ -2011,7 +2219,6 @@ public class FlowDownCheck { SSJavaLattice locOrder = getLatticeByDescriptor(priorityDescriptor); String glbOfPriorityLoc = locOrder.getGLB(priorityLocIdentifierSet); - glbCompLoc.addLocation(new Location(priorityDescriptor, glbOfPriorityLoc)); Set compSet = locId2CompLocSet.get(glbOfPriorityLoc); @@ -2022,7 +2229,8 @@ public class FlowDownCheck { // in this case, do not take care about delta // CompositeLocation inputComp = inputSet.iterator().next(); - for (int i = 1; i < maxTupleSize; i++) { + // for (int i = 1; i < maxTupleSize; i++) { + for (int i = 1; i < minTupleSize; i++) { glbCompLoc.addLocation(Location.createTopLocation(maxCompLoc.get(i).getDescriptor())); } } else { @@ -2072,6 +2280,7 @@ public class FlowDownCheck { } if (innerGLBInput.size() > 0) { + // System.out.println("######innerGLBInput=" + innerGLBInput); CompositeLocation innerGLB = CompositeLattice.calculateGLB(innerGLBInput, errMsg); for (int idx = 0; idx < innerGLB.getSize(); idx++) { glbCompLoc.addLocation(innerGLB.get(idx)); @@ -2094,7 +2303,7 @@ public class FlowDownCheck { } } - // System.out.println("GLB=" + glbCompLoc); + System.out.println("GLB=" + glbCompLoc); return glbCompLoc; } @@ -2273,6 +2482,9 @@ class ReturnLocGenerator { // compute GLB of arguments subset that are same or higher than return // location if (inputGLB.isEmpty()) { + if (args.size() == 0) { + return null; + } CompositeLocation rtr = new CompositeLocation(Location.createTopLocation(args.get(0).get(0).getDescriptor())); return rtr;