import IR.State;
import IR.SymbolTable;
import IR.TypeDescriptor;
+import IR.TypeExtension;
import IR.VarDescriptor;
import IR.Tree.ArrayAccessNode;
import IR.Tree.AssignmentNode;
while (!toAnalyzeMethodIsEmpty()) {
MethodDescriptor md = toAnalyzeMethodNext();
if (ssjava.needTobeAnnotated(md)) {
- System.out.println("SSJAVA: Checking assignments: " + md);
+ if (state.SSJAVADEBUG) {
+ System.out.println("SSJAVA: Checking Flow-down Rules: " + md);
+ }
checkMethodBody(cd, md, null);
}
}
private void checkDeclarationInMethodBody(ClassDescriptor cd, MethodDescriptor md) {
BlockNode bn = state.getMethodBody(md);
-
// first, check annotations on method parameters
List<CompositeLocation> paramList = new ArrayList<CompositeLocation>();
for (int i = 0; i < md.numParameters(); i++) {
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));
+ // 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()));
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 now 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))) {
}
-// System.out.println("\n#checkLocationFromMethodInvokeNode=" + min.printNode(0)
-// + " baseLocation=" + baseLocation + " constraint=" + constraint);
+ // System.out.println("\n#checkLocationFromMethodInvokeNode=" +
+ // min.printNode(0)
+ // + " baseLocation=" + baseLocation + " constraint=" + constraint);
if (constraint != null) {
int compareResult =
// no need to check constraints!
CompositeLocation calleeConstraint =
translateCallerLocToCalleeLoc(calleeMD, baseLocation, constraint);
-// System.out.println("check method body for constraint:" + calleeMD + " calleeConstraint="
-// + calleeConstraint);
+ // System.out.println("check method body for constraint:" + calleeMD +
+ // " calleeConstraint="
+ // + calleeConstraint);
checkMethodBody(calleeMD.getClassDesc(), calleeMD, calleeConstraint);
}
}
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);
translate.addLocation(calleeParamLoc.get(i));
}
-// System.out.println("TRANSLATED=" + translate + " from calleeParamLoc=" + calleeParamLoc);
+ // System.out.println("TRANSLATED=" + translate + " from calleeParamLoc=" +
+ // calleeParamLoc);
return translate;
}
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));
+ // System.out.println("checkCalleeConstraints=" + min.printNode(0));
MethodDescriptor calleemd = min.getMethod();
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,
// 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);
+ // 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 = checkLocationFromExpressionNode(md, nametable, left, loc, constraint, false);
-// System.out.println("### checkLocationFromFieldAccessNode=" + fan.printNode(0));
-// System.out.println("### left=" + left.printNode(0));
+ // 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);
}
-// System.out.println("### field loc=" + loc);
+ // System.out.println("### field loc=" + loc);
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));
+ // System.out.println("\n# ASSIGNMENTNODE=" + an.printNode(0));
ClassDescriptor cd = md.getClassDesc();
CompositeLocation srcLocation;
if (!postinc) {
+
+ checkOwnership(md, an, an.getSrc());
+
rhsLocation =
checkLocationFromExpressionNode(md, nametable, an.getSrc(), new CompositeLocation(),
constraint, false);
}
// }
-// 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))) {
srcLocation = rhsLocation;
}
-// System.out.println("srcLocation=" + srcLocation);
-// System.out.println("rhsLocation=" + rhsLocation);
-// System.out.println("constraint=" + constraint);
+ // System.out.println("srcLocation=" + srcLocation);
+ // System.out.println("rhsLocation=" + rhsLocation);
+ // System.out.println("constraint=" + constraint);
if (!CompositeLattice.isGreaterThan(srcLocation, destLocation, generateErrorMessage(cd, an))) {
+ 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);
}
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) {
public static CompositeLocation calculateGLB(Set<CompositeLocation> 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
}
}
-// System.out.println("GLB=" + glbCompLoc);
+ // System.out.println("GLB=" + glbCompLoc);
return glbCompLoc;
}
import Analysis.Liveness;
import IR.AnnotationDescriptor;
import IR.ClassDescriptor;
+import IR.FieldDescriptor;
import IR.MethodDescriptor;
import IR.Operation;
import IR.State;
State state;
SSJavaAnalysis ssjava;
String needToNullify = null;
- ExpressionNode prevAssignNode;
+ TreeNode prevAssignNode;
Set<TreeNode> linearTypeCheckSet;
}
private void checkMethodBody(ClassDescriptor cd, MethodDescriptor md) {
+ if (state.SSJAVADEBUG) {
+ System.out.println("SSJAVA: Linear Type Checking: " + md);
+ }
BlockNode bn = state.getMethodBody(md);
checkBlockNode(md, md.getParameterTable(), bn);
}
+ "::" + min.getNumLine());
}
+ // delegated arg is no longer to be available from here
+ linearTypeCheckSet.add(argNode);
+ mapTreeNode2FlatMethod.put(argNode, state.getMethodFlat(md));
}
}
postinc = false;
if (!postinc) {
-
checkExpressionNode(md, nametable, an.getSrc());
-
if (isReference(an.getSrc().getType()) && isReference(an.getDest().getType())) {
+ checkAlias(md, an, an.getSrc());
+ }
- if (an.getSrc().kind() == Kind.NameNode) {
-
- NameNode nn = (NameNode) an.getSrc();
+ }
- if (nn.getField() != null) {
- needToNullify = nn.getField().getSymbol();
- prevAssignNode = an;
- } else if (nn.getExpression() != null) {
- if (nn.getExpression() instanceof FieldAccessNode) {
- FieldAccessNode fan = (FieldAccessNode) nn.getExpression();
- needToNullify = fan.printNode(0);
- prevAssignNode = an;
+ }
- }
+ private boolean isFieldOfClass(ClassDescriptor classDesc, String varName) {
+ return classDesc.getFieldTable().contains(varName);
+ }
- } else {
- // local variable case
- linearTypeCheckSet.add(an.getSrc());
- mapTreeNode2FlatMethod.put(an.getSrc(), state.getMethodFlat(md));
- }
- } else if (an.getSrc().kind() == Kind.FieldAccessNode) {
- FieldAccessNode fan = (FieldAccessNode) an.getSrc();
- needToNullify = fan.printNode(0);
- if (needToNullify.startsWith("this.")) {
- needToNullify = needToNullify.substring(5);
- }
- prevAssignNode = an;
- } else if (an.getSrc().kind() == Kind.ArrayAccessNode) {
- TypeDescriptor srcType = an.getSrc().getType();
- if (srcType.isPtr() && !srcType.isString()) {
- throw new Error(
- "Not allowed to create an alias to the middle of the multidimensional array at "
- + md.getClassDesc().getSourceFileName() + "::" + an.getNumLine());
- }
- } else if (an.getSrc().kind() == Kind.CreateObjectNode
- || an.getSrc().kind() == Kind.MethodInvokeNode
- || an.getSrc().kind() == Kind.ArrayInitializerNode
- || an.getSrc().kind() == Kind.LiteralNode) {
+ private boolean isCreatingAlias(ExpressionNode en) {
- } else {
- throw new Error("Not allowed this type of assignment at "
- + md.getClassDesc().getSourceFileName() + "::" + an.getNumLine());
- }
+ int kind = en.kind();
+ if (kind == Kind.NameNode || kind == Kind.ArrayAccessNode || kind == Kind.FieldAccessNode) {
+ return true;
+ }
+ return false;
- if (isCreatingAlias(an.getSrc())) {
+ }
- TypeDescriptor srcType = getTypeDescriptor(an.getSrc());
- boolean isSourceOwned = false;
+ private TypeDescriptor getTypeDescriptor(ExpressionNode en) {
+ if (en.kind() == Kind.NameNode) {
+ NameNode nn = (NameNode) en;
+ if (nn.getField() != null) {
+ return nn.getVar().getType();
+ } else if (nn.getVar() != null) {
+ return nn.getVar().getType();
+ } else {
+ return getTypeDescriptor(nn.getExpression());
+ }
+ } else if (en.kind() == Kind.FieldAccessNode) {
+ FieldAccessNode fan = (FieldAccessNode) en;
+ return getTypeDescriptor(fan.getExpression());
+ } else if (en.kind() == Kind.CreateObjectNode) {
+ CreateObjectNode con = (CreateObjectNode) en;
+ return con.getType();
+ } else if (en.kind() == Kind.ArrayAccessNode) {
+ ArrayAccessNode aan = (ArrayAccessNode) en;
+ return aan.getExpression().getType();
+ }
- if (srcType.getExtension() != null) {
- SSJavaType srcLocationType = (SSJavaType) srcType.getExtension();
- isSourceOwned = srcLocationType.isOwned();
- } else if (md.isConstructor()
- && isFieldOfClass(md.getClassDesc(), an.getSrc().printNode(0))) {
- isSourceOwned = true;
- }
+ return null;
+ }
- if (!isField(an.getDest())) {
- if (isSourceOwned) {
- // here, transfer ownership from LHS to RHS when it creates alias
- TypeDescriptor destType = getTypeDescriptor(an.getDest());
- destType.setExtension(new SSJavaType(isSourceOwned));
- }
- } else {
- // if instance is not owned by the method, not able to store
- // instance into field
- if (!isSourceOwned) {
- throw new Error(
- "Method is not allowed to store an instance not owned by itself into a field at "
- + md.getClassDesc().getSourceFileName() + "::" + an.getNumLine());
- }
- }
+ 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 boolean isField(ExpressionNode en) {
+
+ if (en.kind() == Kind.NameNode) {
+ NameNode nn = (NameNode) en;
+ if (nn.getField() != null) {
+ return true;
+ }
+
+ if (nn.getName() != null && nn.getName().getBase() != null) {
+ return true;
+ }
+
+ } else if (en.kind() == Kind.FieldAccessNode) {
+ return true;
+ }
+ return false;
}
- private void checkSource(MethodDescriptor md, ExpressionNode src, ExpressionNode dst) {
+ private void checkAlias(MethodDescriptor md, TreeNode node, ExpressionNode src) {
if (src.kind() == Kind.NameNode) {
if (nn.getField() != null) {
needToNullify = nn.getField().getSymbol();
- prevAssignNode = src;
+ prevAssignNode = node;
} else if (nn.getExpression() != null) {
if (nn.getExpression() instanceof FieldAccessNode) {
FieldAccessNode fan = (FieldAccessNode) nn.getExpression();
needToNullify = fan.printNode(0);
- prevAssignNode = src;
-
+ prevAssignNode = node;
}
-
} else {
// local variable case
linearTypeCheckSet.add(src);
if (needToNullify.startsWith("this.")) {
needToNullify = needToNullify.substring(5);
}
- prevAssignNode = src;
+ prevAssignNode = node;
} else if (src.kind() == Kind.ArrayAccessNode) {
TypeDescriptor srcType = src.getType();
if (srcType.isPtr() && !srcType.isString()) {
throw new Error(
"Not allowed to create an alias to the middle of the multidimensional array at "
- + md.getClassDesc().getSourceFileName() + "::" + src.getNumLine());
+ + md.getClassDesc().getSourceFileName() + "::" + node.getNumLine());
}
} else if (src.kind() == Kind.CreateObjectNode || src.kind() == Kind.MethodInvokeNode
|| src.kind() == Kind.ArrayInitializerNode || src.kind() == Kind.LiteralNode) {
-
+ if (node.kind() == Kind.DeclarationNode) {
+ DeclarationNode dn = (DeclarationNode) node;
+ dn.getVarDescriptor().getType().setExtension(new SSJavaType(true));
+ }
} else {
throw new Error("Not allowed this type of assignment at "
- + md.getClassDesc().getSourceFileName() + "::" + src.getNumLine());
+ + md.getClassDesc().getSourceFileName() + "::" + node.getNumLine());
}
if (isCreatingAlias(src)) {
if (srcType.getExtension() != null) {
SSJavaType srcLocationType = (SSJavaType) srcType.getExtension();
isSourceOwned = srcLocationType.isOwned();
- } else if (md.isConstructor() && isFieldOfClass(md.getClassDesc(), src.printNode(0))) {
- isSourceOwned = true;
- }
- if (!isField(dst)) {
if (isSourceOwned) {
- // here, transfer ownership from LHS to RHS when it creates alias
- TypeDescriptor destType = getTypeDescriptor(dst);
- destType.setExtension(new SSJavaType(isSourceOwned));
- }
- } else {
- // if instance is not owned by the method, not able to store
- // instance into field
- if (!isSourceOwned) {
- throw new Error(
- "Method is not allowed to store an instance not owned by itself into a field at "
- + md.getClassDesc().getSourceFileName() + "::" + src.getNumLine());
+ if (isField(src)) {
+ ssjava.setFieldOnwership(md, getFieldDescriptorFromExpressionNode(src));
+ }
}
- }
-
- }
-
- }
-
- private boolean isFieldOfClass(ClassDescriptor classDesc, String varName) {
- return classDesc.getFieldTable().contains(varName);
- }
-
- private boolean isCreatingAlias(ExpressionNode en) {
-
- int kind = en.kind();
- if (kind == Kind.NameNode || kind == Kind.ArrayAccessNode || kind == Kind.FieldAccessNode) {
- return true;
- }
- return false;
-
- }
-
- private TypeDescriptor getTypeDescriptor(ExpressionNode en) {
- if (en.kind() == Kind.NameNode) {
- NameNode nn = (NameNode) en;
- if (nn.getField() != null) {
- return nn.getVar().getType();
- } else if (nn.getVar() != null) {
- return nn.getVar().getType();
- } else {
- return getTypeDescriptor(nn.getExpression());
- }
- } else if (en.kind() == Kind.FieldAccessNode) {
- FieldAccessNode fan = (FieldAccessNode) en;
- return getTypeDescriptor(fan.getExpression());
- } else if (en.kind() == Kind.CreateObjectNode) {
- CreateObjectNode con = (CreateObjectNode) en;
- return con.getType();
- } else if (en.kind() == Kind.ArrayAccessNode) {
- ArrayAccessNode aan = (ArrayAccessNode) en;
- return aan.getExpression().getType();
- }
-
- return null;
- }
- private boolean isField(ExpressionNode en) {
-
- if (en.kind() == Kind.NameNode) {
- NameNode nn = (NameNode) en;
- if (nn.getField() != null) {
- return true;
+ } else if (md.isConstructor() && isFieldOfClass(md.getClassDesc(), src.printNode(0))) {
+ isSourceOwned = true;
+ ssjava.setFieldOnwership(md, getFieldDescriptorFromExpressionNode(src));
}
- if (nn.getName() != null && nn.getName().getBase() != null) {
- return true;
+ if (node.kind() == Kind.AssignmentNode) {
+ AssignmentNode an = (AssignmentNode) node;
+ if (isField(an.getDest())) {
+ // if instance is not owned by the method, not able to store
+ // instance into field
+ if (!isSourceOwned) {
+ throw new Error(
+ "Method is not allowed to store an instance not owned by itself into a field at "
+ + md.getClassDesc().getSourceFileName() + "::" + node.getNumLine());
+ }
+ } else {
+ if (isSourceOwned) {
+ // here, transfer ownership from LHS to RHS when it creates alias
+ TypeDescriptor destType = getTypeDescriptor(an.getDest());
+ destType.setExtension(new SSJavaType(isSourceOwned));
+ }
+ }
}
- } else if (en.kind() == Kind.FieldAccessNode) {
- return true;
}
- return false;
+
}
private void checkDeclarationNode(MethodDescriptor md, SymbolTable nametable, DeclarationNode dn) {
if (dn.getExpression() != null) {
- checkExpressionNode(md, nametable, dn.getExpression());
- if (dn.getExpression().kind() == Kind.CreateObjectNode) {
- dn.getVarDescriptor().getType().setExtension(new SSJavaType(true));
- } else if (dn.getExpression().kind() == Kind.ArrayAccessNode
- && dn.getExpression().getType().isPtr()) {
- throw new Error(
- "Not allowed to create an alias to the middle of the multidimensional array at "
- + md.getClassDesc().getSourceFileName() + "::" + dn.getNumLine());
+ ExpressionNode src = dn.getExpression();
+ if (isReference(src.getType())) {
+ checkAlias(md, dn, src);
}
}
-
}
private boolean isReference(TypeDescriptor td) {