use of soot.SootClass in project soot by Sable.
the class DexPrinter method buildMethodAnnotations.
private Set<Annotation> buildMethodAnnotations(SootMethod m) {
Set<String> skipList = new HashSet<String>();
Set<Annotation> annotations = buildCommonAnnotations(m, skipList);
for (Tag t : m.getTags()) {
if (t.getName().equals("VisibilityAnnotationTag")) {
List<ImmutableAnnotation> visibilityItems = buildVisibilityAnnotationTag((VisibilityAnnotationTag) t, skipList);
annotations.addAll(visibilityItems);
}
}
List<SootClass> exceptionList = m.getExceptionsUnsafe();
if (exceptionList != null && !exceptionList.isEmpty()) {
List<ImmutableEncodedValue> valueList = new ArrayList<ImmutableEncodedValue>(exceptionList.size());
for (SootClass exceptionClass : exceptionList) {
valueList.add(new ImmutableTypeEncodedValue(DexType.toDalvikICAT(exceptionClass.getName()).replace(".", "/")));
}
ImmutableArrayEncodedValue valueValue = new ImmutableArrayEncodedValue(valueList);
ImmutableAnnotationElement valueElement = new ImmutableAnnotationElement("value", valueValue);
Set<ImmutableAnnotationElement> elements = Collections.singleton(valueElement);
ImmutableAnnotation ann = new ImmutableAnnotation(AnnotationVisibility.SYSTEM, "Ldalvik/annotation/Throws;", elements);
annotations.add(ann);
}
return annotations;
}
use of soot.SootClass in project soot by Sable.
the class OutFlow method jimplify.
/**
* Main.v() entry point for converting list of Instructions to Jimple statements;
* performs flow analysis, constructs Jimple statements, and fixes jumps.
* @param constant_pool constant pool of ClassFile.
* @param this_class constant pool index of the CONSTANT_Class_info object for
* this' class.
* @param clearStacks if <i>true</i> semantic stacks will be deleted after
* the process is complete.
* @return <i>true</i> if all ok, <i>false</i> if there was an error.
* @see CFG#jimplify(cp_info[], int)
* @see Stmt
*/
void jimplify(cp_info[] constant_pool, int this_class) {
Code_attribute codeAttribute = method.locate_code_attribute();
Set<Instruction> handlerInstructions = new ArraySet<Instruction>();
Map<Instruction, SootClass> handlerInstructionToException = new HashMap<Instruction, SootClass>();
Map<Instruction, TypeStack> instructionToTypeStack;
Map<Instruction, TypeStack> instructionToPostTypeStack;
{
// build graph in
buildInsnCFGfromBBCFG();
// Put in successors due to exception handlers
{
for (int i = 0; i < codeAttribute.exception_table_length; i++) {
Instruction startIns = codeAttribute.exception_table[i].start_inst;
Instruction endIns = codeAttribute.exception_table[i].end_inst;
Instruction handlerIns = codeAttribute.exception_table[i].handler_inst;
handlerInstructions.add(handlerIns);
// Determine exception to catch
{
int catchType = codeAttribute.exception_table[i].catch_type;
SootClass exception;
if (catchType != 0) {
CONSTANT_Class_info classinfo = (CONSTANT_Class_info) constant_pool[catchType];
String name = ((CONSTANT_Utf8_info) (constant_pool[classinfo.name_index])).convert();
name = name.replace('/', '.');
exception = cm.getSootClass(name);
} else
exception = cm.getSootClass("java.lang.Throwable");
handlerInstructionToException.put(handlerIns, exception);
}
if (startIns == endIns)
throw new RuntimeException("Empty catch range for exception handler");
Instruction ins = startIns;
for (; ; ) {
Instruction[] succs = ins.succs;
Instruction[] newsuccs = new Instruction[succs.length + 1];
System.arraycopy(succs, 0, newsuccs, 0, succs.length);
newsuccs[succs.length] = handlerIns;
ins.succs = newsuccs;
ins = ins.next;
if (ins == endIns || ins == null)
break;
}
}
}
}
Set<Instruction> reachableInstructions = new HashSet<Instruction>();
// Mark all the reachable instructions
{
LinkedList<Instruction> instructionsToVisit = new LinkedList<Instruction>();
reachableInstructions.add(firstInstruction);
instructionsToVisit.addLast(firstInstruction);
while (!instructionsToVisit.isEmpty()) {
Instruction ins = instructionsToVisit.removeFirst();
Instruction[] succs = ins.succs;
for (Instruction succ : succs) {
if (!reachableInstructions.contains(succ)) {
reachableInstructions.add(succ);
instructionsToVisit.addLast(succ);
}
}
}
}
/*
// Check to see if any instruction is unmarked.
{
BasicBlock b = cfg;
while(b != null)
{
Instruction ins = b.head;
while(ins != null)
{
if(!reachableInstructions.contains(ins))
throw new RuntimeException("Method to jimplify contains unreachable code! (not handled for now)");
ins = ins.next;
}
b = b.next;
}
}
*/
// Perform the flow analysis, and build up instructionToTypeStack and instructionToLocalArray
{
instructionToTypeStack = new HashMap<Instruction, TypeStack>();
instructionToPostTypeStack = new HashMap<Instruction, TypeStack>();
Set<Instruction> visitedInstructions = new HashSet<Instruction>();
List<Instruction> changedInstructions = new ArrayList<Instruction>();
TypeStack initialTypeStack;
// Build up initial type stack and initial local array (for the first instruction)
{
initialTypeStack = TypeStack.v();
// the empty stack with nothing on it.
}
// Get the loop cranked up.
{
instructionToTypeStack.put(firstInstruction, initialTypeStack);
visitedInstructions.add(firstInstruction);
changedInstructions.add(firstInstruction);
}
{
while (!changedInstructions.isEmpty()) {
Instruction ins = changedInstructions.get(0);
changedInstructions.remove(0);
OutFlow ret = processFlow(ins, instructionToTypeStack.get(ins), constant_pool);
instructionToPostTypeStack.put(ins, ret.typeStack);
Instruction[] successors = ins.succs;
for (Instruction s : successors) {
if (!visitedInstructions.contains(s)) {
if (handlerInstructions.contains(s)) {
TypeStack exceptionTypeStack = (TypeStack.v()).push(RefType.v(handlerInstructionToException.get(s).getName()));
instructionToTypeStack.put(s, exceptionTypeStack);
} else {
instructionToTypeStack.put(s, ret.typeStack);
}
visitedInstructions.add(s);
changedInstructions.add(s);
// logger.debug("adding successor: " + s);
} else {
// logger.debug("considering successor: " + s);
TypeStack newTypeStack, oldTypeStack = instructionToTypeStack.get(s);
if (handlerInstructions.contains(s)) {
// The type stack for an instruction handler should always be that of
// single object on the stack.
TypeStack exceptionTypeStack = (TypeStack.v()).push(RefType.v(handlerInstructionToException.get(s).getName()));
newTypeStack = exceptionTypeStack;
} else {
try {
newTypeStack = ret.typeStack.merge(oldTypeStack);
} catch (RuntimeException re) {
logger.debug("Considering " + s);
throw re;
}
}
if (!newTypeStack.equals(oldTypeStack)) {
changedInstructions.add(s);
// logger.debug("requires a revisit: " + s);
}
instructionToTypeStack.put(s, newTypeStack);
}
}
}
}
}
// logger.debug("Producing Jimple code...");
// Jimplify each statement
{
BasicBlock b = cfg;
while (b != null) {
Instruction ins = b.head;
b.statements = new ArrayList<Stmt>();
List<Stmt> blockStatements = b.statements;
for (; ; ) {
List<Stmt> statementsForIns = new ArrayList<Stmt>();
if (reachableInstructions.contains(ins))
generateJimple(ins, instructionToTypeStack.get(ins), instructionToPostTypeStack.get(ins), constant_pool, statementsForIns, b);
else
statementsForIns.add(Jimple.v().newNopStmt());
if (!statementsForIns.isEmpty()) {
for (int i = 0; i < statementsForIns.size(); i++) {
units.add(statementsForIns.get(i));
blockStatements.add(statementsForIns.get(i));
}
instructionToFirstStmt.put(ins, statementsForIns.get(0));
instructionToLastStmt.put(ins, statementsForIns.get(statementsForIns.size() - 1));
}
if (ins == b.tail)
break;
ins = ins.next;
}
b = b.next;
}
}
// fix up jump targets
jimpleTargetFixup();
/*
// Print out basic blocks
{
BasicBlock b = cfg;
logger.debug("Basic blocks for: " + jmethod.getName());
while(b != null)
{
Instruction ins = b.head;
while(ins != null)
{
logger.debug(""+ins.toString());
ins = ins.next;
}
b = b.next;
}
}
*/
// Insert beginCatch/endCatch statements for exception handling
{
Map<Stmt, Stmt> targetToHandler = new HashMap<Stmt, Stmt>();
for (int i = 0; i < codeAttribute.exception_table_length; i++) {
Instruction startIns = codeAttribute.exception_table[i].start_inst;
Instruction endIns = codeAttribute.exception_table[i].end_inst;
Instruction targetIns = codeAttribute.exception_table[i].handler_inst;
if (!instructionToFirstStmt.containsKey(startIns) || (endIns != null && (!instructionToLastStmt.containsKey(endIns)))) {
throw new RuntimeException("Exception range does not coincide with jimple instructions");
}
if (!instructionToFirstStmt.containsKey(targetIns)) {
throw new RuntimeException("Exception handler does not coincide with jimple instruction");
}
SootClass exception;
// Determine exception to catch
{
int catchType = codeAttribute.exception_table[i].catch_type;
if (catchType != 0) {
CONSTANT_Class_info classinfo = (CONSTANT_Class_info) constant_pool[catchType];
String name = ((CONSTANT_Utf8_info) (constant_pool[classinfo.name_index])).convert();
name = name.replace('/', '.');
exception = cm.getSootClass(name);
} else
exception = cm.getSootClass("java.lang.Throwable");
}
Stmt newTarget;
// Insert assignment of exception
{
Stmt firstTargetStmt = instructionToFirstStmt.get(targetIns);
if (targetToHandler.containsKey(firstTargetStmt))
newTarget = targetToHandler.get(firstTargetStmt);
else {
Local local = Util.v().getLocalCreatingIfNecessary(listBody, "$stack0", UnknownType.v());
newTarget = Jimple.v().newIdentityStmt(local, Jimple.v().newCaughtExceptionRef());
// changed to account for catch blocks which are also part of normal control flow
// units.insertBefore(newTarget, firstTargetStmt);
((PatchingChain<Unit>) units).insertBeforeNoRedirect(newTarget, firstTargetStmt);
targetToHandler.put(firstTargetStmt, newTarget);
if (units.getFirst() != newTarget) {
Unit prev = (Unit) units.getPredOf(newTarget);
if (prev != null && prev.fallsThrough())
units.insertAfter(Jimple.v().newGotoStmt(firstTargetStmt), prev);
}
}
}
// Insert trap
{
Stmt firstStmt = instructionToFirstStmt.get(startIns);
Stmt afterEndStmt;
if (endIns == null) {
// A kludge which isn't really correct, but
// gets us closer to correctness (until we
// clean up the rest of Soot to properly
// represent Traps which extend to the end
// of a method): if the protected code extends
// to the end of the method, use the last Stmt
// as the endUnit of the Trap, even though
// that will leave the last unit outside
// the protected area.
afterEndStmt = (Stmt) units.getLast();
} else {
afterEndStmt = instructionToLastStmt.get(endIns);
IdentityStmt catchStart = (IdentityStmt) targetToHandler.get(afterEndStmt);
// (Cast to IdentityStmt as an assertion check.)
if (catchStart != null) {
// before the old afterEndStmt.
if (catchStart != units.getPredOf(afterEndStmt)) {
throw new IllegalStateException("Assertion failure: catchStart != pred of afterEndStmt");
}
afterEndStmt = catchStart;
}
}
Trap trap = Jimple.v().newTrap(exception, firstStmt, afterEndStmt, newTarget);
listBody.getTraps().add(trap);
}
}
}
/* convert line number table to tags attached to statements */
if (Options.v().keep_line_number()) {
HashMap<Stmt, Tag> stmtstags = new HashMap<Stmt, Tag>();
LinkedList<Stmt> startstmts = new LinkedList<Stmt>();
attribute_info[] attrs = codeAttribute.attributes;
for (attribute_info element : attrs) {
if (element instanceof LineNumberTable_attribute) {
LineNumberTable_attribute lntattr = (LineNumberTable_attribute) element;
for (line_number_table_entry element0 : lntattr.line_number_table) {
Stmt start_stmt = instructionToFirstStmt.get(element0.start_inst);
if (start_stmt != null) {
LineNumberTag lntag = new LineNumberTag(element0.line_number);
stmtstags.put(start_stmt, lntag);
startstmts.add(start_stmt);
}
}
}
}
/* if the predecessor of a statement is a caughtexcetionref,
* give it the tag of its successor */
for (Iterator<Stmt> stmtIt = new ArrayList<Stmt>(stmtstags.keySet()).iterator(); stmtIt.hasNext(); ) {
final Stmt stmt = stmtIt.next();
Stmt pred = stmt;
Tag tag = stmtstags.get(stmt);
while (true) {
pred = (Stmt) units.getPredOf(pred);
if (pred == null)
break;
if (!(pred instanceof IdentityStmt))
break;
stmtstags.put(pred, tag);
pred.addTag(tag);
}
}
/* attach line number tag to each statement. */
for (int i = 0; i < startstmts.size(); i++) {
Stmt stmt = startstmts.get(i);
Tag tag = stmtstags.get(stmt);
stmt.addTag(tag);
stmt = (Stmt) units.getSuccOf(stmt);
while (stmt != null && !stmtstags.containsKey(stmt)) {
stmt.addTag(tag);
stmt = (Stmt) units.getSuccOf(stmt);
}
}
}
}
use of soot.SootClass in project soot by Sable.
the class DavaPrinter method printTo.
public void printTo(SootClass cl, PrintWriter out) {
// IterableSet packagesUsed = new IterableSet();
IterableSet importList = new IterableSet();
{
String curPackage = cl.getJavaPackageName();
if (!curPackage.equals("")) {
out.println("package " + curPackage + ";");
out.println();
}
if (cl.hasSuperclass()) {
SootClass superClass = cl.getSuperclass();
importList.add(superClass.toString());
// packagesUsed.add(superClass.getJavaPackageName());
}
Iterator<SootClass> interfaceIt = cl.getInterfaces().iterator();
while (interfaceIt.hasNext()) {
String interfacePackage = ((SootClass) interfaceIt.next()).toString();
if (!importList.contains(interfacePackage))
importList.add(interfacePackage);
// if (!packagesUsed.contains(interfacePackage))
// packagesUsed.add(interfacePackage);
}
Iterator<SootMethod> methodIt = cl.methodIterator();
while (methodIt.hasNext()) {
SootMethod dm = (SootMethod) methodIt.next();
if (dm.hasActiveBody()) {
// packagesUsed = packagesUsed.union(((DavaBody) dm.getActiveBody()).get_PackagesUsed());
importList = importList.union(((DavaBody) dm.getActiveBody()).getImportList());
}
Iterator<SootClass> eit = dm.getExceptions().iterator();
while (eit.hasNext()) {
String thrownPackage = eit.next().toString();
if (!importList.contains(thrownPackage))
importList.add(thrownPackage);
// if (!packagesUsed.contains(thrownPackage))
// packagesUsed.add(thrownPackage);
}
Iterator<Type> pit = dm.getParameterTypes().iterator();
while (pit.hasNext()) {
Type t = (Type) pit.next();
if (t instanceof RefType) {
String paramPackage = ((RefType) t).getSootClass().toString();
if (!importList.contains(paramPackage))
importList.add(paramPackage);
// if (packagesUsed.contains(paramPackage) == false)
// packagesUsed.add(paramPackage);
}
}
Type t = dm.getReturnType();
if (t instanceof RefType) {
String returnPackage = ((RefType) t).getSootClass().toString();
if (!importList.contains(returnPackage))
importList.add(returnPackage);
// if (packagesUsed.contains(returnPackage) == false)
// packagesUsed.add(returnPackage);
}
}
Iterator<SootField> fieldIt = cl.getFields().iterator();
while (fieldIt.hasNext()) {
SootField f = (SootField) fieldIt.next();
if (f.isPhantom())
continue;
Type t = f.getType();
if (t instanceof RefType) {
String fieldPackage = ((RefType) t).getSootClass().toString();
if (!importList.contains(fieldPackage))
importList.add(fieldPackage);
}
}
Iterator<String> pit = importList.iterator();
List<String> toImport = new ArrayList<String>();
while (pit.hasNext()) {
/*
* dont import any file which has currentPackage.className
* dont import any file which starts with java.lang
*/
String temp = (String) pit.next();
// System.out.println("temp is "+temp);
if (temp.indexOf("java.lang") > -1) {
// problem is that we need to import sub packages java.lang.ref
// for instance if the type is java.lang.ref.WeakReference
String tempClassName = RemoveFullyQualifiedName.getClassName(temp);
if (temp.equals("java.lang." + tempClassName)) {
// System.out.println("temp was not printed as it belongs to java.lang");
continue;
}
}
if (curPackage.length() > 0 && temp.indexOf(curPackage) > -1) {
// System.out.println("here "+temp);
continue;
}
if (cl.toString().equals(temp))
continue;
// System.out.println("printing"+);
toImport.add(temp);
}
/*
* Check that we are not importing two classes with the same last name
* If yes then remove explicit import and import the whole package
* else output explicit import statement
*/
Iterator it = toImport.iterator();
while (it.hasNext()) {
String temp = (String) it.next();
if (RemoveFullyQualifiedName.containsMultiple(toImport.iterator(), temp, null)) {
// import package add *
if (temp.lastIndexOf('.') > -1) {
temp = temp.substring(0, temp.lastIndexOf('.'));
out.println("import " + temp + ".*;");
} else
throw new DecompilationException("Cant find the DOT . for fullyqualified name");
} else {
if (temp.lastIndexOf('.') == -1) {
// dot not found this is a class belonging to this package so dont add
} else
out.println("import " + temp + ";");
}
}
boolean addNewLine = false;
addNewLine = true;
if (addNewLine)
out.println();
/*if (!packagesUsed.isEmpty())
out.println();
packagesUsed.add("java.lang");
packagesUsed.add(curPackage);
*/
Dava.v().set_CurrentPackageContext(importList);
// Dava.v().set_CurrentPackageContext(packagesUsed);
Dava.v().set_CurrentPackage(curPackage);
}
// Print class name + modifiers
{
String classPrefix = "";
classPrefix = classPrefix + " " + Modifier.toString(cl.getModifiers());
classPrefix = classPrefix.trim();
if (!cl.isInterface()) {
classPrefix = classPrefix + " class";
classPrefix = classPrefix.trim();
}
out.print(classPrefix + " " + cl.getShortJavaStyleName());
}
// Print extension
if (cl.hasSuperclass() && !(cl.getSuperclass().getName().equals("java.lang.Object"))) {
String superClassName = cl.getSuperclass().getName();
// Nomair Naeem 8th Feb 2006
// also check if the super class name is not a fully qualified
// name. in which case if the package is imported no need for
// the long name
superClassName = RemoveFullyQualifiedName.getReducedName(importList, superClassName, cl.getType());
out.print(" extends " + superClassName + "");
}
// Print interfaces
{
Iterator<SootClass> interfaceIt = cl.getInterfaces().iterator();
if (interfaceIt.hasNext()) {
if (cl.isInterface())
out.print(" extends ");
else
out.print(" implements ");
out.print("" + (interfaceIt.next()).getName() + "");
while (interfaceIt.hasNext()) out.print(", " + (interfaceIt.next()).getName() + "");
}
}
out.println();
out.println("{");
// Print fields
{
Iterator<SootField> fieldIt = cl.getFields().iterator();
if (fieldIt.hasNext()) {
while (fieldIt.hasNext()) {
SootField f = fieldIt.next();
if (f.isPhantom())
continue;
String declaration = null;
Type fieldType = f.getType();
String qualifiers = Modifier.toString(f.getModifiers()) + " ";
qualifiers += RemoveFullyQualifiedName.getReducedName(importList, fieldType.toString(), fieldType);
qualifiers = qualifiers.trim();
if (qualifiers.equals(""))
declaration = Scene.v().quotedNameOf(f.getName());
else
declaration = qualifiers + " " + Scene.v().quotedNameOf(f.getName()) + "";
if (f.isFinal() && f.isStatic()) {
if (fieldType instanceof DoubleType && f.hasTag("DoubleConstantValueTag")) {
double val = ((DoubleConstantValueTag) f.getTag("DoubleConstantValueTag")).getDoubleValue();
out.println(" " + declaration + " = " + val + ";");
} else if (fieldType instanceof FloatType && f.hasTag("FloatConstantValueTag")) {
float val = ((FloatConstantValueTag) f.getTag("FloatConstantValueTag")).getFloatValue();
out.println(" " + declaration + " = " + val + "f;");
} else if (fieldType instanceof LongType && f.hasTag("LongConstantValueTag")) {
long val = ((LongConstantValueTag) f.getTag("LongConstantValueTag")).getLongValue();
out.println(" " + declaration + " = " + val + "l;");
} else if (fieldType instanceof CharType && f.hasTag("IntegerConstantValueTag")) {
int val = ((IntegerConstantValueTag) f.getTag("IntegerConstantValueTag")).getIntValue();
out.println(" " + declaration + " = '" + ((char) val) + "';");
} else if (fieldType instanceof BooleanType && f.hasTag("IntegerConstantValueTag")) {
int val = ((IntegerConstantValueTag) f.getTag("IntegerConstantValueTag")).getIntValue();
if (val == 0)
out.println(" " + declaration + " = false;");
else
out.println(" " + declaration + " = true;");
} else if ((fieldType instanceof IntType || fieldType instanceof ByteType || fieldType instanceof ShortType) && f.hasTag("IntegerConstantValueTag")) {
int val = ((IntegerConstantValueTag) f.getTag("IntegerConstantValueTag")).getIntValue();
out.println(" " + declaration + " = " + val + ";");
} else if (f.hasTag("StringConstantValueTag")) {
String val = ((StringConstantValueTag) f.getTag("StringConstantValueTag")).getStringValue();
out.println(" " + declaration + " = \"" + val + "\";");
} else {
// System.out.println("Couldnt find type of
// field"+f.getDeclaration());
out.println(" " + declaration + ";");
}
} else // field is static final
{
out.println(" " + declaration + ";");
}
}
}
}
// Print methods
{
Iterator<SootMethod> methodIt = cl.methodIterator();
if (methodIt.hasNext()) {
if (cl.getMethodCount() != 0)
out.println();
while (methodIt.hasNext()) {
SootMethod method = (SootMethod) methodIt.next();
if (method.isPhantom())
continue;
if (!Modifier.isAbstract(method.getModifiers()) && !Modifier.isNative(method.getModifiers())) {
if (!method.hasActiveBody())
throw new RuntimeException("method " + method.getName() + " has no active body!");
else
printTo(method.getActiveBody(), out);
if (methodIt.hasNext())
out.println();
} else {
// if method is abstract then print the declaration
out.print(" ");
out.print(method.getDavaDeclaration());
out.println(";");
if (methodIt.hasNext())
out.println();
}
}
}
}
if (G.v().SootClassNeedsDavaSuperHandlerClass.contains(cl)) {
out.println("\n private static class DavaSuperHandler{");
out.println(" java.util.Vector myVector = new java.util.Vector();");
out.println("\n public Object get(int pos){");
out.println(" return myVector.elementAt(pos);");
out.println(" }");
out.println("\n public void store(Object obj){");
out.println(" myVector.add(obj);");
out.println(" }");
out.println(" }");
}
out.println("}");
}
use of soot.SootClass in project soot by Sable.
the class SootUtil method getAmbiguousMethodByName.
public static SootMethod getAmbiguousMethodByName(String methodName) {
SootClass sc = Scene.v().tryLoadClass(getClassName(methodName), SootClass.SIGNATURES);
SootMethod sm = sc.getMethodByName(getMethodName(methodName));
return sm;
}
use of soot.SootClass in project soot by Sable.
the class ExceptionChecker method checkInvokeExpr.
protected void checkInvokeExpr(Body b, InvokeExpr ie, Stmt s) {
if (ie instanceof InstanceInvokeExpr && ((InstanceInvokeExpr) ie).getBase().getType() instanceof ArrayType && ie.getMethodRef().name().equals("clone") && ie.getMethodRef().parameterTypes().size() == 0)
// the call is to the clone() method of an array type, which
return;
// is defined not to throw any exceptions; if we left this to
// normal resolution we'd get the method in Object which does
// throw CloneNotSupportedException
List exceptions = ie instanceof InterfaceInvokeExpr ? // the method in supertypes.
getExceptionSpec(ie.getMethodRef().declaringClass(), ie.getMethodRef().getSubSignature()) : // Otherwise, we just do normal resolution.
ie.getMethod().getExceptionsUnsafe();
if (exceptions == null)
return;
Iterator it = exceptions.iterator();
while (it.hasNext()) {
SootClass sc = (SootClass) it.next();
if (isThrowDeclared(b, sc) || isExceptionCaught(b, s, sc.getType()))
continue;
if (reporter != null) {
if (s instanceof InvokeStmt) {
reporter.reportError(new ExceptionCheckerError(b.getMethod(), sc, s, (SourceLnPosTag) s.getTag("SourceLnPosTag")));
} else if (s instanceof AssignStmt) {
reporter.reportError(new ExceptionCheckerError(b.getMethod(), sc, s, (SourceLnPosTag) ((AssignStmt) s).getRightOpBox().getTag("SourceLnPosTag")));
}
}
}
}
Aggregations