Package edu.umd.cs.findbugs

Examples of edu.umd.cs.findbugs.BugAccumulator


    private final BugAccumulator bugAccumulator;

    public FindSleepWithLockHeld(BugReporter bugReporter) {
        this.bugReporter = bugReporter;
        this.bugAccumulator = new BugAccumulator(bugReporter);
    }
View Full Code Here


    private int state;

    public FindFloatEquality(BugReporter bugReporter) {
        this.bugReporter = bugReporter;
        this.bugAccumulator = new BugAccumulator(bugReporter);
    }
View Full Code Here

    private final BugAccumulator bugAccumulator;

    public FindMismatchedWaitOrNotify(BugReporter bugReporter) {
        this.bugReporter = bugReporter;
        this.bugAccumulator = new BugAccumulator(bugReporter);
    }
View Full Code Here

    private void analyzeMethod(ClassContext classContext, Method method) throws CFGBuilderException, DataflowAnalysisException {
        if (BCELUtil.isSynthetic(method) || !prescreen(classContext, method)) {
            return;
        }
        BugAccumulator accumulator = new BugAccumulator(bugReporter);

        CFG cfg = classContext.getCFG(method);
        TypeDataflow typeDataflow = classContext.getTypeDataflow(method);
        IsNullValueDataflow isNullDataflow = classContext.getIsNullValueDataflow(method);
        Set<ValueNumber> paramValueNumberSet = null;

        ValueNumberDataflow vnaDataflow = null;

        ConstantPoolGen cpg = classContext.getConstantPoolGen();
        MethodGen methodGen = classContext.getMethodGen(method);
        if (methodGen == null) {
            return;
        }
        String methodName = methodGen.getClassName() + "." + methodGen.getName();
        String sourceFile = classContext.getJavaClass().getSourceFileName();
        if (DEBUG) {
            System.out.println("Checking " + methodName);
        }

        Set<SourceLineAnnotation> haveInstanceOf = new HashSet<SourceLineAnnotation>();
        Set<SourceLineAnnotation> haveCast = new HashSet<SourceLineAnnotation>();
        Set<SourceLineAnnotation> haveMultipleInstanceOf = new HashSet<SourceLineAnnotation>();
        Set<SourceLineAnnotation> haveMultipleCast = new HashSet<SourceLineAnnotation>();
        for (Iterator<Location> i = cfg.locationIterator(); i.hasNext();) {
            Location location = i.next();
            InstructionHandle handle = location.getHandle();
            Instruction ins = handle.getInstruction();

            if (!(ins instanceof CHECKCAST) && !(ins instanceof INSTANCEOF)) {
                continue;
            }

            SourceLineAnnotation sourceLineAnnotation = SourceLineAnnotation.fromVisitedInstruction(classContext, methodGen,
                    sourceFile, handle);
            if (ins instanceof CHECKCAST) {
                if (!haveCast.add(sourceLineAnnotation)) {
                    haveMultipleCast.add(sourceLineAnnotation);
                    if (DEBUG) {
                        System.out.println("Have multiple casts for " + sourceLineAnnotation);
                    }
                }
            } else {
                if (!haveInstanceOf.add(sourceLineAnnotation)) {
                    haveMultipleInstanceOf.add(sourceLineAnnotation);
                    if (DEBUG) {
                        System.out.println("Have multiple instanceof for " + sourceLineAnnotation);
                    }
                }
            }
        }
        BitSet linesMentionedMultipleTimes = classContext.linesMentionedMultipleTimes(method);
        LineNumberTable lineNumberTable = methodGen.getLineNumberTable(methodGen.getConstantPool());
        Map<BugAnnotation, String> instanceOfChecks = new HashMap<BugAnnotation, String>();
        String constantClass = null;
        boolean methodInvocationWasGeneric = false;

        int pcForConstantClass = -1;
        for (Iterator<Location> i = cfg.locationIterator(); i.hasNext();) {
            Location location = i.next();

            InstructionHandle handle = location.getHandle();
            int pc = handle.getPosition();
            Instruction ins = handle.getInstruction();

            boolean wasMethodInvocationWasGeneric = methodInvocationWasGeneric;
            methodInvocationWasGeneric = false;
            if (ins instanceof InvokeInstruction) {
                InvokeInstruction iinv = (InvokeInstruction) ins;
                XMethod m = XFactory.createXMethod(iinv, cpg);
                if (m != null) {
                    String sourceSignature = m.getSourceSignature();
                    methodInvocationWasGeneric = sourceSignature != null
                            && (sourceSignature.startsWith("<") || sourceSignature.indexOf("java/lang/Class") >= 0);
                    if (DEBUG && methodInvocationWasGeneric) {
                        System.out.println(m + " has source signature " + sourceSignature);
                    }
                }

            }
            if (ins instanceof LDC) {
                LDC ldc = (LDC) ins;
                Object value = ldc.getValue(cpg);
                if (value instanceof ConstantClass) {
                    ConstantClass cc = (ConstantClass) value;
                    constantClass = cc.getBytes(classContext.getJavaClass().getConstantPool());
                    pcForConstantClass = pc;
                }
            }

            if (!(ins instanceof CHECKCAST) && !(ins instanceof INSTANCEOF)) {
                continue;
            }

            boolean isCast = ins instanceof CHECKCAST;
            int occurrences = cfg.getLocationsContainingInstructionWithOffset(pc).size();
            boolean split = occurrences > 1;
            if (lineNumberTable != null) {
                int line = lineNumberTable.getSourceLine(handle.getPosition());
                if (line > 0 && linesMentionedMultipleTimes.get(line)) {
                    split = true;
                }
            }

            IsNullValueFrame nullFrame = isNullDataflow.getFactAtLocation(location);
            if (!nullFrame.isValid()) {
                continue;
            }
            IsNullValue operandNullness = nullFrame.getTopValue();
            if (DEBUG) {
                String kind = isCast ? "checkedCast" : "instanceof";
                System.out.println(kind + " at pc: " + pc + " in " + methodName);
                System.out.println(" occurrences: " + occurrences);
                System.out.println("XXX: " + operandNullness);
            }

            if (split && !isCast) {
                // don't report this case; it might be infeasible due to
                // inlining
                continue;
            }

            TypeFrame frame = typeDataflow.getFactAtLocation(location);
            if (!frame.isValid()) {
                // This basic block is probably dead
                continue;
            }

            Type operandType = frame.getTopValue();
            if (operandType.equals(TopType.instance())) {
                // unreachable
                continue;
            }
            boolean operandTypeIsExact = frame.isExact(frame.getStackLocation(0));
            final Type castType = ((TypedInstruction) ins).getType(cpg);

            if (!(castType instanceof ReferenceType)) {
                // This shouldn't happen either
                continue;
            }
            String castSig = castType.getSignature();

            if (operandType.equals(NullType.instance()) || operandNullness.isDefinitelyNull()) {
                SourceLineAnnotation sourceLineAnnotation = SourceLineAnnotation.fromVisitedInstruction(classContext, methodGen,
                        sourceFile, handle);
                assert castSig.length() > 1;
                if (!isCast) {
                    accumulator.accumulateBug(new BugInstance(this, "NP_NULL_INSTANCEOF", split ? LOW_PRIORITY : NORMAL_PRIORITY)
                    .addClassAndMethod(methodGen, sourceFile).addType(castSig), sourceLineAnnotation);
                }
                continue;

            }
            if (!(operandType instanceof ReferenceType)) {
                // Shouldn't happen - illegal bytecode
                continue;
            }
            final ReferenceType refType = (ReferenceType) operandType;
            boolean impliesByGenerics = typeDataflow.getAnalysis().isImpliedByGenericTypes(refType);

            if (impliesByGenerics && !isCast) {
                continue;
            }

            final boolean typesAreEqual = refType.equals(castType);
            if (isCast && typesAreEqual) {
                // System.out.println("self-cast to " +
                // castType.getSignature());
                continue;
            }

            String refSig = refType.getSignature();
            String castSig2 = castSig;
            String refSig2 = refSig;
            while (castSig2.charAt(0) == '[' && refSig2.charAt(0) == '[') {
                castSig2 = castSig2.substring(1);
                refSig2 = refSig2.substring(1);
            }

            SourceLineAnnotation sourceLineAnnotation = SourceLineAnnotation.fromVisitedInstruction(classContext, methodGen,
                    sourceFile, handle);

            if (refSig2.charAt(0) != 'L' || castSig2.charAt(0) != 'L') {
                if (castSig2.charAt(0) == '['
                        && (refSig2.equals("Ljava/io/Serializable;") || refSig2.equals("Ljava/lang/Object;") || refSig2
                                .equals("Ljava/lang/Cloneable;"))) {
                    continue;
                }
                if (refSig2.charAt(0) == '['
                        && (castSig2.equals("Ljava/io/Serializable;") || castSig2.equals("Ljava/lang/Object;") || castSig2
                                .equals("Ljava/lang/Cloneable;"))) {
                    continue;
                }
                int priority = HIGH_PRIORITY;
                if (split && (castSig2.endsWith("Error;") || castSig2.endsWith("Exception;"))) {
                    priority = LOW_PRIORITY;
                }
                // report bug only if types are not equal, see bug 3598482
                if(!typesAreEqual){
                    bugReporter.reportBug(new BugInstance(this, isCast ? "BC_IMPOSSIBLE_CAST" : "BC_IMPOSSIBLE_INSTANCEOF", priority)
                    .addClassAndMethod(methodGen, sourceFile).addFoundAndExpectedType(refType, castType)
                    .addSourceLine(sourceLineAnnotation));
                }
                continue;
            }

            if (!operandTypeIsExact && refSig2.equals("Ljava/lang/Object;")) {
                continue;
            }
            /*
            if (false && isCast && haveMultipleCast.contains(sourceLineAnnotation) || !isCast
                    && haveMultipleInstanceOf.contains(sourceLineAnnotation)) {
                // skip; might be due to JSR inlining
                continue;
            }*/
            String castName = castSig2.substring(1, castSig2.length() - 1).replace('/', '.');
            String refName = refSig2.substring(1, refSig2.length() - 1).replace('/', '.');

            if (vnaDataflow == null) {
                vnaDataflow = classContext.getValueNumberDataflow(method);
            }
            ValueNumberFrame vFrame = vnaDataflow.getFactAtLocation(location);
            if (paramValueNumberSet == null) {
                paramValueNumberSet = getParameterValueNumbers(classContext, method, cfg);
            }
            ValueNumber valueNumber = vFrame.getTopValue();
            BugAnnotation valueSource = ValueNumberSourceInfo.findAnnotationFromValueNumber(method, location, valueNumber, vFrame,
                    "VALUE_OF");
            // XXX call below causes 86% of all OpcodeStackDetector.EarlyExitException (getPC() == targetPC) thrown (13000 on java* JDK7 classes)
            BugAnnotation source = BugInstance.getSourceForTopStackValue(classContext, method, location);
            boolean isParameter = paramValueNumberSet.contains(valueNumber) && source instanceof LocalVariableAnnotation;

            try {
                JavaClass castJavaClass = Repository.lookupClass(castName);
                JavaClass refJavaClass = Repository.lookupClass(refName);

                boolean upcast = Repository.instanceOf(refJavaClass, castJavaClass);
                if (upcast || typesAreEqual) {
                    if (!isCast) {
                        accumulator.accumulateBug(new BugInstance(this, "BC_VACUOUS_INSTANCEOF", NORMAL_PRIORITY)
                        .addClassAndMethod(methodGen, sourceFile).addFoundAndExpectedType(refType, castType),
                        sourceLineAnnotation);
                    }
                } else {
                    boolean castMayThrow = !Repository.instanceOf(refJavaClass, castJavaClass);
                    boolean downCast = Repository.instanceOf(castJavaClass, refJavaClass);

                    if (!operandTypeIsExact && refName.equals("java.lang.Object")) {
                        continue;
                    }
                    double rank = 0.0;
                    boolean castToConcreteCollection = concreteCollectionClasses.contains(castName)
                            && abstractCollectionClasses.contains(refName);
                    boolean castToAbstractCollection = abstractCollectionClasses.contains(castName)
                            && veryAbstractCollectionClasses.contains(refName);
                    int position = location.getHandle().getPosition();
                    int catchSize = Util.getSizeOfSurroundingTryBlock(classContext.getJavaClass().getConstantPool(), method.getCode(),
                            "java/lang/ClassCastException", position);



                    if (!operandTypeIsExact) {
                        rank = Analyze.deepInstanceOf(refJavaClass, castJavaClass);
                        if (castToConcreteCollection && rank > 0.6) {
                            rank = (rank + 0.6) / 2;
                        } else if (castToAbstractCollection && rank > 0.3) {
                            rank = (rank + 0.3) / 2;
                        }
                    }
                    /*
                    if (false) {
                        System.out.println("Rank:\t" + rank + "\t" + refName + "\t" + castName);
                    }
                     */
                    boolean completeInformation = (!castJavaClass.isInterface() && !refJavaClass.isInterface())
                            || refJavaClass.isFinal() || castJavaClass.isFinal();
                    if (DEBUG) {
                        System.out.println(" In " + classContext.getFullyQualifiedMethodName(method));
                        System.out.println("At pc: " + handle.getPosition());
                        System.out.println("cast from " + refName + " to " + castName);
                        System.out.println("  cast may throw: " + castMayThrow);
                        System.out.println("  is downcast: " + downCast);
                        System.out.println("  operand type is exact: " + operandTypeIsExact);

                        System.out.println("  complete information: " + completeInformation);
                        System.out.println("  isParameter: " + valueNumber);
                        System.out.println("  score: " + rank);
                        System.out.println("  source is: " + valueSource);
                        if (catchSize < Integer.MAX_VALUE) {
                            System.out.println("  catch block size is: " + catchSize);
                        }
                        if (constantClass != null) {
                            System.out.println("  constant class " + constantClass + " at " + pcForConstantClass);
                        }
                        if (handle.getPrev() == null) {
                            System.out.println("  prev is null");
                        } else {
                            System.out.println("  prev is " + handle.getPrev());
                        }
                    }
                    if (!isCast && castMayThrow && valueSource != null) {
                        String oldCheck = instanceOfChecks.get(valueSource);
                        if (oldCheck == null) {
                            instanceOfChecks.put(valueSource, castName);
                        } else if (!oldCheck.equals(castName)) {
                            instanceOfChecks.put(valueSource, "");
                        }
                    }
                    if (!downCast && completeInformation || operandTypeIsExact) {
                        String bugPattern;
                        if (isCast) {
                            if (downCast && operandTypeIsExact) {
                                if (refSig.equals("[Ljava/lang/Object;") && source instanceof MethodAnnotation
                                        && ((MethodAnnotation) source).getMethodName().equals("toArray")
                                        && ((MethodAnnotation) source).getMethodSignature().equals("()[Ljava/lang/Object;")) {
                                    bugPattern = "BC_IMPOSSIBLE_DOWNCAST_OF_TOARRAY";
                                } else {
                                    bugPattern = "BC_IMPOSSIBLE_DOWNCAST";
                                }
                            } else {
                                bugPattern = "BC_IMPOSSIBLE_CAST";
                            }
                        } else {
                            bugPattern = "BC_IMPOSSIBLE_INSTANCEOF";
                        }

                        bugReporter.reportBug(new BugInstance(this, bugPattern, isCast ? HIGH_PRIORITY : NORMAL_PRIORITY)
                        .addClassAndMethod(methodGen, sourceFile)
                        .addFoundAndExpectedType(refType, castType).addOptionalUniqueAnnotations(valueSource, source)
                        .addSourceLine(sourceLineAnnotation));
                    } else if (isCast && rank < 0.9
                            && !valueNumber.hasFlag(ValueNumber.ARRAY_VALUE)) {

                        int priority = NORMAL_PRIORITY;

                        @CheckForNull String oldCheck = instanceOfChecks.get(valueSource);
                        if (DEBUG) {
                            System.out.println("Old check: " + oldCheck);
                        }
                        if (castName.equals(oldCheck)) {
                            priority += 1;
                        } else if ("".equals(oldCheck)) {
                            priority += 1;
                            if (!(source instanceof LocalVariableAnnotation)) {
                                continue;
                            }
                        }

                        if (rank > 0.75) {
                            priority += 2;
                        } else if (rank > 0.5) {
                            priority += 1;
                        } else if (rank > 0.25) {
                            priority += 0;
                        } else {
                            priority--;
                        }



                        if (DEBUG) {
                            System.out.println(" priority a: " + priority);
                        }
                        if (methodGen.getClassName().startsWith(refName) || methodGen.getClassName().startsWith(castName)) {
                            priority += 1;
                        }
                        if (DEBUG) {
                            System.out.println(" priority b: " + priority);
                        }
                        if (castJavaClass.isInterface() && !castToAbstractCollection) {
                            priority++;
                        }
                        if (DEBUG) {
                            System.out.println(" priority c: " + priority);
                        }
                        if (castToConcreteCollection && veryAbstractCollectionClasses.contains(refName)) {
                            priority--;
                        }
                        if (DEBUG) {
                            System.out.println(" priority d: " + priority);
                        }
                        if (priority <= LOW_PRIORITY && !castToAbstractCollection && !castToConcreteCollection
                                && (refJavaClass.isInterface() || refJavaClass.isAbstract())) {
                            priority++;
                        }
                        if (DEBUG) {
                            System.out.println(" priority e: " + priority);
                        }
                        if (DEBUG) {
                            System.out.println(" ref name: " + refName);
                        }
                        if (methodGen.getName().equals("compareTo")) {
                            priority++;
                        } else if (methodGen.isPublic() && isParameter && !castName.equals(oldCheck)) {
                            priority--;
                        }
                        if (wasMethodInvocationWasGeneric && valueNumber.hasFlag(ValueNumber.RETURN_VALUE)) {
                            continue;
                        }
                        if (constantClass != null && pcForConstantClass +20 >= pc && valueNumber.hasFlag(ValueNumber.RETURN_VALUE)
                                && ClassName.toDottedClassName(constantClass).equals(castName)) {
                            priority += 2;
                        }
                        if (DEBUG) {
                            System.out.println(" priority f: " + priority);
                        }
                        if (source instanceof MethodAnnotation) {
                            MethodAnnotation m = (MethodAnnotation) source;
                            XMethod xm = m.toXMethod();
                            if (xm != null && (xm.isPrivate() || xm.isStatic()) && priority == Priorities.LOW_PRIORITY) {
                                continue;
                            }
                        }

                        if (valueNumber.hasFlag(ValueNumber.RETURN_VALUE) &&  priority < Priorities.LOW_PRIORITY) {
                            priority = Priorities.LOW_PRIORITY;
                        }
                        if (DEBUG) {
                            System.out.println(" priority g: " + priority);
                        }

                        if (DEBUG) {
                            System.out.println(" priority h: " + priority);
                        }

                        if (catchSize < 15) {
                            return;
                        }
                        if (catchSize < 25) {
                            priority++;
                        }
                        if (DEBUG) {
                            System.out.println(" priority i: " + priority);
                        }


                        if (priority < HIGH_PRIORITY) {
                            priority = HIGH_PRIORITY;
                        }
                        if (priority <= LOW_PRIORITY) {
                            String bug = "BC_UNCONFIRMED_CAST";
                            if (valueNumber.hasFlag(ValueNumber.RETURN_VALUE) || valueSource instanceof MethodAnnotation) {
                                bug = "BC_UNCONFIRMED_CAST_OF_RETURN_VALUE";
                            } else if (castToConcreteCollection) {
                                bug = "BC_BAD_CAST_TO_CONCRETE_COLLECTION";
                            } else if (castToAbstractCollection) {
                                bug = "BC_BAD_CAST_TO_ABSTRACT_COLLECTION";
                            }

                            BugInstance bugInstance = new BugInstance(this, bug, priority)
                            .addClassAndMethod(methodGen, sourceFile).addFoundAndExpectedType(refType, castType)
                            .addOptionalAnnotation(valueSource);

                            accumulator.accumulateBug(bugInstance, sourceLineAnnotation);
                        }

                    }

                }
            } catch (ClassNotFoundException e) {
                if (DEBUG) {
                    e.printStackTrace(System.out);
                }
                if (isCast && refSig.equals("[Ljava/lang/Object;") && source instanceof MethodAnnotation
                        && ((MethodAnnotation) source).getMethodName().equals("toArray")
                        && ((MethodAnnotation) source).getMethodSignature().equals("()[Ljava/lang/Object;")) {
                    bugReporter.reportBug(new BugInstance(this,  "BC_IMPOSSIBLE_DOWNCAST_OF_TOARRAY", isCast ? HIGH_PRIORITY : NORMAL_PRIORITY)
                    .addClassAndMethod(methodGen, sourceFile)
                    .addFoundAndExpectedType(refType, castType).addOptionalUniqueAnnotations(valueSource, source)
                    .addSourceLine(sourceLineAnnotation));
                }


            }
        }
        accumulator.reportAccumulatedBugs();
    }
View Full Code Here

public class BadUseOfReturnValue extends BytecodeScanningDetector {

    BugAccumulator bugAccumulator;

    public BadUseOfReturnValue(BugReporter bugReporter) {
        this.bugAccumulator = new BugAccumulator(bugReporter);
    }
View Full Code Here

    private int locationOfCall;

    private String lastCallClass = null, lastCallMethod = null, lastCallSig = null;

    public ReadReturnShouldBeChecked(BugReporter bugReporter) {
        this.accumulator = new BugAccumulator(bugReporter);
    }
View Full Code Here

    final private BugAccumulator accumulator;

    public URLProblems(BugReporter bugReporter) {
        this.bugReporter = bugReporter;
        this.accumulator = new BugAccumulator(bugReporter);
    }
View Full Code Here

    final BugAccumulator accumulator;

    public CrossSiteScripting(BugReporter bugReporter) {
        this.bugReporter = bugReporter;
        this.accumulator = new BugAccumulator(bugReporter);
    }
View Full Code Here

    private ValueNumberDataflow vnaDataflow;

    public NoiseNullDeref(BugReporter bugReporter) {
        this.bugReporter = bugReporter;
        this.bugAccumulator = new BugAccumulator(bugReporter);
    }
View Full Code Here

        XMethod xmethod = XFactory.createXMethod(classContext.getJavaClass(), method);
        if (xmethod.isSynthetic()) {
            return;
        }

        BugAccumulator accumulator = new BugAccumulator(bugReporter);

        CFG cfg = classContext.getCFG(method);
        TypeDataflow typeDataflow = classContext.getTypeDataflow(method);
        ValueNumberDataflow vnDataflow = classContext.getValueNumberDataflow(method);

        ConstantPoolGen cpg = classContext.getConstantPoolGen();
        MethodGen methodGen = classContext.getMethodGen(method);
        if (methodGen == null) {
            return;
        }
        String fullMethodName = methodGen.getClassName() + "." + methodGen.getName();

        String sourceFile = classContext.getJavaClass().getSourceFileName();
        if (DEBUG) {
            System.out.println("\n" + fullMethodName);
        }

        // Process each instruction
        for (Iterator<Location> iter = cfg.locationIterator(); iter.hasNext();) {
            Location location = iter.next();
            InstructionHandle handle = location.getHandle();
            Instruction ins = handle.getInstruction();

            // Only consider invoke instructions
            if (!(ins instanceof InvokeInstruction)) {
                continue;
            }

            InvokeInstruction inv = (InvokeInstruction) ins;

            XMethod invokedMethod = XFactory.createXMethod(inv, cpg);

            String invokedMethodName = invokedMethod.getName();
            String argSignature = invokedMethod.getSignature();
            argSignature = argSignature.substring(0, argSignature.indexOf(')') + 1);
            String call = invokedMethodName+argSignature;
            SignatureParser sigParser = new SignatureParser(inv.getSignature(cpg));

            Collection<Info> collection = callMap.get(call);
            if (!callMap.containsKey(call)) {
                continue;
            }
            for(Info info : collection) {
                Subtypes2 subtypes2 = AnalysisContext.currentAnalysisContext().getSubtypes2();
                if (DEBUG) {
                    System.out.println("at " + handle.getPosition() + " Checking call to " + info.interfaceForCall + " : " + invokedMethod);
                }
                try {
                    if (!subtypes2.isSubtype(invokedMethod.getClassDescriptor(), info.interfaceForCall)) {
                        continue;
                    }
                } catch (ClassNotFoundException e) {
                    if (info.interfaceForCall.getClassName().equals("java/util/Collection")
                            && invokedMethod.getClassName().equals("com.google.common.collect.Multiset")) {
                        assert true;
                        // we know this is OK without needing to find definition of Multiset
                    } else {
                        AnalysisContext.reportMissingClass(e);
                        continue;
                    }
                }

                boolean allMethod;

                int typeArgument;
                if (info.typeIndex >= 0) {
                    allMethod = false;
                    typeArgument = info.typeIndex;
                } else {
                    allMethod = true;
                    typeArgument = -(1+info.typeIndex);
                }
                int pos = info.argumentIndex;


                int lhsPos;
                if (inv instanceof INVOKESTATIC) {
                    lhsPos = sigParser.getSlotsFromTopOfStackForParameter(0);
                } else {
                    lhsPos = sigParser.getTotalArgumentSize();
                }

                int stackPos = sigParser.getSlotsFromTopOfStackForParameter(pos);

                TypeFrame frame = typeDataflow.getFactAtLocation(location);
                if (!frame.isValid()) {
                    // This basic block is probably dead
                    continue;
                }


                Type operandType = frame.getStackValue(stackPos);
                if (operandType.equals(TopType.instance())) {
                    // unreachable
                    continue;
                }

                if (operandType.equals(NullType.instance())) {
                    // ignore
                    continue;
                }

                ValueNumberFrame vnFrame = vnDataflow.getFactAtLocation(location);

                if (!vnFrame.isValid()) {
                    AnalysisContext.logError("Invalid value number frame in " + xmethod);
                    continue;
                }

                ValueNumber objectVN = vnFrame.getStackValue(lhsPos);
                ValueNumber argVN = vnFrame.getStackValue(stackPos);

                if (objectVN.equals(argVN)) {
                    String bugPattern = "DMI_COLLECTIONS_SHOULD_NOT_CONTAIN_THEMSELVES";
                    int priority = HIGH_PRIORITY;
                    if (invokedMethodName.equals("removeAll")) {
                        bugPattern = "DMI_USING_REMOVEALL_TO_CLEAR_COLLECTION";
                        priority = NORMAL_PRIORITY;
                    } else if (invokedMethodName.endsWith("All")) {
                        bugPattern = "DMI_VACUOUS_SELF_COLLECTION_CALL";
                        priority = NORMAL_PRIORITY;
                    }
                    if (invokedMethodName.startsWith("contains")) {
                        InstructionHandle next = handle.getNext();
                        if (next != null) {
                            Instruction nextIns = next.getInstruction();

                            if (nextIns instanceof InvokeInstruction) {
                                XMethod nextMethod = XFactory.createXMethod((InvokeInstruction) nextIns, cpg);
                                if (nextMethod.getName().equals("assertFalse")) {
                                    continue;
                                }
                            }
                        }
                    }
                    accumulator.accumulateBug(
                            new BugInstance(this, bugPattern, priority)
                            .addClassAndMethod(methodGen, sourceFile)
                            .addCalledMethod(methodGen, (InvokeInstruction) ins)
                            .addOptionalAnnotation(
                                    ValueNumberSourceInfo.findAnnotationFromValueNumber(method, location, objectVN,
                                            vnFrame, "INVOKED_ON")), SourceLineAnnotation.fromVisitedInstruction(
                                                    classContext, methodGen, sourceFile, handle));
                }

                // Only consider generic...
                Type objectType = frame.getStackValue(lhsPos);
                if (!(objectType instanceof GenericObjectType)) {
                    continue;
                }

                GenericObjectType operand = (GenericObjectType) objectType;

                int expectedTypeParameters = 1;
                String simpleName = info.interfaceForCall.getSimpleName();
                if ( simpleName.toLowerCase().endsWith("map") || simpleName.equals("Hashtable")) {
                    expectedTypeParameters = 2;
                } else if (simpleName.equals("Table")) {
                    expectedTypeParameters = 3;
                }

                // ... containers
                if (!operand.hasParameters()) {
                    continue;
                }
                if (operand.getNumParameters() != expectedTypeParameters) {
                    continue;
                }
                ClassDescriptor operandClass = DescriptorFactory.getClassDescriptor(operand);
                if (!isGenericCollection(operandClass)) {
                    continue;
                }

                if (expectedTypeParameters == 2 &&
                        Subtypes2.instanceOf(operandClass, Map.class)
                        && !TypeFrameModelingVisitor.isStraightGenericMap(operandClass)) {
                    continue;
                }
                Type expectedType;
                if (allMethod) {
                    expectedType = operand;
                } else {
                    expectedType = operand.getParameterAt(typeArgument);
                }
                Type actualType = frame.getStackValue(stackPos);
                Type equalsType = actualType;
                if (allMethod) {
                    if (!(actualType instanceof GenericObjectType)) {
                        continue;
                    }
                    equalsType = ((GenericObjectType)actualType).getParameterAt(typeArgument);
                }


                IncompatibleTypes matchResult = compareTypes(expectedType, actualType, allMethod);

                boolean parmIsObject = expectedType.getSignature().equals("Ljava/lang/Object;");
                boolean selfOperation = !allMethod && operand.equals(actualType) && !parmIsObject;
                if (!allMethod && !parmIsObject && actualType instanceof GenericObjectType) {

                    GenericObjectType p2 = (GenericObjectType) actualType;
                    List<? extends ReferenceType> parameters = p2.getParameters();
                    if (parameters != null && parameters.equals(operand.getParameters())) {
                        selfOperation = true;
                    }
                }

                if (!selfOperation && ( matchResult == IncompatibleTypes.SEEMS_OK || matchResult.getPriority() == Priorities.IGNORE_PRIORITY)) {
                    continue;
                }

                if (invokedMethodName.startsWith("contains") || invokedMethodName.equals("remove")) {
                    InstructionHandle next = handle.getNext();
                    if (next != null) {
                        Instruction nextIns = next.getInstruction();

                        if (nextIns instanceof InvokeInstruction) {
                            XMethod nextMethod = XFactory.createXMethod((InvokeInstruction) nextIns, cpg);
                            if (nextMethod.getName().equals("assertFalse")) {
                                continue;
                            }
                        }
                    }
                } else if (invokedMethodName.equals("get") || invokedMethodName.equals("remove")) {
                    InstructionHandle next = handle.getNext();
                    if (next != null) {
                        Instruction nextIns = next.getInstruction();

                        if (nextIns instanceof InvokeInstruction) {
                            XMethod nextMethod = XFactory.createXMethod((InvokeInstruction) nextIns, cpg);
                            if (nextMethod.getName().equals("assertNull")) {
                                continue;
                            }
                        }
                    }
                }
                boolean noisy = false;
                if (invokedMethodName.equals("get")) {
                    UnconditionalValueDerefDataflow unconditionalValueDerefDataflow = classContext
                            .getUnconditionalValueDerefDataflow(method);

                    UnconditionalValueDerefSet unconditionalDeref = unconditionalValueDerefDataflow.getFactAtLocation(location);
                    ValueNumberFrame vnAfter = vnDataflow.getFactAfterLocation(location);
                    ValueNumber top = vnAfter.getTopValue();
                    noisy = unconditionalDeref.getValueNumbersThatAreUnconditionallyDereferenced().contains(top);
                }
                // Prepare bug report
                SourceLineAnnotation sourceLineAnnotation = SourceLineAnnotation.fromVisitedInstruction(classContext, methodGen,
                        sourceFile, handle);

                // Report a bug that mentions each of the failed arguments in
                // matches

                if (expectedType instanceof GenericObjectType) {
                    expectedType = ((GenericObjectType) expectedType).getUpperBound();
                }

                int priority = matchResult.getPriority();
                if (!operandClass.getClassName().startsWith("java/util") && priority == Priorities.HIGH_PRIORITY) {
                    priority = Math.max(priority, Priorities.NORMAL_PRIORITY);
                }
                if (TestCaseDetector.likelyTestCase(xmethod)) {
                    priority = Math.max(priority, Priorities.NORMAL_PRIORITY);
                } else if (selfOperation) {
                    priority = Priorities.HIGH_PRIORITY;
                }
                ClassDescriptor expectedClassDescriptor = DescriptorFactory
                        .createClassOrObjectDescriptorFromSignature(expectedType.getSignature());
                ClassDescriptor actualClassDescriptor = DescriptorFactory.createClassOrObjectDescriptorFromSignature(equalsType
                        .getSignature());
                ClassSummary classSummary = AnalysisContext.currentAnalysisContext().getClassSummary();
                Set<XMethod> targets = null;
                try {
                    targets = Hierarchy2.resolveVirtualMethodCallTargets(actualClassDescriptor, "equals",
                            "(Ljava/lang/Object;)Z", false, false);
                    boolean allOk = targets.size() > 0;
                    for (XMethod m2 : targets) {
                        if (!classSummary.mightBeEqualTo(m2.getClassDescriptor(), expectedClassDescriptor)) {
                            allOk = false;
                        }
                    }
                    if (allOk) {
                        priority += 2;
                    }
                } catch (ClassNotFoundException e) {
                    AnalysisContext.reportMissingClass(e);
                }
                String bugPattern = "GC_UNRELATED_TYPES";

                BugInstance bug = new BugInstance(this, bugPattern, priority)
                .addClassAndMethod(methodGen, sourceFile)
                .addFoundAndExpectedType(actualType, expectedType)
                .addCalledMethod(methodGen, (InvokeInstruction) ins)
                .addOptionalAnnotation(
                        ValueNumberSourceInfo.findAnnotationFromValueNumber(method, location, objectVN, vnFrame,
                                "INVOKED_ON"))
                                .addOptionalAnnotation(
                                        ValueNumberSourceInfo.findAnnotationFromValueNumber(method, location, argVN, vnFrame, "ARGUMENT"))
                                        .addEqualsMethodUsed(targets);
                if (noisy) {
                    WarningPropertySet<WarningProperty> propertySet = new WarningPropertySet<WarningProperty>();

                    propertySet.addProperty(GeneralWarningProperty.NOISY_BUG);
                    propertySet.decorateBugInstance(bug);
                }
                accumulator.accumulateBug(bug, sourceLineAnnotation);
            }
        }
        accumulator.reportAccumulatedBugs();
    }
View Full Code Here

TOP

Related Classes of edu.umd.cs.findbugs.BugAccumulator

Copyright © 2018 www.massapicom. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.