Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
   /* Soot - a J*va Optimization Framework
    * Copyright (C) 1997-2000 Etienne Gagnon.  All rights reserved.
    *
    * 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.
   */
  
  /*
   * Modified by the Sable Research Group and others 1997-1999.  
   * See the 'credits' file distributed with Soot for the complete list of
   * contributors.  (Soot is distributed at http://www.sable.mcgill.ca/soot)
   */
  
  
  package soot.jimple.toolkits.typing;
  
  import soot.*;
  import soot.jimple.*;
  import java.util.*;
  import java.io.*;
  
  {
    private final ClassHierarchy hierarchy;
    private final boolean fix;  // if true, fix constraint violations
    
    private JimpleBody stmtBody;
  
    public ConstraintChecker(TypeResolver resolverboolean fix)
    {
      this. = fix;
  
       = resolver.hierarchy();
    }
  
    public void check(Stmt stmtJimpleBody stmtBodythrows TypeException
    {
      try
        {
  	this. = stmtBody;
  	stmt.apply(this);
        }
      catch(RuntimeTypeException e)
        {
          StringWriter st = new StringWriter();
          PrintWriter pw = new PrintWriter(st);
  	e.printStackTrace(pw);
  	pw.close();
  	throw new TypeException(st.toString());
        }
    }
  
    private static class RuntimeTypeException extends RuntimeException
    {
      RuntimeTypeException(String message)
      {
        super(message);
      }
    }
  
    static void error(String message)
    {
      throw new RuntimeTypeException(message);
    }
  
    private void handleInvokeExpr(InvokeExpr ieStmt invokestmt)
    {
      if(ie instanceof InterfaceInvokeExpr)
        {
  	
  	SootMethodRef method = invoke.getMethodRef();
  	Value base = invoke.getBase();
  	
  	if(base instanceof Local)
  	  {
  	    Local local = (Localbase;
  	    
  	      {
  		if()
  		  {
  		    invoke.setBase(insertCast(localmethod.declaringClass().getType(), invokestmt));
  		  }
  		else
  		  {
  		    error("Type Error(7): local " + local + " is of incompatible type " +  local.getType());
 		  }
 	      }
 	  }
 	
 	int count = invoke.getArgCount();
 	
 	for(int i = 0; i < counti++)
 	  {
 	    if(invoke.getArg(iinstanceof Local)
 	      {
 		Local local = (Localinvoke.getArg(i);
 
 		  {
 		    if()
 		      {
 			invoke.setArg(iinsertCast(localmethod.parameterType(i), invokestmt));
 		      }
 		    else
 		      {
 			error("Type Error(8)");
 		      }
 		  }
 	      }
 	  }
       }
     else if(ie instanceof SpecialInvokeExpr)
       {
 
 	SootMethodRef method = invoke.getMethodRef();
 	Value base = invoke.getBase();
 
 	if(base instanceof Local)
 	  {
 	    Local local = (Localbase;
 
 	      {
 		if()
 		  {
 		    invoke.setBase(insertCast(localmethod.declaringClass().getType(), invokestmt));
 		  }
 		else
 		  {
 		    error("Type Error(9)");
 		  }
 	      }
 	  }
 
 	int count = invoke.getArgCount();
 
 	for(int i = 0; i < counti++)
 	  {
 	    if(invoke.getArg(iinstanceof Local)
 	      {
 		Local local = (Localinvoke.getArg(i);
 
 		  {
 		    if()
 		      {
 			invoke.setArg(iinsertCast(localmethod.parameterType(i), invokestmt));
 		      }
 		    else
 		      {
 			error("Type Error(10)");
 		      }
 		  }
 	      }
 	  }
       }
     else if(ie instanceof VirtualInvokeExpr)
       {
 
 	SootMethodRef method = invoke.getMethodRef();
 	Value base = invoke.getBase();
 
 	if(base instanceof Local)
 	  {
 	    Local local = (Localbase;
 
 	      {
 		if()
 		  {
 		    invoke.setBase(insertCast(localmethod.declaringClass().getType(), invokestmt));
 		  }
 		else
 		  {
 		    error("Type Error(13)");
 		  }
 	      }
 	  }
 
 	int count = invoke.getArgCount();
 
 	for(int i = 0; i < counti++)
 	  {
 	    if(invoke.getArg(iinstanceof Local)
 	      {
 		Local local = (Localinvoke.getArg(i);
 
 		  {
 		    if()
 		      {
 			invoke.setArg(iinsertCast(localmethod.parameterType(i), invokestmt));
 		      }
 		    else
 		      {
 			error("Type Error(14)");
 		      }
 		  }
 	      }
 	  }
       }
     else if(ie instanceof StaticInvokeExpr)
       {
 
 	SootMethodRef method = invoke.getMethodRef();
 
 	int count = invoke.getArgCount();
 
 	for(int i = 0; i < counti++)
 	  {
 	    if(invoke.getArg(iinstanceof Local)
 	      {
 		Local local = (Localinvoke.getArg(i);
 
 		  {
 		    if()
 		      {
 			invoke.setArg(iinsertCast(localmethod.parameterType(i), invokestmt));
 		      }
 		    else
 		      {
 			error("Type Error(15)");
 		      }
 		  }
 	      }
 	  }
       }
     else
       {
 	throw new RuntimeException("Unhandled invoke expression type: " + ie.getClass());
       }
   }
 
   public void caseBreakpointStmt(BreakpointStmt stmt)
   {
     // Do nothing
   }
 
   public void caseInvokeStmt(InvokeStmt stmt)
   {
     handleInvokeExpr(stmt.getInvokeExpr(), stmt);
   }
 
   public void caseAssignStmt(AssignStmt stmt)
   {
     Value l = stmt.getLeftOp();
     Value r = stmt.getRightOp();
 
     TypeNode left = null;
 
     //******** LEFT ********
 
     if(l instanceof ArrayRef)
       {
 	ArrayRef ref = (ArrayRefl;
 	TypeNode base = .typeNode(((Localref.getBase()).getType());
 
 	if(!base.isArray())
 	  {
 	    error("Type Error(16)");
 	  }
 
 	left = base.element();
 	
 	Value index = ref.getIndex();
 	
 	if(index instanceof Local)
 	  {
 	    if(!.typeNode(((Localindex).getType()).hasAncestorOrSelf(.typeNode(IntType.v())))
 	      {
 		error("Type Error(17)");
 	      }
 	  }
       }
     else if(l instanceof Local)
       {
 	try
 	  {
 	    left = .typeNode(((Locall).getType());
 	  }
 	  {
 	    G.v()..println("untyped local: " + l);
 	    throw e;
 	  }
       }
     else if(l instanceof InstanceFieldRef)
       {
 	
 	TypeNode base = .typeNode(((Localref.getBase()).getType());
 	
 	  {
 	    if()
 	      {
 		ref.setBase(insertCast((Localref.getBase(), ref.getField().getDeclaringClass().getType(), stmt));
 	      }
 	    else
 	      {
 		error("Type Error(18)");
 	      }
 	  }
 
 	left = .typeNode(ref.getField().getType());
       }
     else if(l instanceof StaticFieldRef)
       {
 	left = .typeNode(ref.getField().getType());
       }
     else
       {
 	throw new RuntimeException("Unhandled assignment left hand side type: " + l.getClass());
       }
 
     //******** RIGHT ********
 
     if(r instanceof ArrayRef)
       {
 	ArrayRef ref = (ArrayRefr;
 	TypeNode base = .typeNode(((Localref.getBase()).getType());
 
 	if(!base.isArray())
 	  {
 	    error("Type Error(19): " + base + " is not an array type");
 	  }
 
 	if(base == .)
 	  {
 	    return;
 	  }
 
 	if(!left.hasDescendantOrSelf(base.element()))
 	  {
 	    if()
 	      {
 		Type lefttype = left.type();
 		if(lefttype instanceof ArrayType)
 		  {
 		    ArrayType atype = (ArrayTypelefttype;
 		    ref.setBase(insertCast((Localref.getBase(), ArrayType.v(atype.baseTypeatype.numDimensions + 1), stmt));
 		  }
 		else
 		  {
 		    ref.setBase(insertCast((Localref.getBase(), ArrayType.v(lefttype, 1), stmt));
 		  }
 	      }
 	    else
 	      {
 		error("Type Error(20)");
 	      }
 	  }
 
 	Value index = ref.getIndex();
 	
 	if(index instanceof Local)
 	{
 	  if(!.typeNode(((Localindex).getType()).hasAncestorOrSelf(.typeNode(IntType.v())))
 	    {
 	      error("Type Error(21)");
 	    }
 	}
       }
     else if(r instanceof DoubleConstant)
       {
 	if(!left.hasDescendantOrSelf(.typeNode(DoubleType.v())))
 	  {
 	    error("Type Error(22)");
 	  }
       }
     else if(r instanceof FloatConstant)
       {
 	if(!left.hasDescendantOrSelf(.typeNode(FloatType.v())))
 	  {
 	    error("Type Error(45)");
 	  }
       }
     else if(r instanceof IntConstant)
       {
 	if(!left.hasDescendantOrSelf(.typeNode(IntType.v())))
 	  {
 	    error("Type Error(23)");
 	  }
       }
     else if(r instanceof LongConstant)
       {
 	if(!left.hasDescendantOrSelf(.typeNode(LongType.v())))
 	  {
 	    error("Type Error(24)");
 	  }
       }
     else if(r instanceof NullConstant)
       {
 	if(!left.hasDescendantOrSelf(.typeNode(NullType.v())))
 	  {
 	    error("Type Error(25)");
 	  }
       }
     else if(r instanceof StringConstant)
       {
 	if(!left.hasDescendantOrSelf(.typeNode(RefType.v("java.lang.String"))))
 	  {
 	    error("Type Error(26)");
 	  }
       }
     else if(r instanceof ClassConstant)
       {
 	if(!left.hasDescendantOrSelf(.typeNode(RefType.v("java.lang.Class"))))
 	  {
 	    error("Type Error(27)");
 	  }
       }
     else if(r instanceof BinopExpr)
       {
 	//******** BINOP EXPR ********
 	
 	BinopExpr be = (BinopExprr;
 
 	Value lv = be.getOp1();
 	Value rv = be.getOp2();
 	
 	TypeNode lop;
 	TypeNode rop;
 
 	//******** LEFT ********
 	if(lv instanceof Local)
 	  {
 	    lop = .typeNode(((Locallv).getType());
 	  }
 	else if(lv instanceof DoubleConstant)
 	  {
 	    lop = .typeNode(DoubleType.v());
 	  }
 	else if(lv instanceof FloatConstant)
 	  {
 	    lop = .typeNode(FloatType.v());
 	  }
 	else if(lv instanceof IntConstant)
 	  {
 	    lop = .typeNode(IntType.v());
 	  }
 	else if(lv instanceof LongConstant)
 	  {
 	    lop = .typeNode(LongType.v());
 	  }
 	else if(lv instanceof NullConstant)
 	  {
 	    lop = .typeNode(NullType.v());
 	  }
 	else if(lv instanceof StringConstant)
 	  {
 	    lop = .typeNode(RefType.v("java.lang.String"));
 	  }
 	else if(lv instanceof ClassConstant)
 	  {
 	    lop = .typeNode(RefType.v("java.lang.Class"));
 	  }
 	else
 	  {
 	    throw new RuntimeException("Unhandled binary expression left operand type: " + lv.getClass());
 	  }
 	
 	//******** RIGHT ********
 	if(rv instanceof Local)
 	  {
 	    rop = .typeNode(((Localrv).getType());
 	  }
 	else if(rv instanceof DoubleConstant)
 	  {
 	    rop = .typeNode(DoubleType.v());
 	  }
 	else if(rv instanceof FloatConstant)
 	  {
 	    rop = .typeNode(FloatType.v());
 	  }
 	else if(rv instanceof IntConstant)
 	  {
 	    rop = .typeNode(IntType.v());
 	  }
 	else if(rv instanceof LongConstant)
 	  {
 	    rop = .typeNode(LongType.v());
 	  }
 	else if(rv instanceof NullConstant)
 	  {
 	    rop = .typeNode(NullType.v());
 	  }
 	else if(rv instanceof StringConstant)
 	  {
 	    rop = .typeNode(RefType.v("java.lang.String"));
 	  }
 	else if(rv instanceof ClassConstant)
 	  {
 	    rop = .typeNode(RefType.v("java.lang.Class"));
 	  }
 	else
 	  {
 	    throw new RuntimeException("Unhandled binary expression right operand type: " + rv.getClass());
 	  }
 	
 	if((be instanceof AddExpr) ||
 	   (be instanceof SubExpr) ||
 	   (be instanceof MulExpr) ||
 	   (be instanceof DivExpr) ||
 	   (be instanceof RemExpr) ||
 	   (be instanceof AndExpr) ||
 	   (be instanceof OrExpr) ||
 	   (be instanceof XorExpr))
 	  {
 	    if(!(left.hasDescendantOrSelf(lop) && 
 		 left.hasDescendantOrSelf(rop)))
 	      {
 		error("Type Error(27)");
 	      }
 	  }
 	else if((be instanceof ShlExpr) ||
 		(be instanceof ShrExpr) ||
 		(be instanceof UshrExpr))
 	  {
 	    if(!(left.hasDescendantOrSelf(lop) && 
 		 .typeNode(IntType.v()).hasAncestorOrSelf(rop)))
 	      {
 		error("Type Error(28)");
 	      }
 	  }
 	else if((be instanceof CmpExpr) ||
 		(be instanceof CmpgExpr) ||
 		(be instanceof CmplExpr) ||
 		(be instanceof EqExpr) ||
 		(be instanceof GeExpr) ||
 		(be instanceof GtExpr) ||
 		(be instanceof LeExpr) ||
 		(be instanceof LtExpr) ||
 		(be instanceof NeExpr))
 	  {
 	    try
 	      {
 		lop.lca(rop);
 	      }
 	    catch(TypeException e)
 	      {
 	      }
 
 	    if(!left.hasDescendantOrSelf(.typeNode(IntType.v())))
 	      {
 		error("Type Error(29)");
 	      }
 	  }
 	else
 	  {
 	    throw new RuntimeException("Unhandled binary expression type: " + be.getClass());
 	  }
       }
     else if(r instanceof CastExpr)
       {
 	CastExpr ce = (CastExprr;
 	if(ce.getOp() instanceof Local)
 	{
 	  TypeNode op = .typeNode(((Localce.getOp()).getType());
 
 	  try
 	    {
 	      // we must be careful not to reject primitive type casts (e.g. int to long)
 	      if(cast.isClassOrInterface() || op.isClassOrInterface())
 	        {
 		  cast.lca(op);
 	        }
 	    }
 	  catch(TypeException e)
 	    {
 	      G.v()..println(r + "[" + op + "<->" + cast + "]");
 	      error(e.getMessage());
 	    }
 	}
 
 	if(!left.hasDescendantOrSelf(cast))
 	  {
 	    error("Type Error(30)");
 	  }
       }
     else if(r instanceof InstanceOfExpr)
       {
 	
 	try
 	  {
 	    op.lca(type);
 	  }
 	catch(TypeException e)
 	  {
 	    G.v()..println(r + "[" + op + "<->" + type + "]");
 	    error(e.getMessage());
 	  }
 	
 	if(!left.hasDescendantOrSelf(.typeNode(IntType.v())))
 	  {
 	    error("Type Error(31)");
 	  }
       }
     else if(r instanceof InvokeExpr)
       {
 	InvokeExpr ie = (InvokeExprr;
 
 	handleInvokeExpr(iestmt);
 
 	  {
 	    error("Type Error(32)");
 	  }
       }
     else if(r instanceof NewArrayExpr)
       {
 	NewArrayExpr nae = (NewArrayExprr;
 
 	Type baseType = nae.getBaseType();
 	TypeNode right;
 
 	if(baseType instanceof ArrayType)
 	  {
 	    right = .typeNode(ArrayType.v(((ArrayTypebaseType).
 						      ((ArrayTypebaseType). + 1));
 	  }
 	else
 	  {
 	    right = .typeNode(ArrayType.v(baseType, 1));
 	  }
 
 	if(!left.hasDescendantOrSelf(right))
 	  {
 	    error("Type Error(33)");
 	  }
 
 
 	Value size = nae.getSize();
 	if(size instanceof Local)
 	  {
 	    TypeNode var = .typeNode(((Localsize).getType());
 
 	    if(!var.hasAncestorOrSelf(.typeNode(IntType.v())))
 	      {
 		error("Type Error(34)");
 	      }
 	  }
       }
     else if(r instanceof NewExpr)
       {
 	NewExpr ne = (NewExprr;
 
 	  {
 	    error("Type Error(35)");
 	  }
       }
     else if(r instanceof NewMultiArrayExpr)
       {
 
 	  {
 	    error("Type Error(36)");
 	  }
 
 	for(int i = 0; i < nmae.getSizeCount(); i++)
 	  {
 	    Value size = nmae.getSize(i);
 	    if(size instanceof Local)
 	      {
 		TypeNode var = .typeNode(((Localsize).getType());
 
 		if(!var.hasAncestorOrSelf(.typeNode(IntType.v())))
 		  {
 		    error("Type Error(37)");
 		  }
 	      }
 	  }
       }
     else if(r instanceof LengthExpr)
       {
 	LengthExpr le = (LengthExprr;
 
 	if(!left.hasDescendantOrSelf(.typeNode(IntType.v())))
 	  {
 	    error("Type Error(38)");
 	  }
 
 	if(le.getOp() instanceof Local)
 	  {
 	    if(!.typeNode(((Localle.getOp()).getType()).isArray())
 	      {
 		error("Type Error(39)");
 	      }
 	  }
       }
     else if(r instanceof NegExpr)
       {
 	NegExpr ne = (NegExprr;
 	TypeNode right;
 
 	if(ne.getOp() instanceof Local)
 	  {
 	    right = .typeNode(((Localne.getOp()).getType());
 	  }
 	else if(ne.getOp() instanceof DoubleConstant)
 	  {
 	    right = .typeNode(DoubleType.v());
 	  }
 	else if(ne.getOp() instanceof FloatConstant)
 	  {
 	    right = .typeNode(FloatType.v());
 	  }
 	else if(ne.getOp() instanceof IntConstant)
 	  {
 	    right = .typeNode(IntType.v());
 	  }
 	else if(ne.getOp() instanceof LongConstant)
 	  {
 	    right = .typeNode(LongType.v());
 	  }
 	else
 	  {
 	    throw new RuntimeException("Unhandled neg expression operand type: " + ne.getOp().getClass());
 	  }
 	
 	if(!left.hasDescendantOrSelf(right))
 	  {
 	    error("Type Error(40)");
 	  }
       }
     else if(r instanceof Local)
       {
 	  {
 	    if()
 	      {
 		stmt.setRightOp(insertCast((Localrleft.type(), stmt));
 	      }
 	    else
 	      {
 		error("Type Error(41)");
 	      }
 	  }
       }
     else if(r instanceof InstanceFieldRef)
       {
 
 	TypeNode baseType = .typeNode(((Localref.getBase()).getType());
 	  {
 	    if()
 	      {
 		ref.setBase(insertCast((Localref.getBase(), ref.getField().getDeclaringClass().getType(), stmt));
 	      }
 	    else
 	      {
 		error("Type Error(42)");
 	      }	    
 	  }
 	
 	  {
 	    error("Type Error(43)");
 	  }
       }
     else if(r instanceof StaticFieldRef)
       {
 
 	  {
 	    error("Type Error(44)");
 	  }
       }
     else
       {
 	throw new RuntimeException("Unhandled assignment right hand side type: " + r.getClass());
       }
   }
 
   public void caseIdentityStmt(IdentityStmt stmt)
   {
     TypeNode left = .typeNode(((Localstmt.getLeftOp()).getType());
 
     Value r = stmt.getRightOp();
 
     if(!(r instanceof CaughtExceptionRef))
       {
 	if(!left.hasDescendantOrSelf(right))
 	  {
 	    error("Type Error(46) [" + left + " <- " + right + "]");
 	  }
       }
     else
       {
 	List exceptionTypes = TrapManager.getExceptionTypesOf(stmt);
 	Iterator typeIt = exceptionTypes.iterator();
 	
 	while(typeIt.hasNext())
 	  {
 	    Type t = (TypetypeIt.next();
 	    
 	    if(!left.hasDescendantOrSelf(.typeNode(t)))
 	      {
 		error("Type Error(47)");
 	      }
 	  }
 	
 	if(!left.hasAncestorOrSelf(.typeNode(RefType.v("java.lang.Throwable"))))
 	  {
 	    error("Type Error(48)");
 	  }
       }
   }
 
   public void caseEnterMonitorStmt(EnterMonitorStmt stmt)
   {
     if(stmt.getOp() instanceof Local)
       {
 	TypeNode op = .typeNode(((Localstmt.getOp()).getType());
 	
 	if(!op.hasAncestorOrSelf(.typeNode(RefType.v("java.lang.Object"))))
 	  {
 	    error("Type Error(49)");
 	  }    
       }
   }
 
   public void caseExitMonitorStmt(ExitMonitorStmt stmt)
   {
     if(stmt.getOp() instanceof Local)
       {
 	TypeNode op = .typeNode(((Localstmt.getOp()).getType());
 	
 	if(!op.hasAncestorOrSelf(.typeNode(RefType.v("java.lang.Object"))))
 	  {
 	    error("Type Error(49)");
 	  }    
       }
   }
 
   public void caseGotoStmt(GotoStmt stmt)
   {
   }
 
   public void caseIfStmt(IfStmt stmt)
   {
     ConditionExpr cond = (ConditionExprstmt.getCondition();
     
     BinopExpr expr = cond;
     Value lv = expr.getOp1();
     Value rv = expr.getOp2();
     
     TypeNode lop;
     TypeNode rop;
     
     //******** LEFT ********
     if(lv instanceof Local)
       {
 	lop = .typeNode(((Locallv).getType());
       }
     else if(lv instanceof DoubleConstant)
       {
 	lop = .typeNode(DoubleType.v());
       }
     else if(lv instanceof FloatConstant)
       {
 	lop = .typeNode(FloatType.v());
       }
     else if(lv instanceof IntConstant)
       {
 	lop = .typeNode(IntType.v());
       }
     else if(lv instanceof LongConstant)
       {
 	lop = .typeNode(LongType.v());
       }
     else if(lv instanceof NullConstant)
       {
 	lop = .typeNode(NullType.v());
       }
     else if(lv instanceof StringConstant)
       {
 	lop = .typeNode(RefType.v("java.lang.String"));
       }
     else if(lv instanceof ClassConstant)
       {
 	lop = .typeNode(RefType.v("java.lang.Class"));
       }
     else
       {
 	throw new RuntimeException("Unhandled binary expression left operand type: " + lv.getClass());
       }
     
     //******** RIGHT ********
     if(rv instanceof Local)
       {
 	rop = .typeNode(((Localrv).getType());
       }
     else if(rv instanceof DoubleConstant)
       {
 	rop = .typeNode(DoubleType.v());
       }
     else if(rv instanceof FloatConstant)
       {
 	rop = .typeNode(FloatType.v());
 	  }
     else if(rv instanceof IntConstant)
       {
 	rop = .typeNode(IntType.v());
       }
     else if(rv instanceof LongConstant)
       {
 	rop = .typeNode(LongType.v());
       }
     else if(rv instanceof NullConstant)
       {
 	rop = .typeNode(NullType.v());
       }
     else if(rv instanceof StringConstant)
       {
 	rop = .typeNode(RefType.v("java.lang.String"));
       }
     else if(rv instanceof ClassConstant)
       {
 	rop = .typeNode(RefType.v("java.lang.Class"));
       }
     else
       {
 	throw new RuntimeException("Unhandled binary expression right operand type: " + rv.getClass());
       }
     
     try
       {
 	lop.lca(rop);
       }
     catch(TypeException e)
       {
       }
   }
 
   public void caseLookupSwitchStmt(LookupSwitchStmt stmt)
   {
     Value key = stmt.getKey();
 
     if(key instanceof Local)
       {
 	  {
 	    error("Type Error(50)");
 	  }
       }
   }
 
   public void caseNopStmt(NopStmt stmt)
   {
   }
 
   public void caseReturnStmt(ReturnStmt stmt)
   {
     if(stmt.getOp() instanceof Local)
       {
 	if(!.typeNode(((Localstmt.getOp()).getType()).
 	  {
 	    if()
 	      {
 		stmt.setOp(insertCast((Localstmt.getOp(), .getMethod().getReturnType(), stmt));
 	      }
 	    else
 	      {
 		error("Type Error(51)");
 	      }
 	  }
       }
  }
  public void caseReturnVoidStmt(ReturnVoidStmt stmt)
  {
  }
  public void caseTableSwitchStmt(TableSwitchStmt stmt)
  {
    Value key = stmt.getKey();
    if(key instanceof Local)
      {
	  {
	    error("Type Error(52)");
	  }
      }
  }
  public void caseThrowStmt(ThrowStmt stmt)
  {
    if(stmt.getOp() instanceof Local)
      {
	    
	if(!op.hasAncestorOrSelf(.typeNode(RefType.v("java.lang.Throwable"))))
	  {
	    if()
	      {
		stmt.setOp(insertCast((Localstmt.getOp(), RefType.v("java.lang.Throwable"), stmt));
	      }
	    else
	      {
		error("Type Error(53)");
	      }
	  }
      }
  }
  public void defaultCase(Stmt stmt)
  {
    throw new RuntimeException("Unhandled statement type: " + stmt.getClass());
  }
  private Local insertCast(Local oldlocalType typeStmt stmt)
  {
    Local newlocal = Jimple.v().newLocal("tmp"type);
    .getLocals().add(newlocal);
    
    .getUnits().insertBefore(Jimple.v().newAssignStmt(newlocal, Jimple.v().newCastExpr(oldlocaltype)), stmt);
    return newlocal;
  }