org.apache.bcel.generic.INVOKESTATIC Java Examples

The following examples show how to use org.apache.bcel.generic.INVOKESTATIC. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: Pass3aVerifier.java    From commons-bcel with Apache License 2.0 6 votes vote down vote up
/** Checks if the constraints of operands of the said instruction(s) are satisfied. */
@Override
public void visitINVOKESTATIC(final INVOKESTATIC o) {
    try {
    // INVOKESTATIC is a LoadClass; the Class where the referenced method is declared in,
    // is therefore resolved/verified.
    // INVOKESTATIC is an InvokeInstruction, the argument and return types are resolved/verified,
    // too. So are the allowed method names.
    final String classname = o.getClassName(constantPoolGen);
    final JavaClass jc = Repository.lookupClass(classname);
    final Method m = getMethodRecursive(jc, o);
    if (m == null) {
        constraintViolated(o, "Referenced method '"+o.getMethodName(constantPoolGen)+"' with expected signature '"+
            o.getSignature(constantPoolGen) +"' not found in class '"+jc.getClassName()+"'.");
    } else if (! (m.isStatic())) { // implies it's not abstract, verified in pass 2.
        constraintViolated(o, "Referenced method '"+o.getMethodName(constantPoolGen)+"' has ACC_STATIC unset.");
    }

    } catch (final ClassNotFoundException e) {
    // FIXME: maybe not the best way to handle this
    throw new AssertionViolatedException("Missing class: " + e, e);
    }
}
 
Example #2
Source File: Hierarchy2.java    From spotbugs with GNU Lesser General Public License v2.1 6 votes vote down vote up
/**
 * Find the declared exceptions for the method called by given instruction.
 *
 * @param inv
 *            the InvokeInstruction
 * @param cpg
 *            the ConstantPoolGen used by the class the InvokeInstruction
 *            belongs to
 * @return array of ObjectTypes of thrown exceptions, or null if we can't
 *         find the method implementation
 */
public static @CheckForNull ObjectType[] findDeclaredExceptions(InvokeInstruction inv, ConstantPoolGen cpg) {
    XMethod method = findInvocationLeastUpperBound(inv, cpg, inv instanceof INVOKESTATIC ? STATIC_METHOD : INSTANCE_METHOD);

    if (method == null) {
        return null;
    }
    String[] exceptions = method.getThrownExceptions();

    if (exceptions == null) {
        return new ObjectType[0];
    }

    ObjectType[] result = new ObjectType[exceptions.length];
    for (int i = 0; i < exceptions.length; ++i) {
        result[i] = ObjectTypeFactory.getInstance(ClassName.toDottedClassName(exceptions[i]));
    }
    return result;
}
 
Example #3
Source File: Hierarchy.java    From spotbugs with GNU Lesser General Public License v2.1 5 votes vote down vote up
/**
 * Determine if given Instruction is a monitor wait.
 *
 * @param ins
 *            the Instruction
 * @param cpg
 *            the ConstantPoolGen for the Instruction
 *
 * @return true if the instruction is a monitor wait, false if not
 */
public static boolean isMonitorWait(Instruction ins, ConstantPoolGen cpg) {
    if (!(ins instanceof InvokeInstruction)) {
        return false;
    }
    if (ins.getOpcode() == Const.INVOKESTATIC) {
        return false;
    }

    InvokeInstruction inv = (InvokeInstruction) ins;
    String methodName = inv.getMethodName(cpg);
    String methodSig = inv.getSignature(cpg);

    return isMonitorWait(methodName, methodSig);
}
 
Example #4
Source File: Hierarchy.java    From spotbugs with GNU Lesser General Public License v2.1 5 votes vote down vote up
/**
 * Get the InnerClassAccess for access method called by given INVOKESTATIC.
 *
 * @param inv
 *            the INVOKESTATIC instruction
 * @param cpg
 *            the ConstantPoolGen for the method
 * @return the InnerClassAccess, or null if the instruction is not an
 *         inner-class access
 */
public static InnerClassAccess getInnerClassAccess(INVOKESTATIC inv, ConstantPoolGen cpg) throws ClassNotFoundException {

    String className = inv.getClassName(cpg);
    String methodName = inv.getName(cpg);
    String methodSig = inv.getSignature(cpg);

    InnerClassAccess access = AnalysisContext.currentAnalysisContext().getInnerClassAccessMap()
            .getInnerClassAccess(className, methodName);
    return (access != null && access.getMethodSignature().equals(methodSig)) ? access : null;
}
 
Example #5
Source File: Hierarchy.java    From spotbugs with GNU Lesser General Public License v2.1 5 votes vote down vote up
/**
 * Determine if given Instruction is a monitor wait.
 *
 * @param ins
 *            the Instruction
 * @param cpg
 *            the ConstantPoolGen for the Instruction
 *
 * @return true if the instruction is a monitor wait, false if not
 */
public static boolean isMonitorNotify(Instruction ins, ConstantPoolGen cpg) {
    if (!(ins instanceof InvokeInstruction)) {
        return false;
    }
    if (ins.getOpcode() == Const.INVOKESTATIC) {
        return false;
    }

    InvokeInstruction inv = (InvokeInstruction) ins;
    String methodName = inv.getMethodName(cpg);
    String methodSig = inv.getSignature(cpg);

    return isMonitorNotify(methodName, methodSig);
}
 
Example #6
Source File: ValueNumberFrameModelingVisitor.java    From spotbugs with GNU Lesser General Public License v2.1 5 votes vote down vote up
public void visitInvokeOnException(Instruction obj) {
    if (!REDUNDANT_LOAD_ELIMINATION || !getFrame().hasAvailableLoads()) {
        return;
    }
    if (obj instanceof INVOKEDYNAMIC) {
        killLoadsOfObjectsPassed((INVOKEDYNAMIC) obj);
        return;
    }
    InvokeInstruction inv = (InvokeInstruction) obj;
    if ((inv instanceof INVOKEINTERFACE || inv instanceof INVOKEVIRTUAL)
            && inv.getMethodName(cpg).toLowerCase().indexOf("lock") >= 0) {
        // Don't know what this method invocation is doing.
        // Kill all loads.
        getFrame().killAllLoads();
        return;
    }
    if (inv instanceof INVOKEVIRTUAL && "cast".equals(inv.getMethodName(cpg)) && "java.lang.Class".equals(inv.getClassName(cpg))) {
        // No-op
        return;
    }
    if (inv instanceof INVOKESTATIC) {
        String methodName = inv.getName(cpg);
        if (("forName".equals(methodName) && "java.lang.Class".equals(inv.getClassName(cpg)) || "class$".equals(methodName))
                && "(Ljava/lang/String;)Ljava/lang/Class;".equals(inv.getSignature(cpg))
                || (Hierarchy.isInnerClassAccess((INVOKESTATIC) inv, cpg) && loadedFieldSet.getField(handle) != null)) {
            return;
        }
    }

    killLoadsOfObjectsPassed(inv);
    if (inv instanceof INVOKESTATIC) {
        getFrame().killAllLoadsOf(null);
    }
}
 
Example #7
Source File: TargetEnumeratingVisitor.java    From spotbugs with GNU Lesser General Public License v2.1 5 votes vote down vote up
@Override
public void visitINVOKESTATIC(INVOKESTATIC ins) {
    // Find calls to System.exit(), since this effectively terminates the
    // basic block.

    String className = ins.getClassName(constPoolGen);
    String methodName = ins.getName(constPoolGen);
    String methodSig = ins.getSignature(constPoolGen);

    if ("java.lang.System".equals(className) && "exit".equals(methodName) && "(I)V".equals(methodSig)) {
        isExit = true;
    }
}
 
Example #8
Source File: FindSleepWithLockHeld.java    From spotbugs with GNU Lesser General Public License v2.1 5 votes vote down vote up
private boolean isSleep(INVOKESTATIC ins, ConstantPoolGen cpg) {
    String className = ins.getClassName(cpg);
    if (!"java.lang.Thread".equals(className)) {
        return false;
    }
    String methodName = ins.getMethodName(cpg);
    String signature = ins.getSignature(cpg);

    return "sleep".equals(methodName) && ("(J)V".equals(signature) || "(JI)V".equals(signature));
}
 
Example #9
Source File: FindSleepWithLockHeld.java    From spotbugs with GNU Lesser General Public License v2.1 5 votes vote down vote up
private void analyzeMethod(ClassContext classContext, Method method) throws CFGBuilderException, DataflowAnalysisException {
    // System.out.println("Checking " + method);

    CFG cfg = classContext.getCFG(method);
    LockDataflow lockDataflow = classContext.getLockDataflow(method);

    for (Iterator<Location> i = cfg.locationIterator(); i.hasNext();) {
        Location location = i.next();
        Instruction ins = location.getHandle().getInstruction();

        if (!(ins instanceof INVOKESTATIC)) {
            continue;
        }

        if (!isSleep((INVOKESTATIC) ins, classContext.getConstantPoolGen())) {
            continue;
        }

        // System.out.println("Found sleep at " + location.getHandle());

        LockSet lockSet = lockDataflow.getFactAtLocation(location);
        if (lockSet.getNumLockedObjects() > 0) {
            bugAccumulator.accumulateBug(
                    new BugInstance(this, "SWL_SLEEP_WITH_LOCK_HELD", NORMAL_PRIORITY).addClassAndMethod(
                            classContext.getJavaClass(), method), classContext, method, location);
        }
    }
    bugAccumulator.reportAccumulatedBugs();
}
 
Example #10
Source File: SelfCalls.java    From spotbugs with GNU Lesser General Public License v2.1 5 votes vote down vote up
/**
 * Is the given instruction a self-call?
 */
private Method isSelfCall(InvokeInstruction inv) {
    ConstantPoolGen cpg = classContext.getConstantPoolGen();
    JavaClass jclass = classContext.getJavaClass();

    String calledClassName = inv.getClassName(cpg);

    // FIXME: is it possible we would see a superclass name here?
    // Not a big deal for now, as we are mostly just interested in calls
    // to private methods, for which we will definitely see the right
    // called class name.
    if (!calledClassName.equals(jclass.getClassName())) {
        return null;
    }

    String calledMethodName = inv.getMethodName(cpg);
    String calledMethodSignature = inv.getSignature(cpg);
    boolean isStaticCall = (inv instanceof INVOKESTATIC);

    // Scan methods for one that matches.
    Method[] methods = jclass.getMethods();
    for (Method method : methods) {
        String methodName = method.getName();
        String signature = method.getSignature();
        boolean isStatic = method.isStatic();

        if (methodName.equals(calledMethodName) && signature.equals(calledMethodSignature) && isStatic == isStaticCall) {
            // This method looks like a match.
            return wantCallsFor(method) ? method : null;
        }
    }

    // Hmm...no matching method found.
    // This is almost certainly because the named method
    // was inherited from a superclass.
    LOG.debug("No method found for {}.{} : {}", calledClassName, calledMethodName, calledMethodSignature);
    return null;
}
 
Example #11
Source File: FindRefComparison.java    From spotbugs with GNU Lesser General Public License v2.1 5 votes vote down vote up
public MethodDescriptor getInvokedMethod(ConstantPoolGen cpg, InvokeInstruction inv) {
    String invoked = inv.getClassName(cpg);
    String methodName = inv.getMethodName(cpg);
    String methodSig = inv.getSignature(cpg);
    MethodDescriptor invokedMethod =
            DescriptorFactory.instance().getMethodDescriptor(ClassName.toSlashedClassName(invoked), methodName, methodSig,
                    inv instanceof INVOKESTATIC);
    return invokedMethod;
}
 
Example #12
Source File: FindUnrelatedTypesInGenericContainer.java    From spotbugs with GNU Lesser General Public License v2.1 5 votes vote down vote up
/**
 * Use this to screen out methods that do not contain invocations.
 */
public boolean prescreen(ClassContext classContext, Method method) {
    BitSet bytecodeSet = classContext.getBytecodeSet(method);
    return bytecodeSet != null
            && (bytecodeSet.get(Const.INVOKEINTERFACE) || bytecodeSet.get(Const.INVOKEVIRTUAL)
                    || bytecodeSet.get(Const.INVOKESPECIAL) || bytecodeSet.get(Const.INVOKESTATIC) || bytecodeSet
                            .get(Const.INVOKENONVIRTUAL));
}
 
Example #13
Source File: FindRefComparison.java    From spotbugs with GNU Lesser General Public License v2.1 5 votes vote down vote up
@Override
public void visitINVOKESTATIC(INVOKESTATIC obj) {
    if (returnsString(obj)) {
        consumeStack(obj);

        String className = obj.getClassName(getCPG());
        if (Values.DOTTED_JAVA_LANG_STRING.equals(className)) {
            pushValue(dynamicStringTypeInstance);
        } else {
            pushReturnType(obj);
        }
    } else {
        super.visitINVOKESTATIC(obj);
    }
}
 
Example #14
Source File: FindSleepWithLockHeld.java    From spotbugs with GNU Lesser General Public License v2.1 5 votes vote down vote up
private boolean prescreen(ClassContext classContext, Method method) {
    BitSet bytecodeSet = classContext.getBytecodeSet(method);
    if (bytecodeSet == null
            // method must acquire a lock
            || (!bytecodeSet.get(Const.MONITORENTER) && !method.isSynchronized())) {
        return false;
    }

    // and contain a static method invocation
    return bytecodeSet.get(Const.INVOKESTATIC);
}
 
Example #15
Source File: Hierarchy.java    From spotbugs with GNU Lesser General Public License v2.1 4 votes vote down vote up
/**
 * Resolve possible instance method call targets.
 *
 * @param receiverType
 *            type of the receiver object
 * @param invokeInstruction
 *            the InvokeInstruction
 * @param cpg
 *            the ConstantPoolGen
 * @param receiverTypeIsExact
 *            if true, the receiver type is known exactly, which should
 *            allow a precise result
 * @return Set of methods which might be called
 * @throws ClassNotFoundException
 */
public static Set<JavaClassAndMethod> resolveMethodCallTargets(ReferenceType receiverType,
        InvokeInstruction invokeInstruction, ConstantPoolGen cpg, boolean receiverTypeIsExact) throws ClassNotFoundException {
    HashSet<JavaClassAndMethod> result = new HashSet<>();

    if (invokeInstruction.getOpcode() == Const.INVOKESTATIC) {
        throw new IllegalArgumentException();
    }

    String methodName = invokeInstruction.getName(cpg);
    String methodSig = invokeInstruction.getSignature(cpg);

    // Array method calls aren't virtual.
    // They should just resolve to Object methods.
    if (receiverType instanceof ArrayType) {
        JavaClass javaLangObject = AnalysisContext.currentAnalysisContext().lookupClass(Values.DOTTED_JAVA_LANG_OBJECT);
        JavaClassAndMethod classAndMethod = findMethod(javaLangObject, methodName, methodSig, INSTANCE_METHOD);
        if (classAndMethod != null) {
            result.add(classAndMethod);
        }
        return result;
    }

    if (receiverType instanceof NullType) {
        return Collections.<JavaClassAndMethod>emptySet();
    }
    AnalysisContext analysisContext = AnalysisContext.currentAnalysisContext();

    // Get the receiver class.
    String receiverClassName = ((ObjectType) receiverType).getClassName();
    JavaClass receiverClass = analysisContext.lookupClass(receiverClassName);
    ClassDescriptor receiverDesc = DescriptorFactory.createClassDescriptorFromDottedClassName(receiverClassName);

    // Figure out the upper bound for the method.
    // This is what will be called if this is not a virtual call site.
    JavaClassAndMethod upperBound = findMethod(receiverClass, methodName, methodSig, CONCRETE_METHOD);
    if (upperBound == null) {
        upperBound = findInvocationLeastUpperBound(receiverClass, methodName, methodSig, CONCRETE_METHOD, false);
    }
    if (upperBound != null) {
        if (DEBUG_METHOD_LOOKUP) {
            System.out.println("Adding upper bound: "
                    + SignatureConverter.convertMethodSignature(upperBound.getJavaClass(), upperBound.getMethod()));
        }
        result.add(upperBound);
    }

    // Is this a virtual call site?
    boolean virtualCall = (invokeInstruction.getOpcode() == Const.INVOKEVIRTUAL || invokeInstruction.getOpcode() == Const.INVOKEINTERFACE)
            && (upperBound == null || !upperBound.getJavaClass().isFinal() && !upperBound.getMethod().isFinal())
            && !receiverTypeIsExact;

    if (virtualCall) {
        if (!Values.DOTTED_JAVA_LANG_OBJECT.equals(receiverClassName)) {

            // This is a true virtual call: assume that any concrete
            // subtype method may be called.
            Set<ClassDescriptor> subTypeSet = analysisContext.getSubtypes2().getSubtypes(receiverDesc);
            for (ClassDescriptor subtype : subTypeSet) {
                XMethod concreteSubtypeMethod = findMethod(subtype, methodName, methodSig, false);
                if (concreteSubtypeMethod != null && (concreteSubtypeMethod.getAccessFlags() & Const.ACC_ABSTRACT) == 0) {
                    result.add(new JavaClassAndMethod(concreteSubtypeMethod));
                }
            }
            if (false && subTypeSet.size() > 500) {
                new RuntimeException(receiverClassName + " has " + subTypeSet.size() + " subclasses, " + result.size()
                        + " of which implement " + methodName + methodSig + " " + invokeInstruction)
                                .printStackTrace(System.out);
            }

        }
    }
    return result;
}
 
Example #16
Source File: ASTFunAppl.java    From commons-bcel with Apache License 2.0 4 votes vote down vote up
/**
   * Fifth pass, produce Java byte code.
   */
  @Override
  public void byte_code(final InstructionList il, final MethodGen method, final ConstantPoolGen cp) {
    final String     fname = name.getName();
//    Function   f     = function;
    //ASTIdent   fun   = f.getName();
//    ASTIdent[] args  = f.getArgs();
    final String     class_name = method.getClassName();

    if(fname.equals("READ")) {
        il.append(new INVOKESTATIC(cp.addMethodref(class_name,
                                                 "_readInt",
                                                 "()I")));
    } else if(fname.equals("WRITE")) {
      exprs[0].byte_code(il, method, cp);
      ASTFunDecl.pop();
      il.append(new INVOKESTATIC(cp.addMethodref(class_name,
                                                 "_writeInt",
                                                 "(I)I")));
    }
    else { // Normal function
      final int size    = exprs.length;
      Type[] argv = null;

      if(exprs != null) {
        argv = new Type[size];

        for(int i=0; i < size; i++) {
          argv[i] = Type.INT;
          exprs[i].byte_code(il, method, cp);
        }

        //ASTFunDecl.push(size);
      }

      ASTFunDecl.pop(size);

      // Function call
      il.append(new INVOKESTATIC(cp.addMethodref(class_name,
                                                 fname,
                                                 Type.getMethodSignature(Type.INT,
                                                                         argv))));
    }

    ASTFunDecl.push();
  }
 
Example #17
Source File: ReferenceVisitor.java    From contribution with GNU Lesser General Public License v2.1 4 votes vote down vote up
/** @see org.apache.bcel.generic.Visitor */
public void visitINVOKESTATIC(INVOKESTATIC aINVOKESTATIC)
{
    addInvokeReference(
        new InvokeReference(aINVOKESTATIC, mCurrentPoolGen));
}
 
Example #18
Source File: ReferenceVisitor.java    From cacheonix-core with GNU Lesser General Public License v2.1 4 votes vote down vote up
/** @see org.apache.bcel.generic.Visitor */
public void visitINVOKESTATIC(INVOKESTATIC aINVOKESTATIC)
{
    addInvokeReference(
        new InvokeReference(aINVOKESTATIC, mCurrentPoolGen));
}
 
Example #19
Source File: IsNullValueFrameModelingVisitor.java    From spotbugs with GNU Lesser General Public License v2.1 4 votes vote down vote up
@Override
public void visitINVOKESTATIC(INVOKESTATIC obj) {
    handleInvoke(obj);
}
 
Example #20
Source File: Hierarchy2.java    From spotbugs with GNU Lesser General Public License v2.1 4 votes vote down vote up
/**
 * Resolve possible method call targets. This works for both static and
 * instance method calls.
 *
 * @param invokeInstruction
 *            the InvokeInstruction
 * @param typeFrame
 *            the TypeFrame containing the types of stack values
 * @param cpg
 *            the ConstantPoolGen
 * @return Set of methods which might be called
 * @throws DataflowAnalysisException
 * @throws ClassNotFoundException
 */
public static @Nonnull Set<XMethod> resolveMethodCallTargets(InvokeInstruction invokeInstruction, TypeFrame typeFrame, ConstantPoolGen cpg)
        throws DataflowAnalysisException, ClassNotFoundException {

    short opcode = invokeInstruction.getOpcode();

    if (opcode == Const.INVOKESTATIC) {
        return Util.emptyOrNonnullSingleton(findInvocationLeastUpperBound(invokeInstruction, cpg, STATIC_METHOD));
    }

    if (!typeFrame.isValid()) {
        return Collections.<XMethod>emptySet();
    }

    // XXX handle INVOKEDYNAMIC
    if (opcode == Const.INVOKEDYNAMIC) {
        return Collections.<XMethod>emptySet();
    }

    Type receiverType;
    boolean receiverTypeIsExact;

    if (opcode == Const.INVOKESPECIAL) {
        // invokespecial instructions are dispatched to EXACTLY
        // the class specified by the instruction
        receiverType = ObjectTypeFactory.getInstance(invokeInstruction.getClassName(cpg));
        receiverTypeIsExact = false; // Doesn't actually matter
    } else {
        // For invokevirtual and invokeinterface instructions, we have
        // virtual dispatch. By taking the receiver type (which may be a
        // subtype of the class specified by the instruction),
        // we may get a more precise set of call targets.
        int instanceStackLocation = typeFrame.getInstanceStackLocation(invokeInstruction, cpg);
        receiverType = typeFrame.getStackValue(instanceStackLocation);
        if (!(receiverType instanceof ReferenceType)) {
            return Collections.<XMethod>emptySet();
        }
        receiverTypeIsExact = typeFrame.isExact(instanceStackLocation);
    }
    if (DEBUG_METHOD_LOOKUP) {
        System.out.println("[receiver type is " + receiverType + ", " + (receiverTypeIsExact ? "exact]" : " not exact]"));
    }

    return resolveMethodCallTargets((ReferenceType) receiverType, invokeInstruction, cpg, receiverTypeIsExact);
}
 
Example #21
Source File: Hierarchy2.java    From spotbugs with GNU Lesser General Public License v2.1 4 votes vote down vote up
public static @CheckForNull XMethod findInvocationLeastUpperBound(InvokeInstruction inv, ConstantPoolGen cpg,
        JavaClassAndMethodChooser methodChooser) {

    if (DEBUG_METHOD_LOOKUP) {
        System.out.println("Find prototype method for " + SignatureConverter.convertMethodSignature(inv, cpg));
    }

    short opcode = inv.getOpcode();

    if (opcode == Const.INVOKESTATIC) {
        if (methodChooser == INSTANCE_METHOD) {
            return null;
        }
    } else {
        if (methodChooser == STATIC_METHOD) {
            return null;
        }
    }

    // Find the method
    if (opcode == Const.INVOKESPECIAL) {
        // Non-virtual dispatch
        return findExactMethod(inv, cpg, methodChooser);
    } else {
        String className = inv.getClassName(cpg);
        String methodName = inv.getName(cpg);
        String methodSig = inv.getSignature(cpg);
        if (DEBUG_METHOD_LOOKUP) {
            System.out.println("[Class name is " + className + "]");
            System.out.println("[Method name is " + methodName + "]");
            System.out.println("[Method signature is " + methodSig + "]");
        }

        if (className.startsWith(Values.SIG_ARRAY_PREFIX)) {
            // Java 1.5 allows array classes to appear as the class name
            className = Values.DOTTED_JAVA_LANG_OBJECT;
        }

        try {
            return thisOrNothing(
                    findInvocationLeastUpperBound(getXClassFromDottedClassName(className), methodName, methodSig,
                            opcode == Const.INVOKESTATIC, opcode == Const.INVOKEINTERFACE), methodChooser);
        } catch (CheckedAnalysisException e) {
            return null;
        }

    }
}
 
Example #22
Source File: Hierarchy.java    From spotbugs with GNU Lesser General Public License v2.1 4 votes vote down vote up
/**
 * Resolve possible method call targets. This works for both static and
 * instance method calls.
 *
 * @param invokeInstruction
 *            the InvokeInstruction
 * @param typeFrame
 *            the TypeFrame containing the types of stack values
 * @param cpg
 *            the ConstantPoolGen
 * @return Set of methods which might be called
 * @throws DataflowAnalysisException
 * @throws ClassNotFoundException
 */
public static Set<JavaClassAndMethod> resolveMethodCallTargets(InvokeInstruction invokeInstruction, TypeFrame typeFrame,
        ConstantPoolGen cpg) throws DataflowAnalysisException, ClassNotFoundException {

    short opcode = invokeInstruction.getOpcode();

    if (opcode == Const.INVOKESTATIC) {
        HashSet<JavaClassAndMethod> result = new HashSet<>();
        JavaClassAndMethod targetMethod = findInvocationLeastUpperBound(invokeInstruction, cpg, CONCRETE_METHOD);
        if (targetMethod != null) {
            result.add(targetMethod);
        }
        return result;
    }

    if (!typeFrame.isValid()) {
        return new HashSet<>();
    }

    Type receiverType;
    boolean receiverTypeIsExact;

    if (opcode == Const.INVOKESPECIAL) {
        // invokespecial instructions are dispatched to EXACTLY
        // the class specified by the instruction
        receiverType = ObjectTypeFactory.getInstance(invokeInstruction.getClassName(cpg));
        receiverTypeIsExact = false; // Doesn't actually matter
    } else if (opcode == Const.INVOKEDYNAMIC) {
        // XXX handle INVOKEDYNAMIC
        return new HashSet<>();
    } else {
        // For invokevirtual and invokeinterface instructions, we have
        // virtual dispatch. By taking the receiver type (which may be a
        // subtype of the class specified by the instruction),
        // we may get a more precise set of call targets.
        int instanceStackLocation = typeFrame.getInstanceStackLocation(invokeInstruction, cpg);
        receiverType = typeFrame.getStackValue(instanceStackLocation);
        if (!(receiverType instanceof ReferenceType)) {
            return new HashSet<>();
        }
        receiverTypeIsExact = typeFrame.isExact(instanceStackLocation);
    }
    if (DEBUG_METHOD_LOOKUP) {
        System.out.println("[receiver type is " + receiverType + ", " + (receiverTypeIsExact ? "exact]" : " not exact]"));
    }

    return resolveMethodCallTargets((ReferenceType) receiverType, invokeInstruction, cpg, receiverTypeIsExact);
}
 
Example #23
Source File: Hierarchy.java    From spotbugs with GNU Lesser General Public License v2.1 4 votes vote down vote up
public static @CheckForNull JavaClassAndMethod findInvocationLeastUpperBound(InvokeInstruction inv, ConstantPoolGen cpg,
        JavaClassAndMethodChooser methodChooser) throws ClassNotFoundException {

    if (DEBUG_METHOD_LOOKUP) {
        System.out.println("Find prototype method for " + SignatureConverter.convertMethodSignature(inv, cpg));
    }

    short opcode = inv.getOpcode();

    if (opcode == Const.INVOKESTATIC) {
        if (methodChooser == INSTANCE_METHOD) {
            return null;
        }
    } else {
        if (methodChooser == STATIC_METHOD) {
            return null;
        }
    }

    // Find the method
    if (opcode == Const.INVOKESPECIAL) {
        // Non-virtual dispatch
        return findExactMethod(inv, cpg, methodChooser);
    }
    if (opcode == Const.INVOKEDYNAMIC) {
        return null;
    }
    String className = inv.getClassName(cpg);
    String methodName = inv.getName(cpg);
    String methodSig = inv.getSignature(cpg);
    if (DEBUG_METHOD_LOOKUP) {
        System.out.println("[Class name is " + className + "]");
        System.out.println("[Method name is " + methodName + "]");
        System.out.println("[Method signature is " + methodSig + "]");
    }

    if (className.startsWith(Values.SIG_ARRAY_PREFIX)) {
        // Java 1.5 allows array classes to appear as the class name
        className = Values.DOTTED_JAVA_LANG_OBJECT;
    }

    JavaClass jClass = Repository.lookupClass(className);
    return findInvocationLeastUpperBound(jClass, methodName, methodSig, methodChooser,
            opcode == Const.INVOKEINTERFACE);
}
 
Example #24
Source File: FindRefComparison.java    From spotbugs with GNU Lesser General Public License v2.1 4 votes vote down vote up
private void inspectLocation(JavaClass jclass, ConstantPoolGen cpg, Method method, MethodGen methodGen,
        LinkedList<WarningWithProperties> refComparisonList, LinkedList<WarningWithProperties> stringComparisonList,
        RefComparisonTypeFrameModelingVisitor visitor, TypeDataflow typeDataflow, Location location)
        throws DataflowAnalysisException {
    Instruction ins = location.getHandle().getInstruction();
    short opcode = ins.getOpcode();
    if (opcode == Const.IF_ACMPEQ || opcode == Const.IF_ACMPNE) {
        checkRefComparison(location, jclass, method, methodGen, visitor, typeDataflow, stringComparisonList,
                refComparisonList);
    } else if (ins instanceof InvokeInstruction) {
        InvokeInstruction inv = (InvokeInstruction) ins;
        boolean isStatic = inv instanceof INVOKESTATIC;
        @DottedClassName
        String className = inv.getClassName(cpg);
        String methodName = inv.getMethodName(cpg);
        String methodSig = inv.getSignature(cpg);
        if ("assertSame".equals(methodName) && "(Ljava/lang/Object;Ljava/lang/Object;)V".equals(methodSig)) {
            checkRefComparison(location, jclass, method, methodGen, visitor, typeDataflow, stringComparisonList,
                    refComparisonList);
        } else if ("assertFalse".equals(methodName) && "(Z)V".equals(methodSig)) {
            SourceLineAnnotation lastLocation = bugAccumulator.getLastBugLocation();
            InstructionHandle prevHandle = location.getHandle().getPrev();
            if (lastLocation != null && prevHandle != null && lastLocation.getEndBytecode() == prevHandle.getPosition()) {
                bugAccumulator.forgetLastBug();
                if (DEBUG) {
                    System.out.println("Forgetting last bug due to call to " + className + "." + methodName);
                }
            }

        } else {
            boolean equalsMethod = !isStatic && "equals".equals(methodName) && "(Ljava/lang/Object;)Z".equals(methodSig)
                    || isStatic && "assertEquals".equals(methodName)
                            && "(Ljava/lang/Object;Ljava/lang/Object;)V".equals(methodSig)
                    || isStatic && "equal".equals(methodName) && "(Ljava/lang/Object;Ljava/lang/Object;)Z".equals(methodSig)
                            && "com.google.common.base.Objects".equals(className)
                    || isStatic && "equals".equals(methodName) && "(Ljava/lang/Object;Ljava/lang/Object;)Z".equals(methodSig)
                            && "java.util.Objects".equals(className);

            if (equalsMethod) {
                checkEqualsComparison(location, jclass, method, methodGen, cpg, typeDataflow);
            }
        }
    }

}
 
Example #25
Source File: TaintFrameModelingVisitor.java    From Android_Code_Arbiter with GNU Lesser General Public License v3.0 4 votes vote down vote up
@Override
public void visitINVOKESTATIC(INVOKESTATIC obj) {
    visitInvoke(obj);
}
 
Example #26
Source File: FindRefComparison.java    From spotbugs with GNU Lesser General Public License v2.1 4 votes vote down vote up
private void checkRefComparison(Location location, JavaClass jclass, Method method, MethodGen methodGen,
        RefComparisonTypeFrameModelingVisitor visitor, TypeDataflow typeDataflow,
        List<WarningWithProperties> stringComparisonList, List<WarningWithProperties> refComparisonList)
        throws DataflowAnalysisException {

    InstructionHandle handle = location.getHandle();

    TypeFrame frame = typeDataflow.getFactAtLocation(location);
    if (frame.getStackDepth() < 2) {
        throw new DataflowAnalysisException("Stack underflow", methodGen, handle);
    }

    int numSlots = frame.getNumSlots();
    Type lhsType = frame.getValue(numSlots - 2);
    Type rhsType = frame.getValue(numSlots - 1);

    if (lhsType instanceof NullType || rhsType instanceof NullType) {
        return;
    }
    if (lhsType instanceof ReferenceType && rhsType instanceof ReferenceType) {
        IncompatibleTypes result = IncompatibleTypes.getPriorityForAssumingCompatible(lhsType, rhsType, true);
        if (result != IncompatibleTypes.SEEMS_OK && result != IncompatibleTypes.UNCHECKED) {
            String sourceFile = jclass.getSourceFileName();

            boolean isAssertSame = handle.getInstruction() instanceof INVOKESTATIC;
            if (isAssertSame) {
                if (testingEnabled) {
                    bugAccumulator.accumulateBug(
                            new BugInstance(this, "TESTING", result.getPriority())
                                    .addClassAndMethod(methodGen, sourceFile)
                                    .addString("Calling assertSame with two distinct objects")
                                    .addFoundAndExpectedType(rhsType, lhsType)
                                    .addSomeSourceForTopTwoStackValues(classContext, method, location),
                            SourceLineAnnotation.fromVisitedInstruction(classContext, methodGen, sourceFile, handle));
                }
            } else {
                bugAccumulator.accumulateBug(
                        new BugInstance(this, "EC_UNRELATED_TYPES_USING_POINTER_EQUALITY", result.getPriority())
                                .addClassAndMethod(methodGen, sourceFile).addFoundAndExpectedType(rhsType, lhsType)
                                .addSomeSourceForTopTwoStackValues(classContext, method, location),
                        SourceLineAnnotation.fromVisitedInstruction(classContext, methodGen, sourceFile, handle));
            }
            return;
        }
        if (lhsType.equals(Type.OBJECT) && rhsType.equals(Type.OBJECT)) {
            return;
        }
        String lhs = SignatureConverter.convert(lhsType.getSignature());
        String rhs = SignatureConverter.convert(rhsType.getSignature());

        if (Values.DOTTED_JAVA_LANG_STRING.equals(lhs) || Values.DOTTED_JAVA_LANG_STRING.equals(rhs)) {
            handleStringComparison(jclass, method, methodGen, visitor, stringComparisonList, location, lhsType, rhsType);
        } else if (suspiciousSet.contains(lhs)) {
            handleSuspiciousRefComparison(jclass, method, methodGen, refComparisonList, location, lhs,
                    (ReferenceType) lhsType, (ReferenceType) rhsType);
        } else if (suspiciousSet.contains(rhs)) {
            handleSuspiciousRefComparison(jclass, method, methodGen, refComparisonList, location, rhs,
                    (ReferenceType) lhsType, (ReferenceType) rhsType);
        }
    }
}
 
Example #27
Source File: ResourceValueFrameModelingVisitor.java    From spotbugs with GNU Lesser General Public License v2.1 4 votes vote down vote up
@Override
public void visitINVOKESTATIC(INVOKESTATIC inv) {
    handleInvoke(inv);
}
 
Example #28
Source File: MethodDescriptor.java    From spotbugs with GNU Lesser General Public License v2.1 4 votes vote down vote up
public MethodDescriptor(InvokeInstruction iins, ConstantPoolGen cpg) {
    super(ClassName.toSlashedClassName(iins.getClassName(cpg)), iins.getMethodName(cpg), iins.getSignature(cpg), iins instanceof INVOKESTATIC);
}
 
Example #29
Source File: FindInconsistentSync2.java    From spotbugs with GNU Lesser General Public License v2.1 4 votes vote down vote up
/**
 * Determine whether or not the the given method is a getter method. I.e.,
 * if it just returns the value of an instance field.
 *
 * @param classContext
 *            the ClassContext for the class containing the method
 * @param method
 *            the method
 */
public static boolean isGetterMethod(ClassContext classContext, Method method) {
    MethodGen methodGen = classContext.getMethodGen(method);
    if (methodGen == null) {
        return false;
    }
    InstructionList il = methodGen.getInstructionList();
    // System.out.println("Checking getter method: " + method.getName());
    if (il.getLength() > 60) {
        return false;
    }

    int count = 0;
    for (InstructionHandle ih : il) {
        switch (ih.getInstruction().getOpcode()) {
        case Const.GETFIELD:
            count++;
            if (count > 1) {
                return false;
            }
            break;
        case Const.PUTFIELD:
        case Const.BALOAD:
        case Const.CALOAD:
        case Const.DALOAD:
        case Const.FALOAD:
        case Const.IALOAD:
        case Const.LALOAD:
        case Const.SALOAD:
        case Const.AALOAD:
        case Const.BASTORE:
        case Const.CASTORE:
        case Const.DASTORE:
        case Const.FASTORE:
        case Const.IASTORE:
        case Const.LASTORE:
        case Const.SASTORE:
        case Const.AASTORE:
        case Const.PUTSTATIC:
            return false;
        case Const.INVOKESTATIC:
        case Const.INVOKEVIRTUAL:
        case Const.INVOKEINTERFACE:
        case Const.INVOKESPECIAL:
        case Const.GETSTATIC:
            // no-op

        }
    }
    // System.out.println("Found getter method: " + method.getName());
    return true;
}
 
Example #30
Source File: Hierarchy2.java    From spotbugs with GNU Lesser General Public License v2.1 3 votes vote down vote up
/**
 * Look up the method referenced by given InvokeInstruction. This method
 * does <em>not</em> look for implementations in super or subclasses
 * according to the virtual dispatch rules.
 *
 * @param inv
 *            the InvokeInstruction
 * @param cpg
 *            the ConstantPoolGen used by the class the InvokeInstruction
 *            belongs to
 * @param chooser
 *            JavaClassAndMethodChooser to use to pick the method from among
 *            the candidates
 * @return the JavaClassAndMethod, or null if no such method is defined in
 *         the class
 */
public static XMethod findExactMethod(InvokeInstruction inv, ConstantPoolGen cpg, JavaClassAndMethodChooser chooser) {
    String className = inv.getClassName(cpg);
    String methodName = inv.getName(cpg);
    String methodSig = inv.getSignature(cpg);

    XMethod result = findMethod(DescriptorFactory.createClassDescriptorFromDottedClassName(className), methodName, methodSig,
            inv instanceof INVOKESTATIC);

    return thisOrNothing(result, chooser);
}