Java Code Examples for org.apache.bcel.Const#INVOKESPECIAL

The following examples show how to use org.apache.bcel.Const#INVOKESPECIAL . 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: BuildInterproceduralCallGraph.java    From spotbugs with GNU Lesser General Public License v2.1 6 votes vote down vote up
@Override
public void sawOpcode(int seen) {
    switch (seen) {
    case Const.INVOKESTATIC:
    case Const.INVOKEVIRTUAL:
    case Const.INVOKEINTERFACE:
    case Const.INVOKESPECIAL:
        MethodDescriptor called = getMethodDescriptorOperand();
        XMethod calledXMethod = XFactory.createXMethod(called);
        InterproceduralCallGraphVertex calledVertex = findVertex(calledXMethod);
        callGraph.createEdge(currentVertex, calledVertex);
        break;
    default:
        break;
    }
}
 
Example 2
Source File: FindCircularDependencies.java    From spotbugs with GNU Lesser General Public License v2.1 6 votes vote down vote up
@Override
public void sawOpcode(int seen) {
    if ((seen == Const.INVOKESPECIAL) || (seen == Const.INVOKESTATIC) || (seen == Const.INVOKEVIRTUAL)) {
        String refClsName = getClassConstantOperand();
        refClsName = refClsName.replace('/', '.');
        if (refClsName.startsWith("java")) {
            return;
        }

        if (clsName.equals(refClsName)) {
            return;
        }

        if (clsName.startsWith(refClsName) && (refClsName.indexOf('$') >= 0)) {
            return;
        }

        if (refClsName.startsWith(clsName) && (clsName.indexOf('$') >= 0)) {
            return;
        }

        Set<String> dependencies = dependencyGraph.computeIfAbsent(clsName, k -> new HashSet<>());

        dependencies.add(refClsName);
    }
}
 
Example 3
Source File: InvalidJUnitTest.java    From spotbugs with GNU Lesser General Public License v2.1 6 votes vote down vote up
@Override
public void sawOpcode(int seen) {
    switch (state) {
    case SEEN_NOTHING:
        if (seen == Const.ALOAD_0) {
            state = SEEN_ALOAD_0;
        }
        break;

    case SEEN_ALOAD_0:
        if ((seen == Const.INVOKESPECIAL) && (getNameConstantOperand().equals(getMethodName()))
                && (getSigConstantOperand().equals("()V"))) {
            sawSuperCall = true;
        }
        state = SEEN_NOTHING;
        break;
    default:
        state = SEEN_NOTHING;
    }
}
 
Example 4
Source File: IntCast2LongAsInstant.java    From spotbugs with GNU Lesser General Public License v2.1 5 votes vote down vote up
@Override
public void sawOpcode(int seen) {
    if (seen == Const.SIPUSH) {
        lastConstantForSIPUSH = getIntConstant();
    }
    if (seen == Const.INVOKEINTERFACE || seen == Const.INVOKEVIRTUAL || seen == Const.INVOKESPECIAL || seen == Const.INVOKESTATIC) {
        String signature = getSigConstantOperand();

        int numberArguments = PreorderVisitor.getNumberArguments(signature);

        for (int i = 0; i < numberArguments; i++) {
            Item item = stack.getStackItem(numberArguments - 1 - i);
            if (item.getSpecialKind() == OpcodeStack.Item.RESULT_OF_I2L) {
                ParameterProperty property = database.getProperty(getMethodDescriptorOperand());
                if (property != null && property.hasProperty(i)) {
                    int priority = NORMAL_PRIORITY;

                    if (getPrevOpcode(1) == Const.I2L && getPrevOpcode(2) == Const.IMUL && getPrevOpcode(3) == Const.SIPUSH
                            && lastConstantForSIPUSH == 1000) {
                        priority = HIGH_PRIORITY;

                    } else if (getPrevOpcode(1) == Const.I2L && getPrevOpcode(2) == Const.IMUL && getPrevOpcode(4) == Const.SIPUSH
                            && lastConstantForSIPUSH == 1000) {
                        priority = HIGH_PRIORITY;
                    }
                    BugInstance bug = new BugInstance(this, "ICAST_INT_2_LONG_AS_INSTANT", priority).addClassAndMethod(this)
                            .addCalledMethod(this).addValueSource(item, this).addSourceLine(this);
                    bugReporter.reportBug(bug);
                }

            }
        }

    }
}
 
Example 5
Source File: DumbMethods.java    From spotbugs with GNU Lesser General Public License v2.1 5 votes vote down vote up
@Override
public void sawOpcode(int seen) {
    if (seen == Const.INVOKEVIRTUAL && "java/util/Random".equals(getClassConstantOperand())
            && (freshRandomOnTos || freshRandomOneBelowTos)) {
        accumulator.accumulateBug(new BugInstance(DumbMethods.this, "DMI_RANDOM_USED_ONLY_ONCE", HIGH_PRIORITY)
                .addClassAndMethod(DumbMethods.this).addCalledMethod(DumbMethods.this), DumbMethods.this);

    }
    freshRandomOneBelowTos = freshRandomOnTos && isRegisterLoad();
    freshRandomOnTos = seen == Const.INVOKESPECIAL && "java/util/Random".equals(getClassConstantOperand())
            && Const.CONSTRUCTOR_NAME.equals(getNameConstantOperand());
}
 
Example 6
Source File: FieldSetAnalysis.java    From spotbugs with GNU Lesser General Public License v2.1 5 votes vote down vote up
private void handleInstruction(InstructionHandle handle, BasicBlock basicBlock, FieldSet fact) {
    Instruction ins = handle.getInstruction();
    short opcode = ins.getOpcode();
    XField field;

    switch (opcode) {
    case Const.GETFIELD:
    case Const.GETSTATIC:
        field = lookupField(handle, (FieldInstruction) ins);
        if (field != null) {
            sawLoad(fact, field);
        }
        break;

    case Const.PUTFIELD:
    case Const.PUTSTATIC:
        field = lookupField(handle, (FieldInstruction) ins);
        if (field != null) {
            sawStore(fact, field);
        }
        break;

    case Const.INVOKEINTERFACE:
    case Const.INVOKESPECIAL:
    case Const.INVOKESTATIC:
    case Const.INVOKEVIRTUAL:
        // Assume that the called method assigns loads and stores all
        // possible fields
        fact.setBottom();
        break;
    default:
        break;
    }
}
 
Example 7
Source File: InstructionFactory.java    From commons-bcel with Apache License 2.0 5 votes vote down vote up
/** Create an invoke instruction. (Except for invokedynamic.)
 *
 * @param class_name name of the called class
 * @param name name of the called method
 * @param ret_type return type of method
 * @param arg_types argument types of method
 * @param kind how to invoke: INVOKEINTERFACE, INVOKESTATIC, INVOKEVIRTUAL, or INVOKESPECIAL
 * @param use_interface force use of InterfaceMethodref
 * @return A new InvokeInstruction.
 * @since 6.5.0
 */
public InvokeInstruction createInvoke( final String class_name, final String name, final Type ret_type,
    final Type[] arg_types, final short kind, final boolean use_interface) {
    if (kind != Const.INVOKESPECIAL && kind != Const.INVOKEVIRTUAL && kind != Const.INVOKESTATIC
        && kind != Const.INVOKEINTERFACE && kind != Const.INVOKEDYNAMIC) {
        throw new IllegalArgumentException("Unknown invoke kind: " + kind);
    }
    int index;
    int nargs = 0;
    final String signature = Type.getMethodSignature(ret_type, arg_types);
    for (final Type arg_type : arg_types) {
        nargs += arg_type.getSize();
    }
    if (use_interface) {
        index = cp.addInterfaceMethodref(class_name, name, signature);
    } else {
        index = cp.addMethodref(class_name, name, signature);
    }
    switch (kind) {
    case Const.INVOKESPECIAL:
        return new INVOKESPECIAL(index);
    case Const.INVOKEVIRTUAL:
        return new INVOKEVIRTUAL(index);
    case Const.INVOKESTATIC:
        return new INVOKESTATIC(index);
    case Const.INVOKEINTERFACE:
        return new INVOKEINTERFACE(index, nargs + 1);
    case Const.INVOKEDYNAMIC:
        return new INVOKEDYNAMIC(index);
    default:
        // Can't happen
        throw new IllegalStateException("Unknown invoke kind: " + kind);
    }
}
 
Example 8
Source File: OverridingEqualsNotSymmetrical.java    From spotbugs with GNU Lesser General Public License v2.1 5 votes vote down vote up
private boolean callToInvoke(int seen) {
    if (seen == Const.INVOKEVIRTUAL || seen == Const.INVOKEINTERFACE || seen == Const.INVOKESPECIAL) {
        return invokesMethodWithEqualLikeName() && EQUALS_SIGNATURE.equals(getSigConstantOperand());
    }
    if (seen == Const.INVOKESTATIC) {
        String sig = getSigConstantOperand();
        return invokesMethodWithEqualLikeName() && sig.endsWith("Ljava/lang/Object;)Z");
    }

    return false;

}
 
Example 9
Source File: DismantleBytecode.java    From spotbugs with GNU Lesser General Public License v2.1 5 votes vote down vote up
public boolean isMethodCall() {
    switch (opcode) {
    default:
        return false;
    case Const.INVOKEINTERFACE:
    case Const.INVOKESPECIAL:
    case Const.INVOKEVIRTUAL:
    case Const.INVOKESTATIC:
        return true;

    }
}
 
Example 10
Source File: CloneIdiom.java    From spotbugs with GNU Lesser General Public License v2.1 5 votes vote down vote up
@Override
public void sawOpcode(int seen) {
    if (seen == Const.INVOKESPECIAL && "clone".equals(getNameConstantOperand()) && getSigConstantOperand().startsWith("()")) {
        /*
         * System.out.println("Saw call to " + nameConstant + ":" +
         * sigConstant + " in " + betterMethodName);
         */
        invokesSuperClone = true;
    }
}
 
Example 11
Source File: RepeatedConditionals.java    From spotbugs with GNU Lesser General Public License v2.1 5 votes vote down vote up
private boolean hasSideEffect(int seen) {
    if (seen == Const.INVOKEVIRTUAL || seen == Const.INVOKESPECIAL || seen == Const.INVOKEINTERFACE || seen == Const.INVOKESTATIC) {
        return noSideEffectMethods.is(getMethodDescriptorOperand(), MethodSideEffectStatus.SE, MethodSideEffectStatus.OBJ);
    }
    return isRegisterStore() || isReturn(seen) || isSwitch(seen) || seen == Const.INVOKEDYNAMIC || seen == Const.PUTFIELD
            || seen == Const.PUTSTATIC;
}
 
Example 12
Source File: NoteDirectlyRelevantTypeQualifiers.java    From spotbugs with GNU Lesser General Public License v2.1 5 votes vote down vote up
@Override
public void sawOpcode(int seen) {
    switch (seen) {
    case Const.INVOKEINTERFACE:
    case Const.INVOKEVIRTUAL:
    case Const.INVOKESTATIC:
    case Const.INVOKESPECIAL:
        // We don't need to look for method invocations
        // if Analysis.FIND_EFFECTIVE_RELEVANT_QUALIFIERS is enabled -
        // that will build an interprocedural call graph which
        // we'll use at a later point to find relevant qualifiers
        // stemming from called methods.

        if (!Analysis.FIND_EFFECTIVE_RELEVANT_QUALIFIERS) {
            XMethod m = getXMethodOperand();
            if (m != null) {
                updateApplicableAnnotations(m);
            }
        }
        break;

    case Const.GETSTATIC:
    case Const.PUTSTATIC:
    case Const.GETFIELD:
    case Const.PUTFIELD: {
        XField f = getXFieldOperand();
        if (f != null) {
            Collection<TypeQualifierAnnotation> annotations = TypeQualifierApplications.getApplicableApplications(f);
            Analysis.addKnownTypeQualifiers(applicableApplications, annotations);
        }

        break;
    }
    default:
        break;
    }
}
 
Example 13
Source File: UncallableMethodOfAnonymousClass.java    From spotbugs with GNU Lesser General Public License v2.1 5 votes vote down vote up
@Override
public void sawOpcode(int seen) {
    if (seen == Const.INVOKESPECIAL) {
        XMethod m = getXMethodOperand();
        if (m == null) {
            return;
        }
        XClass c = getXClass();
        int nameDistance = EditDistance.editDistance(m.getName(), getMethodName());
        if (nameDistance < 4 && c.findMatchingMethod(m.getMethodDescriptor()) == null && !m.isFinal()) {
            potentialSuperCall = m;
        }
    }
}
 
Example 14
Source File: FindNoSideEffectMethods.java    From spotbugs with GNU Lesser General Public License v2.1 4 votes vote down vote up
@Override
public void sawOpcode(int seen) {
    if (!allowedFields.isEmpty() && seen == Const.PUTFIELD) {
        Item objItem = getStack().getStackItem(1);
        if (objItem.getRegisterNumber() == 0) {
            if (allowedFields.contains(getFieldDescriptorOperand())) {
                Item valueItem = getStack().getStackItem(0);
                if (!isNew(valueItem) && !valueItem.isNull()) {
                    allowedFields.remove(getFieldDescriptorOperand());
                }
            }
        }
    }
    if (status == SideEffectStatus.SIDE_EFFECT && allowedFields.isEmpty()) {
        // Nothing to do: skip the rest of the method
        throw new EarlyExitException();
    }
    if (status == SideEffectStatus.SIDE_EFFECT) {
        return;
    }
    switch (seen) {
    case Const.ASTORE:
    case Const.ASTORE_0:
    case Const.ASTORE_1:
    case Const.ASTORE_2:
    case Const.ASTORE_3:
        if (finallyTargets.contains(getPC())) {
            finallyExceptionRegisters.add(getRegisterOperand());
        }
        break;
    case Const.ATHROW: {
        Item exceptionItem = getStack().getStackItem(0);
        if (!finallyExceptionRegisters.remove(exceptionItem.getRegisterNumber())) {
            uselessVoidCandidate = false;
            try {
                JavaClass javaClass = exceptionItem.getJavaClass();
                if (javaClass != null && ALLOWED_EXCEPTIONS.contains(javaClass.getClassName())) {
                    break;
                }
            } catch (ClassNotFoundException e) {
            }
            status = SideEffectStatus.SIDE_EFFECT;
        }
        break;
    }
    case Const.PUTSTATIC:
        if (classInit) {
            if (getClassConstantOperand().equals(getClassName())) {
                break;
            }
        }
        status = SideEffectStatus.SIDE_EFFECT;
        break;
    case Const.INVOKEDYNAMIC:
        status = SideEffectStatus.SIDE_EFFECT;
        break;
    case Const.PUTFIELD:
        sawCall(getMethodCall(FIELD_STORE_STUB_METHOD), false);
        break;
    case Const.AASTORE:
    case Const.DASTORE:
    case Const.CASTORE:
    case Const.BASTORE:
    case Const.IASTORE:
    case Const.LASTORE:
    case Const.FASTORE:
    case Const.SASTORE:
        sawCall(getMethodCall(ARRAY_STORE_STUB_METHOD), false);
        break;
    case Const.INVOKESTATIC:
        if (changesOnlyNewObjects(getMethodDescriptorOperand())) {
            break;
        }
        sawCall(new MethodCall(getMethodDescriptorOperand(), TARGET_OTHER), false);
        break;
    case Const.INVOKESPECIAL:
    case Const.INVOKEINTERFACE:
    case Const.INVOKEVIRTUAL: {
        XMethod xMethodOperand = getXMethodOperand();
        MethodDescriptor methodDescriptorOperand = xMethodOperand == null ? getMethodDescriptorOperand()
                : xMethodOperand
                        .getMethodDescriptor();
        if (changesOnlyNewObjects(getMethodDescriptorOperand())) {
            break;
        }
        MethodCall methodCall = getMethodCall(methodDescriptorOperand);
        sawCall(methodCall, false);
        break;
    }
    default:
        break;
    }
}
 
Example 15
Source File: VarArgsProblems.java    From spotbugs with GNU Lesser General Public License v2.1 4 votes vote down vote up
@Override
public void sawOpcode(int seen) {
    // System.out.println("State:" + state);
    if (seen == Const.GOTO && getBranchOffset() == 4) {
        state = SEEN_GOTO;
    } else {
        switch (state) {
        case SEEN_NOTHING:
            if ((seen == Const.ICONST_1)) {
                state = SEEN_ICONST_1;
            }
            break;

        case SEEN_ICONST_1:
            if (seen == Const.ANEWARRAY && primitiveArray.matcher(getClassConstantOperand()).matches()) {
                // System.out.println("Allocation of array of type " +
                // getClassConstantOperand());
                primitiveArraySig = getClassConstantOperand();
                state = SEEN_ANEWARRAY;
            } else {
                state = SEEN_NOTHING;
            }
            break;

        case SEEN_ANEWARRAY:
            if (seen == Const.DUP) {
                state = SEEN_DUP;
            } else {
                state = SEEN_NOTHING;
            }
            break;
        case SEEN_DUP:
            if (seen == Const.ICONST_0) {
                state = SEEN_ICONST_0;
            } else {
                state = SEEN_NOTHING;
            }
            break;
        case SEEN_ICONST_0:
            if (((seen >= Const.ALOAD_0) && (seen < Const.ALOAD_3)) || (seen == Const.ALOAD)) {
                state = SEEN_ALOAD;
            } else {
                state = SEEN_NOTHING;
            }
            break;

        case SEEN_ALOAD:
            if (seen == Const.AASTORE) {
                state = SEEN_AASTORE;
            } else {
                state = SEEN_NOTHING;
            }
            break;

        case SEEN_AASTORE:
            if (seen == Const.INVOKESTATIC || seen == Const.INVOKEINTERFACE || seen == Const.INVOKESPECIAL || seen == Const.INVOKEVIRTUAL) {
                // System.out.println(getClassConstantOperand());
                // System.out.println(getNameConstantOperand());
                // System.out.println(getSigConstantOperand());
                if (getSigConstantOperand().indexOf("Ljava/lang/Object;)") == -1) {
                    break;
                }
                int priority = NORMAL_PRIORITY;
                if ("asList".equals(getNameConstantOperand()) && "java/util/Arrays".equals(getClassConstantOperand())) {
                    priority = HIGH_PRIORITY;
                }
                bugReporter.reportBug(new BugInstance(this, "VA_PRIMITIVE_ARRAY_PASSED_TO_OBJECT_VARARG", priority)
                        .addClassAndMethod(this).addType(primitiveArraySig).describe(TypeAnnotation.FOUND_ROLE)
                        .addCalledMethod(this).addSourceLine(this));
            }
            state = SEEN_NOTHING;
            break;

        case SEEN_GOTO:
            state = SEEN_NOTHING;
            break;
        default:
            throw new IllegalStateException("State " + state + " not expected");

        }
    }
}
 
Example 16
Source File: FieldItemSummary.java    From spotbugs with GNU Lesser General Public License v2.1 4 votes vote down vote up
@Override
public void sawOpcode(int seen) {
    if (Const.CONSTRUCTOR_NAME.equals(getMethodName()) && seen == Const.INVOKEVIRTUAL) {
        XMethod m = getXMethodOperand();
        if (m != null && !m.isPrivate() && !m.isFinal()) {
            int args = PreorderVisitor.getNumberArguments(m.getSignature());
            OpcodeStack.Item item = stack.getStackItem(args);
            if (item.getRegisterNumber() == 0) {
                try {
                    Set<XMethod> targets = Hierarchy2.resolveVirtualMethodCallTargets(m, false, false);
                    Subtypes2 subtypes2 = AnalysisContext.currentAnalysisContext().getSubtypes2();

                    for (XMethod called : targets) {
                        if (!called.isAbstract() && !called.equals(m)
                                && subtypes2.isSubtype(called.getClassDescriptor(), getClassDescriptor())) {
                            fieldSummary.setCalledFromSuperConstructor(new ProgramPoint(this), called);
                        }
                    }
                } catch (ClassNotFoundException e) {
                    AnalysisContext.reportMissingClass(e);
                }

            }

        }

    }

    if (seen == Const.INVOKESPECIAL && Const.CONSTRUCTOR_NAME.equals(getMethodName()) && Const.CONSTRUCTOR_NAME.equals(
            getNameConstantOperand())) {

        String classOperand = getClassConstantOperand();
        OpcodeStack.Item invokedOn = stack.getItemMethodInvokedOn(this);
        if (invokedOn.getRegisterNumber() == 0 && !classOperand.equals(getClassName())) {
            sawInitializeSuper = true;
            XMethod invoked = getXMethodOperand();
            if (invoked != null) {
                fieldSummary.sawSuperCall(getXMethod(), invoked);
            }
        }

    }

    if (seen == Const.PUTFIELD || seen == Const.PUTSTATIC) {
        XField fieldOperand = getXFieldOperand();
        if (fieldOperand == null) {
            return;
        }
        touched.add(fieldOperand);
        if (!fieldOperand.getClassDescriptor().getClassName().equals(getClassName())) {
            fieldSummary.addWrittenOutsideOfConstructor(fieldOperand);
        } else if (seen == Const.PUTFIELD) {
            OpcodeStack.Item addr = stack.getStackItem(1);
            {
                if (addr.getRegisterNumber() != 0 || !Const.CONSTRUCTOR_NAME.equals(getMethodName())) {
                    fieldSummary.addWrittenOutsideOfConstructor(fieldOperand);
                }
            }
        } else if (seen == Const.PUTSTATIC && !Const.STATIC_INITIALIZER_NAME.equals(getMethodName())) {
            fieldSummary.addWrittenOutsideOfConstructor(fieldOperand);
        }
        OpcodeStack.Item top = stack.getStackItem(0);
        fieldSummary.mergeSummary(fieldOperand, top);
    }

}
 
Example 17
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 18
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 19
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 20
Source File: FindNonShortCircuit.java    From spotbugs with GNU Lesser General Public License v2.1 4 votes vote down vote up
private void scanForBooleanValue(int seen) {
    switch (seen) {

    case Const.IAND:
    case Const.IOR:
        switch (prevOpcode) {
        case Const.ILOAD:
        case Const.ILOAD_0:
        case Const.ILOAD_1:
        case Const.ILOAD_2:
        case Const.ILOAD_3:
            clearAll();
            break;
        default:
            break;
        }
        break;
    case Const.ICONST_1:
        stage1 = 1;
        switch (prevOpcode) {
        case Const.IFNONNULL:
        case Const.IFNULL:
            sawNullTest = true;
            break;
        case Const.IF_ICMPGT:
        case Const.IF_ICMPGE:
        case Const.IF_ICMPLT:
        case Const.IF_ICMPLE:
            sawNumericTest = true;
            break;
        }

        break;
    case Const.GOTO:
        if (stage1 == 1) {
            stage1 = 2;
        } else {
            stage1 = 0;
            clearAll();
        }
        break;
    case Const.ICONST_0:
        if (stage1 == 2) {
            sawBooleanValue();
        }
        stage1 = 0;
        break;
    case Const.INVOKEINTERFACE:
    case Const.INVOKEVIRTUAL:
    case Const.INVOKESPECIAL:
    case Const.INVOKESTATIC:
        String sig = getSigConstantOperand();
        if (sig.endsWith(")Z")) {
            sawBooleanValue();
        }
        stage1 = 0;
        break;
    default:
        stage1 = 0;
    }
}