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;
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);
}
}
}
private void checkDeclarationInMethodBody(ClassDescriptor cd, MethodDescriptor md) {
BlockNode bn = state.getMethodBody(md);
- System.out.println("\n#checkDeclarationInMethodBody=" + md);
-
// first, check annotations on method parameters
List<CompositeLocation> paramList = new ArrayList<CompositeLocation>();
for (int i = 0; i < md.numParameters(); i++) {
}
Vector<AnnotationDescriptor> 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
md2ReturnLoc.put(md, returnLocComp);
- // check this location
+ }
+
+ if (!md.getReturnType().isVoid() && !ssjava.getMethodContainingSSJavaLoop().equals(md)) {
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());
- }
- 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
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 =
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<CompositeLocation> inputGLB = new HashSet<CompositeLocation>();
+ // inputGLB.add(returnValueLoc);
+ // inputGLB.add(constraint);
+ // returnValueLoc =
+ // CompositeLattice.calculateGLB(inputGLB,
+ // generateErrorMessage(md.getClassDesc(), rn));
+ // }
+
if (constraint != null) {
- Set<CompositeLocation> inputGLB = new HashSet<CompositeLocation>();
- inputGLB.add(returnValueLoc);
- inputGLB.add(constraint);
- returnValueLoc =
- CompositeLattice.calculateGLB(inputGLB, generateErrorMessage(md.getClassDesc(), rn));
+
+ // Set<CompositeLocation> inputGLB = new HashSet<CompositeLocation>();
+ // 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,
// 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 =
private CompositeLocation checkLocationFromIfStatementNode(MethodDescriptor md,
SymbolTable nametable, IfStatementNode isn, CompositeLocation constraint) {
+ System.out.println("checkLocationFromIfStatementNode=" + isn);
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) {
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) {
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))) {
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);
// 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))) {
CompositeLocation constraint) {
ClassDescriptor cd = md.getClassDesc();
- MethodDescriptor calleeMD = min.getMethod();
+ MethodDescriptor calleeMethodDesc = min.getMethod();
NameDescriptor baseName = min.getBaseName();
boolean isSystemout = false;
isSystemout = baseName.getSymbol().equals("System.out");
}
- if (!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) {
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<CompositeLocation> callerArgList = new ArrayList<CompositeLocation>();
+
+ // setup the location list of callee's parameters
+ MethodLattice<String> calleeLattice = ssjava.getMethodLattice(calleeMethodDesc);
+ List<CompositeLocation> calleeParamList = new ArrayList<CompositeLocation>();
+
+ 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);
+
+ // 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.LESS) {
+
+ 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 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);
// 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;
}
}
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);
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;
+ }
+
+ // 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);
translate.addLocation(calleeParamLoc.get(i));
}
- System.out.println("TRANSLATED=" + translate + " from calleeParamLoc=" + calleeParamLoc);
+ // System.out.println("TRANSLATED=" + translate + " from calleeParamLoc=" +
+ // calleeParamLoc);
return translate;
}
List<CompositeLocation> argList = new ArrayList<CompositeLocation>();
// 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);
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;
private void checkCalleeConstraints(MethodDescriptor md, SymbolTable nametable,
MethodInvokeNode min, CompositeLocation callerBaseLoc, CompositeLocation constraint) {
- System.out.println("checkCalleeConstraints=" + min.printNode(0));
-
MethodDescriptor calleemd = min.getMethod();
MethodLattice<String> calleeLattice = ssjava.getMethodLattice(calleemd);
- CompositeLocation calleeThisLoc =
- new CompositeLocation(new Location(calleemd, calleeLattice.getThisLoc()));
+
+ System.out.println("checkCalleeConstraints=" + calleemd + " calleeLattice.getThisLoc()="
+ + calleeLattice.getThisLoc());
List<CompositeLocation> callerArgList = new ArrayList<CompositeLocation>();
List<CompositeLocation> calleeParamList = new ArrayList<CompositeLocation>();
// 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);
// 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);
CompositeLocation calleeLoc = d2loc.get(calleevd);
- System.out.println("calleevd=" + calleevd + " loc=" + calleeLoc);
+ // System.out.println("calleevd=" + calleevd + " loc=" + calleeLoc);
calleeParamList.add(calleeLoc);
}
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) {
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(
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();
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(),
// 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();
inputSet.add(rightLoc);
CompositeLocation glbCompLoc =
CompositeLattice.calculateGLB(inputSet, generateErrorMessage(cd, on));
- System.out.println("# glbCompLoc=" + glbCompLoc);
return glbCompLoc;
default:
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;
loc.addLocation(fieldLoc);
} else if (d == null) {
// access static field
- ClassDescriptor cd = nn.getClassDesc();
+ FieldDescriptor fd = nn.getField();
MethodLattice<String> localLattice = ssjava.getMethodLattice(md);
String globalLocId = localLattice.getGlobalLoc();
+ generateErrorMessage(md.getClassDesc(), nn));
}
loc.addLocation(new Location(md, globalLocId));
+
+ Location fieldLoc = (Location) fd.getType().getExtension();
+ loc.addLocation(fieldLoc);
+
return loc;
}
}
+
return loc;
}
return loc;
}
}
-
- if(left instanceof ArrayAccessNode){
- System.out.println("HEREE!!");
- ArrayAccessNode aan=(ArrayAccessNode)left;
- left=aan.getExpression();
+
+ Set<CompositeLocation> inputGLB = new HashSet<CompositeLocation>();
+ if (left instanceof ArrayAccessNode) {
+ ArrayAccessNode aan = (ArrayAccessNode) left;
+ 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();
}
+ 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<CompositeLocation> inputGLBSet = new HashSet<CompositeLocation>();
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<CompositeLocation> srcGLBSet = new HashSet<CompositeLocation>();
+ 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))) {
+ " at " + cd.getSourceFileName() + "::" + an.getNumLine());
}
+ if (srcLocation.equals(destLocation)) {
+ // keep it for definitely written analysis
+ Set<FlatNode> flatNodeSet = ssjava.getBuildFlat().getFlatNodeSet(an);
+ for (Iterator iterator = flatNodeSet.iterator(); iterator.hasNext();) {
+ FlatNode fn = (FlatNode) iterator.next();
+ ssjava.addSameHeightWriteFlatNode(fn);
+ }
+
+ }
+
} else {
destLocation =
rhsLocation =
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)) {
}
+ if (srcLocation.equals(destLocation)) {
+ // keep it for definitely written analysis
+ Set<FlatNode> flatNodeSet = ssjava.getBuildFlat().getFlatNodeSet(an);
+ for (Iterator iterator = flatNodeSet.iterator(); iterator.hasNext();) {
+ FlatNode fn = (FlatNode) iterator.next();
+ ssjava.addSameHeightWriteFlatNode(fn);
+ }
+ }
+
}
return destLocation;
+ 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);
}
-
}
}
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);
}
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) + ".");
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);
+ }
}
}
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) {
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) {
SSJavaLattice<String> locOrder = getLatticeByDescriptor(priorityDescriptor);
String glbOfPriorityLoc = locOrder.getGLB(priorityLocIdentifierSet);
-
glbCompLoc.addLocation(new Location(priorityDescriptor, glbOfPriorityLoc));
Set<CompositeLocation> compSet = locId2CompLocSet.get(glbOfPriorityLoc);
}
}
- System.out.println("GLB=" + glbCompLoc);
+ System.out.println("GLB=" + glbCompLoc + "\n");
return glbCompLoc;
}
// 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;