+ private void checkAlias(MethodDescriptor md, TreeNode node, ExpressionNode src) {
+
+ if (src.kind() == Kind.NameNode) {
+
+ NameNode nn = (NameNode) src;
+
+ if (nn.getField() != null) {
+ needToNullify = nn.getField().getSymbol();
+ prevAssignNode = node;
+ } else if (nn.getExpression() != null) {
+ if (nn.getExpression() instanceof FieldAccessNode) {
+ FieldAccessNode fan = (FieldAccessNode) nn.getExpression();
+ needToNullify = fan.printNode(0);
+ prevAssignNode = node;
+ }
+ } else {
+ // local variable case
+ linearTypeCheckSet.add(src);
+ mapTreeNode2FlatMethod.put(src, state.getMethodFlat(md));
+ }
+ } else if (src.kind() == Kind.FieldAccessNode) {
+ FieldAccessNode fan = (FieldAccessNode) src;
+ needToNullify = fan.printNode(0);
+ if (needToNullify.startsWith("this.")) {
+ needToNullify = needToNullify.substring(5);
+ }
+ prevAssignNode = node;
+ } else if (src.kind() == Kind.ArrayAccessNode) {
+ ArrayAccessNode aan = (ArrayAccessNode) src;
+ TypeDescriptor srcType = src.getType();
+ if (srcType.isPtr() && srcType.getArrayCount() > 0) {
+ throw new Error(
+ "Not allowed to create an alias to the middle of the multidimensional array at "
+ + md.getClassDesc().getSourceFileName() + "::" + node.getNumLine());
+ } else {
+ needToNullify = aan.printNode(0);
+ prevAssignNode = node;
+ }
+ } 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() + "::" + node.getNumLine());
+ }
+
+ if (isCreatingAlias(src)) {
+
+ TypeDescriptor srcType = getTypeDescriptor(src);
+ boolean isSourceOwned = false;
+
+ if (srcType.getExtension() != null) {
+ SSJavaType srcLocationType = (SSJavaType) srcType.getExtension();
+ isSourceOwned = srcLocationType.isOwned();
+
+ if (isSourceOwned) {
+ if (isField(src)) {
+ ssjava.setFieldOnwership(md, getFieldDescriptorFromExpressionNode(src));
+ }
+ }
+
+ } else if (md.isConstructor() && isFieldOfClass(md.getClassDesc(), src.printNode(0))) {
+ isSourceOwned = true;
+ ssjava.setFieldOnwership(md, getFieldDescriptorFromExpressionNode(src));
+ }
+
+ 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());
+ }