capturing partially implemented taints before altering implementation
[IRC.git] / Robust / src / Analysis / Disjoint / Taint.java
1 package Analysis.Disjoint;
2
3 import IR.*;
4 import IR.Flat.*;
5 import java.util.*;
6 import java.io.*;
7
8 ///////////////////////////////////////////
9 //  IMPORTANT
10 //  This class is an immutable Canonical, so
11 //
12 //  0) construct them with a factory pattern
13 //  to ensure only canonical versions escape
14 //
15 //  1) any operation that modifies a Canonical
16 //  is a static method in the Canonical class
17 //
18 //  2) operations that just read this object
19 //  should be defined here
20 //
21 //  3) every Canonical subclass hashCode should
22 //  throw an error if the hash ever changes
23 //
24 ///////////////////////////////////////////
25
26 // a taint is applied to a reference edge, and
27 // is used to associate an effect with an
28 // sese (rblock) and in-
29
30 public class Taint extends Canonical {
31
32   // taints can either be associated with
33   // a callsite and parameter index or
34   // an sese (rblock) and an in-set var
35   // only one set of identifying objects
36   // will be non-null
37
38   // identify a parameter index
39   protected FlatCall callSite;
40   protected Integer  paramIndex;
41   
42   // identify an sese (rblock) + inset var
43   protected FlatSESEEnterNode sese;
44   protected TempDescriptor    insetVar;
45
46   // either type of taint also includes
47   // an allocation site
48   protected AllocSite allocSite;
49
50   // existance predicates must be true in a caller
51   // context for this taint's effects to transfer from this
52   // callee to that context
53   protected ExistPredSet preds;
54
55
56   public static Taint factory( FlatCall          fc,
57                                Integer           pi,
58                                FlatSESEEnterNode s,
59                                TempDescriptor    iv,
60                                AllocSite         as ) {
61     Taint out = new Taint( fc, pi, s, iv, as );
62     out.preds = ExistPredSet.factory();
63     out = (Taint) Canonical.makeCanonical( out );
64     return out;
65   }
66
67   public static Taint factory( FlatCall          fc,
68                                Integer           pi,
69                                FlatSESEEnterNode s,
70                                TempDescriptor    iv,
71                                AllocSite         as,
72                                ExistPredSet      eps ) {
73     Taint out = new Taint( fc, pi, s, iv, as );
74     out.preds = eps;
75     out = (Taint) Canonical.makeCanonical( out );
76     return out;
77   }
78
79   protected Taint( FlatCall          fc,
80                    Integer           pi,
81                    FlatSESEEnterNode s,
82                    TempDescriptor    iv,
83                    AllocSite         as ) {    
84
85     // either fc and pi are non-null, OR s and iv are non-null
86     assert 
87       (fc != null && pi != null && s == null && iv == null) ||
88       (fc == null && pi == null && s != null && iv != null);
89
90     assert as != null;
91     
92     callSite   = fc;
93     paramIndex = pi;
94     sese       = s;
95     insetVar   = iv;
96     allocSite  = as;
97   }
98
99   public boolean isParamTaint() {
100     return callSite != null;
101   }
102
103   public boolean isSESETaint() {
104     return sese != null;
105   }
106
107   public FlatCall getCallSite() {
108     return callSite;
109   }
110
111   public Integer getParamIndex() {
112     return paramIndex;
113   }
114
115   public FlatSESEEnterNode getSESE() {
116     return sese;
117   }
118
119   public TempDescriptor getInSetVar() {
120     return insetVar;
121   }
122
123   public AllocSite getAllocSite() {
124     return allocSite;
125   }
126
127   public ExistPredSet getPreds() {
128     return preds;
129   }
130
131   public boolean equalsSpecific( Object o ) {
132     if( !equalsIgnorePreds( o ) ) {
133       return false;
134     }
135         
136     Taint t = (Taint) o;
137     return preds.equals( t.preds );
138   }
139
140   public boolean equalsIgnorePreds( Object o ) {
141     if( o == null ) {
142       return false;
143     }
144
145     if( !(o instanceof Taint) ) {
146       return false;
147     }
148
149     Taint t = (Taint) o;
150
151     boolean fcMatches = true;
152     if( callSite == null ) {
153       fcMatches = t.callSite == null;
154     } else {
155       fcMatches = callSite.equals( t.callSite );
156     }
157
158     boolean piMatches = true;
159     if( paramIndex == null ) {
160       piMatches = t.paramIndex == null;
161     } else {
162       piMatches = paramIndex.equals( t.paramIndex );
163     }
164
165     boolean sMatches = true;
166     if( sese == null ) {
167       sMatches = t.sese == null;
168     } else {
169       sMatches = sese.equals( t.sese );
170     }
171
172     boolean ivMatches = true;
173     if( insetVar == null ) {
174       ivMatches = t.insetVar == null;
175     } else {
176       ivMatches = insetVar.equals( t.insetVar );
177     }
178
179     return allocSite.equals( t.allocSite ) &&
180       piMatches && sMatches && ivMatches;
181   }
182
183   public int hashCodeSpecific() {
184     int hash = allocSite.hashCode();
185
186     if( callSite != null ) {
187       hash = hash ^ callSite.hashCode();
188     }
189
190     if( paramIndex != null ) {
191       hash = hash ^ paramIndex.hashCode();
192     }
193
194     if( sese != null ) {
195       hash = hash ^ sese.hashCode();
196     }
197
198     if( insetVar != null ) {
199       hash = hash ^ insetVar.hashCode();
200     }
201
202     return hash;
203   }
204
205   public String toString() {
206     String s = "(";
207
208     if( isParamTaint() ) {
209       s += "cs"+callSite.nodeid+"-"+paramIndex;
210     } else {
211       s += sese.toPrettyString()+"-"+insetVar;
212     }
213
214     return s+", "+allocSite.toStringBrief()+"):"+preds;
215   }
216 }