public void AssertInequality(
                    VersionedVariable left,
                    VersionedVariable right,
                    ISymbolicHeapContext context)
                {
                    this.cachedState = null;

                    var leftState  = this.GetOrCreateVariableState(left, context);
                    var rightState = this.GetOrCreateVariableState(right, context);

                    if (this.TryGetConstantComparisonResult(leftState, rightState) is bool areEqual)
                    {
                        if (areEqual)
                        {
                            this.IsConflicting = true;
                        }
                    }
                    else
                    {
                        if (IsNullStateAndVarState(leftState, rightState, out var varState))
                        {
                            // No need to assert it again if it has been already done before
                            if (varState.CanBeNull)
                            {
                                this.variableStates[varState.Id] = varState.WithCanBeNull(false);

                                context.AddAssertion(leftState.Representation != rightState.Representation);
                            }
                        }
                        else
                        {
                            context.AddAssertion(leftState.Representation != rightState.Representation);
                        }
                    }
                }
示例#2
0
            public ModelRecorder(IModel smtModel, HeapState state)
            {
                this.smtModel = smtModel;
                this.state    = state;

                this.inputHeap.Add(HeapModelLocation.NullId, new LocationInfo()
                {
                    LastModifiedVersion = 0
                });
            }
                public Builder(HeapState state)
                {
                    this.variableStates        = state.variableStates?.ToBuilder();
                    this.variableToStateIdMap  = state.variableToStateIdMap?.ToBuilder();
                    this.stateIdToVariablesMap = state.stateIdToVariablesMap?.ToBuilder();
                    this.fieldToVariableMap    = state.fieldToVariableMap?.ToBuilder();
                    this.nextVariableStateId   = state.nextVariableStateId;
                    this.nextReferenceValue    = state.nextReferenceValue;

                    this.cachedState   = state;
                    this.IsConflicting = (state == ConflictState);
                }
示例#4
0
        private ArrayTheorySymbolicHeap(
            ISymbolicHeapContext context,
            Stack <HeapState> stateStack,
            HeapState currentState)
        {
            this.context      = context;
            this.currentState = currentState.ToBuilder();

            foreach (var state in stateStack.Reverse())
            {
                this.stateStack.Push(state);
            }
        }
                public void ReadField(
                    VersionedVariable result,
                    VersionedVariable reference,
                    IFieldDefinition field,
                    ISymbolicHeapContext context)
                {
                    this.cachedState = null;

                    var refState = this.TrySecureNotNull(reference, context);

                    if (this.IsConflicting)
                    {
                        return;
                    }

                    Contract.Assert(refState.IsInput);

                    Expression resultVar;

                    if (result.Variable.IsReference)
                    {
                        // Secure that the result variable is initialized
                        var resultState = this.GetOrCreateVariableState(result, context);
                        Contract.Assert(resultState.IsInput);

                        resultVar = resultState.Representation;

                        // Mark as derived from the input heap
                        this.variableStates[resultState.Id] = resultState.WithIsInputDerived(true);
                    }
                    else
                    {
                        // Don't store scalar values in the state
                        resultVar = context.GetNamedVariable(result);
                    }

                    // Initialize the particular field
                    var fieldVar = this.GetOrAddFieldVariable(field, context);

                    // Propagate the read to the SMT solver
                    var selectAssert = (BoolHandle)ExpressionFactory.Equal(
                        resultVar,
                        fieldVar.Select(refState.Representation));

                    context.AddAssertion(selectAssert);
                }
                public void WriteField(
                    VersionedVariable reference,
                    IFieldDefinition field,
                    Expression value,
                    ISymbolicHeapContext context)
                {
                    this.cachedState = null;

                    var refState = this.TrySecureNotNull(reference, context);

                    if (this.IsConflicting)
                    {
                        return;
                    }

                    Expression valExpr;

                    if (value.Sort == References.Sort)
                    {
                        if (!(value is FlowVariable valVar))
                        {
                            throw new NotSupportedException("Only versioned flow variables supported as references");
                        }

                        // Secure that the result variable is initialized
                        var versionedVal = context.GetVersioned(valVar);
                        var valState     = this.GetOrCreateVariableState(versionedVal, context);
                        valExpr = valState.Representation;
                    }
                    else
                    {
                        // Don't store scalar values in the state
                        valExpr = value;
                    }

                    // Get current and new version of the field
                    var oldFieldVar = this.GetOrAddFieldVariable(field, context);
                    var newFieldVar = this.CreateNewFieldVariableVersion(field, context);

                    var storeAssert = (oldFieldVar == newFieldVar.Store(refState.Representation, (Handle)valExpr));

                    context.AddAssertion(storeAssert);
                }
                public HeapState ToState()
                {
                    if (this.IsConflicting)
                    {
                        return(ConflictState);
                    }
                    else if (this.cachedState == null)
                    {
                        this.cachedState = new HeapState(
                            this.variableStates.ToImmutable(),
                            this.variableToStateIdMap.ToImmutable(),
                            this.stateIdToVariablesMap.ToImmutable(),
                            this.fieldToVariableMap.ToImmutable(),
                            this.nextVariableStateId,
                            this.nextReferenceValue);
                    }

                    return(this.cachedState);
                }
                public BoolHandle GetEqualityExpression(
                    bool areEqual,
                    VersionedVariable left,
                    VersionedVariable right,
                    ISymbolicHeapContext context)
                {
                    this.cachedState = null;

                    var leftState  = this.GetOrCreateVariableState(left, context);
                    var rightState = this.GetOrCreateVariableState(right, context);

                    if (this.TryGetConstantComparisonResult(leftState, rightState) is bool constResult)
                    {
                        return(constResult);
                    }
                    else
                    {
                        return(areEqual
                            ? leftState.Representation == rightState.Representation
                            : leftState.Representation != rightState.Representation);
                    }
                }
                public void AssertEquality(
                    VersionedVariable left,
                    VersionedVariable right,
                    ISymbolicHeapContext context)
                {
                    this.cachedState = null;

                    var leftState  = this.GetOrCreateVariableState(left, context);
                    var rightState = this.GetOrCreateVariableState(right, context);

                    if (this.TryGetConstantComparisonResult(leftState, rightState) is bool areEqual)
                    {
                        if (!areEqual)
                        {
                            this.IsConflicting = true;
                        }
                    }
                    else
                    {
                        context.AddAssertion(leftState.Representation == rightState.Representation);
                    }
                }
                public void AssignReference(
                    VersionedVariable result,
                    VersionedVariable value,
                    ISymbolicHeapContext context)
                {
                    this.cachedState = null;

                    var resultState = this.GetVariableStateOrNull(result);
                    var valueState  = this.GetVariableStateOrNull(value);

                    if (resultState != null && valueState != null)
                    {
                        Contract.Assert(resultState.IsInput);

                        context.AddAssertion(resultState.Representation == valueState.Representation);
                        this.MapToVariableState(result, valueState);
                    }
                    else if (resultState == null && valueState == null)
                    {
                        var newVar   = context.CreateVariable(Sort.Int, value.Variable.ToString());
                        var newState = VariableState.CreateInput(this.nextVariableStateId, newVar, true);
                        this.nextVariableStateId++;

                        this.MapToVariableState(result, newState);
                        this.MapToVariableState(value, newState);
                    }
                    else if (resultState != null)
                    {
                        Contract.Assert(valueState == null);

                        this.MapToVariableState(value, resultState);
                    }
                    else
                    {
                        Contract.Assert(valueState != null && resultState == null);

                        this.MapToVariableState(result, valueState);
                    }
                }
                public void AllocateNew(
                    VersionedVariable result,
                    ISymbolicHeapContext context)
                {
                    this.cachedState = null;

                    var newState = VariableState.CreateValue(this.nextVariableStateId, this.nextReferenceValue);

                    this.nextVariableStateId++;
                    this.nextReferenceValue++;

                    if (this.variableToStateIdMap.TryGetValue(result, out int curStateId))
                    {
                        var curState = this.variableStates[curStateId];
                        Contract.Assert(curState.IsInput);

                        // Unify a previously known value with its current allocated number
                        context.AddAssertion(curState.Representation == newState.Representation);
                    }

                    this.MapToVariableState(result, newState);
                }