From 03e4ef747b4dc3b230bc431ad476c773f09751d4 Mon Sep 17 00:00:00 2001 From: yeom Date: Tue, 2 Aug 2011 18:45:45 +0000 Subject: [PATCH] changes. --- Robust/src/Analysis/SSJava/FlowDownCheck.java | 217 +++++++++++++----- 1 file changed, 160 insertions(+), 57 deletions(-) diff --git a/Robust/src/Analysis/SSJava/FlowDownCheck.java b/Robust/src/Analysis/SSJava/FlowDownCheck.java index 2d5a6a20..e2dc7384 100644 --- a/Robust/src/Analysis/SSJava/FlowDownCheck.java +++ b/Robust/src/Analysis/SSJava/FlowDownCheck.java @@ -306,32 +306,26 @@ public class FlowDownCheck { if (!md.getReturnType().isVoid()) { CompositeLocation returnLocComp = null; - String rtrStr = ssjava.getMethodLattice(md).getReturnLoc(); - if (rtrStr != null) { - returnLocComp = new CompositeLocation(new Location(md, rtrStr)); - } else { - if (methodAnnotations != null) { - for (int i = 0; i < methodAnnotations.size(); i++) { - AnnotationDescriptor an = methodAnnotations.elementAt(i); - if (an.getMarker().equals(ssjava.RETURNLOC)) { - // this case, developer explicitly defines method lattice - String returnLocDeclaration = an.getValue(); - returnLocComp = parseLocationDeclaration(md, null, returnLocDeclaration); - } - } - } else { - // if developer does not define method lattice - // search return location in the method default lattice - if (returnLocComp == null) { - MethodLattice methodDefaultLattice = ssjava.getMethodDefaultLattice(cd); - if (methodDefaultLattice.getReturnLoc() != null) { - returnLocComp = - parseLocationDeclaration(md, null, methodDefaultLattice.getReturnLoc()); - } + 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; } } } + if (!hasReturnLocDeclaration) { + // if developer does not define method lattice + // search return location in the method default lattice + String rtrStr = ssjava.getMethodLattice(md).getReturnLoc(); + returnLocComp = new CompositeLocation(new Location(md, rtrStr)); + } + if (returnLocComp == null) { throw new Error("Return location is not specified for the method " + md + " at " + cd.getSourceFileName()); @@ -351,8 +345,8 @@ public class FlowDownCheck { System.out.println("### ReturnLocGenerator=" + md); System.out.println("### md2ReturnLoc.get(md)=" + md2ReturnLoc.get(md)); - md2ReturnLocGen.put(md, new ReturnLocGenerator(md2ReturnLoc.get(md), paramList, md + " of " - + cd.getSourceFileName())); + md2ReturnLocGen.put(md, new ReturnLocGenerator(md2ReturnLoc.get(md), md, paramList, md + + " of " + cd.getSourceFileName())); } // fourth, check declarations inside of method @@ -860,6 +854,8 @@ public class FlowDownCheck { checkCalleeConstraints(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 @@ -872,6 +868,86 @@ public class FlowDownCheck { } + private void checkCallerArgumentLocationConstraints(MethodDescriptor md, SymbolTable nametable, + MethodInvokeNode min, CompositeLocation baseLoc, CompositeLocation constraint) { + // if parameter location consists of THIS and FIELD location, + // caller should pass an argument that is comparable to the declared + // parameter location + // and is not lower than the declared parameter location in the field + // lattice. + + MethodDescriptor calleemd = min.getMethod(); + + List callerArgList = new ArrayList(); + List calleeParamList = new ArrayList(); + + MethodLattice calleeLattice = ssjava.getMethodLattice(calleemd); + Location calleeThisLoc = new Location(calleemd, calleeLattice.getThisLoc()); + + 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 callee params set + for (int i = 0; i < calleemd.numParameters(); i++) { + VarDescriptor calleevd = (VarDescriptor) calleemd.getParameter(i); + CompositeLocation calleeLoc = d2loc.get(calleevd); + calleeParamList.add(calleeLoc); + } + + String errorMsg = generateErrorMessage(md.getClassDesc(), min); + + for (int i = 0; i < calleeParamList.size(); i++) { + CompositeLocation calleeParamLoc = calleeParamList.get(i); + if (calleeParamLoc.get(0).equals(calleeThisLoc) && calleeParamLoc.getSize() > 1) { + // callee parameter location has field information + CompositeLocation argLocation = + translateCallerLocToCallee(md, calleeThisLoc, callerArgList.get(i),errorMsg); + + if (!CompositeLattice.isGreaterThan(argLocation, calleeParamLoc, errorMsg)) { + throw new Error("Caller argument '" + min.getArg(i).printNode(0) + + "' should be higher than corresponding callee's parameter at " + errorMsg); + } + + } + } + + } + + private CompositeLocation translateCallerLocToCallee(MethodDescriptor md, Location calleeThisLoc, + CompositeLocation callerArgLoc,String errorMsg) { + + ClassDescriptor calleeClassDesc = md.getClassDesc(); + CompositeLocation translate = new CompositeLocation(); + + int startIdx = 0; + for (int i = 0; i < callerArgLoc.getSize(); i++) { + if (callerArgLoc.get(i).getDescriptor().equals(calleeClassDesc)) { + startIdx = i; + } + } + + if (startIdx == 0) { + // caller arg location doesn't have field information + throw new Error("Caller argument location " + callerArgLoc + + " does not contain field information while callee has ordering constraints on field at "+errorMsg); + } + + translate.addLocation(calleeThisLoc); + + for (int i = startIdx + 1; i < callerArgLoc.getSize(); i++) { + translate.addLocation(callerArgLoc.get(i)); + } + + System.out.println("TRANSLATED=" + translate + " from callerArgLoc=" + callerArgLoc); + + return translate; + } + private CompositeLocation computeCeilingLocationForCaller(MethodDescriptor md, SymbolTable nametable, MethodInvokeNode min, CompositeLocation baseLocation, CompositeLocation constraint) { @@ -1908,50 +1984,77 @@ class ReturnLocGenerator { public static final int PARAMISSAME = 1; public static final int IGNORE = 2; - Hashtable paramIdx2paramType; + private Hashtable paramIdx2paramType; - public ReturnLocGenerator(CompositeLocation returnLoc, List params, String msg) { - // creating mappings - paramIdx2paramType = new Hashtable(); - for (int i = 0; i < params.size(); i++) { - CompositeLocation param = params.get(i); - int compareResult = CompositeLattice.compare(param, returnLoc, true, msg); + private CompositeLocation declaredReturnLoc = null; - int type; - if (compareResult == ComparisonResult.GREATER) { - type = 0; - } else if (compareResult == ComparisonResult.EQUAL) { - type = 1; - } else { - type = 2; + public ReturnLocGenerator(CompositeLocation returnLoc, MethodDescriptor md, + List params, String msg) { + + CompositeLocation thisLoc = params.get(0); + if (returnLoc.get(0).equals(thisLoc.get(0)) && returnLoc.getSize() > 1) { + // if the declared return location consists of THIS and field location, + // return location for the caller's side has to have same field element + this.declaredReturnLoc = returnLoc; + } else { + // creating mappings + paramIdx2paramType = new Hashtable(); + for (int i = 0; i < params.size(); i++) { + CompositeLocation param = params.get(i); + int compareResult = CompositeLattice.compare(param, returnLoc, true, msg); + + int type; + if (compareResult == ComparisonResult.GREATER) { + type = 0; + } else if (compareResult == ComparisonResult.EQUAL) { + type = 1; + } else { + type = 2; + } + paramIdx2paramType.put(new Integer(i), new Integer(type)); } - paramIdx2paramType.put(new Integer(i), new Integer(type)); } } public CompositeLocation computeReturnLocation(List args) { - // compute the highest possible location in caller's side - assert paramIdx2paramType.keySet().size() == args.size(); - - Set inputGLB = new HashSet(); - for (int i = 0; i < args.size(); i++) { - int type = (paramIdx2paramType.get(new Integer(i))).intValue(); - CompositeLocation argLoc = args.get(i); - if (type == PARAMISHIGHER) { - // return loc is lower than param - DeltaLocation delta = new DeltaLocation(argLoc, 1); - inputGLB.add(delta); - } else if (type == PARAMISSAME) { - // return loc is equal or lower than param - inputGLB.add(argLoc); + if (declaredReturnLoc != null) { + // when developer specify that the return value is [THIS,field] + // needs to translate to the caller's location + CompositeLocation callerLoc = new CompositeLocation(); + CompositeLocation callerBaseLocation = args.get(0); + + for (int i = 0; i < callerBaseLocation.getSize(); i++) { + callerLoc.addLocation(callerBaseLocation.get(i)); + } + for (int i = 1; i < declaredReturnLoc.getSize(); i++) { + callerLoc.addLocation(declaredReturnLoc.get(i)); } + return callerLoc; + } else { + // compute the highest possible location in caller's side + assert paramIdx2paramType.keySet().size() == args.size(); + + Set inputGLB = new HashSet(); + for (int i = 0; i < args.size(); i++) { + int type = (paramIdx2paramType.get(new Integer(i))).intValue(); + CompositeLocation argLoc = args.get(i); + if (type == PARAMISHIGHER) { + // return loc is lower than param + DeltaLocation delta = new DeltaLocation(argLoc, 1); + inputGLB.add(delta); + } else if (type == PARAMISSAME) { + // return loc is equal or lower than param + inputGLB.add(argLoc); + } + } + + // compute GLB of arguments subset that are same or higher than return + // location + CompositeLocation glb = CompositeLattice.calculateGLB(inputGLB, ""); + return glb; } - // compute GLB of arguments subset that are same or higher than return - // location - CompositeLocation glb = CompositeLattice.calculateGLB(inputGLB, ""); - return glb; } } -- 2.34.1