}
}
}// while (!icq.isEmpty()) END
InstructionHandle ih = start.getInstruction();
do{
if ((ih.getInstruction() instanceof ReturnInstruction) && (!(cfg.isDead(ih)))) {
InstructionContext ic = cfg.contextOf(ih);
Frame f = ic.getOutFrame(new ArrayList<InstructionContext>()); // TODO: This is buggy, we check only the top-level return instructions this way. Maybe some maniac returns from a method when in a subroutine?
LocalVariables lvs = f.getLocals();
for (int i=0; i<lvs.maxLocals(); i++){
if (lvs.get(i) instanceof UninitializedObjectType){
this.addMessage("Warning: ReturnInstruction '"+ic+"' may leave method with an uninitialized object in the local variables array '"+lvs+"'.");
}
}
OperandStack os = f.getStack();
for (int i=0; i<os.size(); i++){
if (os.peek(i) instanceof UninitializedObjectType){
this.addMessage("Warning: ReturnInstruction '"+ic+"' may leave method with an uninitialized object on the operand stack '"+os+"'.");
}
}
//see JVM $4.8.2
//TODO implement all based on stack
Type returnedType = null;
if( ih.getPrev().getInstruction() instanceof InvokeInstruction )
{
returnedType = ((InvokeInstruction)ih.getPrev().getInstruction()).getType(m.getConstantPool());
}
if( ih.getPrev().getInstruction() instanceof LoadInstruction )
{
int index = ((LoadInstruction)ih.getPrev().getInstruction()).getIndex();
returnedType = lvs.get(index);
}
if( ih.getPrev().getInstruction() instanceof GETFIELD )
{
returnedType = ((GETFIELD)ih.getPrev().getInstruction()).getType(m.getConstantPool());
}
if( returnedType != null )
{
if( returnedType instanceof ObjectType )
{
try
{
if( !((ObjectType)returnedType).isAssignmentCompatibleWith(m.getReturnType()) )
{
throw new StructuralCodeConstraintException("Returned type "+returnedType+" does not match Method's return type "+m.getReturnType());
}
}
catch (Exception e)
{
//dont know what do do now, so raise RuntimeException
throw new RuntimeException(e);
}
}
else if( !returnedType.equals(m.getReturnType()) )
{
throw new StructuralCodeConstraintException("Returned type "+returnedType+" does not match Method's return type "+m.getReturnType());
}
}
}
}while ((ih = ih.getNext()) != null);
}