use of com.mebigfatguy.fbcontrib.utils.StopOpcodeParsingException in project fb-contrib by mebigfatguy.
the class CopiedOverriddenMethod method visitCode.
/**
* overrides the visitor to find code blocks of methods that are the same as its parents
*
* @param obj
* the code object of the currently parsed method
*/
@Override
public void visitCode(Code obj) {
try {
Method m = getMethod();
if ((!m.isPublic() && !m.isProtected()) || m.isAbstract() || m.isSynthetic()) {
return;
}
CodeInfo superCode = superclassCode.remove(curMethodInfo);
if (superCode != null) {
if (sameAccess(getMethod().getAccessFlags(), superCode.getAccess()) && codeEquals(obj, superCode.getCode())) {
bugReporter.reportBug(new BugInstance(this, BugType.COM_COPIED_OVERRIDDEN_METHOD.name(), NORMAL_PRIORITY).addClass(this).addMethod(this).addSourceLine(classContext, this, getPC()));
return;
}
if ((getMethod().getAccessFlags() & Const.ACC_SYNCHRONIZED) != (superCode.getAccess() & Const.ACC_SYNCHRONIZED)) {
return;
}
parmTypes = getMethod().getArgumentTypes();
nextParmIndex = 0;
nextParmOffset = getMethod().isStatic() ? 0 : 1;
sawAload0 = nextParmOffset == 0;
sawParentCall = false;
super.visitCode(obj);
}
} catch (StopOpcodeParsingException e) {
// method is unique
}
}
use of com.mebigfatguy.fbcontrib.utils.StopOpcodeParsingException in project fb-contrib by mebigfatguy.
the class MethodReturnsConstant method visitCode.
/**
* implements the visitor to reset the stack and proceed for private methods
*
* @param obj
* the context object of the currently parsed code block
*/
@Override
public void visitCode(Code obj) {
Method m = getMethod();
if (overloadedMethods.contains(m)) {
return;
}
int aFlags = m.getAccessFlags();
if ((((aFlags & Const.ACC_PRIVATE) != 0) || ((aFlags & Const.ACC_STATIC) != 0)) && ((aFlags & Const.ACC_SYNTHETIC) == 0) && (!m.getSignature().endsWith(")Z"))) {
stack.resetForMethodEntry(this);
returnRegister = Values.NEGATIVE_ONE;
returnConstant = null;
registerConstants.clear();
returnPC = -1;
try {
super.visitCode(obj);
if ((returnConstant != null)) {
BugInstance bi = new BugInstance(this, BugType.MRC_METHOD_RETURNS_CONSTANT.name(), ((aFlags & Const.ACC_PRIVATE) != 0) ? NORMAL_PRIORITY : LOW_PRIORITY).addClass(this).addMethod(this);
if (returnPC >= 0) {
bi.addSourceLine(this, returnPC);
}
bi.addString(returnConstant.toString());
bugReporter.reportBug(bi);
}
} catch (StopOpcodeParsingException e) {
// method was not suspect
}
}
}
use of com.mebigfatguy.fbcontrib.utils.StopOpcodeParsingException in project fb-contrib by mebigfatguy.
the class BuryingLogic method visitCode.
@Override
public void visitCode(Code obj) {
Method m = getMethod();
if (m.getReturnType() == Type.VOID) {
return;
}
stack.resetForMethodEntry(this);
ifBlocks.clear();
activeUnconditional = null;
CodeException[] ces = obj.getExceptionTable();
if (CollectionUtils.isEmpty(ces)) {
catchPCs = null;
} else {
catchPCs = new BitSet();
for (CodeException ce : ces) {
catchPCs.set(ce.getHandlerPC());
}
}
gotoBranchPCs.clear();
casePositions.clear();
lookingForResetOp = false;
try {
super.visitCode(obj);
} catch (StopOpcodeParsingException e) {
// reported an issue, so get out
}
}
use of com.mebigfatguy.fbcontrib.utils.StopOpcodeParsingException in project fb-contrib by mebigfatguy.
the class BuryingLogic method sawOpcode.
/**
* the difficult problem is to figure out when you are at the bottom of an if/else chain when all the above if/else blocks leave via returns. then there is
* only one branch target to the statement after the last else, which is indistinquishable from a simple if/else.
*/
@Override
public void sawOpcode(int seen) {
try {
int blockCount = ifBlocks.countBlockEndsAtPC(getPC());
if (blockCount > 1) {
activeUnconditional = null;
} else if (blockCount == 1) {
lookingForResetOp = true;
}
if (!casePositions.isEmpty()) {
int firstCasePos = casePositions.nextSetBit(0);
if (firstCasePos == getPC()) {
casePositions.clear(firstCasePos);
activeUnconditional = null;
lookingForResetOp = false;
}
}
if (lookingForResetOp) {
if (isResetOp(seen)) {
lookingForResetOp = false;
} else {
return;
}
}
if (isBranch(seen)) {
if (activeUnconditional != null) {
activeUnconditional = null;
}
int target = getBranchTarget();
if (getBranchOffset() > 0) {
if ((seen == Const.GOTO) || (seen == Const.GOTO_W)) {
gotoBranchPCs.set(target);
} else if ((catchPCs == null) || !catchPCs.get(getNextPC())) {
ifBlocks.add(new IfBlock(getNextPC(), target));
}
} else {
ifBlocks.removeLoopBlocks(target);
}
} else if (isReturn(seen)) {
if ((activeUnconditional != null) && !gotoBranchPCs.get(activeUnconditional.getEnd())) {
int ifSize = activeUnconditional.getEnd() - activeUnconditional.getStart();
// +1 for the return itself
int elseSize = (getPC() - activeUnconditional.getEnd()) + 1;
double ratio = (double) ifSize / (double) elseSize;
if (ratio > lowBugRatioLimit) {
bugReporter.reportBug(new BugInstance(this, BugType.BL_BURYING_LOGIC.name(), ratio > normalBugRatioLimit ? NORMAL_PRIORITY : LOW_PRIORITY).addClass(this).addMethod(this).addSourceLineRange(this, activeUnconditional.getStart(), activeUnconditional.getEnd()));
throw new StopOpcodeParsingException();
}
activeUnconditional = null;
} else {
IfBlock blockAtPC = ifBlocks.getBlockAt(getPC());
if ((blockAtPC != null) && (getNextPC() == blockAtPC.getEnd()) && !gotoAcrossPC(getNextPC())) {
activeUnconditional = blockAtPC;
}
}
} else if ((seen == Const.TABLESWITCH) || (seen == Const.LOOKUPSWITCH)) {
int[] offsets = getSwitchOffsets();
int pc = getPC();
for (int offset : offsets) {
casePositions.set(pc + offset);
}
casePositions.set(pc + getDefaultSwitchOffset());
}
} finally {
stack.sawOpcode(this, seen);
}
}
Aggregations