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)));
}
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;
}
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;
}
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("Permission denied");
* </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;
}
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);
}
Aggregations