Exemplo n.º 1
0
  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;
  }
Exemplo n.º 2
0
 public Item createInitialItem(FlowGraph graph, Term node, boolean entry) {
   if (node == graph.root() && entry) {
     return DataFlowItem.REACHABLE;
   } else {
     return DataFlowItem.NOT_REACHABLE;
   }
 }
Exemplo n.º 3
0
 public Item createInitialItem(FlowGraph graph, Term node) {
   if (node == graph.entryNode()) {
     return DataFlowItem.REACHABLE;
   } else {
     return DataFlowItem.NOT_REACHABLE;
   }
 }
Exemplo n.º 4
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;
  }
Exemplo n.º 5
0
  /**
   * Check that the conditions of initialization are not broken.
   *
   * <p>To summarize the conditions: - Local variables must be initialized before use, (i.e. min
   * count > 0) - Final local variables (including Formals) cannot be assigned to more than once
   * (i.e. max count <= 1) - Final non-static fields whose target is this cannot be assigned to more
   * than once - Final static fields whose target is the current class cannot be assigned to more
   * than once
   *
   * <p>This method is also responsible for maintaining state between the dataflows over
   * Initializers, by copying back the appropriate MinMaxInitCounts to the map
   * currClassFinalFieldInitCounts.
   */
  public void check(FlowGraph graph, Term n, Item inItem, Map outItems) throws SemanticException {
    DataFlowItem dfIn = (DataFlowItem) inItem;
    if (dfIn == null) {
      // There is no input data flow item. This can happen if we are
      // checking an unreachable term, and so no Items have flowed
      // through the term. For example, in the code fragment:
      //     a: do { break a; } while (++i < 10);
      // the expression "++i < 10" is unreachable, but the as there is
      // no unreachable statement, the Java Language Spec permits it.

      // Set inItem to a default Item
      dfIn = createInitDFI();
    }

    DataFlowItem dfOut = null;
    if (outItems != null && !outItems.isEmpty()) {
      // due to the flow equations, all DataFlowItems in the outItems map
      // are the same, so just take the first one.
      dfOut = (DataFlowItem) outItems.values().iterator().next();
    }

    if (n instanceof Local) {
      checkLocal(graph, (Local) n, dfIn, dfOut);
    } else if (n instanceof LocalAssign) {
      checkLocalAssign(graph, (LocalAssign) n, dfIn, dfOut);
    } else if (n instanceof FieldAssign) {
      checkFieldAssign(graph, (FieldAssign) n, dfIn, dfOut);
    } else if (n instanceof ClassBody) {
      // we need to check that the locals used inside this class body
      // have all been defined at this point.
      Set localsUsed = (Set) currCBI.localsUsedInClassBodies.get(n);

      if (localsUsed != null) {
        checkLocalsUsedByInnerClass(graph, (ClassBody) n, localsUsed, dfIn, dfOut);
      }
    }

    if (n == graph.finishNode()) {
      if (currCBI.currCodeDecl instanceof Initializer) {
        finishInitializer(graph, (Initializer) currCBI.currCodeDecl, dfIn, dfOut);
      }
      if (currCBI.currCodeDecl instanceof ConstructorDecl) {
        finishConstructorDecl(graph, (ConstructorDecl) currCBI.currCodeDecl, dfIn, dfOut);
      }
    }
  }
Exemplo n.º 6
0
 /**
  * The initial item to be given to the entry point of the dataflow contains the init counts for
  * the final fields.
  */
 public Item createInitialItem(FlowGraph graph, Term node) {
   if (node == graph.startNode()) {
     return createInitDFI();
   }
   return BOTTOM;
 }