示例#1
0
 override public void VisitUnaryEx(UnaryEx x)
 {
     _serializer.StartSerialize(typeof(UnaryEx).Name, SerializeSpan(x.Span),
                                new NodeObj("Operation", x.Operation.ToString()));
     base.VisitUnaryEx(x);
     _serializer.EndSerialize();
 }
示例#2
0
        /// <summary>
        /// Connects TrueBranch and FalseBranch to From. TrueBranch is followed from From if the condition holds,
        /// FalseBranch is followed from From if the condition does not hold.
        ///
        /// If decompose is true, it decomposes the condition expression using logical operations with respect to
        /// shortcircuit evaluation.
        /// Note that analyzer now expects that the condition expressions are decomposed and it no longer supports
        /// condition expressions that are not decomposed.
        /// </summary>
        /// <param name="condition">the condition of the branching.</param>
        /// <param name="From">the basic block where from which the branching starts.</param>
        /// <param name="TrueBranch">the branch which is taken if the condition holds.</param>
        /// <param name="FalseBranch">the branch which is taken if the condition does not hold.</param>
        /// <param name="decompose"></param>
        internal static void ConnectConditionalBranching(Expression condition, BasicBlock From, BasicBlock TrueBranch, BasicBlock FalseBranch, bool decompose = true)
        {
            var binaryCondition = condition as BinaryEx;

            if (!decompose || binaryCondition == null || (binaryCondition.PublicOperation != Operations.And && binaryCondition.PublicOperation != Operations.Or && binaryCondition.PublicOperation != Operations.Xor))
            {
                ConditionalEdge.AddConditionalEdge(From, TrueBranch, condition);
                DirectEdge.ConnectDirectEdge(From, FalseBranch);
                return;
            }

            BasicBlock intermediateBasicBlock = null;

            switch (binaryCondition.PublicOperation)
            {
            case Operations.And:
                intermediateBasicBlock = new BasicBlock();
                ConnectConditionalBranching(binaryCondition.LeftExpr, From, intermediateBasicBlock, FalseBranch);
                From = intermediateBasicBlock;
                ConnectConditionalBranching(binaryCondition.RightExpr, From, TrueBranch, FalseBranch);
                break;

            case Operations.Or:
                intermediateBasicBlock = new BasicBlock();
                ConnectConditionalBranching(binaryCondition.LeftExpr, From, TrueBranch, intermediateBasicBlock);
                From = intermediateBasicBlock;
                ConnectConditionalBranching(binaryCondition.RightExpr, From, TrueBranch, FalseBranch);
                break;

            case Operations.Xor:
                // Expands A xor B to (A and !B) || (!A and B)

                // Expansion expands A to A and !A and B to B and !B
                // For A and !A we the AST elements cannot be shared (must be unique) - the same for B and !B
                // We thus make copies of ast elements of left and right expression and use the copies to represent !A and !B
                var leftNegation  = new UnaryEx(Operations.LogicNegation, CFGVisitor.DeepCopyAstExpressionCopyVisitor(binaryCondition.LeftExpr));
                var rightNegation = new UnaryEx(Operations.LogicNegation, CFGVisitor.DeepCopyAstExpressionCopyVisitor(binaryCondition.RightExpr));

                var leftExpression  = new BinaryEx(Operations.And, binaryCondition.LeftExpr, rightNegation);
                var rightExpression = new BinaryEx(Operations.And, leftNegation, binaryCondition.RightExpr);
                var xorExpression   = new BinaryEx(Operations.Or, leftExpression, rightExpression);
                ConnectConditionalBranching(xorExpression, From, TrueBranch, FalseBranch);

                /*
                 * // Translation of xor in the level of control flow graph. More efficient than expansion of AST (translation in the level of program code).
                 * // Does not work because AST of sharing AST elements
                 * var intermediateBasicBlock1 = new BasicBlock();
                 * var intermediateBasicBlock2 = new BasicBlock();
                 * VisitIfStmtRec(binaryCondition.LeftExpr, intermediateBasicBlock1, intermediateBasicBlock2);
                 * FromBlock = intermediateBasicBlock1;
                 * VisitIfStmtRec(binaryCondition.RightExpr, FalseSink, TrueSink);
                 * FromBlock = intermediateBasicBlock2;
                 * VisitIfStmtRec(binaryCondition.RightExpr, TrueSink, FalseSink);*/
                break;
            }
        }
示例#3
0
 /// <summary>
 /// Makes the assumption in case of <c>false</c> as a condition result.
 /// </summary>
 /// <param name="langElement">The language element to assume.</param>
 /// <param name="memoryContext">The memory context of the code block and it's variables.</param>
 /// <param name="flowOutputSet">The Output set of a program point.</param>
 private void AssumeFalse(LangElement langElement, MemoryContext memoryContext, FlowOutputSet flowOutputSet)
 {
     if (langElement is BinaryEx)
     {
         BinaryEx binaryExpression = (BinaryEx)langElement;
         if (binaryExpression.PublicOperation == Operations.Equal)
         {
             AssumeNotEquals(binaryExpression.LeftExpr, binaryExpression.RightExpr, memoryContext);
         }
         else if (binaryExpression.PublicOperation == Operations.NotEqual)
         {
             AssumeEquals(binaryExpression.LeftExpr, binaryExpression.RightExpr, memoryContext, flowOutputSet.Snapshot);
         }
         else if (binaryExpression.PublicOperation == Operations.GreaterThan)
         {
             AssumeLesserThan(binaryExpression.LeftExpr, binaryExpression.RightExpr, true, memoryContext, flowOutputSet.Snapshot);
         }
         else if (binaryExpression.PublicOperation == Operations.GreaterThanOrEqual)
         {
             AssumeLesserThan(binaryExpression.LeftExpr, binaryExpression.RightExpr, false, memoryContext, flowOutputSet.Snapshot);
         }
         else if (binaryExpression.PublicOperation == Operations.LessThan)
         {
             AssumeGreaterThan(binaryExpression.LeftExpr, binaryExpression.RightExpr, true, memoryContext, flowOutputSet.Snapshot);
         }
         else if (binaryExpression.PublicOperation == Operations.LessThanOrEqual)
         {
             AssumeGreaterThan(binaryExpression.LeftExpr, binaryExpression.RightExpr, false, memoryContext, flowOutputSet.Snapshot);
         }
     }
     else if (langElement is UnaryEx)
     {
         UnaryEx unaryExpression = (UnaryEx)langElement;
         if (unaryExpression.PublicOperation == Operations.LogicNegation)
         {
             AssumeTrue(unaryExpression.Expr, memoryContext, flowOutputSet);
         }
     }
     else if (langElement is VarLikeConstructUse)
     {
         var variableLikeUse = (VarLikeConstructUse)langElement;
         AssumeFalseElementUse(variableLikeUse, memoryContext, flowOutputSet.Snapshot);
     }
     else if (langElement is IssetEx)
     {
         IssetEx issetEx = (IssetEx)langElement;
         AssumeIsset(issetEx, memoryContext, flowOutputSet.Snapshot, false);
     }
 }
示例#4
0
 public override void VisitUnaryEx(UnaryEx x)
 {
     ConsumeToken(TokenFacts.GetOperationToken(x.Operation), x.OperationPosition);
     VisitElement(x.Expr);
 }
示例#5
0
 /// <summary>
 /// Visit unary expression.
 /// </summary>
 /// <param name="x"></param>
 virtual public void VisitUnaryEx(UnaryEx x)
 {
     VisitElement(x.Expr);
 }
示例#6
0
        public override void VisitUnaryEx(UnaryEx x)
        {
            var operand = CreateRValue(x.Expr);

            Result(new UnaryExPoint(x, operand));
        }
示例#7
0
 /// <inheritdoc />
 public override void VisitUnaryEx(UnaryEx x)
 {
     RValueResult(x);
 }
示例#8
0
 /// <summary>
 /// Initializes a new instance of the <see cref="UnaryExPoint" /> class.
 /// </summary>
 /// <param name="expression">Unary expression</param>
 /// <param name="operand">Program point with unary operand</param>
 internal UnaryExPoint(UnaryEx expression, ValuePoint operand)
 {
     Expression = expression;
     Operand    = operand;
 }
示例#9
0
        /// <summary>
        /// Makes the assumption in case of <c>false</c> as a condition result.
        /// </summary>
        /// <param name="langElement">The language element to assume.</param>
        /// <param name="memoryContext">The memory context of the code block and it's variables.</param>
        /// <param name="flowOutputSet">The Output set of a program point.</param>
        void AssumeFalse(LangElement langElement, MemoryContext memoryContext, FlowOutputSet flowOutputSet)
        {
            if (langElement is BinaryEx)
            {
                BinaryEx binaryExpression = (BinaryEx)langElement;
                if (binaryExpression.PublicOperation == Operations.Equal)
                {
                    AssumeNotEquals(binaryExpression.LeftExpr, binaryExpression.RightExpr, memoryContext);
                }
                else if (binaryExpression.PublicOperation == Operations.NotEqual)
                {
                    AssumeEquals(binaryExpression.LeftExpr, binaryExpression.RightExpr, memoryContext, flowOutputSet.Snapshot);
                }
                else if (binaryExpression.PublicOperation == Operations.GreaterThan)
                {
                    AssumeLesserThan(binaryExpression.LeftExpr, binaryExpression.RightExpr, true, memoryContext, flowOutputSet.Snapshot);
                }
                else if (binaryExpression.PublicOperation == Operations.GreaterThanOrEqual)
                {
                    AssumeLesserThan(binaryExpression.LeftExpr, binaryExpression.RightExpr, false, memoryContext, flowOutputSet.Snapshot);
                }
                else if (binaryExpression.PublicOperation == Operations.LessThan)
                {
                    AssumeGreaterThan(binaryExpression.LeftExpr, binaryExpression.RightExpr, true, memoryContext, flowOutputSet.Snapshot);
                }
                else if (binaryExpression.PublicOperation == Operations.LessThanOrEqual)
                {
                    AssumeGreaterThan(binaryExpression.LeftExpr, binaryExpression.RightExpr, false, memoryContext, flowOutputSet.Snapshot);
                }
                else if (binaryExpression.PublicOperation == Operations.And ||
                         binaryExpression.PublicOperation == Operations.Or ||
                         binaryExpression.PublicOperation == Operations.Xor)
                {
                    ConditionForm conditionForm = ConditionForm.SomeNot; // !(a AND b) --> !a OR !b
                    if (binaryExpression.PublicOperation == Operations.Or)
                    {
                        conditionForm = ConditionForm.None; // !(a OR b) --> !a AND !b
                    }
                    else if (binaryExpression.PublicOperation == Operations.Xor)
                    {
                        conditionForm = ConditionForm.NotExactlyOne; //!(a XOR b) --> !((a OR b) AND !(a AND b)) --> (!a AND !b) OR (a AND b)
                    }

                    MemoryContext  currentMemoryContext = new MemoryContext(log, flowOutputSet);
                    ConditionParts condition            = new ConditionParts(conditionForm, flowOutputSet, log, binaryExpression.LeftExpr, binaryExpression.RightExpr);
                    condition.MakeAssumption(currentMemoryContext);
                    memoryContext.UnionMerge(currentMemoryContext);
                }
            }
            else if (langElement is UnaryEx)
            {
                UnaryEx unaryExpression = (UnaryEx)langElement;
                if (unaryExpression.PublicOperation == Operations.LogicNegation)
                {
                    AssumeTrue(unaryExpression.Expr, memoryContext, flowOutputSet);
                }
            }
            else if (langElement is DirectVarUse)
            {
                DirectVarUse directVarUse = (DirectVarUse)langElement;
                AssumeFalseDirectVarUse(directVarUse, memoryContext, flowOutputSet.Snapshot);
            }
            else if (langElement is IssetEx)
            {
                IssetEx issetEx = (IssetEx)langElement;
                AssumeIsset(issetEx, memoryContext, flowOutputSet.Snapshot, false);
            }
        }
示例#10
0
        /// <summary>
        /// Makes the assumption in case of <c>true</c> as a condition result.
        /// </summary>
        /// <param name="langElement">The language element to assume.</param>
        /// <param name="memoryContext">The memory context of the code block and it's variables.</param>
        /// <param name="flowOutputSet">The Output set of a program point.</param>
        void AssumeTrue(LangElement langElement, MemoryContext memoryContext, FlowOutputSet flowOutputSet)
        {
            if (langElement is BinaryEx)
            {
                BinaryEx binaryExpression = (BinaryEx)langElement;
                if (binaryExpression.PublicOperation == Operations.Equal)
                {
                    AssumeEquals(binaryExpression.LeftExpr, binaryExpression.RightExpr, memoryContext, flowOutputSet.Snapshot);
                }
                else if (binaryExpression.PublicOperation == Operations.NotEqual)
                {
                    AssumeNotEquals(binaryExpression.LeftExpr, binaryExpression.RightExpr, memoryContext);
                }
                else if (binaryExpression.PublicOperation == Operations.GreaterThan)
                {
                    AssumeGreaterThan(binaryExpression.LeftExpr, binaryExpression.RightExpr, false, memoryContext, flowOutputSet.Snapshot);
                }
                else if (binaryExpression.PublicOperation == Operations.GreaterThanOrEqual)
                {
                    AssumeGreaterThan(binaryExpression.LeftExpr, binaryExpression.RightExpr, true, memoryContext, flowOutputSet.Snapshot);
                }
                else if (binaryExpression.PublicOperation == Operations.LessThan)
                {
                    AssumeLesserThan(binaryExpression.LeftExpr, binaryExpression.RightExpr, false, memoryContext, flowOutputSet.Snapshot);
                }
                else if (binaryExpression.PublicOperation == Operations.LessThanOrEqual)
                {
                    AssumeLesserThan(binaryExpression.LeftExpr, binaryExpression.RightExpr, true, memoryContext, flowOutputSet.Snapshot);
                }
                else if (binaryExpression.PublicOperation == Operations.And ||
                         binaryExpression.PublicOperation == Operations.Or ||
                         binaryExpression.PublicOperation == Operations.Xor)
                {
                    ConditionForm conditionForm = ConditionForm.All;
                    if (binaryExpression.PublicOperation == Operations.Or)
                    {
                        conditionForm = ConditionForm.Some;
                    }
                    else if (binaryExpression.PublicOperation == Operations.Xor)
                    {
                        conditionForm = ConditionForm.ExactlyOne;
                    }

                    MemoryContext  currentMemoryContext = new MemoryContext(log, flowOutputSet);
                    ConditionParts condition            = new Weverca.Analysis.FlowResolver.Deprecated.ConditionParts(conditionForm, flowOutputSet, log, binaryExpression.LeftExpr, binaryExpression.RightExpr);
                    condition.MakeAssumption(currentMemoryContext);
                    memoryContext.UnionMerge(currentMemoryContext);
                }
            }
            else if (langElement is UnaryEx)
            {
                UnaryEx unaryExpression = (UnaryEx)langElement;
                if (unaryExpression.PublicOperation == Operations.LogicNegation)
                {
                    AssumeFalse(unaryExpression.Expr, memoryContext, flowOutputSet);
                }
            }
            else if (langElement is DirectVarUse)
            {
                DirectVarUse directVarUse = (DirectVarUse)langElement;
                AssumeTrueDirectVarUse(directVarUse, memoryContext, flowOutputSet.Snapshot);
            }
            else if (langElement is IssetEx)
            {
                IssetEx issetEx = (IssetEx)langElement;
                AssumeIsset(issetEx, memoryContext, flowOutputSet.Snapshot, true);
            }
        }
示例#11
0
        /// <inheritdoc />
        override public void VisitUnaryEx(UnaryEx x)
        {
            VisitElement(x.Expr);

            result = new UnaryEx(x.PublicOperation, (Expression)result);
        }