X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=Robust%2Fsrc%2FAnalysis%2FSSJava%2FFlowDownCheck.java;h=85b36731c909080f71cf361ad6e092edd00b47cb;hb=34e201e35ec38f4d644a5279a9fa6d9a4ca1e08d;hp=a1397dae02aa1ccaff911dff574af5c1f5318eaf;hpb=4b05874dbd7d1a97136996f9e4f792b47ac04ae5;p=IRC.git diff --git a/Robust/src/Analysis/SSJava/FlowDownCheck.java b/Robust/src/Analysis/SSJava/FlowDownCheck.java index a1397dae..85b36731 100644 --- a/Robust/src/Analysis/SSJava/FlowDownCheck.java +++ b/Robust/src/Analysis/SSJava/FlowDownCheck.java @@ -23,7 +23,9 @@ import IR.Operation; import IR.State; import IR.SymbolTable; import IR.TypeDescriptor; +import IR.TypeExtension; import IR.VarDescriptor; +import IR.Flat.FlatNode; import IR.Tree.ArrayAccessNode; import IR.Tree.AssignmentNode; import IR.Tree.BlockExpressionNode; @@ -221,8 +223,11 @@ public class FlowDownCheck { while (!toAnalyzeMethodIsEmpty()) { MethodDescriptor md = toAnalyzeMethodNext(); if (ssjava.needTobeAnnotated(md)) { - System.out.println("SSJAVA: Checking assignments: " + md); - checkMethodBody(cd, md, null); + if (state.SSJAVADEBUG) { + System.out.println("SSJAVA: Checking Flow-down Rules: " + md); + } + CompositeLocation calleePCLOC = ssjava.getPCLocation(md); + checkMethodBody(cd, md, calleePCLOC); } } } @@ -292,7 +297,6 @@ public class FlowDownCheck { private void checkDeclarationInMethodBody(ClassDescriptor cd, MethodDescriptor md) { BlockNode bn = state.getMethodBody(md); - // first, check annotations on method parameters List paramList = new ArrayList(); for (int i = 0; i < md.numParameters(); i++) { @@ -303,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()) { if (!hasReturnLocDeclaration) { // if developer does not define method lattice // search return location in the method default lattice @@ -336,19 +349,17 @@ public class FlowDownCheck { md2ReturnLoc.put(md, returnLocComp); - // check this location + } + + if (!md.getReturnType().isVoid()) { MethodLattice methodLattice = ssjava.getMethodLattice(md); String thisLocId = methodLattice.getThisLoc(); - if (thisLocId == null) { + if ((!md.isStatic()) && 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); - -// System.out.println("### ReturnLocGenerator=" + md); -// System.out.println("### md2ReturnLoc.get(md)=" + md2ReturnLoc.get(md)); - md2ReturnLocGen.put(md, new ReturnLocGenerator(md2ReturnLoc.get(md), md, paramList, md + " of " + cd.getSourceFileName())); } @@ -542,15 +553,20 @@ public class FlowDownCheck { checkLocationFromExpressionNode(md, nametable, returnExp, new CompositeLocation(), constraint, false); + // System.out.println("# RETURN VALUE LOC=" + returnValueLoc + + // " with constraint=" + constraint); + + // TODO: do we need to check here? // if this return statement is inside branch, return value has an implicit // flow from conditional location - if (constraint != null) { - Set inputGLB = new HashSet(); - inputGLB.add(returnValueLoc); - inputGLB.add(constraint); - returnValueLoc = - CompositeLattice.calculateGLB(inputGLB, 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)); + // } // check if return value is equal or higher than RETRUNLOC of method // declaration annotation @@ -598,6 +614,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 = @@ -657,6 +679,32 @@ public class FlowDownCheck { return new CompositeLocation(); } + private void checkOwnership(MethodDescriptor md, TreeNode tn, ExpressionNode srcExpNode) { + + if (srcExpNode.kind() == Kind.NameNode || srcExpNode.kind() == Kind.FieldAccessNode) { + if (srcExpNode.getType().isPtr() && !srcExpNode.getType().isNull()) { + // first, check the linear type + // RHS reference should be owned by the current method + FieldDescriptor fd = getFieldDescriptorFromExpressionNode(srcExpNode); + boolean isOwned; + if (fd == null) { + // local var case + isOwned = ((SSJavaType) srcExpNode.getType().getExtension()).isOwned(); + } else { + // field case + isOwned = ssjava.isOwnedByMethod(md, fd); + } + if (!isOwned) { + throw new Error( + "It is not allowed to create the reference alias from the reference not owned by the method at " + + generateErrorMessage(md.getClassDesc(), tn)); + } + + } + } + + } + private CompositeLocation checkLocationFromDeclarationNode(MethodDescriptor md, SymbolTable nametable, DeclarationNode dn, CompositeLocation constraint) { @@ -665,12 +713,16 @@ public class FlowDownCheck { CompositeLocation destLoc = d2loc.get(vd); if (dn.getExpression() != null) { + + checkOwnership(md, dn, dn.getExpression()); + CompositeLocation expressionLoc = checkLocationFromExpressionNode(md, nametable, dn.getExpression(), new CompositeLocation(), constraint, false); // addTypeLocation(dn.getExpression().getType(), expressionLoc); if (expressionLoc != null) { + // checking location order if (!CompositeLattice.isGreaterThan(expressionLoc, destLoc, generateErrorMessage(md.getClassDesc(), dn))) { @@ -691,11 +743,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); @@ -809,6 +862,13 @@ public class FlowDownCheck { // values // in this case, we don't need to check flow down rule! + // System.out.println("\n#tertiary cond=" + tn.getCond().printNode(0) + + // " Loc=" + condLoc); + // System.out.println("# true=" + tn.getTrueExpr().printNode(0) + " Loc=" + + // trueLoc); + // 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))) { @@ -843,7 +903,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; @@ -851,8 +911,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) { @@ -871,28 +932,83 @@ public class FlowDownCheck { String thisLocId = ssjava.getMethodLattice(md).getThisLoc(); baseLocation = new CompositeLocation(new Location(md, thisLocId)); } - } -// System.out.println("\n#checkLocationFromMethodInvokeNode=" + min.printNode(0) -// + " baseLocation=" + baseLocation + " constraint=" + constraint); + // System.out.println("\n#checkLocationFromMethodInvokeNode=" + + // 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.LESS) { - throw new Error("Method invocation does not respect the current branch constraint at " - + generateErrorMessage(cd, min)); - } else 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); + + // need to check that param is higher than PCLOC + if (!argLocation.get(0).isTop() + && CompositeLattice.compare(argLocation, constraint, true, + generateErrorMessage(cd, min)) == ComparisonResult.GREATER) { + + CompositeLocation paramLocation = calleeParamList.get(idx); + + int paramCompareResult = + CompositeLattice.compare(calleePCLOC, paramLocation, true, + generateErrorMessage(cd, min)); + + if (paramCompareResult == ComparisonResult.GREATER) { + throw new Error( + "The program counter location " + + constraint + + " is lower than the argument(idx=" + + idx + + ") location " + + argLocation + + ". Need to specify that the initial PC location of the callee, which is currently set to " + + calleePCLOC + ", is lower than " + paramLocation + " in the method " + + calleeMethodDesc.getSymbol() + ":" + min.getNumLine()); + } + + } + } + } checkCalleeConstraints(md, nametable, min, baseLocation, constraint); @@ -964,8 +1080,10 @@ public class FlowDownCheck { String errorMsg = generateErrorMessage(md.getClassDesc(), min); -// System.out.println("checkCallerArgumentLocationConstraints=" + min.printNode(0)); -// System.out.println("base location=" + callerBaseLoc + " constraint=" + constraint); + // System.out.println("checkCallerArgumentLocationConstraints=" + + // min.printNode(0)); + // System.out.println("base location=" + callerBaseLoc + " constraint=" + + // constraint); for (int i = 0; i < calleeParamList.size(); i++) { CompositeLocation calleeParamLoc = calleeParamList.get(i); @@ -1010,7 +1128,8 @@ public class FlowDownCheck { translate.addLocation(calleeParamLoc.get(i)); } -// System.out.println("TRANSLATED=" + translate + " from calleeParamLoc=" + calleeParamLoc); + // System.out.println("TRANSLATED=" + translate + " from calleeParamLoc=" + + // calleeParamLoc); return translate; } @@ -1031,9 +1150,10 @@ 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); + // System.out.println("## ReturnLocation=" + ceilLoc); return ceilLoc; @@ -1042,11 +1162,10 @@ 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())); @@ -1059,7 +1178,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); @@ -1071,12 +1191,13 @@ public class FlowDownCheck { // setup callee params set // first, add callee's this location - calleeParamList.add(calleeThisLoc); + if (!calleemd.isStatic()) + 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); + // System.out.println("calleevd=" + calleevd + " loc=" + calleeLoc); calleeParamList.add(calleeLoc); } @@ -1096,15 +1217,27 @@ public class FlowDownCheck { continue CHECK; } -// System.out.println("calleeLoc1=" + calleeLoc1); -// System.out.println("calleeLoc2=" + calleeLoc2 + "calleeParamList=" + calleeParamList); + // System.out.println("calleeLoc1=" + calleeLoc1); + // System.out.println("calleeLoc2=" + calleeLoc2 + + // "calleeParamList=" + calleeParamList); int callerResult = CompositeLattice.compare(callerLoc1, callerLoc2, true, generateErrorMessage(md.getClassDesc(), min)); + // System.out.println("callerResult=" + callerResult); int calleeResult = CompositeLattice.compare(calleeLoc1, calleeLoc2, true, generateErrorMessage(md.getClassDesc(), min)); + // System.out.println("calleeResult=" + calleeResult); + + if (callerResult == ComparisonResult.EQUAL) { + if (ssjava.isSharedLocation(callerLoc1.get(callerLoc1.getSize() - 1)) + && ssjava.isSharedLocation(callerLoc2.get(callerLoc2.getSize() - 1))) { + // if both of them are shared locations, promote them to + // "GREATER relation" + callerResult = ComparisonResult.GREATER; + } + } if (calleeResult == ComparisonResult.GREATER && callerResult != ComparisonResult.GREATER) { @@ -1148,6 +1281,7 @@ public class FlowDownCheck { CompositeLocation arrayLoc = checkLocationFromExpressionNode(md, nametable, aan.getExpression(), new CompositeLocation(), constraint, isLHS); + // addTypeLocation(aan.getExpression().getType(), arrayLoc); CompositeLocation indexLoc = checkLocationFromExpressionNode(md, nametable, aan.getIndex(), new CompositeLocation(), @@ -1196,11 +1330,13 @@ 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()); -// if (on.getRight() != null) { -// System.out.println("# right loc=" + rightLoc + " from " + on.getRight().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().getClass()); + // } Operation op = on.getOp(); @@ -1239,7 +1375,6 @@ public class FlowDownCheck { inputSet.add(rightLoc); CompositeLocation glbCompLoc = CompositeLattice.calculateGLB(inputSet, generateErrorMessage(cd, on)); -// System.out.println("# glbCompLoc=" + glbCompLoc); return glbCompLoc; default: @@ -1289,7 +1424,7 @@ public class FlowDownCheck { VarDescriptor vd = (VarDescriptor) d; // localLoc = d2loc.get(vd); // the type of var descriptor has a composite location! - loc = ((CompositeLocation) vd.getType().getExtension()).clone(); + loc = ((SSJavaType) vd.getType().getExtension()).getCompLoc().clone(); } else if (d instanceof FieldDescriptor) { // the type of field descriptor has a location! FieldDescriptor fd = (FieldDescriptor) d; @@ -1322,7 +1457,7 @@ public class FlowDownCheck { loc.addLocation(fieldLoc); } else if (d == null) { // access static field - ClassDescriptor cd = nn.getClassDesc(); + FieldDescriptor fd = nn.getField(); MethodLattice localLattice = ssjava.getMethodLattice(md); String globalLocId = localLattice.getGlobalLoc(); @@ -1331,6 +1466,10 @@ public class FlowDownCheck { + generateErrorMessage(md.getClassDesc(), nn)); } loc.addLocation(new Location(md, globalLocId)); + + Location fieldLoc = (Location) fd.getType().getExtension(); + loc.addLocation(fieldLoc); + return loc; } @@ -1361,26 +1500,36 @@ 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()) { - Location fieldLoc = getFieldLocation(fd); - loc.addLocation(fieldLoc); + + if (!fd.getSymbol().equals("length")) { + // array.length access, return the location of the array + Location fieldLoc = getFieldLocation(fd); + loc.addLocation(fieldLoc); + } + } -// System.out.println("### field loc=" + loc); + + inputGLB.add(loc); + loc = CompositeLattice.calculateGLB(inputGLB, generateErrorMessage(md.getClassDesc(), fan)); return loc; } private Location getFieldLocation(FieldDescriptor fd) { -// System.out.println("### getFieldLocation=" + fd); -// System.out.println("### fd.getType().getExtension()=" + fd.getType().getExtension()); + // System.out.println("### getFieldLocation=" + fd); + // System.out.println("### fd.getType().getExtension()=" + + // fd.getType().getExtension()); Location fieldLoc = (Location) fd.getType().getExtension(); @@ -1394,11 +1543,29 @@ public class FlowDownCheck { } + private FieldDescriptor getFieldDescriptorFromExpressionNode(ExpressionNode en) { + + if (en.kind() == Kind.NameNode) { + NameNode nn = (NameNode) en; + if (nn.getField() != null) { + return nn.getField(); + } + + if (nn.getName() != null && nn.getName().getBase() != null) { + return getFieldDescriptorFromExpressionNode(nn.getExpression()); + } + + } else if (en.kind() == Kind.FieldAccessNode) { + FieldAccessNode fan = (FieldAccessNode) en; + return fan.getField(); + } + + return null; + } + private CompositeLocation checkLocationFromAssignmentNode(MethodDescriptor md, SymbolTable nametable, AssignmentNode an, CompositeLocation loc, CompositeLocation constraint) { -// System.out.println("\n# ASSIGNMENTNODE=" + an.printNode(0)); - ClassDescriptor cd = md.getClassDesc(); Set inputGLBSet = new HashSet(); @@ -1419,24 +1586,29 @@ public class FlowDownCheck { CompositeLocation srcLocation; if (!postinc) { + + checkOwnership(md, an, an.getSrc()); + rhsLocation = 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(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); if (!CompositeLattice.isGreaterThan(srcLocation, destLocation, generateErrorMessage(cd, an))) { @@ -1450,6 +1622,16 @@ public class FlowDownCheck { + " at " + cd.getSourceFileName() + "::" + an.getNumLine()); } + if (srcLocation.equals(destLocation)) { + // keep it for definitely written analysis + Set flatNodeSet = ssjava.getBuildFlat().getFlatNodeSet(an); + for (Iterator iterator = flatNodeSet.iterator(); iterator.hasNext();) { + FlatNode fn = (FlatNode) iterator.next(); + ssjava.addSameHeightWriteFlatNode(fn); + } + + } + } else { destLocation = rhsLocation = @@ -1464,10 +1646,6 @@ public class FlowDownCheck { 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)) { @@ -1482,6 +1660,15 @@ public class FlowDownCheck { } + if (srcLocation.equals(destLocation)) { + // keep it for definitely written analysis + Set flatNodeSet = ssjava.getBuildFlat().getFlatNodeSet(an); + for (Iterator iterator = flatNodeSet.iterator(); iterator.hasNext();) { + FlatNode fn = (FlatNode) iterator.next(); + ssjava.addSameHeightWriteFlatNode(fn); + } + } + } return destLocation; @@ -1500,33 +1687,36 @@ public class FlowDownCheck { + generateErrorMessage(cd, n)); } - if (annotationVec.size() > 1) { // variable can have at most one location - throw new Error(vd.getSymbol() + " has more than one location."); - } + int locDecCount = 0; + for (int i = 0; i < annotationVec.size(); i++) { + AnnotationDescriptor ad = annotationVec.elementAt(i); - AnnotationDescriptor ad = annotationVec.elementAt(0); + if (ad.getType() == AnnotationDescriptor.SINGLE_ANNOTATION) { - if (ad.getType() == AnnotationDescriptor.SINGLE_ANNOTATION) { + if (ad.getMarker().equals(SSJavaAnalysis.LOC)) { + locDecCount++; + if (locDecCount > 1) {// variable can have at most one location + throw new Error(vd.getSymbol() + " has more than one location declaration."); + } + String locDec = ad.getValue(); // check if location is defined - if (ad.getMarker().equals(SSJavaAnalysis.LOC)) { - String locDec = ad.getValue(); // check if location is defined + if (locDec.startsWith(SSJavaAnalysis.DELTA)) { + DeltaLocation deltaLoc = parseDeltaDeclaration(md, n, locDec); + d2loc.put(vd, deltaLoc); + addLocationType(vd.getType(), deltaLoc); + } else { + CompositeLocation compLoc = parseLocationDeclaration(md, n, locDec); - if (locDec.startsWith(SSJavaAnalysis.DELTA)) { - DeltaLocation deltaLoc = parseDeltaDeclaration(md, n, locDec); - d2loc.put(vd, deltaLoc); - addLocationType(vd.getType(), deltaLoc); - } else { - CompositeLocation compLoc = parseLocationDeclaration(md, n, locDec); + Location lastElement = compLoc.get(compLoc.getSize() - 1); + if (ssjava.isSharedLocation(lastElement)) { + ssjava.mapSharedLocation2Descriptor(lastElement, vd); + } - Location lastElement = compLoc.get(compLoc.getSize() - 1); - if (ssjava.isSharedLocation(lastElement)) { - ssjava.mapSharedLocation2Descriptor(lastElement, vd); + d2loc.put(vd, compLoc); + addLocationType(vd.getType(), compLoc); } - d2loc.put(vd, compLoc); - addLocationType(vd.getType(), compLoc); } - } } @@ -1562,7 +1752,8 @@ public class FlowDownCheck { Descriptor d = state.getClassSymbolTable().get(className); if (d == null) { -// System.out.println("state.getClassSymbolTable()=" + state.getClassSymbolTable()); + // System.out.println("state.getClassSymbolTable()=" + + // state.getClassSymbolTable()); throw new Error("The class in the location declaration '" + decl + "' does not exist at " + msg); } @@ -1685,7 +1876,15 @@ public class FlowDownCheck { private void addLocationType(TypeDescriptor type, CompositeLocation loc) { if (type != null) { - type.setExtension(loc); + TypeExtension te = type.getExtension(); + SSJavaType ssType; + if (te != null) { + ssType = (SSJavaType) te; + ssType.setCompLoc(loc); + } else { + ssType = new SSJavaType(loc); + type.setExtension(ssType); + } } } @@ -1699,7 +1898,8 @@ public class FlowDownCheck { public static boolean isGreaterThan(CompositeLocation loc1, CompositeLocation loc2, String msg) { -// System.out.println("\nisGreaterThan=" + loc1 + " " + loc2 + " msg=" + 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) { @@ -1718,7 +1918,7 @@ public class FlowDownCheck { public static int compare(CompositeLocation loc1, CompositeLocation loc2, boolean ignore, String msg) { -// System.out.println("compare=" + loc1 + " " + loc2); + // System.out.println("compare=" + loc1 + " " + loc2); int baseCompareResult = compareBaseLocationSet(loc1, loc2, false, ignore, msg); if (baseCompareResult == ComparisonResult.EQUAL) { @@ -1835,7 +2035,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 @@ -1967,7 +2167,7 @@ public class FlowDownCheck { } } -// System.out.println("GLB=" + glbCompLoc); + // System.out.println("GLB=" + glbCompLoc); return glbCompLoc; }