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

The following examples show how to use org.apache.bcel.Const#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: 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: FindRoughConstants.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.LDC || seen == Const.LDC_W || seen == Const.LDC2_W) {
        Constant c = getConstantRefOperand();
        if (c instanceof ConstantFloat) {
            checkConst(((ConstantFloat) c).getBytes());
        } else if (c instanceof ConstantDouble) {
            checkConst(((ConstantDouble) c).getBytes());
        }
        return;
    }
    // Lower priority if the constant is put into array immediately or after the boxing:
    // this is likely to be just similar number in some predefined dataset (like lookup table)
    if (seen == Const.INVOKESTATIC && lastBug != null) {
        if (getNextOpcode() == Const.AASTORE
                && getNameConstantOperand().equals("valueOf")
                && (getClassConstantOperand().equals("java/lang/Double") || getClassConstantOperand().equals(
                        "java/lang/Float"))) {
            lastBug = ((BugInstance) lastBug.clone());
            lastBug.setPriority(lastPriority + 1);
            bugAccumulator.forgetLastBug();
            bugAccumulator.accumulateBug(lastBug, this);
        }
    }
    lastBug = null;
}
 
Example 3
Source File: DefaultEncodingDetector.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.INVOKEVIRTUAL:
    case Const.INVOKESPECIAL:
    case Const.INVOKESTATIC:
        XMethod callSeen = XFactory.createXMethod(MethodAnnotation.fromCalledMethod(this));
        DefaultEncodingAnnotation annotation = defaultEncodingAnnotationDatabase.getDirectAnnotation(callSeen);
        if (annotation != null) {
            bugAccumulator.accumulateBug(new BugInstance(this, "DM_DEFAULT_ENCODING", HIGH_PRIORITY).addClassAndMethod(this)
                    .addCalledMethod(this), this);
        }
        break;
    default:
        break;
    }
}
 
Example 4
Source File: DismantleBytecode.java    From spotbugs with GNU Lesser General Public License v2.1 5 votes vote down vote up
public void printOpCode(int seen) {
    System.out.print("  " + this.getClass().getSimpleName() + ": [" + formatter.format(getPC()) + "]  " + Const.getOpcodeName(seen));
    if ((seen == Const.INVOKEVIRTUAL) || (seen == Const.INVOKESPECIAL) || (seen == Const.INVOKEINTERFACE) || (seen == Const.INVOKESTATIC)) {
        System.out.print("   " + getClassConstantOperand() + "." + getNameConstantOperand() + " " + getSigConstantOperand());
    } else if (seen == Const.LDC || seen == Const.LDC_W || seen == Const.LDC2_W) {
        Constant c = getConstantRefOperand();
        if (c instanceof ConstantString) {
            System.out.print("   \"" + getStringConstantOperand() + "\"");
        } else if (c instanceof ConstantClass) {
            System.out.print("   " + getClassConstantOperand());
        } else {
            System.out.print("   " + c);
        }
    } else if ((seen == Const.ALOAD) || (seen == Const.ASTORE)) {
        System.out.print("   " + getRegisterOperand());
    } else if ((seen == Const.GOTO) || (seen == Const.GOTO_W) || (seen == Const.IF_ACMPEQ) || (seen == Const.IF_ACMPNE)
            || (seen == Const.IF_ICMPEQ)
            || (seen == Const.IF_ICMPGE) || (seen == Const.IF_ICMPGT) || (seen == Const.IF_ICMPLE) || (seen == Const.IF_ICMPLT)
            || (seen == Const.IF_ICMPNE) || (seen == Const.IFEQ) || (seen == Const.IFGE) || (seen == Const.IFGT) || (seen == Const.IFLE)
            || (seen == Const.IFLT)
            || (seen == Const.IFNE) || (seen == Const.IFNONNULL) || (seen == Const.IFNULL)) {
        System.out.print("   " + getBranchTarget());
    } else if ((seen == Const.NEW) || (seen == Const.INSTANCEOF)) {
        System.out.print("   " + getClassConstantOperand());
    } else if ((seen == Const.TABLESWITCH) || (seen == Const.LOOKUPSWITCH)) {
        System.out.print("    [");
        int switchPC = getPC();
        int[] offsets = getSwitchOffsets();
        for (int offset : offsets) {
            System.out.print((switchPC + offset) + ",");
        }
        System.out.print((switchPC + getDefaultSwitchOffset()) + "]");
    }

    System.out.println();
}
 
Example 5
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 6
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.INVOKESTATIC && getClassConstantOperand().equals("java/lang/Math") && (getMethodDescriptorOperand().getName().equals(
            "max")
            || getMethodDescriptorOperand().getName().equals("min"))) {
        Object const1 = stack.getStackItem(0).getConstant();
        Object const2 = stack.getStackItem(1).getConstant();
        Number n = null;
        if (const1 != null ^ const2 != null) {
            n = (const1 instanceof Number) ? (Number) const1 : (Number) const2;
            if (getMethodDescriptorOperand().getName().equals("min")) {
                upperBound = n;
            } else {
                lowerBound = n;
            }
        } else {
            upperBound = lowerBound = null;
        }
        XMethod rvo1 = stack.getStackItem(0).getReturnValueOf();
        XMethod rvo2 = stack.getStackItem(1).getReturnValueOf();
        if (rvo1 != null ^ rvo2 != null) {
            XMethod rvo = rvo1 == null ? rvo2 : rvo1;
            if (lowerBound instanceof Comparable && upperBound != null && upperBound.getClass() == lowerBound.getClass()
                    && rvo.getClassDescriptor().getClassName().equals("java/lang/Math")
                    && (rvo.getName().equals("max") || rvo.getName().equals("min"))) {
                @SuppressWarnings("unchecked")
                int result = ((Comparable<Number>) lowerBound).compareTo(upperBound);
                if (result > 0) {
                    accumulator.accumulateBug(
                            new BugInstance("DM_INVALID_MIN_MAX", HIGH_PRIORITY).addClassAndMethod(DumbMethods.this)
                                    .addString(String.valueOf(n)),
                            DumbMethods.this);
                }
            }
        }
    }
}
 
Example 7
Source File: IDivResultCastToDouble.java    From spotbugs with GNU Lesser General Public License v2.1 5 votes vote down vote up
@Override
public void sawOpcode(int seen) {

    if (DEBUG) {
        System.out.println("Saw opcode " + Const.getOpcodeName(seen) + " " + pendingIdivCastToDivBugLocation);
    }

    if ((prevOpCode == Const.I2D || prevOpCode == Const.L2D) && seen == Const.INVOKESTATIC && ClassName.isMathClass(getClassConstantOperand())
            && "ceil".equals(getNameConstantOperand())) {
        bugAccumulator
                .accumulateBug(new BugInstance(this, "ICAST_INT_CAST_TO_DOUBLE_PASSED_TO_CEIL", HIGH_PRIORITY)
                        .addClassAndMethod(this), this);
        pendingIdivCastToDivBugLocation = null;
    } else if ((prevOpCode == Const.I2F || prevOpCode == Const.L2F) && seen == Const.INVOKESTATIC
            && ClassName.isMathClass(getClassConstantOperand()) && "round".equals(getNameConstantOperand())) {
        bugAccumulator.accumulateBug(
                new BugInstance(this, "ICAST_INT_CAST_TO_FLOAT_PASSED_TO_ROUND", NORMAL_PRIORITY).addClassAndMethod(this),
                this);
        pendingIdivCastToDivBugLocation = null;
    } else if (pendingIdivCastToDivBugLocation != null) {
        bugAccumulator.accumulateBug(
                new BugInstance(this, "ICAST_IDIV_CAST_TO_DOUBLE", NORMAL_PRIORITY).addClassAndMethod(this),
                pendingIdivCastToDivBugLocation);
        pendingIdivCastToDivBugLocation = null;
    }

    if (prevOpCode == Const.IDIV && (seen == Const.I2D || seen == Const.I2F) || prevOpCode == Const.LDIV && (seen == Const.L2D
            || seen == Const.L2F)) {
        pendingIdivCastToDivBugLocation = SourceLineAnnotation.fromVisitedInstruction(this);
    }
    prevOpCode = seen;
}
 
Example 8
Source File: ReflectiveClasses.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.INVOKESTATIC) {
        // System.out.println(getClassConstantOperand()+ "." +
        // getNameConstantOperand());
        if (constantString != null && "java/lang/Class".equals(getClassConstantOperand())
                && "forName".equals(getNameConstantOperand())) {
            process(ClassName.toSlashedClassName(constantString));
        }

    }
    constantString = null;
}
 
Example 9
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 10
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 11
Source File: FormatStringChecker.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(getPC() + " " + Const.getOpcodeName(seen) + " " + state);

    if (stack.getStackDepth() < stackDepth) {
        state = FormatState.NONE;
        stackDepth = 0;
        arguments = null;
    }
    if (seen == Const.ANEWARRAY && stack.getStackDepth() >= 2) {
        Object size = stack.getStackItem(0).getConstant();
        Object formatStr = stack.getStackItem(1).getConstant();
        if (size instanceof Integer && formatStr instanceof String) {
            arguments = new OpcodeStack.Item[(Integer) size];
            this.formatString = (String) formatStr;
            state = FormatState.READY_FOR_FORMAT;
            stackDepth = stack.getStackDepth();
        }
    } else if (state == FormatState.READY_FOR_FORMAT && seen == Const.DUP) {
        state = FormatState.EXPECTING_ASSIGNMENT;
    } else if (state == FormatState.EXPECTING_ASSIGNMENT && stack.getStackDepth() == stackDepth + 3 && seen == Const.AASTORE) {
        Object pos = stack.getStackItem(1).getConstant();
        OpcodeStack.Item value = stack.getStackItem(0);
        if (pos instanceof Integer) {
            int index = (Integer) pos;
            if (index >= 0 && index < arguments.length) {
                arguments[index] = value;
                state = FormatState.READY_FOR_FORMAT;
            } else {
                state = FormatState.NONE;
            }
        } else {
            state = FormatState.NONE;
        }
    } else if (state == FormatState.READY_FOR_FORMAT
            && (seen == Const.INVOKESPECIAL || seen == Const.INVOKEVIRTUAL || seen == Const.INVOKESTATIC || seen == Const.INVOKEINTERFACE)
            && stack.getStackDepth() == stackDepth) {

        String cl = getClassConstantOperand();
        String nm = getNameConstantOperand();
        String sig = getSigConstantOperand();
        XMethod m = getXMethodOperand();
        if ((m == null || m.isVarArgs())
                && sig.indexOf("Ljava/lang/String;[Ljava/lang/Object;)") >= 0
                && ("java/util/Formatter".equals(cl) && "format".equals(nm) || "java/lang/String".equals(cl)
                        && "format".equals(nm) || "java/io/PrintStream".equals(cl) && "format".equals(nm)
                        || "java/io/PrintStream".equals(cl) && "printf".equals(nm) || cl.endsWith("Writer")
                                && "format".equals(nm) || cl.endsWith("Writer") && "printf".equals(nm)) || cl.endsWith("Logger")
                                        && nm.endsWith("fmt")) {

            if (formatString.indexOf('\n') >= 0) {
                bugReporter.reportBug(new BugInstance(this, "VA_FORMAT_STRING_USES_NEWLINE", NORMAL_PRIORITY)
                        .addClassAndMethod(this).addCalledMethod(this).addString(formatString)
                        .describe(StringAnnotation.FORMAT_STRING_ROLE).addSourceLine(this));
            }
        }

    }
}
 
Example 12
Source File: InefficientMemberAccess.java    From spotbugs with GNU Lesser General Public License v2.1 4 votes vote down vote up
@Override
public void sawOpcode(int seen) {

    if (seen == Const.INVOKESTATIC) {
        String methodName = getNameConstantOperand();
        if (!methodName.startsWith(ACCESS_PREFIX)) {
            return;
        }

        String methodSig = getSigConstantOperand();
        Type[] argTypes = Type.getArgumentTypes(methodSig);
        if ((argTypes.length < 1) || (argTypes.length > 2)) {
            return;
        }
        String parCls = argTypes[0].getSignature();
        if (parCls.length() < 3) {
            return;
        }
        parCls = parCls.substring(1, parCls.length() - 1);
        if (!parCls.equals(getClassConstantOperand())) {
            return;
        }
        if ((argTypes.length == 2) && !argTypes[1].getSignature().equals(new SignatureParser(methodSig).getReturnTypeSignature())) {
            return;
        }

        InnerClassAccess access = null;
        try {
            String dottedClassConstantOperand = getDottedClassConstantOperand();
            access = AnalysisContext.currentAnalysisContext().getInnerClassAccessMap().getInnerClassAccess(dottedClassConstantOperand,
                    methodName);
            if (access != null) {
                // if the enclosing class of the field differs from the enclosing class of the method, we shouln't report
                // because there is nothing wrong: see bug 1226
                if (!access.getField().getClassName().equals(dottedClassConstantOperand)) {
                    return;
                }
                // the access method is created to access the synthetic reference to the enclosing class, we shouln't report
                // user can't do anything here, see bug 1191
                if (access.getField().isSynthetic()) {
                    return;
                }
            }
        } catch (ClassNotFoundException e) {
        }

        BugInstance bug = new BugInstance(this, "IMA_INEFFICIENT_MEMBER_ACCESS", LOW_PRIORITY).addClassAndMethod(this)
                .addSourceLine(this);
        if (access != null) {
            bug.addField(access.getField());
        }
        bugReporter.reportBug(bug);
    }
}
 
Example 13
Source File: INVOKESTATIC.java    From commons-bcel with Apache License 2.0 4 votes vote down vote up
public INVOKESTATIC(final int index) {
    super(Const.INVOKESTATIC, index);
}
 
Example 14
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 15
Source File: WrongMapIterator.java    From spotbugs with GNU Lesser General Public License v2.1 4 votes vote down vote up
@Override
public void sawOpcode(int seen) {
    boolean loadedPreserved = false;
    if (isRegisterStore() && !isRegisterLoad()) {
        handleStore(getRegisterOperand());
    } else {
        switch (seen) {
        case Const.INVOKEINTERFACE:
        case Const.INVOKEVIRTUAL:
            if (!loadedVariable.none() &&
                    "keySet".equals(getNameConstantOperand()) && "()Ljava/util/Set;".equals(getSigConstantOperand())
                    // Following check solves sourceforge bug 1830576
                    && implementsMap(getClassDescriptorOperand())) {
                try {
                    LocationAndFactPair lfp = getClassContext().getTypeDataflow(getMethod()).getLocationAndFactForInstruction(
                            getPC());
                    // Skip EnumMap if TypeAnalysis knows that the type is EnumMap
                    if (lfp != null && lfp.frame.getTopValue().getSignature().equals("Ljava/util/EnumMap;")) {
                        break;
                    }
                } catch (DataflowAnalysisException | CFGBuilderException e) {
                    // ignore
                }
                mapVariable = loadedVariable;
                removedFromStack(true);
                keySetRegister = IN_STACK;
            } else if ((keySetRegister == IN_STACK || loadedVariable.isRegister(keySetRegister))
                    && "iterator".equals(getNameConstantOperand()) && "()Ljava/util/Iterator;".equals(getSigConstantOperand())) {
                removedFromStack(true);
                iteratorRegister = IN_STACK;
            } else if ((iteratorRegister == IN_STACK || loadedVariable.isRegister(iteratorRegister))
                    && "next".equals(getNameConstantOperand())
                    && "()Ljava/lang/Object;".equals(getSigConstantOperand())) {
                removedFromStack(true);
                keyRegister = IN_STACK;
            } else if (mapAndKeyLoaded && "get".equals(getNameConstantOperand())
                    && "(Ljava/lang/Object;)Ljava/lang/Object;".equals(getSigConstantOperand())) {
                MethodAnnotation ma = MethodAnnotation.fromVisitedMethod(this);
                bugAccumulator.accumulateBug(mapVariable
                        .annotate(new BugInstance(this, "WMI_WRONG_MAP_ITERATOR", NORMAL_PRIORITY).addClass(this).addMethod(ma)),
                        this);
                reset();
            } else if (("intValue".equals(getNameConstantOperand()) && "java/lang/Integer".equals(getClassConstantOperand())) ||
                    ("longValue".equals(getNameConstantOperand()) && "java/lang/Long".equals(getClassConstantOperand())) ||
                    ("doubleValue".equals(getNameConstantOperand()) && "java/lang/Double".equals(getClassConstantOperand())) ||
                    ("floatValue".equals(getNameConstantOperand()) && "java/lang/Float".equals(getClassConstantOperand()))) {
                removedFromStack(false);
            } else {
                removedFromStack(true);
            }
            break;
        case Const.INVOKESTATIC:
            if ("valueOf".equals(getNameConstantOperand())
                    && ("java/lang/Integer".equals(getClassConstantOperand())
                            || "java/lang/Long".equals(getClassConstantOperand())
                            || "java/lang/Double".equals(getClassConstantOperand()) || "java/lang/Float"
                                    .equals(getClassConstantOperand()))) {
                loadedPreserved = true;
            }
            removedFromStack(true);
            break;
        case Const.CHECKCAST:
            removedFromStack(false);
            break;
        default:
            removedFromStack(true);
        }
    }
    if (!loadedPreserved) {
        boolean mapLoaded = !loadedVariable.none() && loadedVariable.same(mapVariable);
        loadedVariable = loadedVariable.seen(seen);
        mapAndKeyLoaded = mapLoaded && loadedVariable.isRegister(keyRegister);
    }
}
 
Example 16
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 17
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 18
Source File: Invoke.java    From spotbugs with GNU Lesser General Public License v2.1 4 votes vote down vote up
@Override
public MatchResult match(InstructionHandle handle, ConstantPoolGen cpg, ValueNumberFrame before, ValueNumberFrame after,
        BindingSet bindingSet) throws DataflowAnalysisException {

    // See if the instruction is an InvokeInstruction
    Instruction ins = handle.getInstruction();
    if (!(ins instanceof InvokeInstruction)) {
        return null;
    }
    InvokeInstruction inv = (InvokeInstruction) ins;

    String methodName = inv.getMethodName(cpg);
    boolean isStatic = inv.getOpcode() == Const.INVOKESTATIC;
    boolean isCtor = Const.CONSTRUCTOR_NAME.equals(methodName);

    int actualMode = 0;

    if (isStatic) {
        actualMode |= STATIC;
    }
    if (isCtor) {
        actualMode |= CONSTRUCTOR;
    }
    if (!isStatic && !isCtor) {
        actualMode |= INSTANCE;
    }

    // Intersection of actual and desired modes must be nonempty.
    if ((actualMode & mode) == 0) {
        return null;
    }

    // Check class name, method name, and method signature.
    if (!methodNameMatcher.match(methodName) || !methodSigMatcher.match(inv.getSignature(cpg))
            || !classNameMatcher.match(inv.getClassName(cpg))) {
        return null;
    }

    // It's a match!
    return new MatchResult(this, bindingSet);

}
 
Example 19
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 20
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;
}