private void handleInvoke(InvokeInstruction obj) {
        if (obj instanceof INVOKEDYNAMIC) {
            // should not happen
            return;
        }
        Type returnType = obj.getReturnType(getCPG());

        Location location = getLocation();

        if (trackValueNumbers) {
            try {
                ValueNumberFrame vnaFrame = vnaDataflow.getFactAtLocation(location);
                Set<ValueNumber> nonnullParameters = UnconditionalValueDerefAnalysis.checkAllNonNullParams(location, vnaFrame,
                        cpg, null, null, typeDataflow);

                if (!nonnullParameters.isEmpty()) {
                    IsNullValue kaboom = IsNullValue.noKaboomNonNullValue(location);
                    IsNullValueFrame frame = getFrame();
                    for (ValueNumber vn : nonnullParameters) {
                        IsNullValue knownValue = frame.getKnownValue(vn);
                        if (knownValue != null && !knownValue.isDefinitelyNotNull()) {
                            if (knownValue.isDefinitelyNull()) {
                                frame.setTop();
                                return;
                            }
                            frame.setKnownValue(vn, kaboom);
                        }
                        for (int i = 0; i < vnaFrame.getNumSlots(); i++) {
                            IsNullValue value = frame.getValue(i);
                            if (vnaFrame.getValue(i).equals(vn) && !value.isDefinitelyNotNull()) {
                                frame.setValue(i, kaboom);
                                if (value.isDefinitelyNull()) {
                                    frame.setTop();
                                    return;
                                }
                            }
                        }
                    }

                }
            } catch (DataflowAnalysisException e) {
                AnalysisContext.logError("Error looking up nonnull parameters for invoked method", e);
            }
        }
        // Determine if we are going to model the return value of this call.
        boolean modelCallReturnValue = MODEL_NONNULL_RETURN && returnType instanceof ReferenceType;

        if (!modelCallReturnValue) {
            // Normal case: Assume returned values are non-reporting non-null.
            handleNormalInstruction(obj);
        } else {
            // Special case: some special value is pushed on the stack for the
            // return value
            IsNullValue result = null;
            TypeFrame typeFrame;
            try {
                typeFrame = typeDataflow.getFactAtLocation(location);

                Set<XMethod> targetSet = Hierarchy2.resolveMethodCallTargets(obj, typeFrame, cpg);

                if (targetSet.isEmpty()) {
                    XMethod calledMethod = XFactory.createXMethod(obj, getCPG());
                    result = getReturnValueNullness(calledMethod);
                } else {
                    for (XMethod calledMethod : targetSet) {
                        IsNullValue pushValue = getReturnValueNullness(calledMethod);
                        if (result == null) {
                            result = pushValue;
                        } else {
                            result = IsNullValue.merge(result, pushValue);
                        }
                    }
                }
            } catch (DataflowAnalysisException e) {
                result = IsNullValue.nonReportingNotNullValue();
            } catch (ClassNotFoundException e) {
                result = IsNullValue.nonReportingNotNullValue();
            }
            modelInstruction(obj, getNumWordsConsumed(obj), getNumWordsProduced(obj), result);
            newValueOnTOS();
        }

    }
private void handleInvoke ( InvokeInstruction obj ) { if ( obj instanceof INVOKEDYNAMIC ) { return ; } Type returnType = obj . getReturnType ( getCPG ( ) ) ; Location location = getLocation ( ) ; if ( trackValueNumbers ) { try { ValueNumberFrame vnaFrame = vnaDataflow . getFactAtLocation ( location ) ; Set < ValueNumber > nonnullParameters = UnconditionalValueDerefAnalysis . checkAllNonNullParams ( location , vnaFrame , cpg , null , null , typeDataflow ) ; if ( ! nonnullParameters . isEmpty ( ) ) { IsNullValue kaboom = IsNullValue . noKaboomNonNullValue ( location ) ; IsNullValueFrame frame = getFrame ( ) ; for ( ValueNumber vn : nonnullParameters ) { IsNullValue knownValue = frame . getKnownValue ( vn ) ; if ( knownValue != null && ! knownValue . isDefinitelyNotNull ( ) ) { if ( knownValue . isDefinitelyNull ( ) ) { frame . setTop ( ) ; return ; } frame . setKnownValue ( vn , kaboom ) ; } for ( int i = 0 ; i < vnaFrame . getNumSlots ( ) ; i ++ ) { IsNullValue value = frame . getValue ( i ) ; if ( vnaFrame . getValue ( i ) . equals ( vn ) && ! value . isDefinitelyNotNull ( ) ) { frame . setValue ( i , kaboom ) ; if ( value . isDefinitelyNull ( ) ) { frame . setTop ( ) ; return ; } } } } } } catch ( DataflowAnalysisException e ) { AnalysisContext . logError ( "Error looking up nonnull parameters for invoked method" , e ) ; } } boolean modelCallReturnValue = MODEL_NONNULL_RETURN && returnType instanceof ReferenceType ; if ( ! modelCallReturnValue ) { handleNormalInstruction ( obj ) ; } else { IsNullValue result = null ; TypeFrame typeFrame ; try { typeFrame = typeDataflow . getFactAtLocation ( location ) ; Set < XMethod > targetSet = Hierarchy2 . resolveMethodCallTargets ( obj , typeFrame , cpg ) ; if ( targetSet . isEmpty ( ) ) { XMethod calledMethod = XFactory . createXMethod ( obj , getCPG ( ) ) ; result = getReturnValueNullness ( calledMethod ) ; } else { for ( XMethod calledMethod : targetSet ) { IsNullValue pushValue = getReturnValueNullness ( calledMethod ) ; if ( result == null ) { result = pushValue ; } else { result = IsNullValue . merge ( result , pushValue ) ; } } } } catch ( DataflowAnalysisException e ) { result = IsNullValue . nonReportingNotNullValue ( ) ; } catch ( ClassNotFoundException e ) { result = IsNullValue . nonReportingNotNullValue ( ) ; } modelInstruction ( obj , getNumWordsConsumed ( obj ) , getNumWordsProduced ( obj ) , result ) ; newValueOnTOS ( ) ; } }
Handle method invocations. Generally, we want to get rid of null
information following a call to a likely exception thrower or assertion.