Example #1
0
  /**
   * Returns in the then and else blocks must be consistent with each other. If there is no else
   * block, then the return statement can fall through.
   *
   * @return logical OR of END_* flags
   */
  private int endCheckIf() {
    Node th, el;
    int rv = END_UNREACHED;

    th = next;
    el = ((Jump) this).target;

    rv = th.endCheck();

    if (el != null) rv |= el.endCheck();
    else rv |= END_DROPS_OFF;

    return rv;
  }
Example #2
0
  /**
   * A general block of code is examined statement by statement. If any statement (even compound
   * ones) returns in all branches, then subsequent statements are not examined.
   *
   * @return logical OR of END_* flags
   */
  private int endCheckBlock() {
    Node n;
    int rv = END_DROPS_OFF;

    // check each statment and if the statement can continue onto the next
    // one, then check the next statement
    for (n = first; ((rv & END_DROPS_OFF) != 0) && n != null; n = n.next) {
      rv &= ~END_DROPS_OFF;
      rv |= n.endCheck();
    }
    return rv;
  }
Example #3
0
  /**
   * Consistency of return statements is checked between the case statements. If there is no
   * default, then the switch can fall through. If there is a default,we check to see if all code
   * paths in the default return or if there is a code path that can fall through.
   *
   * @return logical OR of END_* flags
   */
  private int endCheckSwitch() {
    Node n;
    int rv = END_UNREACHED;

    // examine the cases
    for (n = first.next; n != null; n = n.next) {
      if (n.type == Token.CASE) {
        rv |= ((Jump) n).target.endCheck();
      } else break;
    }

    // we don't care how the cases drop into each other
    rv &= ~END_DROPS_OFF;

    // examine the default
    n = ((Jump) this).getDefault();
    if (n != null) rv |= n.endCheck();
    else rv |= END_DROPS_OFF;

    // remove the switch block
    rv |= getIntProp(CONTROL_BLOCK_PROP, END_UNREACHED);

    return rv;
  }