protected Node checkReachability(Term n) throws SemanticException {
    FlowGraph g = currentFlowGraph();
    if (g != null) {
      Collection peers = g.peers(n);
      if (peers != null && !peers.isEmpty()) {
        boolean isInitializer = (n instanceof Initializer);

        for (Iterator iter = peers.iterator(); iter.hasNext(); ) {
          FlowGraph.Peer p = (FlowGraph.Peer) iter.next();

          // the peer is reachable if at least one of its out items
          // is reachable. This would cover all cases, except that some
          // peers may have no successors (e.g. peers that throw an
          // an exception that is not caught by the method). So we need
          // to also check the inItem.
          if (p.inItem() != null) {
            DataFlowItem dfi = (DataFlowItem) p.inItem();
            // there will only be one peer for an initializer,
            // as it cannot occur in a finally block.
            if (isInitializer && !dfi.normalReachable) {
              throw new SemanticException(
                  "Initializers must be able to complete normally.", n.position());
            }

            if (dfi.reachable) {
              return n.reachable(true);
            }
          }

          if (p.outItems != null) {
            for (Iterator k = p.outItems.values().iterator(); k.hasNext(); ) {
              DataFlowItem item = (DataFlowItem) k.next();

              if (item != null && item.reachable) {
                // n is reachable.
                return n.reachable(true);
              }
            }
          }
        }

        // if we fall through to here, then no peer for n was reachable.
        n = n.reachable(false);

        // Compound statements are allowed to be unreachable
        // (e.g., "{ // return; }" or "while (true) S").  If a compound
        // statement is truly unreachable, one of its sub-statements will
        // be also and we will report an error there.

        if ((n instanceof Block && ((Block) n).statements().isEmpty())
            || (n instanceof Stmt && !(n instanceof CompoundStmt))) {
          throw new SemanticException("Unreachable statement.", n.position());
        }
      }
    }
    return n;
  }
Exemple #2
0
  protected Node checkReachability(Term n) {
    FlowGraph g = currentFlowGraph();
    if (g != null) {
      Collection<FlowGraph.Peer> peers = g.peers(n, Term.EXIT);
      if (peers != null && !peers.isEmpty()) {
        boolean isInitializer = (n instanceof Initializer);

        for (FlowGraph.Peer p : peers) {
          // the peer is reachable if at least one of its out items
          // is reachable. This would cover all cases, except that some
          // peers may have no successors (e.g. peers that throw an
          // an exception that is not caught by the method). So we need
          // to also check the inItem.
          if (p.inItem() != null) {
            DataFlowItem dfi = (DataFlowItem) p.inItem();
            // there will only be one peer for an initializer,
            // as it cannot occur in a finally block.
            if (isInitializer && !dfi.normalReachable) {
              reportError(new Errors.InitializersMustCompleteNormally(n.position()));
            }

            if (dfi.reachable) {
              return n.reachable(true);
            }
          }

          if (p.outItems != null) {
            for (Item v : p.outItems.values()) {
              DataFlowItem item = (DataFlowItem) v;

              if (item != null && item.reachable) {
                // n is reachable.
                return n.reachable(true);
              }
            }
          }
        }

        // if we fall through to here, then no peer for n was reachable.
        n = n.reachable(false);
      }
    }
    return n;
  }