// otherwise, no cached result...
TaintSet out = new TaintSet();
- out.taints.addAll( ts1.taints );
- out.taints.addAll( ts2.taints );
+
+ // first add everything from 1, and if it was also in 2
+ // take the OR of the predicates
+ Iterator<Taint> tItr = ts1.iterator();
+ while( tItr.hasNext() ) {
+ Taint t1 = tItr.next();
+ Taint t2 = ts2.containsIgnorePreds( t1 );
+
+ if( t2 != null ) {
+ out.taints.add( Taint.factory( t1.callSite,
+ t1.paramIndex,
+ t1.sese,
+ t1.insetVar,
+ t1.allocSite,
+ Canonical.join( t1.preds,
+ t2.preds
+ )
+ ) );
+ } else {
+ out.taints.add( t1 );
+ }
+ }
+
+ // then add everything in 2 that wasn't in 1
+ tItr = ts2.iterator();
+ while( tItr.hasNext() ) {
+ Taint t2 = tItr.next();
+ Taint t1 = ts1.containsIgnorePreds( t2 );
+
+ if( t1 == null ) {
+ out.taints.add( t2 );
+ }
+ }
out = (TaintSet) makeCanonical( out );
op2result.put( op, out );
// edge uses same ReachState ne_state as node type above
+
// a static debug flag for higher abstraction code
// to enable debug info at this level
public static boolean debug = false;
return null;
}
- // when state is null it is not part of the predicate
- // so we've satisfied the edge existence
- if( ne_state == null ) {
- return edge.getPreds();
+ // only check state as part of the predicate if it
+ // is non-null
+ if( ne_state != null &&
+ // TODO: contains OR containsSuperSet OR containsWithZeroes??
+ hrnDst.getAlpha().containsIgnorePreds( ne_state ) != null
+ ) {
+ return null;
}
-
- // otherwise look for state too
- // TODO: contains OR containsSuperSet OR containsWithZeroes??
- if( hrnDst.getAlpha().containsIgnorePreds( ne_state )
- == null ) {
- return edge.getPreds();
- }
-
- return null;
+
+ // predicate satisfied
+ return edge.getPreds();
}
throw new Error( "Unknown predicate type" );
if( ne_state != null ) {
hash ^= ne_state.hashCode();
}
-
+
return hash;
}
///////////////////////////////////////////
// a taint is applied to a reference edge, and
-// is used to associate an effect with a heap root
+// is used to associate an effect with an
+// sese (rblock) and in-
public class Taint extends Canonical {
// taints can either be associated with
- // parameters or seses (rblocks),
+ // a callsite and parameter index or
+ // an sese (rblock) and an in-set var
// only one set of identifying objects
// will be non-null
// identify a parameter index
- protected Integer paramIndex;
+ protected FlatCall callSite;
+ protected Integer paramIndex;
// identify an sese (rblock) + inset var
protected FlatSESEEnterNode sese;
// an allocation site
protected AllocSite allocSite;
+ // existance predicates must be true in a caller
+ // context for this taint's effects to transfer from this
+ // callee to that context
+ protected ExistPredSet preds;
- public static Taint factory( Integer pi,
+
+ public static Taint factory( FlatCall fc,
+ Integer pi,
FlatSESEEnterNode s,
TempDescriptor iv,
AllocSite as ) {
- Taint out = new Taint( pi, s, iv, as );
+ Taint out = new Taint( fc, pi, s, iv, as );
+ out.preds = ExistPredSet.factory();
+ out = (Taint) Canonical.makeCanonical( out );
+ return out;
+ }
+
+ public static Taint factory( FlatCall fc,
+ Integer pi,
+ FlatSESEEnterNode s,
+ TempDescriptor iv,
+ AllocSite as,
+ ExistPredSet eps ) {
+ Taint out = new Taint( fc, pi, s, iv, as );
+ out.preds = eps;
out = (Taint) Canonical.makeCanonical( out );
return out;
}
- protected Taint( Integer pi,
+ protected Taint( FlatCall fc,
+ Integer pi,
FlatSESEEnterNode s,
TempDescriptor iv,
AllocSite as ) {
+
+ // either fc and pi are non-null, OR s and iv are non-null
assert
- (pi != null && s == null && iv == null) ||
- (pi == null && s != null && iv != null);
+ (fc != null && pi != null && s == null && iv == null) ||
+ (fc == null && pi == null && s != null && iv != null);
assert as != null;
-
+
+ callSite = fc;
paramIndex = pi;
sese = s;
insetVar = iv;
}
public boolean isParamTaint() {
- return paramIndex != null;
+ return callSite != null;
}
public boolean isSESETaint() {
return sese != null;
}
+ public FlatCall getCallSite() {
+ return callSite;
+ }
+
public Integer getParamIndex() {
return paramIndex;
}
return allocSite;
}
+ public ExistPredSet getPreds() {
+ return preds;
+ }
public boolean equalsSpecific( Object o ) {
+ if( !equalsIgnorePreds( o ) ) {
+ return false;
+ }
+
+ Taint t = (Taint) o;
+ return preds.equals( t.preds );
+ }
+
+ public boolean equalsIgnorePreds( Object o ) {
if( o == null ) {
return false;
}
Taint t = (Taint) o;
+ boolean fcMatches = true;
+ if( callSite == null ) {
+ fcMatches = t.callSite == null;
+ } else {
+ fcMatches = callSite.equals( t.callSite );
+ }
+
boolean piMatches = true;
if( paramIndex == null ) {
piMatches = t.paramIndex == null;
public int hashCodeSpecific() {
int hash = allocSite.hashCode();
+ if( callSite != null ) {
+ hash = hash ^ callSite.hashCode();
+ }
+
if( paramIndex != null ) {
hash = hash ^ paramIndex.hashCode();
}
public String toString() {
String s = "(";
- if( paramIndex != null ) {
- s += "param"+paramIndex;
+ if( isParamTaint() ) {
+ s += "cs"+callSite.nodeid+"-"+paramIndex;
} else {
s += sese.toPrettyString()+"-"+insetVar;
}
- return s+", "+allocSite.toStringBrief()+")";
+ return s+", "+allocSite.toStringBrief()+"):"+preds;
}
}