Ejemplo n.º 1
0
                /// <summary>
                /// Hypothesis: Bound Analysis assumed that <code>0 &le; len </code> and
                /// </summary>
                /// <param name="dest"></param>
                private SimplePartitionAbstractDomain <BoxedVariable <Variable>, BoxedExpression> HandleAllocations(APC pc, Variable dest, Variable len, SimplePartitionAbstractDomain <BoxedVariable <Variable>, BoxedExpression> data)
                {
                    var lenAsExp = BoxedExpression.For(this.Context.Refine(pc, len), this.Decoder.Outdecoder);

                    lenAsExp = this.Decoder.Stripped(lenAsExp);
                    var destAsExp = BoxedExpression.For(this.Context.Refine(pc, dest), this.Decoder.Outdecoder);

                    ALog.BeginTransferFunction(StringClosure.For("[P]Allocation"),
                                               ExpressionPrinter.ToStringClosure(lenAsExp, this.Decoder), PrettyPrintPC(pc), StringClosure.For(data));

                    var refinedDomain = data.Allocation(new BoxedVariable <Variable>(dest), lenAsExp);

                    ALog.EndTransferFunction(StringClosure.For(data));

                    return(refinedDomain);
                }
Ejemplo n.º 2
0
                /// <summary>
                /// Here we catch the calls to methods of String, so that we can apply operations on string, as concatenations. etc.
                /// </summary>
                public override SimpleStringAbstractDomain <BoxedExpression> Call <TypeList, ArgList>(APC pc, Method method, bool tail, bool virt, TypeList extraVarargs, Variable dest, ArgList args, SimpleStringAbstractDomain <BoxedExpression> data)
                // where ArgList : IIndexable<int>
                {
                    string methodName = this.DecoderForMetaData.FullName(method);

                    ALog.BeginTransferFunction(StringClosure.For("call"), StringClosure.For(methodName),
                                               StringClosure.For(pc), StringClosure.For(data));

                    SimpleStringAbstractDomain <BoxedExpression> result;
                    SimpleStringAbstractDomain <BoxedExpression> baseResult = base.Call <TypeList, ArgList>(pc, method, tail, virt, extraVarargs, dest, args, data);

                    if (IsACallToString(methodName))
                    {
                        result = HandleCallToString(pc, methodName, dest, args, baseResult);
                    }
                    else
                    {
                        result = baseResult;
                    }

                    ALog.EndTransferFunction(StringClosure.For(result));

                    return(result);
                }
Ejemplo n.º 3
0
                public override SimplePartitionAbstractDomain <BoxedVariable <Variable>, BoxedExpression> Binary(APC pc, BinaryOperator op, Variable dest, Variable s1, Variable s2, SimplePartitionAbstractDomain <BoxedVariable <Variable>, BoxedExpression> data)
                {
                    Log("Binary:{0}", op);
                    if (OperatorExtensions.IsComparisonBinaryOperator(op))
                    {
                        // TODO: if s1 or s2 includes an array term, partitioning must be done.
                        return(data);
                    }
                    else if (OperatorExtensions.IsBooleanBinaryOperator(op))
                    {
                        // TODO: see above
                        return(data);
                    }
                    else
                    {
                        var destAsExp  = ToBoxedExpression(pc, dest);
                        var leftAsExp  = ToBoxedExpressionWithConstantRefinement(pc, s1);
                        var rightAsExp = ToBoxedExpressionWithConstantRefinement(pc, s2);

                        ALog.BeginTransferFunction(StringClosure.For("Assign"),
                                                   StringClosure.For("{0} := {1}({2}, {3})",
                                                                     ExpressionPrinter.ToStringClosure(destAsExp, this.Decoder), StringClosure.For(op),
                                                                     ExpressionPrinter.ToStringClosure(leftAsExp, this.Decoder), ExpressionPrinter.ToStringClosure(rightAsExp, this.Decoder)),
                                                   PrettyPrintPC(pc), StringClosure.For(data));

                        // Hypothesis : if it is a reminder or division operation, we assume that the dividend is not zero
                        var             refinedDomain = data;
                        BoxedExpression rightOfAssignment;

                        Log("REPACK:{1} {0} {2}", op, s1, s2);

                        if (TryRepackAssignment(op, leftAsExp, rightAsExp, out rightOfAssignment))
                        {
                            var arraysToRefine = data.arraysWithPartitionDefinedOnASubsetExpressionOf(rightOfAssignment);

                            if (!arraysToRefine.IsEmpty)
                            {
                                var assignmentKnowledge         = this.Encoder.CompoundExpressionFor(ExpressionType.Bool, ExpressionOperator.Equal, destAsExp, rightOfAssignment);
                                var assignmentStrippedKnowledge = this.Encoder.CompoundExpressionFor(ExpressionType.Bool, ExpressionOperator.Equal, destAsExp, RecursiveStripped(rightOfAssignment));
                                assignmentKnowledge = this.Encoder.CompoundExpressionFor(ExpressionType.Bool, ExpressionOperator.And, assignmentKnowledge, assignmentStrippedKnowledge);

                                //Log("KNOWLEDGEonREPACK:{0}", rightOfAssignment);

                                foreach (var array in arraysToRefine)
                                {
                                    refinedDomain = HandleIndexAssignment("", pc,
                                                                          array,
                                                                          ToBoxedVariable(dest),
                                                                          rightOfAssignment,
                                                                          assignmentKnowledge, refinedDomain);
                                }
                            }
                        }
                        //else
                        //{
                        //  throw new AbstractInterpretationException(); //TODO : leave the else.
                        //}

                        ALog.EndTransferFunction(StringClosure.For(refinedDomain));

                        return(refinedDomain);
                    }
                }
Ejemplo n.º 4
0
                private SimplePartitionAbstractDomain <BoxedVariable <Variable>, BoxedExpression> HandleIndexAssignment(string name, APC pc,
                                                                                                                        BoxedVariable <Variable> array, BoxedVariable <Variable> index,
                                                                                                                        BoxedExpression assignedAsExp, BoxedExpression assignmentKnowledge,
                                                                                                                        SimplePartitionAbstractDomain <BoxedVariable <Variable>, BoxedExpression> data)
                {
                    ALog.BeginTransferFunction(StringClosure.For("[P]IndexAssignement"),
                                               StringClosure.For(""), PrettyPrintPC(pc), StringClosure.For(data));

                    //var baseVariables = this.Decoder.VariablesIn(indexAsExp);
                    var baseVariables = this.Decoder.VariablesIn(assignedAsExp);

                    Log("VARIABLESIN={0}", baseVariables);

                    var indexAsExp = ToBoxedExpression(pc, index);

                    var indexKnowledge = gatherKnowledge(this.Context.Post(pc), indexAsExp); //TODO: post is not useful here

                    var knowledge = this.Encoder.CompoundExpressionFor(ExpressionType.Bool,
                                                                       ExpressionOperator.And,
                                                                       indexKnowledge,
                                                                       assignmentKnowledge);

                    // TODO : useless if indexAsExp is based on variables already in the partition (which space is delimited)
                    //var indexRange = guessRange(pc, indexAsExp);
                    //Log("LB={0}", indexRange.One);
                    //Log("UB={0}", indexRange.Two);

                    IPartitionAbstraction <BoxedVariable <Variable>, BoxedExpression> arrayPartition;
                    var refinedDomain = data;

                    if (data.TryGetValue(array, out arrayPartition))
                    {
                        var singles = arrayPartition.Singles();
                        Log("SINGLES={0}", singles);

                        var b = baseVariables.Remove(index);

                        foreach (var single in singles)
                        {
                            if (!this.Decoder.IsConstant(single))
                            {
                                var variablesInSingle = this.Decoder.VariablesIn(single);

                                if (baseVariables.IsSubset(variablesInSingle))
                                {
                                    // The general case is very complicated. Here we assume that single has the form of an octagon contraint (+/- y + c)
                                    if (baseVariables.Count == 1)
                                    {
                                        var indexSubstitute = this.Encoder.Substitute(single, ToBoxedExpression(pc, baseVariables.PickAnElement()), indexAsExp);

                                        var notWanted = new Set <BoxedVariable <Variable> >(baseVariables);

                                        if (!indexSubstitute.IsVariable) // HACK due to handling of expression
                                        {
                                            notWanted.Add(this.Decoder.UnderlyingVariable(indexSubstitute));
                                        }

                                        refinedDomain = refinedDomain.ArrayAssignment(array, indexSubstitute, knowledge, notWanted);
                                    }
                                    else // Otherwise we try to partition wrt indexAsExp
                                    {
                                        refinedDomain = refinedDomain.ArrayAssignment(array, indexAsExp, knowledge, baseVariables);
                                    }
                                }
                            }
                        }
                    }
                    else
                    {
                        throw new AbstractInterpretationException();
                    }

                    ALog.EndTransferFunction(StringClosure.For(data));

                    return(refinedDomain);
                }
Ejemplo n.º 5
0
                /// <summary>
                /// Hypothesis: Bound Analysis assumed.
                /// </summary>
                /// <param name="dest"></param>
                private SimplePartitionAbstractDomain <BoxedVariable <Variable>, BoxedExpression> HandleArrayAssignment(
                    string name, APC pc,
                    Variable array, Variable index,
                    SimplePartitionAbstractDomain <BoxedVariable <Variable>, BoxedExpression> data)
                {
                    var arrayAsExp = BoxedExpression.For(this.Context.Refine(pc, array), this.Decoder.Outdecoder);
                    var indexAsExp = BoxedExpression.For(this.Context.Refine(pc, index), this.Decoder.Outdecoder);

                    ALog.BeginTransferFunction(StringClosure.For("[P]ArrayAssignement"),
                                               ExpressionPrinter.ToStringClosure(arrayAsExp, this.Decoder), PrettyPrintPC(pc), StringClosure.For(data));

                    var baseVariables = this.Decoder.VariablesIn(indexAsExp);

                    Log("VARIABLESIN={0}", baseVariables);
                    // TODO: decide wich variables you want in the partition : probably here a variable inside. You must gatherKnowledge for each variable inside, and reconstruct the bounds of interest.
                    // eg. index: sv1; index is (sv2+1); indexKnowledge is (0,sv3); so (sv2+1) go from 1 to sv3+1 (but could be unnecessary if sv2 is already into the partition ...;
                    var notWanted = new Set <BoxedVariable <Variable> >();

                    if (baseVariables.Count > 1 || !baseVariables.Contains(ToBoxedVariable(index)))
                    {
                        notWanted.Add(ToBoxedVariable(index));
                    }

                    var knowledge         = this.Encoder.ConstantFor(true);
                    var equalityKnowledge = this.Encoder.ConstantFor(true);

                    foreach (var e in baseVariables)
                    {
                        knowledge = this.Encoder.CompoundExpressionFor(ExpressionType.Bool,
                                                                       ExpressionOperator.And,
                                                                       knowledge,
                                                                       gatherKnowledge(this.Context.Post(pc), ToBoxedExpression(this.Context.Post(pc), e)));
                    }

                    if (!notWanted.IsEmpty)
                    {
                        // NOTE : even if notWanted will not be part of the split partition used, it can already be present in the current partition.
                        // This is why we provide the information, to be used in simplify.
                        PolynomialOfInt <BoxedVariable <Variable>, BoxedExpression> indexAsPoly;
                        if (PolynomialOfInt <BoxedVariable <Variable>, BoxedExpression> .TryToPolynomialForm(indexAsExp, this.Decoder, out indexAsPoly))
                        {
                            equalityKnowledge = this.Encoder.CompoundExpressionFor(ExpressionType.Bool,
                                                                                   ExpressionOperator.Equal,
                                                                                   indexAsExp,
                                                                                   PolynomialOfInt <BoxedVariable <Variable>, BoxedExpression> .ToPureExpressionForm(indexAsPoly, this.Encoder));

                            knowledge = this.Encoder.CompoundExpressionFor(ExpressionType.Bool, ExpressionOperator.And, knowledge, equalityKnowledge);
                        }
                    }

                    //var indexKnowledge = gatherKnowledge(pc, indexAsExp);

                    foreach (var e in baseVariables)
                    {
                        var indexRange = guessRange(pc, ToBoxedExpression(pc, e)); // carefull : One or Two can be null.
                        Log("LB({1})={0}", indexRange.One, e);
                        Log("UB({1})={0}", indexRange.Two, e);
                    }
                    var indexRange2 = guessRange(pc, indexAsExp); // carefull : One or Two can be null.

                    Log("LB({1})={0}", indexRange2.One, indexAsExp);
                    Log("UB({1})={0}", indexRange2.Two, indexAsExp);

                    var refinedDomain = data.ArrayAssignment(ToBoxedVariable(array), indexAsExp, knowledge, notWanted); //,notWanted

                    ALog.EndTransferFunction(StringClosure.For(data));

                    return(refinedDomain);
                }