Esempio n. 1
0
 /** Check that the local variable <code>l</code> is used correctly. */
 protected void checkLocal(FlowGraph graph, Local l, DataFlowItem dfIn, DataFlowItem dfOut)
     throws SemanticException {
   if (!currCBI.localDeclarations.contains(l.localInstance())) {
     // it's a local variable that has not been declared within
     // this scope. The only way this can arise is from an
     // inner class that is not a member of a class (typically
     // a local class, or an anonymous class declared in a method,
     // constructor or initializer).
     // We need to check that it is a final local, and also
     // keep track of it, to ensure that it has been definitely
     // assigned at this point.
     currCBI.outerLocalsUsed.add(l.localInstance());
   } else {
     MinMaxInitCount initCount = (MinMaxInitCount) dfIn.initStatus.get(l.localInstance());
     if (initCount != null && InitCount.ZERO.equals(initCount.getMin())) {
       // the local variable may not have been initialized.
       // However, we only want to complain if the local is reachable
       if (l.reachable()) {
         throw new SemanticException(
             "Local variable \"" + l.name() + "\" may not have been initialized", l.position());
       }
     }
   }
 }
Esempio n. 2
0
  @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);
  }