Updated taint class to allow call site plus var taints as well
[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 a heap root
28
29 public class Taint extends Canonical {
30
31   // taints can either be associated with
32   // a stall site and live variable or
33   // an sese (rblock) and an in-set var
34   // only one identifer will be non-null
35   
36   // identify an sese (rblock) + inset var
37   protected FlatSESEEnterNode sese;
38
39   // identify a stall site + live variable
40   protected FlatNode stallSite;
41
42   // either type of taint includes a var
43   // and allocation site
44   protected TempDescriptor var;
45   protected AllocSite      allocSite;
46
47   // existance predicates must be true in a caller
48   // context for this taint's effects to transfer from this
49   // callee to that context
50   protected ExistPredSet preds;
51
52   public static Taint factory( FlatSESEEnterNode sese,
53                                TempDescriptor    insetVar,
54                                AllocSite         as,
55                                ExistPredSet      eps ) {
56     Taint out = new Taint( sese, null, insetVar, as, eps );
57     out = (Taint) Canonical.makeCanonical( out );
58     return out;
59   }
60
61   public static Taint factory( FlatNode       stallSite,
62                                TempDescriptor liveVar,
63                                AllocSite      as,
64                                ExistPredSet   eps ) {
65     Taint out = new Taint( null, stallSite, liveVar, as, eps );
66     out = (Taint) Canonical.makeCanonical( out );
67     return out;
68   }
69
70   public static Taint factory( FlatSESEEnterNode sese,
71                                FlatNode          stallSite,
72                                TempDescriptor    liveVar,
73                                AllocSite         as,
74                                ExistPredSet      eps ) {
75     Taint out = new Taint( sese, stallSite, liveVar, as, eps );
76     out = (Taint) Canonical.makeCanonical( out );
77     return out;
78   }
79
80   protected Taint( FlatSESEEnterNode sese,
81                    FlatNode          stallSite,
82                    TempDescriptor    v,
83                    AllocSite         as,
84                    ExistPredSet      eps ) {
85     assert 
86       (sese == null && stallSite != null) ||
87       (sese != null && stallSite == null);
88       
89     assert v   != null;
90     assert as  != null;
91     assert eps != null;
92     
93     this.sese      = sese;
94     this.stallSite = stallSite;
95     this.var       = v;
96     this.allocSite = as;
97     this.preds     = eps;
98   }
99
100   protected Taint( Taint t ) {
101     this( t.sese, 
102           t.stallSite, 
103           t.var, 
104           t.allocSite, 
105           t.preds );
106   }
107
108   public boolean isRBlockTaint() {
109     return sese != null;
110   }
111
112   public boolean isStallSiteTaint() {
113     return stallSite != null;
114   }
115
116   public FlatSESEEnterNode getSESE() {
117     return sese;
118   }
119
120   public FlatNode getStallSite() {
121     return stallSite;
122   }
123
124   public TempDescriptor getVar() {
125     return var;
126   }
127
128   public AllocSite getAllocSite() {
129     return allocSite;
130   }
131
132   public ExistPredSet getPreds() {
133     return preds;
134   }
135
136   public boolean equalsSpecific( Object o ) {
137     if( !equalsIgnorePreds( o ) ) {
138       return false;
139     }
140         
141     Taint t = (Taint) o;
142     return preds.equals( t.preds );
143   }
144
145   public boolean equalsIgnorePreds( Object o ) {
146     if( o == null ) {
147       return false;
148     }
149
150     if( !(o instanceof Taint) ) {
151       return false;
152     }
153
154     Taint t = (Taint) o;
155
156     boolean seseEqual;
157     if( sese == null ) {
158       seseEqual = (t.sese == null);      
159     } else {
160       seseEqual = sese.equals( t.sese );
161     }
162
163     boolean stallSiteEqual;
164     if( stallSite == null ) {
165       stallSiteEqual = (t.stallSite == null);
166     } else {
167       stallSiteEqual = stallSite.equals( t.stallSite );
168     }
169
170     return 
171       seseEqual                      && 
172       stallSiteEqual                 &&
173       var      .equals( t.var  )     &&
174       allocSite.equals( t.allocSite );
175   }
176
177   public int hashCodeSpecific() {
178     int hash = allocSite.hashCode();
179     hash = hash ^ var.hashCode();
180   
181     if( sese != null ) {
182       hash = hash ^ sese.hashCode();
183     }
184
185     if( stallSite != null ) {
186       hash = hash ^ stallSite.hashCode();
187     }
188
189     return hash;
190   }
191
192   public String toString() {
193
194     String s;
195
196     if( isRBlockTaint() ) {
197       if( sese.getIsCallerSESEplaceholder() ) {
198         s = "placeh";
199       } else {
200         s = sese.getPrettyIdentifier();
201       }
202
203     } else {
204       s = stallSite.toString();
205     }
206
207     return 
208       "("+s+
209       "-"+var+
210       ", "+allocSite.toStringBrief()+
211       "):"+preds;
212   }
213 }