Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /* BranchedRefVarsAnalysis
   * Copyright (C) 2000 Patrick Lam, Janus
   *
   * This library is free software; you can redistribute it and/or
   * modify it under the terms of the GNU Lesser General Public
   * License as published by the Free Software Foundation; either
   * version 2.1 of the License, or (at your option) any later version.
   *
   * This library is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, write to the
  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  * Boston, MA 02111-1307, USA.
  */
 
 
 package soot.jimple.toolkits.annotation.nullcheck;
 
 import soot.*;
 import soot.jimple.*;
 import java.util.*;
 
 
 /*
      README FIRST - IMPORTANT IMPLEMENTATION NOTE
 
      As per the analysis presented in the report, there are four possible 
      pairs for given reference r:
      (r, kBottom)
      (r, kNonNull)
      (r, kNull)
      (r, kTop)
 
      To save space an simplify operations, we implemented those 4 values 
      with two bits rather than four, namely:
 
      (r, kTop) in a set is represented by having (r, kNull) and (r, kNonNull) 
      in the set. Ditto, (r, kBottom) is represented by having neither in the set.
     
      Keep this in mind as you read the code, it helps. Honnest :)
 
      -- Janus
 
  */
 
 
 /*
       BranchedRefVarsAnalysis class
 
       Perform the analysis presented in the report.
 
       
       KNOWN LIMITATION: there is a problem in the ForwardBranchedFlowAnalysis
       or maybe the CompleteUnitGraph that prevent the analysis
       (at the ForwardBranchedFlowAnalysis level) to handle properly traps.
       We make the analysis conservative in case of exceptions by setting
       exceptions handler statements In to TOP.
       
 
  */


Deprecated:
THIS IS KNOWN TO BE BUGGY. USE NullnessAnalysis INSTEAD!
 
 {
     /*
         COMPILATION OPTIONS
     */
 
     // we don't want the analysis to be conservative?
     // i.e. we don't want it to only care for locals
     private final  boolean isNotConservative = false;
     
     // do we want the analysis to handle if statements?
     private final  boolean isBranched = true;
     
     // do we want the analysis to care that f and g 
     // could be the same reference?
     private final  boolean careForAliases = false;
     
     // do we want the analysis to care that a method 
     // call could have side effects?
     private final  boolean careForMethodCalls = true;
 
     // **** END OF COMPILATION OPTIONS *****
 
 /*
     {
         if (true) {
             G.v().out.println();
             G.v().out.println();
            G.v().out.println("BranchedRefVarsAnalysis:");
            G.v().out.println("     isNotConservative = "+isNotConservative);
            G.v().out.println("            isBranched = "+isBranched);
            G.v().out.println("        careForAliases = "+careForAliases);
            G.v().out.println("    careForMethodCalls = "+careForMethodCalls);
        }
    } // end 
*/
    // constants for the analysis
    public final static int kBottom = 0;
    public final static int kNull = 1;
    public final static int kNonNull = 2;
    public final static int kTop = 99;
    // bottom and top sets
    protected FlowSet emptySet;
    protected FlowSet fullSet;
    // gen and preserve sets (for each statement)
    protected Map<UnitFlowSetunitToGenerateSet;
    protected Map<UnitFlowSetunitToPreserveSet;
    
    // sets of variables that need a null pointer check (for each statement)
    // keep track of the different kinds of reference types this analysis is working on
    protected List<EquivalentValuerefTypeLocals;
    protected List<EquivalentValuerefTypeValues// sum of all the above
    // used in flowThrough.
    protected FlowSet tempFlowSet = null;
    // fast conversion from Value -> EquivalentValue
    //  because used in  methods
    private final  HashMap<ValueEquivalentValuevalueToEquivValue = new HashMap<ValueEquivalentValue>(2293, 0.7f);
    {
        if (.containsKey(v))
            return .get(v);
        else {
            EquivalentValue ev = new EquivalentValue(v);
            .put(vev);
            return ev;
        }
    } // end getEquivalentValue
    
    // constant (r, v) pairs
    //  because used in  methods
    private final  HashMap<EquivalentValueRefIntPairkRefBotttomPairs = new HashMap<EquivalentValueRefIntPair>(2293, 0.7f);
    private final  HashMap<EquivalentValueRefIntPairkRefNonNullPairs = new HashMap<EquivalentValueRefIntPair>(2293, 0.7f);
    private final  HashMap<EquivalentValueRefIntPairkRefNullPairs = new HashMap<EquivalentValueRefIntPair>(2293, 0.7f);
    private final  HashMap<EquivalentValueRefIntPairkRefTopPairs = new HashMap<EquivalentValueRefIntPair>(2293, 0.7f);
    // make that (r, v) pairs are constants
    // i.e. the same r and v values always generate the same (r, v) object    
    public  RefIntPair getKRefIntPair(EquivalentValue rint v)
    {
        HashMap<EquivalentValueRefIntPairpairsMap = null;
        if (v == )
            pairsMap =  ;
        else if (v == )
            pairsMap = ;
        else if (v == )
            pairsMap = ;
        else if (v == )
            pairsMap = ;
        else
            throw new RuntimeException("invalid constant ("+v+")");
        
        if (pairsMap.containsKey(r))
            return pairsMap.get(r);
        else {
            RefIntPair pair = new RefIntPair(rvthis);
            pairsMap.put(rpair);
            return pair;
        }
    } // end getKRefIntPair
    /*
        Utility methods.
        They are used all over the place. Most of them are declared 
        "private  final" so they can be inlined with javac -O.
     */
    // isAlwaysNull returns true if the reference r is known to be always null
    private  final boolean isAlwaysNull(Value r)
    {
        return ((r instanceof NullConstant) || 
                (r.getType() instanceof NullType));
    } // end isAlwaysNull
    // isAlwaysTop returns true if the reference r is known to be always top for this analysis
    // i.e. its value is undecidable by this analysis
    private  final boolean isAlwaysTop(Value r)
    {
        if ()
            return false;
        else
            return r instanceof InstanceFieldRef || r instanceof StaticFieldRef;
    } // end isAlwaysTop
    protected boolean isAlwaysNonNull(Value ro) {
        ifro instanceof NewExpr ) return true;
        ifro instanceof NewArrayExpr ) return true;
        ifro instanceof NewMultiArrayExpr ) return true;
        ifro instanceof ThisRef ) return true;
        ifro instanceof CaughtExceptionRef ) return true;
        ifro instanceof StringConstant ) return true;
        return false;
    }
    // isAnalyzedRef returns true if the reference r is to be analyzed by this analysis
    // i.e. its value is not always known (or undecidable)
    private  final boolean isAnalyzedRef(Value r)
    {
        if (isAlwaysNull(r) || isAlwaysTop(r)) 
            return false;
        else if (r instanceof Local ||
                 r instanceof InstanceFieldRef ||
                 r instanceof StaticFieldRef) {
            Type rType = r.getType();
            
            return (rType instanceof RefType || rType instanceof ArrayType);
        } else
            return false;
    } // end isAnalyzedRef
    // refInfo is a helper method to tranform our two bit representation back to the four constants
    // For a given reference and a flow set, tell us if r is bottom, top, null or non-null
    // Note: this method will fail if r is not in the flow set
    protected  final int refInfo(EquivalentValue rFlowSet fs)
    {
        boolean isNull = fs.contains(getKRefIntPair(r));
        boolean isNonNull = fs.contains(getKRefIntPair(r));
        
        if (isNull && isNonNull)
            return ;
        else if (isNull)
            return ;
        else if (isNonNull)
            return ;
        else
            return ;
    } // end refInfo
    protected  final int refInfo(Value rFlowSet fs)
    {
        return refInfo(getEquivalentValue(r), fs);
    } // end refInfo
    
    // Like refInfo, but the reference doesn't have to be in the flow set
    // note: it still need to be a reference, i.e. ArrayType or RefType
    public int anyRefInfo(Value rFlowSet f)
    {
        if (isAlwaysNull(r))
            return ;
        else if (isAlwaysTop(r))
            return ;
        else ifisAlwaysNonNull(r) )
            return ;
        else
            return refInfo(rf);
    } // end anyRefInfo
    
    /*
       methods: uAddTopToFlowSet
                uAddInfoToFlowSet
                uListAddTopToFlowSet
       Adding a pair (r, v) to a set is always a two steps process:
       a) remove all pairs (r, *)
       b) add the pair (r, v)
       
       The methods above handle that.
       Most of them come in two flavors: to act on one set or two act on separate
       generate and preserve sets.
    */
    // method to add (r, kTop) to the gen set (and remove it from the pre set)
    private  final void uAddTopToFlowSet(EquivalentValue rFlowSet genFSFlowSet preFS)
    {
        RefIntPair nullPair = getKRefIntPair(r);
        RefIntPair nullNonPair = getKRefIntPair(r);
        
        if (genFS != preFS) {
            preFS.remove(nullPairpreFS);
            preFS.remove(nullNonPairpreFS);
        }
        
        genFS.add(nullPairgenFS);
        genFS.add(nullNonPairgenFS);
    } // end uAddTopToFlowSet
    
    private  final void uAddTopToFlowSet(Value rFlowSet genFSFlowSet preFS)
    {
        uAddTopToFlowSet(getEquivalentValue(r), genFSpreFS);
    } // end uAddTopToFlowSet
    // method to add (r, kTop) to a set
    private  final void uAddTopToFlowSet(Value rFlowSet fs)
    {
        uAddTopToFlowSet(getEquivalentValue(r), fsfs);
    } // end uAddTopToFlowSet
    
    // method to add (r, kTop) to a set
    private  final void uAddTopToFlowSet(EquivalentValue rFlowSet fs)
    {
        uAddTopToFlowSet(rfsfs);
    } // end uAddTopToFlowSet
    // method to add (r, kNonNull) or (r, kNull) to the gen set (and remove it from the pre set)
    private  final void uAddInfoToFlowSet(EquivalentValue rint vFlowSet genFSFlowSet preFS)
    {
        int kill;
        if (v == )
            kill = ;
        else if (v == )
            kill = ;
        else
            throw new RuntimeException("invalid info");
        
        if (genFS != preFS) {
            preFS.remove(getKRefIntPair(rkill), preFS);
        }
        
        genFS.remove(getKRefIntPair(rkill), genFS);
        genFS.add(getKRefIntPair(rv), genFS);
    } // end uAddInfoToFlowSet
    private  final void uAddInfoToFlowSet(Value rint vFlowSet genFFlowSet preF)
    {
        uAddInfoToFlowSet(getEquivalentValue(r), vgenFpreF);
    } // end uAddInfoToFlowSet
    // method to add (r, kNonNull) or (r, kNull) to a set
    private  final void uAddInfoToFlowSet(Value rint vFlowSet fs)
    {
        uAddInfoToFlowSet(getEquivalentValue(r), vfsfs);
    } // end uAddInfoToFlowSet
    // method to add (r, kNonNull) or (r, kNull) to a set
    private  final void uAddInfoToFlowSet(EquivalentValue rint vFlowSet fs)
    {
        uAddInfoToFlowSet(rvfsfs);
    } // end uAddInfoToFlowSet
    // method to apply uAddTopToFlowSet to a whole list of references
    private  final void uListAddTopToFlowSet(List<EquivalentValuerefsFlowSet genFSFlowSet preFS)
    {
        Iterator<EquivalentValueit = refs.iterator();
        while (it.hasNext()) {
            uAddTopToFlowSet(it.next(), genFSpreFS);
        }
    } // end uListAddTopToFlowSet


    
end of utility methods *******
    // here come the method that start it all, the constructor
    // initialize the object and run the analysis
    

Deprecated:
THIS IS KNOWN TO BE BUGGY. USE NullnessAnalysis INSTEAD!
    {
        super(g);
        // initialize all the refType lists
        initRefTypeLists();
        
        // initialize emptySet, fullSet and tempFlowSet
        initUniverseSets();
        
        // initialize unitTo...Sets
        // perform  preservation and generation
        initUnitSets();
        
        doAnalysis();
    } // end constructor
    // method to initialize refTypeLocals, refTypeInstFields, refTypeInstFieldBases
    // refTypeStaticFields, and refTypeValues
    // those lists contains fields that can/need to be analyzed
    private void initRefTypeLists()
    {
         = new ArrayList<EquivalentValue>();
         = new ArrayList<EquivalentValue>();
         = new ArrayList<EquivalentValue>();
         = new ArrayList<EquivalentValue>();
        // build list of locals
        Iterator it = ((UnitGraph)).getBody().getLocals().iterator();
        
        while (it.hasNext()) {
            Local l = (Local) (it.next());
            
            if (l.getType() instanceof RefType ||
                l.getType() instanceof ArrayType) {
                .add(getEquivalentValue(l));
            }
        }
        
        if () {
            // build list of fields
            // if the analysis is not conservative (if it is then we will only work on locals)
            
            Iterator unitIt = .iterator();
            
            while(unitIt.hasNext()) {
                
                Unit s = (UnitunitIt.next();
                
                Iterator boxIt;
                boxIt = s.getUseBoxes().iterator();
                while(boxIt.hasNext()) initRefTypeLists( (ValueBoxboxIt.next() );
                boxIt = s.getDefBoxes().iterator();
                while(boxIt.hasNext()) initRefTypeLists( (ValueBoxboxIt.next() );
                
            }
            
        } // end build list of fields
        
        // G.v().out.println("Analyzed references: " + refTypeValues);
    } // end initRefTypeLists 
    
    private void initRefTypeListsValueBox box ) {
        Value val = box.getValue();
        Type opType = null;
        
        if (val instanceof InstanceFieldRef) {
            
            InstanceFieldRef ir = (InstanceFieldRefval;
            
            opType = ir.getType(); 
            if (opType instanceof RefType ||
                opType instanceof ArrayType) {
                
                EquivalentValue eir = getEquivalentValue(ir); 
                
                if (!.contains(eir)) {
                    .add(eir);
                    EquivalentValue eirbase = getEquivalentValue(ir.getBase());
                    if (!.contains(eirbase))
                        .add(eirbase);
                }
            }
        } else if (val instanceof StaticFieldRef) {
            
            StaticFieldRef sr = (StaticFieldRefval;
            opType = sr.getType();
            
            if (opType instanceof RefType ||
                opType instanceof ArrayType) {
                
                EquivalentValue esr = getEquivalentValue(sr);
                if (!.contains(esr)) {
                    .add(esr);
                }
            }
        }
    }
    // method to initialize the emptySet, fullSet and tempFlowSet
    // from the refTypeValues
    private void initUniverseSets()
    {
        FlowUniverse localUniverse;
        
        Object[] refTypeValuesArray = .toArray();
        int len = refTypeValuesArray.length;
        Object[] universeArray = new Object[2*len];
        int i;
        
        // kRefIntPairs = new HashMap(len*2 + 1, 0.7f);
        // ideally we would like to be able to do the above to avoid that Map growth
        // but that would screw concurent execution of this analysis
        // and making that field non- would require changing our  utility methods to non-
        
        for (i = 0; i < leni++) {
            int j = i*2;
            EquivalentValue  r = (EquivalentValuerefTypeValuesArray[i];
            universeArray[j] = getKRefIntPair(r);
            universeArray[j+1] = getKRefIntPair(r,  );
        }
        
        localUniverse = new ArrayFlowUniverse(universeArray);
        
         = new ArrayPackedSet(localUniverse);   
         = .clone();
        
         = (FlowSetnewInitialFlow();
    } // end initUniverseSets
    
    private void initUnitSets()
    {
        int cap = .size() * 2 + 1;
        float load = 0.7f;
        
         = new HashMap<UnitFlowSet>(capload);
         = new HashMap<UnitFlowSet>(capload);
        
         = new HashMap<UnitHashSet<Value>>(capload);
         = new HashMap<UnitHashSet<Value>>(capload);
         = new HashMap<UnitHashSet<Value>>(capload);
         = new HashMap<UnitHashSet<Value>>(capload);
         = new HashMap<UnitHashSet<Value>>(capload);
        
        
        Iterator unitIt = .iterator();
        
        while(unitIt.hasNext()) {
            
            Unit s = (UnitunitIt.next();
            
            FlowSet genSet = .clone();
            FlowSet preSet = .clone();
            
            HashSet<ValueanalyzedChecksSet = new HashSet<Value>(5,  load);
            HashSet<ValuearrayRefChecksSet = new HashSet<Value>(5,  load);
            HashSet<ValueinstanceFieldRefChecksSet = new HashSet<Value>(5,  load);
            HashSet<ValueinstanceInvokeExprChecksSet = new HashSet<Value>(5,  load);
            HashSet<ValuelengthExprChecksSet = new HashSet<Value>(5,  load);
            
            
            // *** KILL PHASE ***
            
            // naivity here.  kill all the fields after an invoke, i.e. promote them to top
            if ( && ((Stmt)s).containsInvokeExpr()) {
                uListAddTopToFlowSet(genSetpreSet);
                uListAddTopToFlowSet(genSetpreSet);
            }
            
            if ( && (s instanceof AssignStmt)) {
                AssignStmt as = (AssignStmts;
                Value lhs = as.getLeftOp();
                
                if (.contains(lhs)) {
                    // we have a write to a local 'f' and 
                    // there is a reference to f.x.
                    // The LHS will certainly be a local.
                    // here, we kill "f.*".
                    Iterator<EquivalentValuerefTypeInstFieldsIt=.iterator();
                    
                    while (refTypeInstFieldsIt.hasNext()) {
                        EquivalentValue eifr = refTypeInstFieldsIt.next();
                        InstanceFieldRef ifr = (InstanceFieldRefeifr.getValue();
                        
                        if (ifr.getBase() == lhs) {
                            uAddTopToFlowSet(eifrgenSetpreSet);
                        }
                    }
                }
                
                if (lhs instanceof InstanceFieldRef) {
                    
                    // we have a write to 'f.x', 
                    // so we'd better kill 'g.x' for all g.
                    
                    String lhsName = 
                        ((InstanceFieldReflhs).getField().getName();
                    
                    Iterator<EquivalentValuerefTypeInstFieldsIt = .iterator();
                    
                    while (refTypeInstFieldsIt.hasNext()) {
                        EquivalentValue eifr = refTypeInstFieldsIt.next();
                        InstanceFieldRef ifr = (InstanceFieldRefeifr.getValue();
                        
                        String name = ifr.getField().getName();
                        
                        if (name.equals(lhsName)) {
                            uAddTopToFlowSet(eifrgenSetpreSet);
                        }
                    }
                }
            } // end if (s instanceof AssignStmt)
            
            // kill rhs of defs
            {
                Iterator boxIt = s.getDefBoxes().iterator();
                
                while(boxIt.hasNext()) {
                    
                    ValueBox box = (ValueBoxboxIt.next();
                    Value boxValue = box.getValue();
                    
                    if (isAnalyzedRef(boxValue)) {
                        uAddTopToFlowSet(boxValuegenSetpreSet);
                    }
                }
            } // done killing rhs of defs
            
            // GENERATION PHASE
            
            if (s instanceof DefinitionStmt) {
                DefinitionStmt as = (DefinitionStmts;
                Value ro = as.getRightOp();
                Value lo = as.getLeftOp();
                
                // take out the cast from "x = (type) y;"
                if (ro instanceof CastExpr)
                    ro = ((CastExprro).getOp();
                
                if (isAnalyzedRef(lo)) {
                    if (isAlwaysNonNull(ro)) {
                        uAddInfoToFlowSet(logenSetpreSet);
                    } else if (isAlwaysNull(ro)) {
                        uAddInfoToFlowSet(logenSetpreSet);
                    } else if (isAlwaysTop(ro)) {
                        uAddTopToFlowSet(logenSetpreSet);
                    }
                }
            } // end DefinitionStmt gen case
            // check use and def boxes for dereferencing operations
            // since those operations cause a null pointer check
            // after the statement we know the involved references are non-null
            {
                Iterator boxIt;
                boxIt = s.getUseBoxes().iterator();
                while(boxIt.hasNext()) {
                    Value boxValue = ((ValueBoxboxIt.next()).getValue();
                    Value base = null;
                    
                    if(boxValue instanceof InstanceFieldRef) {
                        base = ((InstanceFieldRef) (boxValue)).getBase();
                        instanceFieldRefChecksSet.add(base);
                    } else if (boxValue instanceof ArrayRef) {
                        base = ((ArrayRef) (boxValue)).getBase();
                        arrayRefChecksSet.add(base);
                    } else if (boxValue instanceof InstanceInvokeExpr) {
                        base = ((InstanceInvokeExprboxValue).getBase();
                        instanceInvokeExprChecksSet.add(base);                        
                    } else if (boxValue instanceof LengthExpr) {
                        base = ((LengthExprboxValue).getOp();
                        lengthExprChecksSet.add(base);
                    } else if (s instanceof ThrowStmt) {
                        base = ((ThrowStmt)s).getOp();
                    } else if (s instanceof MonitorStmt) {
                        base = ((MonitorStmt)s).getOp();
                    }
                    
                    if (base != null && isAnalyzedRef(base)) { 
                        uAddInfoToFlowSet(basegenSetpreSet);
                        analyzedChecksSet.add(base);
                    }
                }
                boxIt = s.getDefBoxes().iterator();
                while(boxIt.hasNext()) {
                    
                    Value boxValue = ((ValueBoxboxIt.next()).getValue();
                    Value base = null;
                    
                    if(boxValue instanceof InstanceFieldRef) {
                        base = ((InstanceFieldRef) (boxValue)).getBase();
                        instanceFieldRefChecksSet.add(base);
                    } else if (boxValue instanceof ArrayRef) {
                        base = ((ArrayRef) (boxValue)).getBase();
                        arrayRefChecksSet.add(base);
                    } else if (boxValue instanceof InstanceInvokeExpr) {
                        base = ((InstanceInvokeExprboxValue).getBase();
                        instanceInvokeExprChecksSet.add(base);                        
                    } else if (boxValue instanceof LengthExpr) {
                        base = ((LengthExprboxValue).getOp();
                        lengthExprChecksSet.add(base);
                    } else if (s instanceof ThrowStmt) {
                        base = ((ThrowStmt)s).getOp();
                    } else if (s instanceof MonitorStmt) {
                        base = ((MonitorStmt)s).getOp();
                    }
                    
                    if (base != null && isAnalyzedRef(base)) { 
                        uAddInfoToFlowSet(basegenSetpreSet);
                        analyzedChecksSet.add(base);
                    }
                }
            } // done check use and def boxes
            .put(sgenSet);
            .put(spreSet);
            
            .put(sanalyzedChecksSet);
            .put(sarrayRefChecksSet);
            .put(sinstanceFieldRefChecksSet);
            .put(sinstanceInvokeExprChecksSet);
            .put(slengthExprChecksSet);
        }
    } // initUnitSets
    
    protected void flowThrough(Object inValueUnit stmtList outFallValueList outBranchValues)
    {
        FlowSet in = (FlowSetinValue;
        FlowSet out = ;
        FlowSet pre = .get(stmt);
        FlowSet gen = .get(stmt);
        // Perform perservation
        in.intersection(preout);
        
        // Perform generation
        out.union(genout);
        
        // Manually add any x = y; when x and y are both analyzed references
        // these are not  sets.
        if (stmt instanceof AssignStmt) {
            AssignStmt as = (AssignStmtstmt;
            Value rightOp = as.getRightOp();
            Value leftOp = as.getLeftOp();
            
            // take out the cast from "x = (type) y;"
            if (rightOp instanceof CastExpr)
                rightOp = ((CastExprrightOp).getOp();
            
            if (isAnalyzedRef(leftOp) && isAnalyzedRef(rightOp)) {
                int roInfo = refInfo(rightOpin);
                
                if (roInfo == )
                    uAddTopToFlowSet(leftOpout);
                else if (roInfo != )
                    uAddInfoToFlowSet(leftOproInfoout);
            }
        }
        
        // Copy the out value to all branch boxes.
        {
            Iterator it = outBranchValues.iterator();
            while (it.hasNext()) {
                FlowSet fs = (FlowSet) (it.next());
                
                copy(outfs);
            }
        }
        
        // Copy the out value to the fallthrough box (don't need iterator)
        {
            Iterator it = outFallValue.iterator();
            while (it.hasNext()) {
                FlowSet fs = (FlowSet) (it.next());
                
                copy(outfs);
            }
        }
        
        if ( && (stmt instanceof IfStmt)) {
            Value cond = ((IfStmtstmt).getCondition();
            Value op1 = ((BinopExprcond).getOp1();
            Value op2 = ((BinopExprcond).getOp2();
            // make sure at least one of the op is a reference being analyzed
            // and that none is a reference that is always Top
            if ((!(isAlwaysTop(op1) || isAlwaysTop(op2))) && (isAnalyzedRef(op1) || isAnalyzedRef(op2))) {
                Value toGen = null;
                int toGenInfo = ;
                int op1Info = anyRefInfo(op1in);
                int op2Info = anyRefInfo(op2in);
                boolean op1isKnown = (op1Info ==  || op1Info == );
                boolean op2isKnown = (op2Info ==  || op2Info == );
                
                if (op1isKnown) {
                    if (!op2isKnown) {
                        toGen = op2;
                        toGenInfo = op1Info;
                    }
                } else if (op2isKnown) {
                    toGen =  op1;
                    toGenInfo = op2Info;
                }
                
                // only generate info for analyzed references that are top or bottom
                if ((toGen != null) && isAnalyzedRef(toGen)) {
                    int fInfo = ;
                    int bInfo = ;
                    
                    if (cond instanceof EqExpr) {
                        // branching mean op1 == op2
                        bInfo = toGenInfo;
                        if (toGenInfo == ) {
                            // falling through mean toGen != null
                            fInfo = ;
                        }
                        
                    } else if (cond instanceof NeExpr) {
                        // if we don't branch that mean op1 == op2
                        fInfo = toGenInfo;
                        if (toGenInfo == ) {
                            // branching through mean toGen != null
                            bInfo = ;
                        }
                    } else
                        throw new RuntimeException("invalid condition");
                    if (fInfo != ) {
                        Iterator it = outFallValue.iterator();
                        while(it.hasNext()) {
                            FlowSet fs = (FlowSet) (it.next());
                            copy(outfs);
                            uAddInfoToFlowSet(toGenfInfofs);
                        }
                    }
                    if (bInfo !=  ) {
                        Iterator it = outBranchValues.iterator();
                        while (it.hasNext()) {
                            FlowSet fs = (FlowSet) (it.next());
                            copy(outfs);
                            uAddInfoToFlowSet(toGenbInfofs);
                        }
                    } 
                }
            }
        }
    } // end flowThrough
    protected void merge(Object in1Object in2Object out)
    {
        FlowSet inSet1 = (FlowSetin1;
        FlowSet inSet2 = (FlowSetin2;
        FlowSet inSet1Copy = inSet1.clone();
        FlowSet inSet2Copy = inSet2.clone();
        // we do that in case out is in1 or in2
        FlowSet outSet = (FlowSetout;
        inSet1.intersection(inSet2outSet);
        // first step, set out to the intersection of in1 & in2
        // but we are not over, the intersection doesn't handle the top & bottom cases
        while (it.hasNext()) {
            EquivalentValue r = it.next();
            int refInfoIn1 = refInfo(rinSet1Copy);
            int refInfoIn2 = refInfo(rinSet2Copy);
            if (refInfoIn1 != refInfoIn2) {
                // only process if they are not equal, otherwise the intersection has done its job
                if ((refInfoIn1 == ) || (refInfoIn2 == )) {
                    // ok, r is top in one of the sets but not the other, make it top in the outSet
                    uAddTopToFlowSet(routSet);
                } else if (refInfoIn1 == ) {
                    // r is bottom in set1 but not set2, promote to the value in set2
                    uAddInfoToFlowSet(rrefInfoIn2outSet);
                } else if (refInfoIn2 == ) {
                    // r is bottom in set2 but not set1, promote to the value in set1
                    uAddInfoToFlowSet(rrefInfoIn1outSet);
                } else {
                    // r is known in both set, but it's a different value in each set, make it top
                    uAddTopToFlowSet(routSet);
                }
            }
        }
    } // end merge
    
    protected void copy(Object sourceObject dest)
    {
        FlowSet sourceSet = (FlowSetsource,
            destSet = (FlowSetdest;
            
        sourceSet.copy(destSet);
    } // end copy
    protected Object newInitialFlow()
    {
        return .clone();
    } // end newInitialFlow
    protected Object entryInitialFlow()
    {
        return .clone();
    }
    // try to workaround exception limitation of ForwardBranchedFlowAnalysis
    // this will make for a very conservative analysys when exception handling
    // statements are in the code :-(
    public boolean treatTrapHandlersAsEntries()
    {
        return true;
    }
// end class BranchedRefVarsAnalysis
New to GrepCode? Check out our FAQ X