1 package Analysis.Disjoint;
8 ///////////////////////////////////////////
10 // This class is an immutable Canonical, so
12 // 0) construct them with a factory pattern
13 // to ensure only canonical versions escape
15 // 1) any operation that modifies a Canonical
16 // is a static method in the Canonical class
18 // 2) operations that just read this object
19 // should be defined here
21 // 3) every Canonical subclass hashCode should
22 // throw an error if the hash ever changes
24 ///////////////////////////////////////////
26 // a taint is applied to a reference edge, and
27 // is used to associate an effect with a heap root
29 public class Taint extends Canonical {
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
36 // identify an sese (rblock) + inset var
37 protected FlatSESEEnterNode sese;
39 // identify a stall site + live variable
40 protected FlatNode stallSite;
42 // either type of taint includes a var
43 // and allocation site
44 protected TempDescriptor var;
45 protected Alloc allocSite;
47 // taints have a new, possibly null element which is
48 // the FlatNode at which the tainted reference was
49 // defined, which currently supports DFJ but doesn't
50 // hinder other analysis modes
51 protected FlatNode fnDefined;
53 // existance predicates must be true in a caller
54 // context for this taint's effects to transfer from this
55 // callee to that context
56 protected ExistPredSet preds;
58 public Taint reTaint(FlatNode fn) {
59 Taint out=new Taint(sese, stallSite, var, allocSite, fn, preds);
60 out = (Taint) Canonical.makeCanonical(out);
64 public static Taint factory(FlatSESEEnterNode sese,
65 TempDescriptor insetVar,
67 FlatNode whereDefined,
69 Taint out = new Taint(sese, null, insetVar, as, whereDefined, eps);
70 out = (Taint) Canonical.makeCanonical(out);
74 public static Taint factory(FlatNode stallSite,
77 FlatNode whereDefined,
79 Taint out = new Taint(null, stallSite, var, as, whereDefined, eps);
80 out = (Taint) Canonical.makeCanonical(out);
84 public static Taint factory(FlatSESEEnterNode sese,
88 FlatNode whereDefined,
90 Taint out = new Taint(sese, stallSite, var, as, whereDefined, eps);
91 out = (Taint) Canonical.makeCanonical(out);
95 protected Taint(FlatSESEEnterNode sese,
102 (sese == null && stallSite != null) ||
103 (sese != null && stallSite == null);
110 this.stallSite = stallSite;
113 this.fnDefined = fnDefined;
117 protected Taint(Taint t) {
126 public boolean isRBlockTaint() {
130 public boolean isStallSiteTaint() {
131 return stallSite != null;
134 public FlatSESEEnterNode getSESE() {
138 public FlatNode getStallSite() {
142 public TempDescriptor getVar() {
146 public Alloc getAllocSite() {
150 public FlatNode getWhereDefined() {
154 public ExistPredSet getPreds() {
158 public boolean equalsSpecific(Object o) {
159 if( !equalsIgnorePreds(o) ) {
164 return preds.equals(t.preds);
167 public boolean equalsIgnorePreds(Object o) {
172 if( !(o instanceof Taint) ) {
180 seseEqual = (t.sese == null);
182 seseEqual = sese.equals(t.sese);
185 boolean stallSiteEqual;
186 if( stallSite == null ) {
187 stallSiteEqual = (t.stallSite == null);
189 stallSiteEqual = stallSite.equals(t.stallSite);
192 boolean fnDefinedEqual;
193 if( fnDefined == null ) {
194 fnDefinedEqual = (t.fnDefined == null);
196 fnDefinedEqual = fnDefined.equals(t.fnDefined);
204 allocSite.equals(t.allocSite);
207 public int hashCodeSpecific() {
208 int hash = allocSite.hashCode();
209 hash = hash ^ var.hashCode();
212 hash = hash ^ sese.hashCode();
215 if( stallSite != null ) {
216 hash = hash ^ stallSite.hashCode();
219 if( fnDefined != null ) {
220 hash = hash ^ fnDefined.hashCode();
227 public String toString() {
228 return toString( false );
232 public String toString( boolean suppressPredicates ) {
236 if( isRBlockTaint() ) {
237 s = sese.getPrettyIdentifier();
239 s = stallSite.toString();
243 if( fnDefined != null ) {
248 if( !suppressPredicates ) {
255 ", "+allocSite.toStringBrief()+