@Override public void sawOpcode(int seen) { if (DEBUG) { System.out.printf("%3d %-15s %s%n", getPC(), Const.getOpcodeName(seen), stack); if (isRegisterStore()) { regModifiedAt(getRegisterOperand(), getPC()); if (getBranchOffset() < 0) { BackwardsBranch bb = new BackwardsBranch(stack, getPC(), getBranchTarget()); if (bb.invariantRegisters.size() > 0) { backwardBranches.add(bb); addBackwardsReach(); case Const.LRETURN: case Const.ATHROW: addForwardJump(getPC(), Integer.MAX_VALUE); break; case Const.TABLESWITCH: { OpcodeStack.Item item0 = stack.getStackItem(0); if (getDefaultSwitchOffset() > 0) { forwardConditionalBranches.add(new ForwardConditionalBranch(item0, item0, getPC(), getPC() + getDefaultSwitchOffset())); for (int offset : getSwitchOffsets()) { if (offset > 0) { forwardConditionalBranches.add(new ForwardConditionalBranch(item0, item0, getPC(), getPC() + offset));
int getFurthestJump(int from) { int result = Integer.MIN_VALUE; int from2 = getBackwardsReach(from); assert from2 <= from; from = from2; for (Jump f : forwardJumps) { if (f.from >= from && f.to > result) { result = f.to; } } return result; }
void reportPossibleBug(BugInstance bug) { int catchSize = Util.getSizeOfSurroundingTryBlock(getConstantPool(), getCode(), "java/io/EOFException", getPC()); if (catchSize < Integer.MAX_VALUE) { bug.lowerPriorityALot(); } else { catchSize = Util.getSizeOfSurroundingTryBlock(getConstantPool(), getCode(), "java/lang/NoSuchElementException", getPC()); if (catchSize < Integer.MAX_VALUE) { bug.lowerPriorityALot(); } else { LocalVariableAnnotation lv = bug.getPrimaryLocalVariableAnnotation(); if (lv == null && "run".equals(getMethodName())) { bug.lowerPriority(); } } } bugReporter.reportBug(bug); } }
@Override public void sawBranchTo(int target) { addForwardJump(getPC(), target); }
/** * */ private void addBackwardsReach() { if (getBranchOffset() >= 0) { return; } int target = getBranchTarget(); for (Jump j : backwardReach) { if (j.to < target && target <= j.from) { target = j.to; } } assert target <= getBranchTarget(); assert target < getPC(); for (Iterator<Jump> i = backwardReach.iterator(); i.hasNext();) { Jump j = i.next(); if (target <= j.to && getPC() >= j.from) { i.remove(); } } backwardReach.add(new Jump(getPC(), target)); }
clearRegModified(); backwardBranches.clear(); forwardConditionalBranches.clear(); backwardBranchLoop: for (BackwardsBranch bb : backwardBranches) { LinkedList<ForwardConditionalBranch> myForwardBranches = new LinkedList<>(); int myBackwardsReach = getBackwardsReach(bb.to); if (isConstant(fcb.item0, bb) && isConstant(fcb.item1, bb)) { SourceLineAnnotation loopBottom = SourceLineAnnotation.fromVisitedInstruction(getClassContext(), this, bb.from); int loopBottomLine = loopBottom.getStartLine(); SourceLineAnnotation loopTop = SourceLineAnnotation.fromVisitedInstruction(getClassContext(), this, bb.to); int loopTopLine = loopTop.getStartLine(); BugInstance bug = new BugInstance(this, "IL_INFINITE_LOOP", HIGH_PRIORITY).addClassAndMethod(this) boolean reg0Invariant = true; if (reg0 >= 0 && fcb.item0.getConstant() == null) { reg0Invariant = !isRegModified(reg0, myBackwardsReach, bb.from); SourceLineAnnotation lastChange = SourceLineAnnotation.fromVisitedInstruction(getClassContext(), this, constantSince(fcb.item0)); int lastChangeLine = lastChange.getEndLine(); if (loopBottomLine != -1 && lastChangeLine != -1 && loopTopLine != -1 && loopTopLine <= lastChangeLine bug.add(LocalVariableAnnotation.getLocalVariableAnnotation(getMethod(), reg0, fcb.from, bb.from)) .addSourceLine(lastChange).describe(SourceLineAnnotation.DESCRIPTION_LAST_CHANGE); SourceLineAnnotation lastChange = SourceLineAnnotation.fromVisitedInstruction(getClassContext(), this, constantSince(fcb.item1)); int lastChangeLine = lastChange.getEndLine();
clearRegModified(); backwardBranches.clear(); forwardConditionalBranches.clear(); backwardBranchLoop: for (BackwardsBranch bb : backwardBranches) { LinkedList<ForwardConditionalBranch> myForwardBranches = new LinkedList<ForwardConditionalBranch>(); int myBackwardsReach = getBackwardsReach(bb.to); if (isConstant(fcb.item0, bb) && isConstant(fcb.item1, bb)) { SourceLineAnnotation loopBottom = SourceLineAnnotation.fromVisitedInstruction(getClassContext(), this, bb.from); int loopBottomLine = loopBottom.getStartLine(); SourceLineAnnotation loopTop = SourceLineAnnotation.fromVisitedInstruction(getClassContext(), this, bb.to); int loopTopLine = loopTop.getStartLine(); BugInstance bug = new BugInstance(this, "IL_INFINITE_LOOP", HIGH_PRIORITY).addClassAndMethod(this) boolean reg0Invariant = true; if (reg0 >= 0 && fcb.item0.getConstant() == null) { reg0Invariant = !isRegModified(reg0, myBackwardsReach, bb.from); SourceLineAnnotation lastChange = SourceLineAnnotation.fromVisitedInstruction(getClassContext(), this, constantSince(fcb.item0)); int lastChangeLine = lastChange.getEndLine(); if (loopBottomLine != -1 && lastChangeLine != -1 && loopTopLine != -1 && loopTopLine <= lastChangeLine bug.add(LocalVariableAnnotation.getLocalVariableAnnotation(getMethod(), reg0, fcb.from, bb.from)) .addSourceLine(lastChange).describe(SourceLineAnnotation.DESCRIPTION_LAST_CHANGE); SourceLineAnnotation lastChange = SourceLineAnnotation.fromVisitedInstruction(getClassContext(), this, constantSince(fcb.item1)); int lastChangeLine = lastChange.getEndLine();
/** * */ private void addBackwardsReach() { if (getBranchOffset() >= 0) { return; } int target = getBranchTarget(); for (Jump j : backwardReach) { if (j.to < target && target <= j.from) { target = j.to; } } assert target <= getBranchTarget(); assert target < getPC(); for (Iterator<Jump> i = backwardReach.iterator(); i.hasNext();) { Jump j = i.next(); if (target <= j.to && getPC() >= j.from) { i.remove(); } } backwardReach.add(new Jump(getPC(), target)); }
@Override public void sawBranchTo(int target) { addForwardJump(getPC(), target); }
@Override public void sawOpcode(int seen) { if (DEBUG) { System.out.printf("%3d %-15s %s%n", getPC(), OPCODE_NAMES[seen], stack); if (isRegisterStore()) { regModifiedAt(getRegisterOperand(), getPC()); if (getBranchOffset() < 0) { BackwardsBranch bb = new BackwardsBranch(stack, getPC(), getBranchTarget()); if (bb.invariantRegisters.size() > 0) { backwardBranches.add(bb); addBackwardsReach(); case LRETURN: case ATHROW: addForwardJump(getPC(), Integer.MAX_VALUE); break; case TABLESWITCH: { OpcodeStack.Item item0 = stack.getStackItem(0); if (getDefaultSwitchOffset() > 0) { forwardConditionalBranches.add(new ForwardConditionalBranch(item0, item0, getPC(), getPC() + getDefaultSwitchOffset())); for (int offset : getSwitchOffsets()) { if (offset > 0) { forwardConditionalBranches.add(new ForwardConditionalBranch(item0, item0, getPC(), getPC() + offset));
void reportPossibleBug(BugInstance bug) { int catchSize = Util.getSizeOfSurroundingTryBlock(getConstantPool(), getCode(), "java/io/EOFException", getPC()); if (catchSize < Integer.MAX_VALUE) { bug.lowerPriorityALot(); } else { catchSize = Util.getSizeOfSurroundingTryBlock(getConstantPool(), getCode(), "java/lang/NoSuchElementException", getPC()); if (catchSize < Integer.MAX_VALUE) { bug.lowerPriorityALot(); } else { LocalVariableAnnotation lv = bug.getPrimaryLocalVariableAnnotation(); if (lv == null && "run".equals(getMethodName())) { bug.lowerPriority(); } } } bugReporter.reportBug(bug); } }
private boolean constantSince(Item item1, int branchTarget) { int reg = item1.getRegisterNumber(); if (reg >= 0) { return stack.getLastUpdate(reg) < getBackwardsReach(branchTarget); } if (item1.getConstant() != null) { return true; } return false; }
int getFurthestJump(int from) { int result = Integer.MIN_VALUE; int from2 = getBackwardsReach(from); assert from2 <= from; from = from2; for (Jump f : forwardJumps) { if (f.from >= from && f.to > result) { result = f.to; } } return result; }
private boolean constantSince(Item item1, int branchTarget) { int reg = item1.getRegisterNumber(); if (reg >= 0) { return stack.getLastUpdate(reg) < getBackwardsReach(branchTarget); } if (item1.getConstant() != null) { return true; } return false; }