Exemple #1
0
  /**
   * Check that the set of <code>LocalInstance</code>s <code>localsUsed</code>, which is the set of
   * locals used in the inner class declared by <code>cb</code> are initialized before the class
   * declaration.
   */
  protected void checkLocalsUsedByInnerClass(
      FlowGraph graph, ClassBody cb, Set localsUsed, DataFlowItem dfIn, DataFlowItem dfOut)
      throws SemanticException {
    for (Iterator iter = localsUsed.iterator(); iter.hasNext(); ) {
      LocalInstance li = (LocalInstance) iter.next();
      MinMaxInitCount initCount = (MinMaxInitCount) dfOut.initStatus.get(li);
      if (!currCBI.localDeclarations.contains(li)) {
        // the local wasn't defined in this scope.
        currCBI.outerLocalsUsed.add(li);
      } else if (initCount == null || InitCount.ZERO.equals(initCount.getMin())) {
        // initCount will in general not be null, as the local variable
        // li is declared in the current class; however, if the inner
        // class is declared in the initializer of the local variable
        // declaration, then initCount could in fact be null, as we
        // leave the inner class before we have performed flowLocalDecl
        // for the local variable declaration.

        throw new SemanticException(
            "Local variable \""
                + li.name()
                + "\" must be initialized before the class "
                + "declaration.",
            cb.position());
      }
    }
  }
Exemple #2
0
  /** Check that the assignment to a local variable is correct. */
  protected void checkLocalAssign(
      FlowGraph graph, LocalAssign a, DataFlowItem dfIn, DataFlowItem dfOut)
      throws SemanticException {
    LocalInstance li = ((Local) a.left()).localInstance();
    if (!currCBI.localDeclarations.contains(li)) {
      throw new SemanticException(
          "Final local variable \"" + li.name() + "\" cannot be assigned to in an inner class.",
          a.position());
    }

    MinMaxInitCount initCount = (MinMaxInitCount) dfOut.initStatus.get(li);

    if (li.flags().isFinal() && InitCount.MANY.equals(initCount.getMax())) {
      throw new SemanticException(
          "variable \"" + li.name() + "\" might already have been assigned to", a.position());
    }
  }
  @Override
  public Node labelCheckLHS(LabelChecker lc) throws SemanticException {
    final Assign assign = (Assign) node();
    Local lve = (Local) assign.left();

    JifTypeSystem ts = lc.jifTypeSystem();
    JifContext A = lc.jifContext();
    A = (JifContext) lve.del().enterScope(A);

    List throwTypes = new ArrayList(assign.del().throwTypes(ts));

    final LocalInstance li = lve.localInstance();

    Label L = ts.labelOfLocal(li, A.pc());

    Expr rhs = (Expr) lc.context(A).labelCheck(assign.right());
    PathMap Xr = rhsPathMap(lc.context(A), rhs, throwTypes);
    PathMap X;

    if (assign.operator() != Assign.ASSIGN) {
      PathMap Xv = ts.pathMap();
      Xv = Xv.N(A.pc());
      Xv = Xv.NV(lc.upperBound(L, A.pc()));

      if (assign.throwsArithmeticException()) {
        Type arithExc = ts.ArithmeticException();
        checkAndRemoveThrowType(throwTypes, arithExc);
        X = Xv.join(Xr).exc(Xr.NV(), arithExc);
      } else {
        X = Xv.join(Xr);
      }
    } else {
      X = Xr;
    }

    lc.constrain(
        new NamedLabel(
            "rhs.nv", "label of successful evaluation of right hand of assignment", X.NV()),
        LabelConstraint.LEQ,
        new NamedLabel("label of var " + li.name(), L),
        A.labelEnv(),
        lve.position(),
        new LabelConstraintMessage() {
          @Override
          public String msg() {
            return "Label of right hand side not less "
                + "restrictive than the label for local variable "
                + li.name();
          }

          @Override
          public String detailMsg() {
            return "More information is revealed by the successful "
                + "evaluation of the right hand side of the "
                + "assignment than is allowed to flow to "
                + "the local variable "
                + li.name()
                + ".";
          }

          @Override
          public String technicalMsg() {
            return "Invalid assignment: path NV of rhs is "
                + "not less restrictive than the declared label "
                + "of the local variable <"
                + li.name()
                + ">.";
          }
        });

    if (JLiftOptions.getInstance().safeMutateConstraintSet) {
      // also constrain PC label
      lc.constrain(
          new NamedLabel("pc", "program counter label for assignment", A.pc()),
          LabelConstraint.LEQ,
          new NamedLabel("label of var " + li.name(), L),
          A.labelEnv(),
          lve.position(),
          new LabelConstraintMessage() {
            @Override
            public String msg() {
              return "Program counter not less "
                  + "restrictive than the label for local variable "
                  + li.name();
            }
          });
    }

    Expr lhs = (Expr) updatePathMap(lve, X);
    checkThrowTypes(throwTypes);
    return updatePathMap(assign.right(rhs).left(lhs), X);
  }
  private Node translateExtForArray(ExtendedFor n, List<String> labels) throws SemanticException {
    Position pos = Position.compilerGenerated();
    Type iteratedType = n.decl().type().type();
    // translate "L1,...,Ln: for (C x: e) b" to
    // "{ C[] arr = e; int iter = 0;  L1,...,Ln: while (iter < arr.length)  { C x = arr[iter]; b ;
    // iter = iter + 1; }"
    List<Stmt> stmts = new ArrayList<Stmt>();

    // add the declaration of arr: "C[] arr = e"
    Id arrID = freshName("arr");
    LocalInstance arrLI = ts.localInstance(pos, Flags.NONE, n.expr().type(), arrID.id());
    {
      LocalDecl ld =
          nodeFactory()
              .LocalDecl(
                  pos, Flags.NONE, nodeFactory().CanonicalTypeNode(pos, arrLI.type()), arrID);
      ld = ld.localInstance(arrLI);
      ld = ld.init(n.expr());
      stmts.add(ld);
    }

    // add the declaration of iterator: "int iter = 0"
    Id iterID = freshName("iter");
    LocalInstance iterLI = ts.localInstance(pos, Flags.NONE, ts.Int(), iterID.id());
    {
      LocalDecl ld =
          nodeFactory()
              .LocalDecl(
                  pos, Flags.NONE, nodeFactory().CanonicalTypeNode(pos, iterLI.type()), iterID);
      ld = ld.localInstance(iterLI);
      ld = ld.init(nodeFactory().IntLit(pos, IntLit.INT, 0).type(ts.Int()));
      stmts.add(ld);
    }

    // build the conditional "iter < arr.length"
    Expr cond;
    {
      Local iterLocal =
          (Local) nodeFactory().Local(pos, iterID).localInstance(iterLI).type(ts.Int());
      Local arrLocal =
          (Local) nodeFactory().Local(pos, arrID).localInstance(arrLI).type(arrLI.type());
      Id id = nodeFactory().Id(pos, "length");
      Field field = (Field) nodeFactory().Field(pos, arrLocal, id).type(ts.Int());
      field = field.fieldInstance(ts.findField(arrLI.type().toReference(), "length"));

      cond = nodeFactory().Binary(pos, iterLocal, Binary.LT, field).type(ts.Boolean());
    }

    // build the initlizer for the local decl: arr[iter]
    Expr init;
    {
      Local iterLocal =
          (Local) nodeFactory().Local(pos, iterID).localInstance(iterLI).type(ts.Int());
      Local arrLocal =
          (Local) nodeFactory().Local(pos, arrID).localInstance(arrLI).type(arrLI.type());
      init = nodeFactory().ArrayAccess(pos, arrLocal, iterLocal);
      init = init.type(iteratedType);
    }

    // build the increment for iter (iter = iter + 1;)
    Stmt inc;
    {
      Local iterLocal =
          (Local) nodeFactory().Local(pos, iterID).localInstance(iterLI).type(ts.Int());
      Expr incExpr =
          nodeFactory()
              .Binary(
                  pos,
                  iterLocal.type(ts.Int()),
                  Binary.ADD,
                  nodeFactory().IntLit(pos, IntLit.INT, 1).type(ts.Int()))
              .type(ts.Int());
      Assign incStore =
          (Assign) nodeFactory().Assign(pos, iterLocal, Assign.ASSIGN, incExpr).type(ts.Int());
      inc = nodeFactory().Eval(pos, incStore);
    }

    // build the while loop
    {
      // Create a new loop body from the old body followed by the increment
      Block loopBody = nodeFactory().Block(pos, n.decl().init(init), n.body(), inc);
      While loop = nodeFactory().While(pos, cond, loopBody);
      stmts.add(labelStmt(loop, labels));
    }
    return nodeFactory().Block(pos, stmts);
  }