public void SuggestContractsForExtractedMethod(Preconditions postConditionsAsBE, IOutput output)
            {
                IEnumerable <BoxedExpression> newPreconditions;

                if (this.TryInferPreconditionsFromPostconditions(postConditionsAsBE.ToList(), out newPreconditions))
                {
                    var decompiler = new AnalysisWrapper.TypeBindings <Local, Parameter, Method, Field, Property, Event, Type, Attribute, Assembly, Expression, Variable> .BooleanExpressionsDecompiler <LogOptions>(this.MDriver);

                    var alreadyShown = new Set <string>();

                    foreach (var p in newPreconditions)
                    {
                        var             inPreState = PreconditionSuggestion.ExpressionInPreState(p, this.MDriver.Context, this.MDriver.MetaDataDecoder, this.MDriver.CFG.EntryAfterRequires, allowedKinds: ExpressionInPreStateKind.MethodPrecondition);
                        BoxedExpression decompiled;
                        if (inPreState != null && decompiler.FixIt(this.MDriver.CFG.EntryAfterRequires, inPreState.expr, out decompiled))
                        {
                            var outStr = decompiled.ToString();
                            if (this.Facts.IsTrue(this.MDriver.CFG.EntryAfterRequires, decompiled) == ProofOutcome.Top && !alreadyShown.Contains(outStr))
                            {
                                output.Suggestion(ClousotSuggestion.Kind.Requires, ClousotSuggestion.Kind.Requires.Message(),
                                                  this.MDriver.CFG.Entry, string.Format("Extract method suggestion: Contract.Requires({0});", outStr), null, ClousotSuggestion.ExtraSuggestionInfo.None);
                                alreadyShown.Add(outStr);
                            }
                        }
                    }
                }
            }
Beispiel #2
0
        virtual public bool TryInferConditions(ProofObligation obl, ICodeFixesManager codefixesManager, out InferredConditions preConditions)
        {
            var preConds = PreconditionSuggestion.ExpressionsInPreState(obl.ConditionForPreconditionInference, this.MethodDriver.Context, this.MethodDriver.MetaDataDecoder, obl.PC, allowedKinds: ExpressionInPreStateKind.All);

            preConditions = /*preConds == null ? null : */ preConds.Where(pre => pre.hasVariables).AsInferredPreconditions(isSufficient: true);
            return /*preConditions != null && */ (preConditions.Any());
        }
                //This code should be moved in the inference helper
#if false
                private bool CanAssumeLowerBoundPrecondition(IOutputResults output, BoxedExpression index)
                {
                    bool            hasVariables, hasAccessPath;
                    BoxedExpression indexInPreState = PreconditionSuggestion.ExpressionInPreState(index, this.Context, this.DecoderForMetaData, out hasVariables, out hasAccessPath, this.PC);

                    if (indexInPreState == null || !hasVariables)
                    {
                        return(false);
                    }

                    this.warningContext.Add(new WarningContext(WarningContext.ContextType.PreconditionCanDischarge));

                    BoxedExpression suggestedPre = BoxedExpression.Binary(
                        BinaryOperator.Cle, BoxedExpression.Const(0, this.DecoderForMetaData.System_Int32, this.DecoderForMetaData), indexInPreState);

                    return(InferenceHelper.TryAssumePreCondition(this.PC, suggestedPre, MethodDriver, SuggestedCodeFixes.WARNING_ARRAY_BOUND, "array lower bound", output));
                }
                private BoxedExpression Converter(APC pc, BoxedExpression exp)
                {
                    var inPreState = PreconditionSuggestion.ExpressionInPreState(exp, this.Mdriver.Context, this.Mdriver.MetaDataDecoder, pc, allowedKinds: ExpressionInPreStateKind.All, isSufficient: false);

                    return(inPreState == null || !inPreState.hasVariables ? null : inPreState.expr);
                }
 protected ExpressionInPreState Converter(APC pc, BoxedExpression exp)
 {
     return(PreconditionSuggestion.ExpressionInPreState(exp, this.Mdriver.Context, this.Mdriver.MetaDataDecoder, pc, allowedKinds: ExpressionInPreStateKind.All));
 }
                public override void SuggestPrecondition(ContractInferenceManager inferenceManager, IFixpointInfo <APC, ArrayState> fixpointinfo)
                {
                    Contract.Assume(inferenceManager != null, "Assume for inheritance");

                    if (
                        !this.Options.LogOptions.SuggestRequiresPurityForArrays &&
                        !this.Options.LogOptions.PropagateRequiresPurityForArrays)
                    {
                        return;
                    }

                    ArrayState returnState;

                    if (PreState(this.Context.MethodContext.CFG.NormalExit, fixpointinfo, out returnState))
                    {
                        Contract.Assume(returnState != null);
                        var mySubState = Select(returnState);

#pragma warning disable 0219
                        var first = true; // used in the commented part below
#pragma warning restore

                        foreach (var element in mySubState.Elements)
                        {
#if false // Make it true to debug the content of the result state
                            if (ContainsUnModifiedSegment(element.Value))
                            {
                                if (first)
                                {
                                    Console.WriteLine("Method: {0}", this.Context.MethodContext.CurrentMethod);
                                    first = false;
                                }

                                var arrayName = this.VariablesToPrettyNames(this.Context.MethodContext.CFG.EntryAfterRequires, element.Key);
                                if (arrayName != null)
                                {
                                    var preconditions = element.Value.PrettyPrint(
                                        arrayName,
                                        (var => this.VariablesToPrettyNames(this.Context.MethodContext.CFG.EntryAfterRequires, var)),
                                        (ael => this.PrettyPrint(arrayName, ael))
                                        );
                                    foreach (var str in preconditions)
                                    {
                                        output.WriteLine("Effect on the input array segment: {0}", str);
                                    }
                                }
                            }
#endif
                            var exp = ToBoxedExpression(this.Context.MethodContext.CFG.Entry, element.Key);
                            var pre = PreconditionSuggestion.ExpressionInPreState(exp, this.Context,
                                                                                  this.DecoderForMetaData, this.Context.MethodContext.CFG.EntryAfterRequires,
                                                                                  allowedKinds: ExpressionInPreStateKind.MethodPrecondition);

                            Contract.Assume(element.Value != null);

                            if (pre != null &&
                                AllSegmentsUnmodified(element.Value) &&
                                !this.DecoderForContracts.IsPure(this.Context.MethodContext.CurrentMethod)
                                )
                            {
                                Parameter p;
                                int       pos;
                                Contract.Assume(element.Key != null, "Assuming the precondition");
                                if (TryParameterFor(element.Key, out p, out pos) && !this.DecoderForMetaData.IsPure(this.Context.MethodContext.CurrentMethod, p))
                                {
                                    // TODO: wire those suggestions to the contract inference manager
                                    if (this.Options.LogOptions.SuggestRequiresPurityForArrays)
                                    {
                                        inferenceManager.Output.Suggestion(ClousotSuggestion.Kind.Requires, ClousotSuggestion.Kind.Requires.Message(), this.Context.MethodContext.CFG.EntryAfterRequires,
                                                                           string.Format("Consider adding the [Pure] attribute to the parameter {0}", pre.ToString()), null, ClousotSuggestion.ExtraSuggestionInfo.None);
                                    }

                                    if (this.Options.LogOptions.PropagateRequiresPurityForArrays && pos <= 64)
                                    {
                                        this.DecoderForMetaData.AddPure(this.Context.MethodContext.CurrentMethod, pos);
                                    }
                                }
                            }
                        }
                    }
                }