Search in sources :

Example 1 with AnySubType

use of soot.AnySubType in project soot by Sable.

the class UnitThrowAnalysisTest method testJAssignStmt.

@Test
public void testJAssignStmt() {
    // local0 = 0
    Stmt s = Jimple.v().newAssignStmt(Jimple.v().newLocal("local0", IntType.v()), IntConstant.v(0));
    assertTrue(ExceptionTestUtility.sameMembers(utility.VM_ERRORS, Collections.EMPTY_SET, unitAnalysis.mightThrow(s)));
    assertEquals(utility.VM_ERRORS_PLUS_SUPERTYPES, utility.catchableSubset(unitAnalysis.mightThrow(s)));
    ArrayRef arrayRef = Jimple.v().newArrayRef(Jimple.v().newLocal("local1", ArrayType.v(RefType.v("java.lang.Object"), 1)), IntConstant.v(0));
    Local scalarRef = Jimple.v().newLocal("local2", RefType.v("java.lang.Object"));
    // local2 = local1[0]
    s = Jimple.v().newAssignStmt(scalarRef, arrayRef);
    Set<RefLikeType> expectedRep = new ExceptionHashSet<RefLikeType>(utility.VM_ERRORS);
    expectedRep.add(utility.NULL_POINTER_EXCEPTION);
    expectedRep.add(utility.ARRAY_INDEX_OUT_OF_BOUNDS_EXCEPTION);
    assertTrue(ExceptionTestUtility.sameMembers(expectedRep, Collections.<AnySubType>emptySet(), unitAnalysis.mightThrow(s)));
    Set expectedCatch = new ExceptionHashSet(utility.VM_ERRORS_PLUS_SUPERTYPES);
    expectedCatch.add(utility.NULL_POINTER_EXCEPTION);
    expectedCatch.add(utility.ARRAY_INDEX_OUT_OF_BOUNDS_EXCEPTION);
    expectedCatch.add(utility.INDEX_OUT_OF_BOUNDS_EXCEPTION);
    expectedCatch.add(utility.RUNTIME_EXCEPTION);
    expectedCatch.add(utility.EXCEPTION);
    assertEquals(expectedCatch, utility.catchableSubset(unitAnalysis.mightThrow(s)));
    // local1[0] = local2
    s = Jimple.v().newAssignStmt(arrayRef, scalarRef);
    expectedRep.add(utility.ARRAY_STORE_EXCEPTION);
    assertTrue(ExceptionTestUtility.sameMembers(expectedRep, Collections.EMPTY_SET, unitAnalysis.mightThrow(s)));
    expectedCatch.add(utility.ARRAY_STORE_EXCEPTION);
    assertEquals(expectedCatch, utility.catchableSubset(unitAnalysis.mightThrow(s)));
}
Also used : ArrayRef(soot.jimple.ArrayRef) RefLikeType(soot.RefLikeType) ExceptionHashSet(soot.toolkits.exceptions.ExceptionTestUtility.ExceptionHashSet) Set(java.util.Set) ExceptionHashSet(soot.toolkits.exceptions.ExceptionTestUtility.ExceptionHashSet) Local(soot.Local) AnySubType(soot.AnySubType) ThrowStmt(soot.jimple.ThrowStmt) IfStmt(soot.jimple.IfStmt) Stmt(soot.jimple.Stmt) Test(org.junit.Test)

Example 2 with AnySubType

use of soot.AnySubType in project soot by Sable.

the class ThrowableSet method add.

/**
 * Returns a <code>ThrowableSet</code> which contains <code>e</code> and all
 * of its subclasses as well as the exceptions in this set.
 *
 * <p>
 * <code>e</code> should be an instance of {@link AnySubType} if you know
 * that the compile-time type of the exception you are representing is
 * <code>e</code>, but the exception may be instantiated at run-time by a
 * subclass of <code>e</code>.
 *
 * <p>
 * For example, if you were recording the type of the exception thrown by
 *
 * <pre>
 * catch (IOException e) {
 *    throw e;
 * }
 * </pre>
 *
 * you would call
 *
 * <pre>
 * <code>add(AnySubtype.v(Scene.v().getRefType("java.lang.Exception.IOException")))</code>
 * </pre>
 *
 * since the handler might rethrow any subclass of <code>IOException</code>.
 *
 * @param e
 *            represents a subtree of the exception class hierarchy to add
 *            to this set.
 *
 * @return a set containing <code>e</code> and all its subclasses, as well
 *         as the exceptions represented by this set.
 *
 * @throws ThrowableSet.AlreadyHasExclusionsException
 *             if this <code>ThrowableSet</code> is the result of a
 *             {@link #whichCatchableAs(RefType)} operation and, thus,
 *             unable to represent the addition of <code>e</code>.
 */
public ThrowableSet add(AnySubType e) throws ThrowableSet.AlreadyHasExclusionsException {
    if (INSTRUMENTING) {
        Manager.v().addsOfAnySubType++;
    }
    ThrowableSet result = getMemoizedAdds(e);
    if (result != null) {
        if (INSTRUMENTING) {
            Manager.v().addsInclusionFromMemo++;
            Manager.v().addsExclusionWithoutSearch++;
        }
        return result;
    }
    FastHierarchy hierarchy = Scene.v().getOrMakeFastHierarchy();
    RefType newBase = e.getBase();
    if (INSTRUMENTING) {
        if (exceptionsExcluded.isEmpty()) {
            Manager.v().addsExclusionWithoutSearch++;
        } else {
            Manager.v().addsExclusionWithSearch++;
        }
    }
    for (AnySubType excludedType : exceptionsExcluded) {
        RefType exclusionBase = excludedType.getBase();
        boolean isExcluded = exclusionBase.getSootClass().isPhantom() && exclusionBase.equals(newBase);
        isExcluded |= !exclusionBase.getSootClass().isPhantom() && (hierarchy.canStoreType(newBase, exclusionBase) || hierarchy.canStoreType(exclusionBase, newBase));
        if (isExcluded) {
            if (INSTRUMENTING) {
                // To ensure that the subcategories total properly:
                Manager.v().addsInclusionInterrupted++;
            }
            throw new AlreadyHasExclusionsException("ThrowableSet.add(" + e.toString() + ") to the set [ " + this.toString() + "] where " + exclusionBase.toString() + " is excluded.");
        }
    }
    if (this.exceptionsIncluded.contains(e)) {
        if (INSTRUMENTING) {
            Manager.v().addsInclusionFromMap++;
        }
        return this;
    }
    if (INSTRUMENTING) {
        Manager.v().addsInclusionFromSearch++;
    }
    int changes = 0;
    boolean addNewException = true;
    Set<RefLikeType> resultSet = new HashSet<RefLikeType>();
    for (RefLikeType incumbent : this.exceptionsIncluded) {
        if (incumbent instanceof RefType) {
            if (hierarchy.canStoreType(incumbent, newBase)) {
                // Omit incumbent from result.
                changes++;
            } else {
                resultSet.add(incumbent);
            }
        } else if (incumbent instanceof AnySubType) {
            RefType incumbentBase = ((AnySubType) incumbent).getBase();
            if (newBase.getSootClass().isPhantom()) {
                if (!incumbentBase.equals(newBase))
                    resultSet.add(incumbent);
            } else // the incumbent, or vice versa.
            if (hierarchy.canStoreType(newBase, incumbentBase)) {
                addNewException = false;
                resultSet.add(incumbent);
            } else if (hierarchy.canStoreType(incumbentBase, newBase)) {
                // Omit incumbent from result;
                changes++;
            } else {
                resultSet.add(incumbent);
            }
        } else {
            // assertion failure.
            throw new IllegalStateException("ThrowableSet.add(AnySubType): Set element " + incumbent.toString() + " is neither a RefType nor an AnySubType.");
        }
    }
    if (addNewException) {
        resultSet.add(e);
        changes++;
    }
    if (changes > 0) {
        result = Manager.v().registerSetIfNew(resultSet, this.exceptionsExcluded);
    } else {
        result = this;
    }
    addToMemoizedAdds(e, result);
    return result;
}
Also used : RefType(soot.RefType) RefLikeType(soot.RefLikeType) FastHierarchy(soot.FastHierarchy) AnySubType(soot.AnySubType) HashSet(java.util.HashSet)

Example 3 with AnySubType

use of soot.AnySubType in project soot by Sable.

the class ThrowableSet method add.

/**
 * Returns a <code>ThrowableSet</code> which contains all the exceptions in
 * <code>addedExceptions</code> in addition to those in this
 * <code>ThrowableSet</code>.
 *
 * @param addedExceptions
 *            a set of {@link RefLikeType} and {@link AnySubType} objects to
 *            be added to the types included in this
 *            <code>ThrowableSet</code>.
 *
 * @return a set containing all the <code>addedExceptions</code> as well as
 *         the exceptions in this set.
 */
private ThrowableSet add(Set<RefLikeType> addedExceptions) {
    Set<RefLikeType> resultSet = new HashSet<RefLikeType>(this.exceptionsIncluded);
    int changes = 0;
    FastHierarchy hierarchy = Scene.v().getOrMakeFastHierarchy();
    for (RefLikeType newType : addedExceptions) {
        if (!resultSet.contains(newType)) {
            boolean addNewType = true;
            if (newType instanceof RefType) {
                for (RefLikeType incumbentType : resultSet) {
                    if (incumbentType instanceof RefType) {
                        if (newType == incumbentType) {
                            // assertion failure.
                            throw new IllegalStateException("ThrowableSet.add(Set): resultSet.contains() failed to screen duplicate RefType " + newType);
                        }
                    } else if (incumbentType instanceof AnySubType) {
                        RefType incumbentBase = ((AnySubType) incumbentType).getBase();
                        if (hierarchy.canStoreType(newType, incumbentBase)) {
                            // No need to add this class.
                            addNewType = false;
                        }
                    } else {
                        // assertion failure.
                        throw new IllegalStateException("ThrowableSet.add(Set): incumbent Set element " + incumbentType + " is neither a RefType nor an AnySubType.");
                    }
                }
            } else if (newType instanceof AnySubType) {
                RefType newBase = ((AnySubType) newType).getBase();
                for (Iterator<RefLikeType> j = resultSet.iterator(); j.hasNext(); ) {
                    RefLikeType incumbentType = j.next();
                    if (incumbentType instanceof RefType) {
                        RefType incumbentBase = (RefType) incumbentType;
                        if (hierarchy.canStoreType(incumbentBase, newBase)) {
                            j.remove();
                            changes++;
                        }
                    } else if (incumbentType instanceof AnySubType) {
                        RefType incumbentBase = ((AnySubType) incumbentType).getBase();
                        if (newBase == incumbentBase) {
                            // assertion failure.
                            throw new IllegalStateException("ThrowableSet.add(Set): resultSet.contains() failed to screen duplicate AnySubType " + newBase);
                        } else if (hierarchy.canStoreType(incumbentBase, newBase)) {
                            j.remove();
                            changes++;
                        } else if (hierarchy.canStoreType(newBase, incumbentBase)) {
                            // No need to add this class.
                            addNewType = false;
                        }
                    } else {
                        // assertion failure.
                        throw new IllegalStateException("ThrowableSet.add(Set): old Set element " + incumbentType + " is neither a RefType nor an AnySubType.");
                    }
                }
            } else {
                // assertion failure.
                throw new IllegalArgumentException("ThrowableSet.add(Set): new Set element " + newType + " is neither a RefType nor an AnySubType.");
            }
            if (addNewType) {
                changes++;
                resultSet.add(newType);
            }
        }
    }
    ThrowableSet result = null;
    if (changes > 0) {
        result = Manager.v().registerSetIfNew(resultSet, this.exceptionsExcluded);
    } else {
        result = this;
    }
    return result;
}
Also used : RefLikeType(soot.RefLikeType) RefType(soot.RefType) FastHierarchy(soot.FastHierarchy) Iterator(java.util.Iterator) AnySubType(soot.AnySubType) HashSet(java.util.HashSet)

Example 4 with AnySubType

use of soot.AnySubType in project soot by Sable.

the class ThrowableSet method add.

/**
 * Returns a <code>ThrowableSet</code> which contains <code>e</code> in
 * addition to the exceptions in this <code>ThrowableSet</code>.
 *
 * <p>
 * Add <code>e</code> as a {@link RefType} when you know that the run-time
 * class of the exception you are representing is necessarily <code>e</code>
 * and cannot be a subclass of <code>e</code>.
 *
 * <p>
 * For example, if you were recording the type of the exception thrown by
 *
 * <pre>
 * throw new IOException(&quot;Permission denied&quot;);
 * </pre>
 *
 * you would call
 *
 * <pre>
 * <code>add(Scene.v().getRefType("java.lang.Exception.IOException"))</code>
 * </pre>
 *
 * since the class of the exception is necessarily <code>IOException</code>.
 *
 * @param e
 *            the exception class
 *
 * @return a set containing <code>e</code> as well as the exceptions in this
 *         set.
 *
 * @throws {@link ThrowableSet.IllegalStateException} if this
 *         <code>ThrowableSet</code> is the result of a
 *         {@link #whichCatchableAs(RefType)} operation and, thus, unable to
 *         represent the addition of <code>e</code>.
 */
public ThrowableSet add(RefType e) throws ThrowableSet.AlreadyHasExclusionsException {
    if (INSTRUMENTING) {
        Manager.v().addsOfRefType++;
    }
    if (this.exceptionsIncluded.contains(e)) {
        if (INSTRUMENTING) {
            Manager.v().addsInclusionFromMap++;
            Manager.v().addsExclusionWithoutSearch++;
        }
        return this;
    }
    ThrowableSet result = getMemoizedAdds(e);
    if (result != null) {
        if (INSTRUMENTING) {
            Manager.v().addsInclusionFromMemo++;
            Manager.v().addsExclusionWithoutSearch++;
        }
        return result;
    }
    if (INSTRUMENTING) {
        Manager.v().addsInclusionFromSearch++;
        if (exceptionsExcluded.isEmpty()) {
            Manager.v().addsExclusionWithoutSearch++;
        } else {
            Manager.v().addsExclusionWithSearch++;
        }
    }
    FastHierarchy hierarchy = Scene.v().getOrMakeFastHierarchy();
    for (AnySubType excludedType : exceptionsExcluded) {
        RefType exclusionBase = excludedType.getBase();
        if ((e.getSootClass().isPhantom() && exclusionBase.equals(e)) || (!e.getSootClass().isPhantom() && hierarchy.canStoreType(e, exclusionBase))) {
            throw new AlreadyHasExclusionsException("ThrowableSet.add(RefType): adding" + e.toString() + " to the set [ " + this.toString() + "] where " + exclusionBase.toString() + " is excluded.");
        }
    }
    // in the list through subtyping.
    if (!e.getSootClass().isPhantom())
        for (RefLikeType incumbent : exceptionsIncluded) {
            if (incumbent instanceof AnySubType) {
                // Need to use incumbent.getBase() because
                // hierarchy.canStoreType() assumes that parent
                // is not an AnySubType.
                RefType incumbentBase = ((AnySubType) incumbent).getBase();
                if (hierarchy.canStoreType(e, incumbentBase)) {
                    addToMemoizedAdds(e, this);
                    return this;
                }
            } else if (!(incumbent instanceof RefType)) {
                // assertion failure.
                throw new IllegalStateException("ThrowableSet.add(RefType): Set element " + incumbent.toString() + " is neither a RefType nor an AnySubType.");
            }
        }
    Set<RefLikeType> resultSet = new HashSet<RefLikeType>(this.exceptionsIncluded);
    resultSet.add(e);
    result = Manager.v().registerSetIfNew(resultSet, this.exceptionsExcluded);
    addToMemoizedAdds(e, result);
    return result;
}
Also used : RefType(soot.RefType) RefLikeType(soot.RefLikeType) FastHierarchy(soot.FastHierarchy) AnySubType(soot.AnySubType) HashSet(java.util.HashSet)

Example 5 with AnySubType

use of soot.AnySubType in project soot by Sable.

the class ThrowableSet method whichCatchableAs.

/**
 * Partitions the exceptions in this <code>ThrowableSet</code> into those
 * which would be caught by a handler with the passed <code>catch</code>
 * parameter type and those which would not.
 *
 * @param catcher
 *            type of the handler parameter to be tested.
 *
 * @return a pair of <code>ThrowableSet</code>s, one containing the types in
 *         this <code>ThrowableSet</code> which would be be caught as
 *         <code>catcher</code> and the other containing the types in this
 *         <code>ThrowableSet</code> which would not be caught as
 *         <code>catcher</code>.
 */
public Pair whichCatchableAs(RefType catcher) {
    if (INSTRUMENTING) {
        Manager.v().removesOfAnySubType++;
    }
    FastHierarchy h = Scene.v().getOrMakeFastHierarchy();
    Set<RefLikeType> caughtIncluded = null;
    Set<AnySubType> caughtExcluded = null;
    Set<RefLikeType> uncaughtIncluded = null;
    Set<AnySubType> uncaughtExcluded = null;
    if (INSTRUMENTING) {
        Manager.v().removesFromSearch++;
    }
    for (AnySubType exclusion : exceptionsExcluded) {
        RefType exclusionBase = exclusion.getBase();
        // Is the current type explicitly excluded?
        if (catcher.getSootClass().isPhantom() && exclusionBase.equals(catcher))
            return new Pair(ThrowableSet.Manager.v().EMPTY, this);
        if (h.canStoreType(catcher, exclusionBase)) {
            // caught by catcher.
            return new Pair(ThrowableSet.Manager.v().EMPTY, this);
        } else if (h.canStoreType(exclusionBase, catcher)) {
            // exclusion wouldn't be in exceptionsExcluded if one
            // of its supertypes were not in exceptionsIncluded,
            // so we know the next loop will add either that supertype
            // or catcher to caughtIncluded. Thus:
            caughtExcluded = addExceptionToSet(exclusion, caughtExcluded);
        } else {
            uncaughtExcluded = addExceptionToSet(exclusion, uncaughtExcluded);
        }
    }
    for (RefLikeType inclusion : exceptionsIncluded) {
        if (inclusion instanceof RefType) {
            // only if it is in the inclusion list and ignore any hierarchy.
            if (catcher.getSootClass().isPhantom()) {
                if (inclusion.equals(catcher))
                    caughtIncluded = addExceptionToSet(inclusion, caughtIncluded);
                else
                    uncaughtIncluded = addExceptionToSet(inclusion, uncaughtIncluded);
            } else if (h.canStoreType(inclusion, catcher)) {
                caughtIncluded = addExceptionToSet(inclusion, caughtIncluded);
            } else {
                uncaughtIncluded = addExceptionToSet(inclusion, uncaughtIncluded);
            }
        } else {
            RefType base = ((AnySubType) inclusion).getBase();
            // only if it is in the inclusion list and ignore any hierarchy.
            if (catcher.getSootClass().isPhantom()) {
                if (base.equals(catcher))
                    caughtIncluded = addExceptionToSet(inclusion, caughtIncluded);
                else {
                    if (base.getClassName().equals("java.lang.Throwable"))
                        caughtIncluded = addExceptionToSet(catcher, caughtIncluded);
                    uncaughtIncluded = addExceptionToSet(inclusion, uncaughtIncluded);
                }
            } else if (h.canStoreType(base, catcher)) {
                // All subtypes of base will be caught. Any exclusions
                // will already have been copied to caughtExcluded by
                // the preceding loop.
                caughtIncluded = addExceptionToSet(inclusion, caughtIncluded);
            } else if (h.canStoreType(catcher, base)) {
                // Some subtypes of base will be caught, and
                // we know that not all of those catchable subtypes
                // are among exceptionsExcluded, since in that case we
                // would already have returned from within the
                // preceding loop. So, remove AnySubType(catcher)
                // from the uncaught types.
                uncaughtIncluded = addExceptionToSet(inclusion, uncaughtIncluded);
                uncaughtExcluded = addExceptionToSet(AnySubType.v(catcher), uncaughtExcluded);
                caughtIncluded = addExceptionToSet(AnySubType.v(catcher), caughtIncluded);
            // Any already excluded subtypes of inclusion
            // which are subtypes of catcher will have been
            // added to caughtExcluded by the previous loop.
            } else {
                uncaughtIncluded = addExceptionToSet(inclusion, uncaughtIncluded);
            }
        }
    }
    ThrowableSet caughtSet = Manager.v().registerSetIfNew(caughtIncluded, caughtExcluded);
    ThrowableSet uncaughtSet = Manager.v().registerSetIfNew(uncaughtIncluded, uncaughtExcluded);
    return new Pair(caughtSet, uncaughtSet);
}
Also used : RefLikeType(soot.RefLikeType) RefType(soot.RefType) FastHierarchy(soot.FastHierarchy) AnySubType(soot.AnySubType)

Aggregations

AnySubType (soot.AnySubType)11 RefType (soot.RefType)10 RefLikeType (soot.RefLikeType)9 ArrayType (soot.ArrayType)5 FastHierarchy (soot.FastHierarchy)5 HashSet (java.util.HashSet)4 Type (soot.Type)4 AllocNode (soot.jimple.spark.pag.AllocNode)4 Iterator (java.util.Iterator)2 NullType (soot.NullType)2 SootClass (soot.SootClass)2 SootMethod (soot.SootMethod)2 Node (soot.jimple.spark.pag.Node)2 BitVector (soot.util.BitVector)2 Set (java.util.Set)1 Test (org.junit.Test)1 Local (soot.Local)1 ArrayRef (soot.jimple.ArrayRef)1 IfStmt (soot.jimple.IfStmt)1 Stmt (soot.jimple.Stmt)1