![JAR search and dependency download from the Maven repository](/logo.png)
soot.jimple.toolkits.typing.integer.ConstraintChecker Maven / Gradle / Ivy
/* 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.integer;
import soot.*;
import soot.jimple.*;
import java.io.*;
class ConstraintChecker extends AbstractStmtSwitch
{
private final TypeResolver resolver;
private final boolean fix; // if true, fix constraint violations
private JimpleBody stmtBody;
public ConstraintChecker(TypeResolver resolver, boolean fix)
{
this.resolver = resolver;
this.fix = fix;
}
public void check(Stmt stmt, JimpleBody stmtBody) throws TypeException
{
try
{
this.stmtBody = 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 ie, Stmt invokestmt)
{
if(ie instanceof InterfaceInvokeExpr)
{
InterfaceInvokeExpr invoke = (InterfaceInvokeExpr) ie;
SootMethodRef method = invoke.getMethodRef();
int count = invoke.getArgCount();
for(int i = 0; i < count; i++)
{
if(invoke.getArg(i) instanceof Local)
{
Local local = (Local) invoke.getArg(i);
if(local.getType() instanceof IntegerType)
{
if(!ClassHierarchy.v().typeNode(local.getType()).
hasAncestor_1(ClassHierarchy.v().typeNode(method.parameterType(i))))
{
if(fix)
{
invoke.setArg(i, insertCast(local, method.parameterType(i), invokestmt));
}
else
{
error("Type Error(1)");
}
}
}
}
}
}
else if(ie instanceof SpecialInvokeExpr)
{
SpecialInvokeExpr invoke = (SpecialInvokeExpr) ie;
SootMethodRef method = invoke.getMethodRef();
int count = invoke.getArgCount();
for(int i = 0; i < count; i++)
{
if(invoke.getArg(i) instanceof Local)
{
Local local = (Local) invoke.getArg(i);
if(local.getType() instanceof IntegerType)
{
if(!ClassHierarchy.v().typeNode(local.getType()).
hasAncestor_1(ClassHierarchy.v().typeNode(method.parameterType(i))))
{
if(fix)
{
invoke.setArg(i, insertCast(local, method.parameterType(i), invokestmt));
}
else
{
error("Type Error(2)");
}
}
}
}
}
}
else if(ie instanceof VirtualInvokeExpr)
{
VirtualInvokeExpr invoke = (VirtualInvokeExpr) ie;
SootMethodRef method = invoke.getMethodRef();
int count = invoke.getArgCount();
for(int i = 0; i < count; i++)
{
if(invoke.getArg(i) instanceof Local)
{
Local local = (Local) invoke.getArg(i);
if(local.getType() instanceof IntegerType)
{
if(!ClassHierarchy.v().typeNode(local.getType()).
hasAncestor_1(ClassHierarchy.v().typeNode(method.parameterType(i))))
{
if(fix)
{
invoke.setArg(i, insertCast(local, method.parameterType(i), invokestmt));
}
else
{
error("Type Error(3)");
}
}
}
}
}
}
else if(ie instanceof StaticInvokeExpr)
{
StaticInvokeExpr invoke = (StaticInvokeExpr) ie;
SootMethodRef method = invoke.getMethodRef();
int count = invoke.getArgCount();
for(int i = 0; i < count; i++)
{
if(invoke.getArg(i) instanceof Local)
{
Local local = (Local) invoke.getArg(i);
if(local.getType() instanceof IntegerType)
{
if(!ClassHierarchy.v().typeNode(local.getType()).
hasAncestor_1(ClassHierarchy.v().typeNode(method.parameterType(i))))
{
if(fix)
{
invoke.setArg(i, insertCast(local, method.parameterType(i), invokestmt));
}
else
{
error("Type Error(4)");
}
}
}
}
}
}
else if(ie instanceof DynamicInvokeExpr)
{ // RoboVM note: Added support for DynamicInvokeExpr
DynamicInvokeExpr invoke = (DynamicInvokeExpr) ie;
SootMethodRef method = invoke.getMethodRef();
int count = invoke.getArgCount();
for(int i = 0; i < count; i++)
{
if(invoke.getArg(i) instanceof Local)
{
Local local = (Local) invoke.getArg(i);
if(local.getType() instanceof IntegerType)
{
if(!ClassHierarchy.v().typeNode(local.getType()).
hasAncestor_1(ClassHierarchy.v().typeNode(method.parameterType(i))))
{
if(fix)
{
invoke.setArg(i, insertCast(local, method.parameterType(i), invokestmt));
}
else
{
error("Type Error(5)");
}
}
}
}
}
}
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;
TypeNode right = null;
//******** LEFT ********
if(l instanceof ArrayRef)
{
ArrayRef ref = (ArrayRef) l;
Type baset = ((Local) ref.getBase()).getType();
if (baset instanceof ArrayType)
{
ArrayType base = (ArrayType) baset;
Value index = ref.getIndex();
if((base.numDimensions == 1) &&
(base.baseType instanceof IntegerType))
{
left = ClassHierarchy.v().typeNode(base.baseType);
}
if(index instanceof Local)
{
if(!ClassHierarchy.v().typeNode(((Local) index).getType()).hasAncestor_1(ClassHierarchy.v().INT))
{
if(fix)
{
ref.setIndex(insertCast((Local) index, IntType.v(), stmt));
}
else
{
error("Type Error(5)");
}
}
}
}
}
else if(l instanceof Local)
{
if(((Local) l).getType() instanceof IntegerType)
{
left = ClassHierarchy.v().typeNode(((Local) l).getType());
}
}
else if(l instanceof InstanceFieldRef)
{
InstanceFieldRef ref = (InstanceFieldRef) l;
if(ref.getField().getType() instanceof IntegerType)
{
left = ClassHierarchy.v().typeNode( ref.getField().getType());
}
}
else if(l instanceof StaticFieldRef)
{
StaticFieldRef ref = (StaticFieldRef) l;
if(ref.getField().getType() instanceof IntegerType)
{
left = ClassHierarchy.v().typeNode(ref.getField().getType());
}
}
else
{
throw new RuntimeException("Unhandled assignment left hand side type: " + l.getClass());
}
//******** RIGHT ********
if(r instanceof ArrayRef)
{
ArrayRef ref = (ArrayRef) r;
Type baset = ((Local) ref.getBase()).getType();
if(!(baset instanceof NullType))
{
ArrayType base = (ArrayType) baset;
Value index = ref.getIndex();
if((base.numDimensions == 1) &&
(base.baseType instanceof IntegerType))
{
right = ClassHierarchy.v().typeNode(base.baseType);
}
if(index instanceof Local)
{
if(!ClassHierarchy.v().typeNode(((Local) index).getType()).hasAncestor_1(ClassHierarchy.v().INT))
{
if(fix)
{
ref.setIndex(insertCast((Local) index, IntType.v(), stmt));
}
else
{
error("Type Error(6)");
}
}
}
}
}
else if(r instanceof DoubleConstant)
{
}
else if(r instanceof FloatConstant)
{
}
else if(r instanceof IntConstant)
{
int value = ((IntConstant) r).value;
if(value < -32768)
{
right = ClassHierarchy.v().INT;
}
else if(value < -128)
{
right = ClassHierarchy.v().SHORT;
}
else if(value < 0)
{
right = ClassHierarchy.v().BYTE;
}
else if(value < 2)
{
right = ClassHierarchy.v().R0_1;
}
else if(value < 128)
{
right = ClassHierarchy.v().R0_127;
}
else if(value < 32768)
{
right = ClassHierarchy.v().R0_32767;
}
else if(value < 65536)
{
right = ClassHierarchy.v().CHAR;
}
else
{
right = ClassHierarchy.v().INT;
}
}
else if(r instanceof LongConstant)
{
}
else if(r instanceof NullConstant)
{
}
else if(r instanceof StringConstant)
{
}
else if(r instanceof ClassConstant)
{
}
else if(r instanceof BinopExpr)
{
//******** BINOP EXPR ********
BinopExpr be = (BinopExpr) r;
Value lv = be.getOp1();
Value rv = be.getOp2();
TypeNode lop = null;
TypeNode rop = null;
//******** LEFT ********
if(lv instanceof Local)
{
if(((Local) lv).getType() instanceof IntegerType)
{
lop = ClassHierarchy.v().typeNode(((Local) lv).getType());
}
}
else if(lv instanceof DoubleConstant)
{
}
else if(lv instanceof FloatConstant)
{
}
else if(lv instanceof IntConstant)
{
int value = ((IntConstant) lv).value;
if(value < -32768)
{
lop = ClassHierarchy.v().INT;
}
else if(value < -128)
{
lop = ClassHierarchy.v().SHORT;
}
else if(value < 0)
{
lop = ClassHierarchy.v().BYTE;
}
else if(value < 2)
{
lop = ClassHierarchy.v().R0_1;
}
else if(value < 128)
{
lop = ClassHierarchy.v().R0_127;
}
else if(value < 32768)
{
lop = ClassHierarchy.v().R0_32767;
}
else if(value < 65536)
{
lop = ClassHierarchy.v().CHAR;
}
else
{
lop = ClassHierarchy.v().INT;
}
}
else if(lv instanceof LongConstant)
{
}
else if(lv instanceof NullConstant)
{
}
else if(lv instanceof StringConstant)
{
}
else if(lv instanceof ClassConstant)
{
}
else
{
throw new RuntimeException("Unhandled binary expression left operand type: " + lv.getClass());
}
//******** RIGHT ********
if(rv instanceof Local)
{
if(((Local) rv).getType() instanceof IntegerType)
{
rop = ClassHierarchy.v().typeNode(((Local) rv).getType());
}
}
else if(rv instanceof DoubleConstant)
{
}
else if(rv instanceof FloatConstant)
{
}
else if(rv instanceof IntConstant)
{
int value = ((IntConstant) rv).value;
if(value < -32768)
{
rop = ClassHierarchy.v().INT;
}
else if(value < -128)
{
rop = ClassHierarchy.v().SHORT;
}
else if(value < 0)
{
rop = ClassHierarchy.v().BYTE;
}
else if(value < 2)
{
rop = ClassHierarchy.v().R0_1;
}
else if(value < 128)
{
rop = ClassHierarchy.v().R0_127;
}
else if(value < 32768)
{
rop = ClassHierarchy.v().R0_32767;
}
else if(value < 65536)
{
rop = ClassHierarchy.v().CHAR;
}
else
{
rop = ClassHierarchy.v().INT;
}
}
else if(rv instanceof LongConstant)
{
}
else if(rv instanceof NullConstant)
{
}
else if(rv instanceof StringConstant)
{
}
else if(rv instanceof ClassConstant)
{
}
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))
{
if(lop != null && rop != null)
{
if(!lop.hasAncestor_1(ClassHierarchy.v().INT))
{
if(fix)
{
be.setOp1(insertCast(be.getOp1(), getTypeForCast(lop), IntType.v(), stmt));
}
else
{
error("Type Error(7)");
}
}
if(!rop.hasAncestor_1(ClassHierarchy.v().INT))
{
if(fix)
{
be.setOp2(insertCast(be.getOp2(), getTypeForCast(rop), IntType.v(), stmt));
}
else
{
error("Type Error(8)");
}
}
}
right = ClassHierarchy.v().INT;
}
else if((be instanceof AndExpr) ||
(be instanceof OrExpr) ||
(be instanceof XorExpr))
{
if(lop != null && rop != null)
{
TypeNode lca = lop.lca_1(rop);
if(lca == ClassHierarchy.v().TOP)
{
if(fix)
{
if(!lop.hasAncestor_1(ClassHierarchy.v().INT))
{
be.setOp1(insertCast(be.getOp1(), getTypeForCast(lop), getTypeForCast(rop), stmt));
lca = rop;
}
if(!rop.hasAncestor_1(ClassHierarchy.v().INT))
{
be.setOp2(insertCast(be.getOp2(), getTypeForCast(rop), getTypeForCast(lop), stmt));
lca = lop;
}
}
else
{
error("Type Error(11)");
}
}
right = lca;
}
}
else if(be instanceof ShlExpr)
{
if(lop != null)
{
if(!lop.hasAncestor_1(ClassHierarchy.v().INT))
{
if(fix)
{
be.setOp1(insertCast(be.getOp1(), getTypeForCast(lop), IntType.v(), stmt));
}
else
{
error("Type Error(9)");
}
}
}
if(!rop.hasAncestor_1(ClassHierarchy.v().INT))
{
if(fix)
{
be.setOp2(insertCast(be.getOp2(), getTypeForCast(rop), IntType.v(), stmt));
}
else
{
error("Type Error(10)");
}
}
right = (lop == null) ? null : ClassHierarchy.v().INT;
}
else if((be instanceof ShrExpr) ||
(be instanceof UshrExpr))
{
if(lop != null)
{
if(!lop.hasAncestor_1(ClassHierarchy.v().INT))
{
if(fix)
{
be.setOp1(insertCast(be.getOp1(), getTypeForCast(lop), ByteType.v(), stmt));
lop = ClassHierarchy.v().BYTE;
}
else
{
error("Type Error(9)");
}
}
}
if(!rop.hasAncestor_1(ClassHierarchy.v().INT))
{
if(fix)
{
be.setOp2(insertCast(be.getOp2(), getTypeForCast(rop), IntType.v(), stmt));
}
else
{
error("Type Error(10)");
}
}
right = lop;
}
else if((be instanceof CmpExpr) ||
(be instanceof CmpgExpr) ||
(be instanceof CmplExpr))
{
right = ClassHierarchy.v().BYTE;
}
else if((be instanceof EqExpr) ||
(be instanceof GeExpr) ||
(be instanceof GtExpr) ||
(be instanceof LeExpr) ||
(be instanceof LtExpr) ||
(be instanceof NeExpr))
{
TypeNode lca = lop.lca_1(rop);
if(lca == ClassHierarchy.v().TOP)
{
if(fix)
{
if(!lop.hasAncestor_1(ClassHierarchy.v().INT))
{
be.setOp1(insertCast(be.getOp1(), getTypeForCast(lop), getTypeForCast(rop), stmt));
}
if(!rop.hasAncestor_1(ClassHierarchy.v().INT))
{
be.setOp2(insertCast(be.getOp2(), getTypeForCast(rop), getTypeForCast(lop), stmt));
}
}
else
{
error("Type Error(11)");
}
}
right = ClassHierarchy.v().BOOLEAN;
}
else
{
throw new RuntimeException("Unhandled binary expression type: " + be.getClass());
}
}
else if(r instanceof CastExpr)
{
CastExpr ce = (CastExpr) r;
if(ce.getCastType() instanceof IntegerType)
{
right = ClassHierarchy.v().typeNode(ce.getCastType());
}
}
else if(r instanceof InstanceOfExpr)
{
right = ClassHierarchy.v().BOOLEAN;
}
else if(r instanceof InvokeExpr)
{
InvokeExpr ie = (InvokeExpr) r;
handleInvokeExpr(ie, stmt);
if(ie.getMethodRef().returnType() instanceof IntegerType)
{
right = ClassHierarchy.v().typeNode(ie.getMethodRef().returnType());
}
}
else if(r instanceof NewArrayExpr)
{
NewArrayExpr nae = (NewArrayExpr) r;
Value size = nae.getSize();
if(size instanceof Local)
{
if(!ClassHierarchy.v().typeNode(((Local) size).getType()).
hasAncestor_1(ClassHierarchy.v().INT))
{
if(fix)
{
nae.setSize(insertCast((Local) size, IntType.v(), stmt));
}
else
{
error("Type Error(12)");
}
}
}
}
else if(r instanceof NewExpr)
{
}
else if(r instanceof NewMultiArrayExpr)
{
NewMultiArrayExpr nmae = (NewMultiArrayExpr) r;
for(int i = 0; i < nmae.getSizeCount(); i++)
{
Value size = nmae.getSize(i);
if(size instanceof Local)
{
if(!ClassHierarchy.v().typeNode(((Local) size).getType()).
hasAncestor_1(ClassHierarchy.v().INT))
{
if(fix)
{
nmae.setSize(i, insertCast((Local) size, IntType.v(), stmt));
}
else
{
error("Type Error(13)");
}
}
}
}
}
else if(r instanceof LengthExpr)
{
right = ClassHierarchy.v().INT;
}
else if(r instanceof NegExpr)
{
NegExpr ne = (NegExpr) r;
if(ne.getOp() instanceof Local)
{
Local local = (Local) ne.getOp();
if(local.getType() instanceof IntegerType)
{
TypeNode ltype = ClassHierarchy.v().typeNode(local.getType());
if(!ltype.hasAncestor_1(ClassHierarchy.v().INT))
{
if(fix)
{
ne.setOp(insertCast(local, IntType.v(), stmt));
ltype = ClassHierarchy.v().BYTE;
}
else
{
error("Type Error(14)");
}
}
right = (ltype == ClassHierarchy.v().CHAR) ? ClassHierarchy.v().INT : ltype;
}
}
else if(ne.getOp() instanceof DoubleConstant)
{
}
else if(ne.getOp() instanceof FloatConstant)
{
}
else if(ne.getOp() instanceof IntConstant)
{
right = ClassHierarchy.v().INT;
}
else if(ne.getOp() instanceof LongConstant)
{
}
else
{
throw new RuntimeException("Unhandled neg expression operand type: " + ne.getOp().getClass());
}
}
else if(r instanceof Local)
{
Local local = (Local) r;
if(local.getType() instanceof IntegerType)
{
right = ClassHierarchy.v().typeNode(local.getType());
}
}
else if(r instanceof InstanceFieldRef)
{
InstanceFieldRef ref = (InstanceFieldRef) r;
if(ref.getField().getType() instanceof IntegerType)
{
right = ClassHierarchy.v().typeNode(ref.getField().getType());
}
}
else if(r instanceof StaticFieldRef)
{
StaticFieldRef ref = (StaticFieldRef) r;
if(ref.getField().getType() instanceof IntegerType)
{
right = ClassHierarchy.v().typeNode(ref.getField().getType());
}
}
else
{
throw new RuntimeException("Unhandled assignment right hand side type: " + r.getClass());
}
if(left != null && right != null)
{
if(!right.hasAncestor_1(left))
{
if(fix)
{
stmt.setRightOp(insertCast(stmt.getRightOp(), getTypeForCast(right), getTypeForCast(left), stmt));
}
else
{
error("Type Error(15)");
}
}
}
}
static Type getTypeForCast(TypeNode node)
// This method is a local kludge, for avoiding NullPointerExceptions
// when a R0_1, R0_127, or R0_32767 node is used in a type
// cast. A more elegant solution would work with the TypeNode
// type definition itself, but that would require a more thorough
// knowledge of the typing system than the kludger posesses.
{
if (node.type() == null)
{
if (node == ClassHierarchy.v().R0_1)
{
return BooleanType.v();
}
else if (node == ClassHierarchy.v().R0_127)
{
return ByteType.v();
}
else if (node == ClassHierarchy.v().R0_32767)
{
return ShortType.v();
}
// Perhaps we should throw an exception here, since I don't think
// there should be any other cases where node.type() is null.
// In case that supposition is incorrect, though, we'll just
// go on to return the null, and let the callers worry about it.
}
return node.type();
}
public void caseIdentityStmt(IdentityStmt stmt)
{
Value l = stmt.getLeftOp();
Value r = stmt.getRightOp();
if(l instanceof Local)
{
if(((Local) l).getType() instanceof IntegerType)
{
TypeNode left = ClassHierarchy.v().typeNode((((Local) l).getType()));
TypeNode right = ClassHierarchy.v().typeNode(r.getType());
if(!right.hasAncestor_1(left))
{
if(fix)
{
((soot.jimple.internal.JIdentityStmt) stmt).setLeftOp(insertCastAfter((Local) l, getTypeForCast(left), getTypeForCast(right), stmt));
}
else
{
error("Type Error(16)");
}
}
}
}
}
public void caseEnterMonitorStmt(EnterMonitorStmt stmt)
{
}
public void caseExitMonitorStmt(ExitMonitorStmt stmt)
{
}
public void caseGotoStmt(GotoStmt stmt)
{
}
public void caseIfStmt(IfStmt stmt)
{
ConditionExpr cond = (ConditionExpr) stmt.getCondition();
BinopExpr expr = cond;
Value lv = expr.getOp1();
Value rv = expr.getOp2();
TypeNode lop = null;
TypeNode rop = null;
//******** LEFT ********
if(lv instanceof Local)
{
if(((Local) lv).getType() instanceof IntegerType)
{
lop = ClassHierarchy.v().typeNode(((Local) lv).getType());
}
}
else if(lv instanceof DoubleConstant)
{
}
else if(lv instanceof FloatConstant)
{
}
else if(lv instanceof IntConstant)
{
int value = ((IntConstant) lv).value;
if(value < -32768)
{
lop = ClassHierarchy.v().INT;
}
else if(value < -128)
{
lop = ClassHierarchy.v().SHORT;
}
else if(value < 0)
{
lop = ClassHierarchy.v().BYTE;
}
else if(value < 2)
{
lop = ClassHierarchy.v().R0_1;
}
else if(value < 128)
{
lop = ClassHierarchy.v().R0_127;
}
else if(value < 32768)
{
lop = ClassHierarchy.v().R0_32767;
}
else if(value < 65536)
{
lop = ClassHierarchy.v().CHAR;
}
else
{
lop = ClassHierarchy.v().INT;
}
}
else if(lv instanceof LongConstant)
{
}
else if(lv instanceof NullConstant)
{
}
else if(lv instanceof StringConstant)
{
}
else if(lv instanceof ClassConstant)
{
}
else
{
throw new RuntimeException("Unhandled binary expression left operand type: " + lv.getClass());
}
//******** RIGHT ********
if(rv instanceof Local)
{
if(((Local) rv).getType() instanceof IntegerType)
{
rop = ClassHierarchy.v().typeNode(((Local) rv).getType());
}
}
else if(rv instanceof DoubleConstant)
{
}
else if(rv instanceof FloatConstant)
{
}
else if(rv instanceof IntConstant)
{
int value = ((IntConstant) rv).value;
if(value < -32768)
{
rop = ClassHierarchy.v().INT;
}
else if(value < -128)
{
rop = ClassHierarchy.v().SHORT;
}
else if(value < 0)
{
rop = ClassHierarchy.v().BYTE;
}
else if(value < 2)
{
rop = ClassHierarchy.v().R0_1;
}
else if(value < 128)
{
rop = ClassHierarchy.v().R0_127;
}
else if(value < 32768)
{
rop = ClassHierarchy.v().R0_32767;
}
else if(value < 65536)
{
rop = ClassHierarchy.v().CHAR;
}
else
{
rop = ClassHierarchy.v().INT;
}
}
else if(rv instanceof LongConstant)
{
}
else if(rv instanceof NullConstant)
{
}
else if(rv instanceof StringConstant)
{
}
else if(rv instanceof ClassConstant)
{
}
else
{
throw new RuntimeException("Unhandled binary expression right operand type: " + rv.getClass());
}
if(lop != null && rop != null)
{
if(lop.lca_1(rop) == ClassHierarchy.v().TOP)
{
if(fix)
{
if(!lop.hasAncestor_1(ClassHierarchy.v().INT))
{
expr.setOp1(insertCast(expr.getOp1(), getTypeForCast(lop), getTypeForCast(rop), stmt));
}
if(!rop.hasAncestor_1(ClassHierarchy.v().INT))
{
expr.setOp2(insertCast(expr.getOp2(), getTypeForCast(rop), getTypeForCast(lop), stmt));
}
}
else
{
error("Type Error(17)");
}
}
}
}
public void caseLookupSwitchStmt(LookupSwitchStmt stmt)
{
Value key = stmt.getKey();
if(key instanceof Local)
{
if(!ClassHierarchy.v().typeNode(((Local) key).getType()).
hasAncestor_1(ClassHierarchy.v().INT))
{
if(fix)
{
stmt.setKey(insertCast((Local) key, IntType.v(), stmt));
}
else
{
error("Type Error(18)");
}
}
}
}
public void caseNopStmt(NopStmt stmt)
{
}
public void caseReturnStmt(ReturnStmt stmt)
{
if(stmt.getOp() instanceof Local)
{
if(((Local) stmt.getOp()).getType() instanceof IntegerType)
{
if(!ClassHierarchy.v().typeNode(((Local) stmt.getOp()).getType()).
hasAncestor_1(ClassHierarchy.v().typeNode(stmtBody.getMethod().getReturnType())))
{
if(fix)
{
stmt.setOp(insertCast((Local) stmt.getOp(), stmtBody.getMethod().getReturnType(), stmt));
}
else
{
error("Type Error(19)");
}
}
}
}
}
public void caseReturnVoidStmt(ReturnVoidStmt stmt)
{
}
public void caseTableSwitchStmt(TableSwitchStmt stmt)
{
Value key = stmt.getKey();
if(key instanceof Local)
{
if(!ClassHierarchy.v().typeNode(((Local) key).getType()).
hasAncestor_1(ClassHierarchy.v().INT))
{
if(fix)
{
stmt.setKey(insertCast((Local) key, IntType.v(), stmt));
}
else
{
error("Type Error(20)");
}
}
resolver.typeVariable((Local) key).addParent(resolver.INT);
}
}
public void caseThrowStmt(ThrowStmt stmt)
{
}
public void defaultCase(Stmt stmt)
{
throw new RuntimeException("Unhandled statement type: " + stmt.getClass());
}
private Local insertCast(Local oldlocal, Type type, Stmt stmt)
{
Local newlocal = Jimple.v().newLocal("tmp", type);
stmtBody.getLocals().add(newlocal);
stmtBody.getUnits().insertBefore(Jimple.v().newAssignStmt(newlocal, Jimple.v().newCastExpr(oldlocal, type)), stmt);
return newlocal;
}
private Local insertCastAfter(Local leftlocal, Type lefttype, Type righttype, Stmt stmt)
{
Local newlocal = Jimple.v().newLocal("tmp", righttype);
stmtBody.getLocals().add(newlocal);
stmtBody.getUnits().insertAfter(Jimple.v().newAssignStmt(leftlocal, Jimple.v().newCastExpr(newlocal, lefttype)), stmt);
return newlocal;
}
private Local insertCast(Value oldvalue, Type oldtype, Type type, Stmt stmt)
{
Local newlocal1 = Jimple.v().newLocal("tmp", oldtype);
Local newlocal2 = Jimple.v().newLocal("tmp", type);
stmtBody.getLocals().add(newlocal1);
stmtBody.getLocals().add(newlocal2);
stmtBody.getUnits().insertBefore(Jimple.v().newAssignStmt(newlocal1, oldvalue), stmt);
stmtBody.getUnits().insertBefore(Jimple.v().newAssignStmt(newlocal2, Jimple.v().newCastExpr(newlocal1, type)), stmt);
return newlocal2;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy