Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /* Soot - a J*va Optimization Framework
   * Copyright (C) 2004 Jennifer Lhotak
   *
   * 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.base;
 
 import soot.*;
 import soot.jimple.*;
 import soot.util.*;
 import java.util.*;
 import soot.tagkit.*;
 
 public class ExceptionChecker extends BodyTransformer{
 
 
         this. = r;
     }
 
     protected void internalTransform(Body bString phaseNameMap options){
 
         Iterator it = b.getUnits().iterator();
         while (it.hasNext()){
             Stmt s = (Stmt)it.next();
             if (s instanceof ThrowStmt){
                 ThrowStmt ts = (ThrowStmt)s;
                 checkThrow(bts);
             }
             else if (s instanceof InvokeStmt){
                 InvokeStmt is = (InvokeStmt)s;
                 checkInvoke(bis);
             }
             else if ((s instanceof AssignStmt) && (((AssignStmt)s).getRightOp() instanceof InvokeExpr)){
                 InvokeExpr ie = (InvokeExpr)((AssignStmt)s).getRightOp();
                 checkInvokeExpr(bies);
             }
         }
     }
 
     protected void checkThrow(Body bThrowStmt ts){
         if (isThrowDeclared(b, ((RefType)ts.getOp().getType()).getSootClass()) || isThrowFromCompiler(ts) || isExceptionCaught(bts, (RefType)ts.getOp().getType())) return;
         if ( != null){
             .reportError(new ExceptionCheckerError(b.getMethod(), ((RefType)ts.getOp().getType()).getSootClass(), ts, (SourceLnPosTag)ts.getOpBox().getTag("SourceLnPosTag")));
         }
     }
 
     // does the method declare the throw if its a throw that needs declaring
     // RuntimeException and subclasses do not need to be declared
     // Error and subclasses do not need to be declared
     protected boolean isThrowDeclared(Body bSootClass throwClass){
         if ( == null){
              = new FastHierarchy();
         }
 
         // handles case when exception is RuntimeException or Error
         if (throwClass.equals(Scene.v().getSootClass("java.lang.RuntimeException")) || throwClass.equals(Scene.v().getSootClass("java.lang.Error"))) return true;
         // handles case when exception is a subclass of RuntimeException or Error
         if (.isSubclass(throwClass, Scene.v().getSootClass("java.lang.RuntimeException")) || .isSubclass(throwClass, Scene.v().getSootClass("java.lang.Error"))) return true;
 
         // handles case when exact exception is thrown
         if (b.getMethod().throwsException(throwClass)) return true;
 
         // handles case when a super type of the exception is thrown
         Iterator<SootClassit = b.getMethod().getExceptions().iterator();
         while (it.hasNext()){
             SootClass nextEx = it.next();
             if (.isSubclass(throwClassnextEx)) return true;
         }
         return false;
     }
 
     // is the throw created by the compiler
     protected boolean isThrowFromCompiler(ThrowStmt ts){
         if (ts.hasTag("ThrowCreatedByCompilerTag")) return true;
         return false;
     }
 
     // is the throw caught inside the method
     protected boolean isExceptionCaught(Body bStmt sRefType throwType){
         if ( == null){
              = new FastHierarchy();
         }
        Iterator it = b.getTraps().iterator();
        while (it.hasNext()){
            Trap trap = (Trap)it.next();
            if (trap.getException().getType().equals(throwType) || .isSubclass(throwType.getSootClass(), (trap.getException().getType()).getSootClass())){
                if (isThrowInStmtRange(b, (Stmt)trap.getBeginUnit(), (Stmt)trap.getEndUnit(), s)) return true;
            }
        }
        return false;
    }
    protected boolean isThrowInStmtRange(Body bStmt beginStmt endStmt s){
        Iterator it = b.getUnits().iterator(beginend);
        while (it.hasNext()){
            if (it.next().equals(s)) return true;
        }
        return false;
    }
    protected void checkInvoke(Body bInvokeStmt is){
        checkInvokeExpr(bis.getInvokeExpr(), is);
    }
    // Given a method signature, see if it is declared in the given interface.
    // If so, return the exceptions thrown by the declaration. Otherwise,
    // Do the same thing recursively on superinterfaces and Object
    // and return the intersection. This gives
    // the maximal set of exceptions that could be declared to be thrown if the
    // interface had declared the method. Returns null if no supertype declares
    // the method.
    private List<SootClassgetExceptionSpec(SootClass intrface,NumberedString sig) {
        if(intrface.declaresMethod(sig)) return intrface.getMethod(sig).getExceptions();
        List<SootClassresult=null;
        SootClass obj=Scene.v().getSootClass("java.lang.Object");
        if(obj.declaresMethod(sig)) result=new Vector<SootClass>(obj.getMethod(sig).getExceptions());
        Iterator intrfacesit=intrface.getInterfaces().iterator();
        while(intrfacesit.hasNext()) {
            SootClass suprintr=(SootClassintrfacesit.next();
            List<SootClassother=getExceptionSpec(suprintr,sig);
            if(other!=null)
                if(result==nullresult=other;
                else result.retainAll(other);
        }
        return result;
    }
    protected void checkInvokeExpr(Body bInvokeExpr ieStmt s){
        if(ie instanceof InstanceInvokeExpr &&
           ((InstanceInvokeExprie).getBase().getType() instanceof ArrayType &&
           ie.getMethodRef().name().equals("clone") &&
           ie.getMethodRef().parameterTypes().size()==0)
            return;  // the call is to the clone() method of an array type, which
                     // 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
            // For an invokeinterface, there is no unique resolution for the
            // method reference that will get the "correct" exception spec. We
            // actually need to look at the intersection of all declarations of
            // the method in supertypes.
            ? getExceptionSpec(ie.getMethodRef().declaringClass(),
                               ie.getMethodRef().getSubSignature())
            // Otherwise, we just do normal resolution.
            : ie.getMethod().getExceptions();
        Iterator it = exceptions.iterator();
        while (it.hasNext()){
            SootClass sc = (SootClass)it.next();
            if (isThrowDeclared(bsc) || isExceptionCaught(bssc.getType())) continue;
            if ( != null){
                if (s instanceof InvokeStmt){
                    .reportError(new ExceptionCheckerError(b.getMethod(), scs, (SourceLnPosTag)s.getTag("SourceLnPosTag")));
                }
                else if (s instanceof AssignStmt){
                    .reportError(new ExceptionCheckerError(b.getMethod(), scs, (SourceLnPosTag)((AssignStmt)s).getRightOpBox().getTag("SourceLnPosTag")));
                }
            }
        }
    }
New to GrepCode? Check out our FAQ X