1 package Analysis.SSJava;
3 import java.util.Iterator;
5 import IR.ClassDescriptor;
6 import IR.MethodDescriptor;
8 import IR.Tree.AssignmentNode;
9 import IR.Tree.BlockExpressionNode;
10 import IR.Tree.BlockNode;
11 import IR.Tree.BlockStatementNode;
12 import IR.Tree.CastNode;
13 import IR.Tree.CreateObjectNode;
14 import IR.Tree.DeclarationNode;
15 import IR.Tree.ExpressionNode;
17 import IR.Tree.LoopNode;
18 import IR.Tree.SubBlockNode;
20 public class SingleReferenceCheck {
23 String needToNullify = null;
25 public SingleReferenceCheck(State state) {
29 public void singleReferenceCheck() {
30 Iterator it = state.getClassSymbolTable().getDescriptorsIterator();
31 while (it.hasNext()) {
32 ClassDescriptor cd = (ClassDescriptor) it.next();
33 for (Iterator method_it = cd.getMethods(); method_it.hasNext();) {
34 MethodDescriptor md = (MethodDescriptor) method_it.next();
35 checkMethodBody(cd, md);
40 private void checkMethodBody(ClassDescriptor cd, MethodDescriptor fm) {
41 BlockNode bn = state.getMethodBody(fm);
42 for (int i = 0; i < bn.size(); i++) {
43 checkBlockStatementNode(cd, bn.get(i));
48 private boolean checkNullifying(BlockStatementNode bsn) {
50 if (bsn.kind() == Kind.BlockExpressionNode) {
51 ExpressionNode en = ((BlockExpressionNode) bsn).getExpression();
52 if (en.kind() == Kind.AssignmentNode) {
53 AssignmentNode an = (AssignmentNode) en;
55 if (an.getSrc().getType().isNull() && an.getDest().printNode(0).equals(needToNullify)) {
65 private void checkBlockStatementNode(ClassDescriptor cd, BlockStatementNode bsn) {
67 if (needToNullify != null) {
68 if (!checkNullifying(bsn)) {
70 "Reference field, which is read by a method, should be assigned to null before executing any following statement of the reference copy statement at "
71 + cd.getSourceFileName() + "::" + bsn.getNumLine());
76 case Kind.BlockExpressionNode:
77 checkExpressionNode(((BlockExpressionNode) bsn).getExpression());
80 case Kind.DeclarationNode:
81 checkDeclarationNode((DeclarationNode) bsn);
84 case Kind.SubBlockNode:
85 checkSubBlockNode(cd, (SubBlockNode) bsn);
89 checkLoopNode(cd, (LoopNode) bsn);
95 private void checkLoopNode(ClassDescriptor cd, LoopNode ln) {
96 if (ln.getType() == LoopNode.FORLOOP) {
97 checkBlockNode(cd, ln.getInitializer());
99 checkBlockNode(cd, ln.getBody());
102 private void checkSubBlockNode(ClassDescriptor cd, SubBlockNode sbn) {
103 checkBlockNode(cd, sbn.getBlockNode());
106 private void checkBlockNode(ClassDescriptor cd, BlockNode bn) {
107 for (int i = 0; i < bn.size(); i++) {
108 checkBlockStatementNode(cd, bn.get(i));
112 private void checkExpressionNode(ExpressionNode en) {
115 case Kind.AssignmentNode:
116 checkAssignmentNode((AssignmentNode) en);
122 private void checkAssignmentNode(AssignmentNode an) {
124 if (an.getSrc() != null) {
125 if (an.getSrc().getType().isPtr() && (!an.getSrc().getType().isNull())
126 && !(an.getSrc() instanceof CreateObjectNode)) {
127 if (an.getSrc() instanceof CastNode) {
128 needToNullify = ((CastNode) an.getSrc()).getExpression().printNode(0);
130 needToNullify = an.getSrc().printNode(0);
137 private void checkDeclarationNode(DeclarationNode dn) {
139 if (dn.getExpression() != null) {
140 if (dn.getExpression().getType().isPtr() && !(dn.getExpression() instanceof CreateObjectNode)) {
142 if (dn.getExpression() instanceof CastNode) {
143 needToNullify = ((CastNode) dn.getExpression()).getExpression().printNode(0);
145 needToNullify = dn.getExpression().printNode(0);