Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * fb-contrib - Auxiliary detectors for Java programs
   * Copyright (C) 2005-2014 Dave Brosius
   *
   * 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
  */
 package com.mebigfatguy.fbcontrib.detect;
 
 import java.util.Set;
 
 import  org.apache.bcel.classfile.Code;
 import  org.apache.bcel.classfile.CodeException;
 import  org.apache.bcel.classfile.Method;
 import  org.apache.bcel.generic.Type;
 
 
Looks for methods that store the return result in a local variable, and then immediately returns that local variable.
 
 public class UnnecessaryStoreBeforeReturn extends BytecodeScanningDetector
 {
 	enum State {SEEN_NOTHING, SEEN_STORE, SEEN_LOAD }
 
 	private static final BitSet branchInstructions = new BitSet();
 	private static final BitSet binaryOps = new BitSet();
 	static {
 		.set(IF_ICMPEQ);
 		.set(IF_ICMPNE);
 		.set(IF_ICMPLT);
 		.set(IF_ICMPGE);
 		.set(IF_ICMPGT);
 		.set(IF_ICMPLE);
 		.set(IF_ACMPEQ);
 		.set(IF_ACMPNE);
 		.set(IFNONNULL);
 
 		.set(IADD);
 		.set(LADD);
 		.set(FADD);
 		.set(DADD);
 		.set(ISUB);
 		.set(LSUB);
 		.set(FSUB);
 		.set(DSUB);
 		.set(IMUL);
 		.set(LMUL);
 		.set(FMUL);
 		.set(DMUL);
 		.set(IDIV);
 		.set(LDIV);
 		.set(FDIV);
 		.set(DDIV);
 		.set(IREM);
 		.set(LREM);
 		.set(FREM);
 		.set(DREM);
 		.set(IOR);
 	    .set(LOR);
 	    .set(IAND);
 	    .set(LAND);
 	    .set(IXOR);
 	    .set(LXOR);
 	    .set(ISHL);
 	    .set(LSHL);
         .set(ISHR);  
         .set(LSHR);  
        .set(IUSHR);
        .set(LUSHR);
	}
	private final BugReporter bugReporter;
	private OpcodeStack stack;
	private State state;
	private int storeReg;

constructs a USBR detector given the reporter to report bugs on

Parameters:
bugReporter the sync of bug reports
		this. = bugReporter;
	}

implements the visitor to create and clear the branchTargets

Parameters:
classContext the context object for the currently parsed class
	public void visitClassContext(ClassContext classContext) {
		try {
			 = new OpcodeStack();
			super.visitClassContext(classContext);
finally {
			 = null;
			 = null;
			 = null;
		}
	}
implements the visitor to make sure method returns a value, and then clears the targets

Parameters:
obj the context object of the currently parsed code block
	public void visitCode(Code obj) {
		Method m = getMethod();
		String sig = m.getSignature();
		Type t = Type.getReturnType(sig);
		if (!t.equals(Type.VOID)) {
			CodeException[] ces = obj.getExceptionTable();
			for (CodeException ce : ces) {
				if (ce.getCatchType() != 0) {
					.add(Integer.valueOf(ce.getHandlerPC()));
				}
			}
			super.visitCode(obj);
		}
	}

implements the visitor to look for store of registers immediately before returns of that register

Parameters:
seen the opcode of the currently parsed instruction
	public void sawOpcode(int seen) {
		int lhsReg = -1;
		try {
	        .precomputation(this);
	        
	        switch () {
					if (!.contains(Integer.valueOf(getPC()))) {
						if (lookForStore(seen)) {
							if (.getStackDepth() >= 1) {
								Integer reg = (Integer)item.getUserValue();
								if ((reg == null) || (reg.intValue() != )) {
								}
							}
						}
					}
				break;
					if (.contains(Integer.valueOf(getPC()))) {
						break;
					}
				break;
				case :
					if ((seen >= IRETURN) && (seen <= ARETURN)) {
						.reportBug(new BugInstance(this"USBR_UNNECESSARY_STORE_BEFORE_RETURN", NORMAL_PRIORITY)
							.addClass(this)
							.addMethod(this)
							.addSourceLine(this));
					}
				break;
			}
			if (.get(seen)) {
			}
			lhsReg = processBinOp(seen);
finally {
			TernaryPatcher.pre(seen);
			.sawOpcode(thisseen);
			TernaryPatcher.post(seen);
			if ((lhsReg > -1) && (.getStackDepth() >= 1)) {
				item.setUserValue(Integer.valueOf(lhsReg));
			}
		}
	}

checks if the current opcode is a store, if so saves the register

Parameters:
seen the opcode of the currently parsed instruction
Returns:
if a store was seen
	private boolean lookForStore(int seen) {
		if ((seen >= ISTORE) && (seen <= ASTORE))
		else if ((seen >= ISTORE_0) && (seen <= ISTORE_3))
			 = seen - ISTORE_0;
		else if ((seen >= LSTORE_0) && (seen <= LSTORE_3))
			 = seen - LSTORE_0;
		else if ((seen >= FSTORE_0) && (seen <= FSTORE_3))
			 = seen - FSTORE_0;
		else if ((seen >= DSTORE_0) && (seen <= DSTORE_3))
			 = seen - DSTORE_0;
		else if ((seen >= ASTORE_0) && (seen <= ASTORE_3))
			 = seen - ASTORE_0;
		else
			return false;
		return true;
	}

looks for a load of the register that was just stored

Parameters:
seen the opcode of the currently parsed instruction
Returns:
if the load was seen
	private boolean lookForLoad(int seen) {
		int loadReg;
		if ((seen >= ILOAD) && (seen <= ALOAD))
			loadReg = getRegisterOperand();
		else if ((seen >= ILOAD_0) && (seen <= ILOAD_3))
			loadReg = seen - ILOAD_0;
		else if ((seen >= LLOAD_0) && (seen <= LLOAD_3))
			loadReg = seen - LLOAD_0;
		else if ((seen >= FLOAD_0) && (seen <= FLOAD_3))
			loadReg = seen - FLOAD_0;
		else if ((seen >= DLOAD_0) && (seen <= DLOAD_3))
			loadReg = seen - DLOAD_0;
		else if ((seen >= ALOAD_0) && (seen <= ALOAD_3))
			loadReg = seen - ALOAD_0;
		else
			return false;
		return ( == loadReg);
	}

looks for instructions that are binary operators, and if it is saves the left hand side register (if it exists) in the userValue.

Parameters:
seen the opcode of the currently parsed instruction
Returns:
the lhs register number if it exists or -1
	private int processBinOp(int seen) {
		if (.get(seen)) {
			if (.getStackDepth() >= 2) {
				return item.getRegisterNumber();
			}
		}
		return -1;
	}
New to GrepCode? Check out our FAQ X