Beispiel #1
0
        internal static Statement GenerateForLoop(Variable loopVariable, Expression lowerBound, Expression upperBound, Statement body)
        {
            Block bodyAsBlock = body as Block ?? new Block(new StatementList(body));
            Block init = new Block(new StatementList(2));
            Block increment = new Block(new StatementList(1));
            Block test = new Block(new StatementList(new Branch(
              new BinaryExpression(loopVariable, upperBound, NodeType.Lt), bodyAsBlock))); //, false, true, false)));

            init.Statements.Add(new AssignmentStatement(loopVariable, lowerBound));
            init.Statements.Add(new Branch(null, test));

            increment.Statements.Add(new AssignmentStatement(loopVariable, new BinaryExpression(loopVariable, Literal.Int32One, NodeType.Add)));

            Block forLoop = new Block(new StatementList(4));
            forLoop.Statements.Add(init);
            forLoop.Statements.Add(bodyAsBlock);
            forLoop.Statements.Add(increment);
            forLoop.Statements.Add(test);
            return forLoop;
        }
 public void SetToFalse(Variable v) {
   this.egraph[v] = this.False;
 }
 public static string Name(Variable v) 
 {
   Identifier name = v.Name;
   string nstr = (name == null)?"":name.Name;
   return String.Format("{0}({1})", nstr, v.UniqueKey);
 }
 protected override object VisitSizeOf(Variable dest, TypeNode value_type, Statement stat, object arg) {
   ExposureState estate=(ExposureState)arg; 
   estate.AssignNonPointer(dest);
   return arg;
 }
    protected override object VisitBinaryOperator(NodeType op, Variable dest, Variable operand1, Variable operand2, Statement stat, object arg) {
      ExposureState estate=(ExposureState)arg; 

//      estate.AssignBinary(dest, op, operand1, operand2);

      return arg;
    }
    protected override object VisitReturn(Variable var, Statement stat, object arg) {
      ExposureState estate=(ExposureState)arg;

      // TODO: see if returned value is supposed to be exposed or not and then what do we know about it?
      return arg;
    }
    protected override object VisitLoadField(Variable dest, Variable source, Field field, Statement stat, object arg) {
      ExposureState estate=(ExposureState)arg;

      // Check the receiver here only if one needs to be unpacked for read access
      //CheckReceiver(stat,source,estate);

      return arg;
    }
    protected override object VisitCall(Variable dest, Variable receiver, Method callee, ExpressionList arguments, bool virtcall, Statement stat, object arg) {
      ExposureState estate=(ExposureState)arg;

      if (callee.CciKind == Cci.CciMemberKind.FrameGuardGetter){
        // associate dest with receiver, because unpack is going to happen with dest as receiver
        estate.AssignFrameFor(dest,receiver,callee.DeclaringType); // receiver could be a subtype of the type that the frame guard is for
      }else if (callee == UnpackMethod){
        if(estate.IsFrameExposable(receiver)) {
          // BUGBUG: Using CopyVariable encodes the assumption that StartWritingTransitively returns itself!!! It may not!
          estate.CopyVariable(receiver,dest);
          estate.AssignFrameForExposed(dest);
        }else{
          TypeNode t = estate.LowerBoundOfObjectPointedToByFrame(receiver);
          if (t == null){ // BUGBUG: is this the same as it being Top?
            HandleError(stat, stat, Error.DontKnowIfCanExposeObject);
          }else{
            HandleError(stat, stat, Error.ExposingExposedObject);
          }
          return null;
        }
      }else if (callee == PackMethod){
        estate.AssignFrameForNotExposed(receiver);
      }else if (callee == IsExposableMethod){
        estate.AssignFunctionLink(ExposureState.EqIsExposableId,dest,receiver);
      }else if (callee == IsExposedMethod){
        estate.AssignEqIsExposed(dest,receiver);
      }else if (callee == AssertMethod){
        Variable v = arguments[0] as Variable;
        if (v != null && estate.IsFalse(v))
          return null;
      }

      // Push possible exceptions to handlers.
      for(int i=0;i<callee.Contract.Ensures.Count;i++){
        EnsuresExceptional e=callee.Contract.Ensures[i] as EnsuresExceptional;
        if(e!=null){
          ExposureState newnn=new ExposureState(estate);
          newnn.currentException=e.Type;
          ExposureChecker.PushExceptionState(ExposureChecker.currBlock,newnn);
        }
      }

      return arg;
    }
 public void AssignFrameForNotExposed(Variable guardVariable){
   ISymValue guard = this.egraph[guardVariable];
   ISymValue guardTypeObject = this.egraph[StaticTypeOf,guard];
   Lattice.AVal guardsType = (Lattice.AVal)this.egraph[guardTypeObject];
   ISymValue guardedObject = this.egraph[FrameFor, guard];
   this.egraph[guardedObject] = guardsType;
 }
 public bool IsFrameExposable(Variable guardVariable){
   ISymValue guard = this.egraph[guardVariable];
   ISymValue guardedObject = this.egraph[FrameFor, guard];
   ISymValue guardTypeObject = this.egraph[StaticTypeOf,guard];
   Lattice.AVal guardsType = (Lattice.AVal)this.egraph[guardTypeObject];
   Lattice.AVal guardedObjectsType = (Lattice.AVal)this.egraph[guardedObject];
   return guardsType.lowerBound == guardedObjectsType.lowerBound;
 }
 public void AssignFrameForExposable(Variable guardVariable){
   ISymValue guard = this.egraph[guardVariable];
   this.AssignFrameForExposable(guard);
 }
 public void AssignFrameFor(Variable dest, Variable source, TypeNode t) {
   ISymValue guard = this.egraph.FreshSymbol();
   ISymValue guardedObject = this.egraph[source];
   this.egraph[dest] = guard;
   this.egraph[FrameFor, guard] = guardedObject;
   ISymValue fresh = this.egraph.FreshSymbol();
   this.egraph[fresh] = new Lattice.AVal(t,t);
   this.egraph[StaticTypeOf, guard] = fresh;
 }
 public void CopyVariable(Variable source, Variable dest) {
   this.egraph[dest] = this.egraph[source];
 }
 public void AssignNonPointer(Variable v) {
   this.egraph.Eliminate(v);
 }
 public bool IsFalse(Variable v){
   return this.egraph[v] == this.False;
 }
    protected override object VisitLoadConstant(Variable dest, Literal source, Statement stat, object arg) 
    {
      ExposureState estate=(ExposureState)arg;

      if (source == Literal.False){
        estate.SetToFalse(dest);
      }

      return arg;
    }
    /// <summary>
    /// Note: casts don't require a non-null argument. null value casts always succeed.
    /// </summary>
    protected override object VisitCastClass(Variable dest, TypeNode type, Variable source, Statement stat, object arg) {
      ExposureState estate=(ExposureState)arg;

      // acts like a copy retaining null status
      estate.CopyVariable(source, dest);
      return arg;
    }
 public void AssignEqIsExposed(Variable dest, Variable operand) {
   ISymValue opval = this.egraph[operand];
   ISymValue sv = this.egraph.FreshSymbol();
   this.egraph[dest] = sv; // ?? Ask Manuel: Should it be the sv' that dest maps to that sv should be mapped to here?
   this.egraph[EqIsExposedId, opval] = sv;
 }
    protected override object VisitConstrainedCall(Variable dest, Variable receiver, Method callee, ExpressionList arguments, TypeNode constraint, Statement stat, object arg) {
      Reference rtype = receiver.Type as Reference;
      if (rtype != null && rtype.ElementType != null && !rtype.ElementType.IsValueType) {
        // instance could be a reference type that could be null.

        // BUGBUG: when we track address of, we need to check here that target is indeed non-null
      }
      return VisitCall(dest, receiver, callee, arguments, true, stat, arg);
    }
 public void AssignFunctionLink(Identifier func, Variable dest, Variable operand) {
   ISymValue opval = this.egraph[operand];
   ISymValue sv = this.egraph.FreshSymbol();
   this.egraph[dest] = sv; // ?? Ask Manuel: Should it be the sv' that dest maps to that sv should be mapped to here?
   this.egraph[func, opval] = sv;
 }
    protected override object VisitStoreField(Variable dest, Field field, Variable source, Statement stat, object arg) {
      ExposureState estate=(ExposureState)arg;

      // static Fields
      if(field.IsStatic){
      }

      // BUGBUG!!
      // It seems that it would be better to start off ctors with the method's "this" object
      // in the Exposed state, but I'm not sure how to do that.
      This t = null;
      ThisBinding tb = dest as ThisBinding;
      if (tb != null){
        t = tb.BoundThis;
      }else{
        t = dest as This;
      }
      if (t != null &&
        this.ExposureChecker.currentMethod.NodeType == NodeType.InstanceInitializer
        && this.ExposureChecker.currentMethod.ThisParameter == t){
        ; // skip
      }else{
        ExposureState.Lattice.AVal valueOfdest = estate.GetAVal(dest);
        if (valueOfdest.lowerBound == null || valueOfdest.upperBound == null){
          HandleError(stat, stat, Error.WritingPackedObject, dest.Name.Name);
          return arg;
        }
        if (valueOfdest.lowerBound.IsAssignableTo(field.DeclaringType)){
          HandleError(stat, stat, Error.WritingPackedObject, dest.Name.Name);
          return arg;
        }
      }

      return arg;
    }
    public void RefineBranchInformation(Variable cond, out ExposureState trueState, out ExposureState falseState) {

      ISymValue cv = this.egraph[cond];

      trueState = new ExposureState(this);
      falseState = new ExposureState(this);

      AssumeTrue(cv, ref trueState);
      AssumeFalse(cv, ref falseState);
    }
    protected override object VisitBranch(Variable cond, Block target, Statement stat, object arg) {
      ExposureState estate=(ExposureState)arg;

      if(cond==null)
        return arg;

      ExposureState trueState, falseState;

      estate.RefineBranchInformation(cond, out trueState, out falseState);

      if ( trueState != null ) {
        ExposureChecker.PushState(ExposureChecker.currBlock, ExposureChecker.currBlock.TrueContinuation, trueState);
      }
      if ( falseState != null ) {
        ExposureChecker.PushState(ExposureChecker.currBlock, ExposureChecker.currBlock.FalseContinuation, falseState);
      }
      return null;
    }
    /// <summary>
    /// For the possible receiver v, check if it is nonnull. if no, file an proper
    /// error/warning.
    /// </summary>
    private void CheckReceiver(Statement stat, Variable v, ExposureState estate)
    {
      Node offendingNode = v;
      if (v == null) return;

      if(estate.IsNotExposed(v))
      {
        HandleError(stat, offendingNode, Error.WritingPackedObject, v.Name.Name);
        //estate.AssignExposed(v);
      }
      else if(!estate.IsExposed(v))
      {
        HandleError(stat, offendingNode, Error.WritingPackedObject, v.Name.Name);
        //estate.AssumeNonNull(v);
      }
    }
 protected override object VisitUnaryOperator(NodeType op, Variable dest, Variable operand, Statement stat, object arg) {
   ExposureState estate=(ExposureState)arg; 
   return arg;
 }
    /// <summary>
    /// Copy the source to dest.
    /// 
    /// If source is nonnull, no problem.
    /// If source is null and dest is nonnulltype, Error
    /// If source is possible null and dest is nonnulltype, warning.
    /// Else, nothing.
    /// 
    /// Need to maintain proper heap transformation.
    /// </summary>
    /// <param name="dest"></param>
    /// <param name="source"></param>
    /// <param name="stat"></param>
    /// <param name="arg"></param>
    /// <returns></returns>
    protected override object VisitCopy(Variable dest, Variable source, Statement stat, object arg) {
      ExposureState estate=(ExposureState)arg;

      estate.CopyVariable(source, dest);

      return arg;
    }
 protected override object VisitBox(Variable dest, Variable source, TypeNode type, Statement stat, object arg) {
   ExposureState estate=(ExposureState)arg;
   return arg;
 }
    protected override object VisitLoadFunction(Variable dest, Variable source, Method method, Statement stat, object arg)
    {
      ExposureState estate=(ExposureState)arg;

      if (method.IsVirtual) 
      {
        // Check for Receiver non-nullness
        CheckReceiver(stat,source,estate);
      }

      return arg;

    }
    protected override object VisitLoadNull(Variable dest, Literal source, Statement stat, object arg) {
      ExposureState estate=(ExposureState)arg;

      return arg;
    }
 public void AssignNotExposed(Variable v) {
   AssignAVal(v, Lattice.AVal.IsNotExposed);
 }