+ private void checkAssignmentNode(MethodDescriptor md, SymbolTable nametable, AssignmentNode an) {
+
+ boolean postinc = true;
+ if (an.getOperation().getBaseOp() == null
+ || (an.getOperation().getBaseOp().getOp() != Operation.POSTINC && an.getOperation()
+ .getBaseOp().getOp() != Operation.POSTDEC))
+ postinc = false;
+
+ if (!postinc) {
+
+ checkExpressionNode(md, nametable, an.getSrc());
+
+ if (isReference(an.getSrc().getType()) && isReference(an.getDest().getType())) {
+
+ 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;
+
+ }
+
+ } 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) {
+ if (an.getSrc().getType().isPtr()) {
+ throw new Error(
+ "Not allowed to create an alias to the middle of the multidimensional array at "
+ + md.getClassDesc().getSourceFileName() + "::" + an.getNumLine());
+ }
+ }
+
+ if (isCreatingAlias(an.getSrc())) {
+
+ TypeDescriptor srcType = getTypeDescriptor(an.getSrc());
+ boolean isSourceOwned = false;
+
+ if (srcType.getExtension() != null) {
+ SSJavaType srcLocationType = (SSJavaType) srcType.getExtension();
+ isSourceOwned = srcLocationType.isOwned();
+ }
+
+ if (!isField(an.getDest()) && 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 boolean isCreatingAlias(ExpressionNode en) {
+
+ int kind = en.kind();
+ if (kind == Kind.NameNode || kind == Kind.ArrayAccessNode || kind == Kind.FieldAccessNode) {
+ return true;
+ }
+ return false;
+