Examine null values. Report any that are guaranteed to be dereferenced on
non-implicit-exception paths.

@throws CFGBuilderException
@throws DataflowAnalysisException
490741
private void examineNullValues() throws CFGBuilderException, DataflowAnalysisException {
        Set<LocationWhereValueBecomesNull> locationWhereValueBecomesNullSet = invDataflow.getAnalysis()
                .getLocationWhereValueBecomesNullSet();
        if (DEBUG_DEREFS) {
            System.out.println("----------------------- examineNullValues " + locationWhereValueBecomesNullSet.size());
        }

        Map<ValueNumber, SortedSet<Location>> bugStatementLocationMap = new HashMap<>();
        // Inspect the method for locations where a null value is guaranteed to
        // be dereferenced. Add the dereference locations
        Map<ValueNumber, NullValueUnconditionalDeref> nullValueGuaranteedDerefMap = new HashMap<>();

        // Check every location
        CFG cfg = classContext.getCFG(method);
        for (Iterator<Location> i = cfg.locationIterator(); i.hasNext();) {
            Location location = i.next();

            if (DEBUG_DEREFS) {
                System.out.println("At location " + location);
            }

            checkForUnconditionallyDereferencedNullValues(location, bugStatementLocationMap, nullValueGuaranteedDerefMap,
                    vnaDataflow.getFactAtLocation(location), invDataflow.getFactAtLocation(location),
                    uvdDataflow.getFactAfterLocation(location), false);
        }
        HashSet<ValueNumber> npeIfStatementCovered = new HashSet<>(nullValueGuaranteedDerefMap.keySet());
        Map<ValueNumber, SortedSet<Location>> bugEdgeLocationMap = new HashMap<>();

        checkEdges(cfg, nullValueGuaranteedDerefMap, bugEdgeLocationMap);

        Map<ValueNumber, SortedSet<Location>> bugLocationMap = bugEdgeLocationMap;
        bugLocationMap.putAll(bugStatementLocationMap);

        // For each value number that is null somewhere in the
        // method, collect the set of locations where it becomes null.
        // FIXME: we may see some locations that are not guaranteed to be
        // dereferenced (how to fix this?)
        Map<ValueNumber, Set<Location>> nullValueAssignmentMap = findNullAssignments(locationWhereValueBecomesNullSet);

        reportBugs(nullValueGuaranteedDerefMap, npeIfStatementCovered, bugLocationMap, nullValueAssignmentMap);
    }
1354109
private void newValueOnTOS() {
        IsNullValueFrame frame = getFrame();
        if (frame.getStackDepth() < 1) {
            return;
        }
        int tosSlot = frame.getNumSlots() - 1;
        IsNullValue tos = frame.getValue(tosSlot);
        if (tos.isDefinitelyNull()) {
            slotContainingNewNullValue = tosSlot;
        }
        if (trackValueNumbers) {
            try {
                ValueNumberFrame vnaFrameAfter = vnaDataflow.getFactAfterLocation(getLocation());
                if (vnaFrameAfter.isValid()) {
                    ValueNumber tosVN = vnaFrameAfter.getTopValue();
                    getFrame().setKnownValue(tosVN, tos);
                }
            } catch (DataflowAnalysisException e) {
                AnalysisContext.logError("error", e);
            }
        }
    }
812942
@Nullable
  public static Number numberValue(TreePath exprPath, Context context) {
    Constant val = DataFlow.expressionDataflow(exprPath, context, CONSTANT_PROPAGATION);
    if (val == null || !val.isConstant()) {
      return null;
    }
    return val.getValue();
  }
75675
@Override
    public void out() throws Exception {
        Object val = fa.getFieldValue();
//        Object val = access;

        if (ens.shouldFire()) {
            DataflowEvent e = new DataflowEvent(ens.getController(), this, val);
////            DataflowEvent e = new DataflowEvent(ens.getController(), this, access.toObject());
            ens.fireOut(e);
//            // the value might be altered
            val = e.getValue();
        }
        // if data==null this unconsumed @Out, its OK but we do not want to set it.
        if (data != null) {
            data.setFieldValue(val);
        }
        fa.out();
    }
301531
private void checkVanillaForInitializers(VariableDeclarationListTree variables) {
    for (VariableDeclarationTree declaration : variables.declarations) {
      if (declaration.initializer == null) {
        maybeReportNoInitializer(variables.declarationType, declaration.lvalue);
      }
    }
  }
1194654
private void _handleEmptyValue(TypedValueDecoder dec)
        throws XMLStreamException
    {
        try { // default action is to throw an exception
            dec.handleEmptyValue();
        } catch (IllegalArgumentException iae) {
            throw _constructTypeException(iae, "");
        }
    }
1223347
public ValueType getStackValue(int loc) throws DataflowAnalysisException {
        if (!isValid()) {
            throw new DataflowAnalysisException("Accessing TOP or BOTTOM frame!");
        }
        int stackDepth = getStackDepth();
        if (loc >= stackDepth) {
            throw new DataflowAnalysisException("not enough values on stack: access=" + loc + ", avail=" + stackDepth);
        }
        if (loc < 0) {
            throw new DataflowAnalysisException("can't get position " + loc + " of stack");
        }
        int pos = slotList.size() - (loc + 1);
        return slotList.get(pos);
    }
914198
@Override
    public void meetInto(TypeQualifierValueSet fact, Edge edge, TypeQualifierValueSet result) throws DataflowAnalysisException {
        if (fact.isTop() || result.isBottom()) {
            // result does not change
            return;
        } else if (fact.isBottom() || result.isTop()) {
            result.makeSameAs(fact);
            return;
        }

        assert fact.isValid();
        assert result.isValid();

        result.mergeWith(fact);
    }
929327
private @CheckForNull
    ValueNumber findValueKnownNonnullOnBranch(UnconditionalValueDerefSet fact, Edge edge) {

        IsNullValueFrame invFrame = invDataflow.getResultFact(edge.getSource());
        if (!invFrame.isValid()) {
            return null;
        }
        IsNullConditionDecision decision = invFrame.getDecision();
        if (decision == null) {
            return null;
        }

        IsNullValue inv = decision.getDecision(edge.getType());
        if (inv == null || !inv.isDefinitelyNotNull()) {
            return null;
        }
        ValueNumber value = decision.getValue();
        if (DEBUG) {
            System.out.println("Value number " + value + " is known nonnull on " + edge);
        }

        return value;
    }
65241
@SuppressWarnings("unchecked")
	private <T> T nullFor(DataType dataType)
	{
		switch(dataType)
		{
			case Long: return (T)Long.valueOf(-1);
			default: return null;
		}
	}
312759
private void precheckStateAllNull() throws IllegalStateException {
        if ((doubleValue != null) || (doubleArray != null)
            || (longValue != null) || (longArray != null)
            || (stringValue != null) || (stringArray != null)
            || (map != null)) {
            throw new IllegalStateException("Expected all properties to be empty: " + this);
        }
    }
667133
public static void blankValue(CodeBuilder b, TypeDesc type) {
        switch (type.getTypeCode()) {
        default:
            b.loadNull();
            break;

        case TypeDesc.BYTE_CODE:
        case TypeDesc.CHAR_CODE:
        case TypeDesc.SHORT_CODE:
        case TypeDesc.INT_CODE:
            b.loadConstant(0);
            break;

        case TypeDesc.BOOLEAN_CODE:
            b.loadConstant(false);
            break;

        case TypeDesc.LONG_CODE:
            b.loadConstant(0L);
            break;

        case TypeDesc.FLOAT_CODE:
            b.loadConstant(0.0f);
            break;

        case TypeDesc.DOUBLE_CODE:

            b.loadConstant(0.0);
            break;
        }
    }
770175
public void setFlowProperties(Flow[] flows)
    throws SIIncorrectCallException
  {
    if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled())
      SibTr.entry(tc, "setFlowProperties", flows);

    try
    {
      // Take the Write Lock for classifications
      classificationWriteLock.lock();

      // Disallow null flows
      if(flows == null)
      {
        SIIncorrectCallException e =
          new SIIncorrectCallException(
            nls.getFormattedMessage(
                "NULL_FLOW_CLASSIFICATIONS_CWSIP0851",
                new Object[] {
                  "com.ibm.ws.sib.processor.impl.JSConsumerSet.setFlowProperties",
                  "1:877:1.16",
                  label },
                null));
        
        // FFDC
        FFDCFilter.processException(
          e,
          "com.ibm.ws.sib.processor.impl.JSConsumerSet.setFlowProperties",
          "1:885:1.16",
          this);
            
        if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled()) 
          SibTr.exit(tc, "setFlowProperties", "SIIncorrectCallException");
        throw e;
      }
    
      // Set up the new classifications for the ConsumerSet
      boolean weightChangeOnly = classifications.setClassifications(flows);
    
      // Need to notify registered keys of the change but only if the flow change is
      // substantive - i.e. more than just a change in the relative weightings of the 
      // current flows.
      if(!weightChangeOnly)
      {
        Iterator<DispatchableKey> it = keyRegistry.iterator();
        while (it.hasNext())
        {
          DispatchableKey key = (DispatchableKey)it.next();
          // Notify the appropriate key
          if(key instanceof LocalQPConsumerKey)
          {
            ((LocalQPConsumerKey)(key)).notifyResetFlowProperties();
          }
          else if(key instanceof LocalQPConsumerKeyGroup)
          {
            ((LocalQPConsumerKeyGroup)(key)).notifyResetFlowProperties();
          }
        }
      }
    }
    catch(InvalidFlowsException ife)
    {
      // FFDC
      FFDCFilter.processException(
        ife,
        "com.ibm.ws.sib.processor.impl.JSConsumerSet.setFlowProperties",
        "1:923:1.16",
        this);
      
      // Map the InvalidFlowsException to an SIIncorrectCallException
      SIIncorrectCallException e =
        new SIIncorrectCallException(
          nls.getFormattedMessage(
              "INVALID_FLOW_CLASSIFICATIONS_CWSIP0852",
              new Object[] {
                "com.ibm.ws.sib.processor.impl.JSConsumerSet.setFlowProperties",
                "1:933:1.16",
                label },
              null));
          
      if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled()) 
        SibTr.exit(tc, "setFlowProperties", "SIIncorrectCallException");
      throw e;
    }
    finally
    {
      // Free the write lock
      classificationWriteLock.unlock();
    }
    
    if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled())
      SibTr.exit(tc, "setFlowProperties");        
  }
85326
@SuppressWarnings("unused")
    static Void throwUnsafelyIfNonNull(@Nullable Object unused,
                                       @Nullable Throwable cause) {
        throwUnsafelyIfNonNull(cause);
        return null;
    }
313460
public static void checkNull(Object value, String message, Object... args) {
    if (value != null) {
      throw new IllegalArgumentException(String.format(message, args));
    }
  }
123106
@SuppressWarnings("nls")
	private void checkNotNull(Object sourceClass, Object eventSetName, Object alistenerType, Object listenerMethodName)
	{
		if (sourceClass == null)
		{
			throw new NullPointerException(Messages.getString("beans.0C"));
		}
		if (eventSetName == null)
		{
			throw new NullPointerException(Messages.getString("beans.53"));
		}
		if (alistenerType == null)
		{
			throw new NullPointerException(Messages.getString("beans.54"));
		}
		if (listenerMethodName == null)
		{
			throw new NullPointerException(Messages.getString("beans.52"));
		}
	}
602831
function nullFrom(nfa, node) {
  let result = []
  scan(node)
  return result.sort(cmp)

  function scan(node) {
    let edges = nfa[node]
    if (edges.length == 1 && !edges[0].term) return scan(edges[0].to)
    result.push(node)
    for (let i = 0; i < edges.length; i++) {
      let {term, to} = edges[i]
      if (!term && result.indexOf(to) == -1) scan(to)
    }
  }
}