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.DeclarationNode;
14 import IR.Tree.ExpressionNode;
16 import IR.Tree.LoopNode;
17 import IR.Tree.SubBlockNode;
19 public class SingleReferenceCheck {
22 SSJavaAnalysis ssjava;
23 String needToNullify = null;
25 public SingleReferenceCheck(SSJavaAnalysis ssjava, State state) {
30 public void singleReferenceCheck() {
31 Iterator it = state.getClassSymbolTable().getDescriptorsIterator();
32 while (it.hasNext()) {
33 ClassDescriptor cd = (ClassDescriptor) it.next();
34 for (Iterator method_it = cd.getMethods(); method_it.hasNext();) {
35 MethodDescriptor md = (MethodDescriptor) method_it.next();
36 if (ssjava.needTobeAnnotated(md)) {
37 checkMethodBody(cd, md);
43 private void checkMethodBody(ClassDescriptor cd, MethodDescriptor fm) {
44 BlockNode bn = state.getMethodBody(fm);
45 for (int i = 0; i < bn.size(); i++) {
46 checkBlockStatementNode(cd, bn.get(i));
51 private boolean checkNullifying(BlockStatementNode bsn) {
53 if (bsn.kind() == Kind.BlockExpressionNode) {
54 ExpressionNode en = ((BlockExpressionNode) bsn).getExpression();
55 if (en.kind() == Kind.AssignmentNode) {
56 AssignmentNode an = (AssignmentNode) en;
58 if (an.getSrc().getType().isNull() && an.getDest().printNode(0).equals(needToNullify)) {
68 private void checkBlockStatementNode(ClassDescriptor cd, BlockStatementNode bsn) {
70 if (needToNullify != null) {
71 if (!checkNullifying(bsn)) {
73 "Reference field, which is read by a method, should be assigned to null before executing any following statement of the reference copy statement at "
74 + cd.getSourceFileName() + "::" + bsn.getNumLine());
79 case Kind.BlockExpressionNode:
80 checkExpressionNode(((BlockExpressionNode) bsn).getExpression());
83 case Kind.DeclarationNode:
84 checkDeclarationNode((DeclarationNode) bsn);
87 case Kind.SubBlockNode:
88 checkSubBlockNode(cd, (SubBlockNode) bsn);
92 checkLoopNode(cd, (LoopNode) bsn);
98 private void checkLoopNode(ClassDescriptor cd, LoopNode ln) {
99 if (ln.getType() == LoopNode.FORLOOP) {
100 checkBlockNode(cd, ln.getInitializer());
102 checkBlockNode(cd, ln.getBody());
105 private void checkSubBlockNode(ClassDescriptor cd, SubBlockNode sbn) {
106 checkBlockNode(cd, sbn.getBlockNode());
109 private void checkBlockNode(ClassDescriptor cd, BlockNode bn) {
110 for (int i = 0; i < bn.size(); i++) {
111 checkBlockStatementNode(cd, bn.get(i));
115 private void checkExpressionNode(ExpressionNode en) {
118 case Kind.AssignmentNode:
119 checkAssignmentNode((AssignmentNode) en);
125 private void checkAssignmentNode(AssignmentNode an) {
126 needToNullify(an.getSrc());
129 private void checkDeclarationNode(DeclarationNode dn) {
130 needToNullify(dn.getExpression());
133 private void needToNullify(ExpressionNode en) {
135 if (en != null && en.getType().isPtr() && !en.getType().isString()) {
136 if (en.kind() != Kind.CreateObjectNode && en.kind() != Kind.LiteralNode) {
137 if (en.kind() == Kind.CastNode) {
138 needToNullify = ((CastNode) en).getExpression().printNode(0);
140 needToNullify = en.printNode(0);