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;
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);
}
}
}
}
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()) {
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()) {
MethodLattice<String> 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()));
}
// 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 =
}
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));
}
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);
// min.printNode(0)
// + " baseLocation=" + baseLocation + " constraint=" + constraint);
+ // setup the location list of caller's arguments
+ List<CompositeLocation> callerArgList = new ArrayList<CompositeLocation>();
+
+ if (min.numArgs() > 0) {
+ // setup caller args set
+ // first, add caller's base(this) location
+ callerArgList.add(baseLocation);
+ // second, add caller's arguments
+ 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);
+ }
+ }
+
+ // setup the location list of callee's parameters
+ MethodDescriptor calleemd = min.getMethod();
+ MethodLattice<String> calleeLattice = ssjava.getMethodLattice(calleemd);
+ CompositeLocation calleeThisLoc =
+ new CompositeLocation(new Location(calleemd, calleeLattice.getThisLoc()));
+ List<CompositeLocation> calleeParamList = new ArrayList<CompositeLocation>();
+ // first, add callee's this location
+ calleeParamList.add(calleeThisLoc);
+ // second, add callee's parameters
+ for (int i = 0; i < calleemd.numParameters(); i++) {
+ VarDescriptor calleevd = (VarDescriptor) calleemd.getParameter(i);
+ CompositeLocation calleeLoc = d2loc.get(calleevd);
+ calleeParamList.add(calleeLoc);
+ }
+
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(calleemd);
+
+ for (int idx = 0; idx < callerArgList.size(); idx++) {
+ CompositeLocation argLocation = callerArgList.get(idx);
+
+ int compareResult =
+ CompositeLattice
+ .compare(argLocation, constraint, true, generateErrorMessage(cd, min));
+
+ // need to check that param is higher than PCLOC
+ if (compareResult == 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 "
+ + calleeMD.getSymbol() + ":" + min.getNumLine());
+ }
+
+ }
+
}
+
}
checkCalleeConstraints(md, nametable, min, baseLocation, constraint);
}
// }
-// System.out.println("dstLocation=" + destLocation);
-// System.out.println("rhsLocation=" + rhsLocation);
-// System.out.println("srcLocation=" + srcLocation);
-// System.out.println("constraint=" + constraint);
+ // 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))) {
+ " 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 =
}
+ 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;