protected override IDataFlowState VisitStatement(CfgBlock block, Statement statement, IDataFlowState dfstate) {
   // For debug purpose
   try{
     Analyzer.WriteLine(new SampleInstructionVisitor().Visit(statement,null)+"   :::   " +statement.SourceContext.SourceText);
   }catch(Exception){
     Analyzer.WriteLine("Print error: "+statement);
   }
   IDataFlowState result=null;
   try{
     result =(IDataFlowState)(iVisitor.Visit(statement,dfstate));
   }catch(ModifiesException e){
     typeSystem.HandleError(statement,System.Compiler.Error.Warning,":"+e.Message);
   }catch(Exception e){
     typeSystem.HandleError(statement,System.Compiler.Error.Warning,":CFG1:"+e.Message);
   }
   Analyzer.WriteLine(dfstate);
   return dfstate;
 }
Example #2
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;
        }
    protected override object VisitLoadNull(Variable dest, Literal source, Statement stat, object arg) {
      ExposureState estate=(ExposureState)arg;

      return arg;
    }
Example #4
0
        private static bool IsNonTrivial(Statement s)
        {
            if (s == null) return false;

            Block b = s as Block;
            
            if (b != null) return (IsNonTrivial(b));
            
            if (s.NodeType == NodeType.Nop) return false;
            
            return true;
        }
Example #5
0
        public static bool IsClosureCreation(Method containingMethod, Statement s, out Local closureLocal)
        {
            var closureType = IsClosureCreation(containingMethod, s);
            if (closureType != null)
            {
                // it's a closure alright
                var assign = s as AssignmentStatement;
                if (assign != null)
                {
                    closureLocal = assign.Target as Local;
                }
                else
                {
                    closureLocal = null;
                }

                return true;
            }
            
            closureLocal = null;
            return false;
        }
Example #6
0
            /// <summary>
            /// Perform subsitution if necessary (create fresh nodes)
            /// </summary>
            internal Statement Visit(Statement statement)
            {
                Contract.Requires(this.IsValid);
                Contract.Requires(this.Depth >= 0);
                Contract.Ensures(this.Depth >= -1);

                if (statement == null) return null;

                switch (statement.NodeType)
                {
                    case NodeType.Nop:
                    case NodeType.Rethrow:
                    case NodeType.EndFilter:
                    case NodeType.EndFinally:
                        break;

                    case NodeType.Pop:
                        // a pop statement rather than expression
                        this.Depth--;
                        if (this.Depth < 0)
                        {
                            // we popped the original closure from the stack.
                            return null;
                        }

                        return statement;

                    case NodeType.AssignmentStatement:
                        var astmt = (AssignmentStatement) statement.Clone();
                        astmt.Target = Visit(astmt.Target);
                        astmt.Source = Visit(astmt.Source);
                        return astmt;

                    case NodeType.ExpressionStatement:
                        var estmt = (ExpressionStatement) statement.Clone();
                        if (estmt.Expression.NodeType == NodeType.Dup)
                        {
                            if (this.Depth == 0)
                            {
                                // duping the closure. Do nothing:
                                return null;
                            }

                            // otherwise, leave dup
                        }
                        else if (estmt.Expression.NodeType == NodeType.Pop)
                        {
                            var unary = estmt.Expression as UnaryExpression;
                            if (unary != null && unary.Operand != null)
                            {
                                // we are popping the thing we just push, so the depth does not change.
                                unary = (UnaryExpression) unary.Clone();
                                unary.Operand = Visit(unary.Operand);
                                estmt.Expression = unary;
                                return estmt;
                            }

                            // a pop statement rather than expression
                            this.Depth--;
                            if (this.Depth < 0)
                            {
                                // we popped the original closure from the stack.
                                return null;
                            }
                        }
                        else
                        {
                            estmt.Expression = Visit(estmt.Expression);
                            if (!IsVoidType(estmt.Expression.Type))
                            {
                                this.Depth++;
                            }
                        }

                        return estmt;

                    case NodeType.Block:
                        var block = (Block) statement.Clone();
                        block.Statements = Visit(block.Statements);
                        return block;

                    case NodeType.SwitchInstruction:
                        var sw = (SwitchInstruction) statement.Clone();
                        sw.Expression = Visit(sw.Expression);
                        return sw;

                    case NodeType.Throw:
                        var th = (Throw) statement.Clone();
                        th.Expression = Visit(th.Expression);
                        return th;

                    case NodeType.Return:
                        var ret = (Return) statement.Clone();
                        ret.Expression = Visit(ret.Expression);
                        return ret;

                    default:
                        var br = statement as Branch;
                        if (br != null)
                        {
                            br = (Branch) br.Clone();
                            br.Condition = Visit(br.Condition);
                            return br;
                        }

                        throw new NotImplementedException("ClosureNormalization Statement");
                }

                return statement;
            }
		/// <summary>
		/// Checks whether a given CciHelper statement encodes an MSIL Pop instruction.
		/// The correctness of this method depends heavily on what Herman does in the CciHelper reader ...
		/// </summary>
		/// <param name="stat">Statement to check.</param>
		/// <returns><c>true</c> iff <c>stat</c> encodes an MSIL Pop instruction.</returns>
		public static bool IsPopStatement(Statement stat) 
		{
			if(stat.NodeType == NodeType.Pop)
				return true;
			ExpressionStatement expr_stat = stat as ExpressionStatement;
			if(expr_stat == null) return false;

			Expression expr = expr_stat.Expression;

			if (expr.NodeType != NodeType.Pop) return false;

			UnaryExpression unexpr = expr as UnaryExpression;
			if ((unexpr != null ) && (unexpr.Operand != null) && (unexpr.Operand.NodeType != NodeType.Pop)) return false;

			return true;
		}
Example #8
0
    private static Statement WrapTryCatch(Method method, Statement statement)
    {
      Block afterCatches = new Block(new StatementList());
      Block tryBlock = new Block(new StatementList());
      Block blockAfterTryBody = new Block(null);
      tryBlock.Statements.Add(statement);
      tryBlock.Statements.Add(new Branch(null, afterCatches, false, true, true));
      tryBlock.Statements.Add(blockAfterTryBody);
      Block catchBlock = new Block(new StatementList());
      // emit code that pops the exception and fools fxcop
      Block branchTargetToFoolFxCop = new Block(null);
      var branch = new Branch(new Expression(NodeType.Pop), branchTargetToFoolFxCop);
      SourceContext hiddenContext = new SourceContext(HiddenDocument.Document);
      branch.SourceContext = hiddenContext;
      catchBlock.Statements.Add(branch);
      var rethrowStatement = new Throw();
      rethrowStatement.SourceContext = hiddenContext;
      rethrowStatement.NodeType = NodeType.Rethrow;
      catchBlock.Statements.Add(rethrowStatement);
      catchBlock.Statements.Add(branchTargetToFoolFxCop);
      var leave = new Branch(null, afterCatches, false, true, true);
      leave.SourceContext = hiddenContext;
      catchBlock.Statements.Add(leave);
      Block tryCatch = new Block(new StatementList());
      tryCatch.Statements.Add(tryBlock);
      tryCatch.Statements.Add(catchBlock);
      tryCatch.Statements.Add(afterCatches);

      if (method.ExceptionHandlers == null) method.ExceptionHandlers = new ExceptionHandlerList();

      ExceptionHandler exHandler = new ExceptionHandler();
      exHandler.TryStartBlock = tryBlock;
      exHandler.BlockAfterTryEnd = blockAfterTryBody;
      exHandler.HandlerStartBlock = catchBlock;
      exHandler.BlockAfterHandlerEnd = afterCatches;
      exHandler.FilterType = SystemTypes.Exception;
      exHandler.HandlerType = NodeType.Catch;
      method.ExceptionHandlers.Add(exHandler);

      return tryCatch;
    }
    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 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;
    }
    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 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);
    }
    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;
    }
    /// <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;
    }
    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;
    }
Example #16
0
 /// <summary>
 /// Helper method for CCI decoding
 /// </summary>
 internal static Method ExtractCallFromStatement(Statement s)
 {
   MethodCall dummy;
   return ExtractCallFromStatement(s, out dummy);
 }
Example #17
0
 internal static Method ExtractCallFromStatement(Statement s, out MethodCall call)
 {
   call = null;
   ExpressionStatement es = s as ExpressionStatement;
   if (es == null) return null;
   call = es.Expression as MethodCall;
   if (call == null || call.Callee == null) { return null; }
   MemberBinding mb = call.Callee as MemberBinding;
   if (mb == null) { return null; }
   Method m = mb.BoundMember as Method;
   if (m == null) { return null; }
   return m;
 }
 protected override object VisitNop(Statement stat, object arg) {
   return arg;
 }
 public override void VisitReturn(Return Return)
 {
     this.ReturnStatement = Return;
     base.VisitReturn(Return);
 }
    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;
    }
Example #21
0
        /// <summary>
        /// Analyzes a statement to see if it is a call to a method.
        /// </summary>
        /// <param name="s">Any statement.</param>
        /// <returns>The method m if the statement is an expression statement that is a method call to m or null</returns>
        internal static Method IsMethodCall(Statement s)
        {
            if (s == null) return null;

            ExpressionStatement es = s as ExpressionStatement;
            
            if (es == null) return null;
            
            // If the expression statement represents a method call, then it can
            // have two different values as its expression:
            // 0. if the method's return type is void, then the expression is just the
            //    method call.
            // 1. if the method's return type is not void, then the value of the method
            //    isn't needed and it is wrapped inside of a unary expression,
            //    Pop(method call(...)) in order to throw away the return value
            //
            // We want the method call only if its return type is void, so just look
            // for pattern 0.
            //
            MethodCall mc = es.Expression as MethodCall;
            if (mc == null) return null;

            MemberBinding mb = mc.Callee as MemberBinding;
            if (mb == null) return null;
            
            return mb.BoundMember as Method;
        }
    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;
    }
Example #23
0
        private static bool IsDup(Statement statement)
        {
            var expr = statement as ExpressionStatement;
            if (expr == null) return false;

            if (expr.Expression != null && expr.Expression.NodeType == NodeType.Dup) return true;
            
            return false;
        }
 protected override object VisitUnaryOperator(NodeType op, Variable dest, Variable operand, Statement stat, object arg) {
   ExposureState estate=(ExposureState)arg; 
   return arg;
 }
Example #25
0
        internal static TypeNode IsClosureCreation(Method containingMethod, Statement s)
        {
            AssignmentStatement assign = s as AssignmentStatement;
            if (assign == null)
            {
                goto MaybePush;
            }

            Construct ctorCall = assign.Source as Construct;
            if (ctorCall == null)
            {
                return null;
            }
            
            if (IsClosureType(containingMethod.DeclaringType, assign.Target.Type))
            {
                return assign.Target.Type;
            }

        MaybePush:

            ExpressionStatement expr = s as ExpressionStatement;
            if (expr == null)
            {
                return null;
            }

            var construct = expr.Expression as Construct;
            if (construct == null) return null;
            
            if (IsClosureType(containingMethod.DeclaringType, construct.Type))
            {
                return construct.Type;
            }

            return null;
        }
 protected override object VisitSizeOf(Variable dest, TypeNode value_type, Statement stat, object arg) {
   ExposureState estate=(ExposureState)arg; 
   estate.AssignNonPointer(dest);
   return arg;
 }
Example #27
0
            internal void Visit(Statement statement)
            {
                Contract.Requires(this.IsValid);

                if (statement == null) return;

                switch (statement.NodeType)
                {
                    case NodeType.Nop:
                    case NodeType.Rethrow:
                    case NodeType.EndFilter:
                    case NodeType.EndFinally:
                        break;

                    case NodeType.Pop:
                        // a pop statement rather than expression
                        return;

                    case NodeType.AssignmentStatement:
                        var astmt = (AssignmentStatement) statement;
                        Visit(astmt.Source);
                        var savedInStore = this.inStore;
                        
                        try
                        {
                            this.inStore = true;
                            Visit(astmt.Target);
                        }
                        finally
                        {
                            this.inStore = savedInStore;
                        }
                        return;

                    case NodeType.ExpressionStatement:
                        var estmt = (ExpressionStatement) statement;
                        if (estmt.Expression.NodeType == NodeType.Dup)
                        {
                            return; // not an expression
                        }
                        
                        if (estmt.Expression.NodeType == NodeType.Pop)
                        {
                            var unary = estmt.Expression as UnaryExpression;
                            if (unary != null && unary.Operand != null)
                            {
                                // we are popping the thing we just push, so the depth does not change.
                                Visit(unary.Operand);
                                return;
                            }

                            // a pop statement rather than expression
                            return;
                        }

                        Visit(estmt.Expression);

                        return;

                    case NodeType.Block:
                        var block = (Block) statement;
                        Visit(block.Statements);
                        return;

                    case NodeType.SwitchInstruction:
                        var sw = (SwitchInstruction) statement;
                        Visit(sw.Expression);
                        return;

                    case NodeType.Throw:
                        var th = (Throw) statement;
                        Visit(th.Expression);
                        return;

                    case NodeType.Return:
                        var ret = (Return) statement;
                        Visit(ret.Expression);
                        return;

                    default:
                        var br = statement as Branch;
                        if (br != null)
                        {
                            Visit(br.Condition);
                            return;
                        }

                        throw new NotImplementedException(string.Format("Expression scanner: {0}", statement.NodeType));
                }
            }
 protected override object VisitBox(Variable dest, Variable source, TypeNode type, Statement stat, object arg) {
   ExposureState estate=(ExposureState)arg;
   return arg;
 }
            /// <summary>
            /// Determines whether a statement is part of an anonymous delegate construction.
            /// </summary>
            /// <param name="statement">Statement to inspect.</param>
            /// <returns><c>true</c> if <paramref name="statement"/> is part of anonymous delegate construction; otherwise, false.</returns>
            internal static bool IsAnonymousDelegateConstruction(Statement statement)
            {
                AssignmentStatement assignment = statement as AssignmentStatement;
                if (assignment != null)
                {
                    if (assignment.Target != null &&
                        assignment.Target.Type != null &&
                        HelperMethods.IsCompilerGenerated(assignment.Target.Type))
                    {
                        return true;
                    }

                    MemberBinding binding = assignment.Target as MemberBinding;
                    if (binding != null)
                    {
                        if (binding.TargetObject != null &&
                            binding.TargetObject.Type != null &&
                            HelperMethods.IsCompilerGenerated(binding.TargetObject.Type))
                        {
                            return true;
                        }

                        if (HelperMethods.IsCompilerGenerated(binding.BoundMember)) return true;
                    }

                    Local local = assignment.Target as Local;
                    if (local != null &&
                        local.Name != null &&
                        local.Name.Name != null &&
                        local.Name.Name.StartsWith("<"))
                    {
                        return true;
                    }
                }

                return false;
            }
        private static bool IsChainConstructorCall(Statement statement)
        {
            var expression = statement as ExpressionStatement;
            if (expression == null) return false;

            var method = expression.Expression as MethodCall;
            if (method == null) return false;

            var callee = method.Callee as MemberBinding;
            if (callee == null) return false;

            return callee.BoundMember is InstanceInitializer;
        }