Пример #1
0
 public void ReadField(VersionedVariable result, VersionedVariable reference, IFieldDefinition field)
 {
     if (this.CanBeSatisfiable)
     {
         this.CurrentState.ReadField(result, reference, field, this.context);
     }
 }
Пример #2
0
            public void WriteReferenceField(VersionedVariable reference, IFieldDefinition field, VersionedVariable value)
            {
                int refId   = GetIdFromInterpretation(this.GetInterpretation(reference));
                var valIntr = this.GetInterpretation(value);

                this.WriteField(refId, field, valIntr);
            }
                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);
                        }
                    }
                }
Пример #4
0
 public void WriteField(VersionedVariable reference, IFieldDefinition field, Expression value)
 {
     if (this.CanBeSatisfiable)
     {
         this.CurrentState.WriteField(reference, field, value, this.context);
     }
 }
Пример #5
0
 public void AssignReference(VersionedVariable result, VersionedVariable value)
 {
     if (this.CanBeSatisfiable)
     {
         this.CurrentState.AssignReference(result, value, this.context);
     }
 }
Пример #6
0
 public void AllocateNew(VersionedVariable result)
 {
     if (this.CanBeSatisfiable)
     {
         this.CurrentState.AllocateNew(result, this.context);
     }
 }
                private VariableState TrySecureNotNull(
                    VersionedVariable variable,
                    ISymbolicHeapContext context)
                {
                    // Secure that the variable is initialized and not null
                    var state = this.GetVariableStateOrNull(variable);

                    if (state == null)
                    {
                        state = this.CreateNewInputVariableState(variable, context, canBeNull: false);
                        this.MapToVariableState(variable, state);

                        context.AddAssertion(state.Representation != VariableState.Null.Representation);
                    }
                    else if (state == VariableState.Null)
                    {
                        this.IsConflicting = true;
                    }
                    else if (state.CanBeNull)
                    {
                        Contract.Assert(state.IsInput || state.IsInputDerived);

                        this.variableStates[state.Id] = state.WithCanBeNull(false);

                        context.AddAssertion(state.Representation != VariableState.Null.Representation);
                    }

                    return(state);
                }
                private VariableState CreateNewInputVariableState(VersionedVariable variable, ISymbolicHeapContext context, bool canBeNull)
                {
                    var newVar   = context.CreateVariable(Sort.Int, variable.ToString());
                    var newState = VariableState.CreateInput(this.nextVariableStateId, newVar, canBeNull);

                    this.nextVariableStateId++;
                    return(newState);
                }
 public VariableState TryGetVariableState(VersionedVariable variable)
 {
     if (this.variableToStateIdMap.TryGetValue(variable, out int stateId))
     {
         return(this.variableStates[stateId]);
     }
     else
     {
         return(null);
     }
 }
Пример #10
0
        public Expression GetEqualityExpression(bool areEqual, VersionedVariable left, VersionedVariable right)
        {
            if (!this.CanBeSatisfiable)
            {
                // Doesn't matter, the path is unreachable anyway
                return(ExpressionFactory.False);
            }

            var expr = this.CurrentState.GetEqualityExpression(areEqual, left, right, this.context);

            return(expr);
        }
 private VariableState GetVariableStateOrNull(
     VersionedVariable variable)
 {
     if (this.variableToStateIdMap.TryGetValue(variable, out var varStateId))
     {
         return(this.variableStates[varStateId]);
     }
     else
     {
         return(null);
     }
 }
Пример #12
0
 public void AssertEquality(bool areEqual, VersionedVariable left, VersionedVariable right)
 {
     if (this.CanBeSatisfiable)
     {
         if (areEqual)
         {
             this.CurrentState.AssertEquality(left, right, this.context);
         }
         else
         {
             this.CurrentState.AssertInequality(left, right, this.context);
         }
     }
 }
                private void MapToVariableState(
                    VersionedVariable variable,
                    VariableState state)
                {
                    this.variableStates[state.Id] = state;

                    if (this.variableToStateIdMap.TryGetValue(variable, out int curStateId))
                    {
                        if (curStateId == state.Id)
                        {
                            if (this.variableStates[curStateId] != state)
                            {
                                this.variableStates[curStateId] = state;
                            }
                        }
                        else
                        {
                            // Update the states of all the variables pointing to the old one and erase it
                            var currentVars = this.stateIdToVariablesMap[curStateId];
                            var newVars     = this.stateIdToVariablesMap.GetValueOrDefault(state.Id)
                                              ?? ImmutableList <VersionedVariable> .Empty;
                            newVars = newVars.AddRange(currentVars);
                            if (!currentVars.Any(v => v == variable))
                            {
                                // TODO: Consider turning it into a set to make this more effective
                                newVars = newVars.Add(variable);
                            }

                            this.variableStates.Remove(curStateId);
                            this.stateIdToVariablesMap.Remove(curStateId);
                            this.stateIdToVariablesMap[state.Id] = newVars;

                            foreach (var newVar in newVars)
                            {
                                this.variableToStateIdMap[newVar] = state.Id;
                            }
                        }
                    }
                    else
                    {
                        this.variableToStateIdMap[variable] = state.Id;

                        var curMappedVars = this.stateIdToVariablesMap.GetValueOrDefault(state.Id)
                                            ?? ImmutableList <VersionedVariable> .Empty;
                        var newMappedVars = curMappedVars.Add(variable);
                        this.stateIdToVariablesMap[state.Id] = newMappedVars;
                    }
                }
                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);
                }
Пример #15
0
            public HeapModelLocation AllocateNew(VersionedVariable result)
            {
                int id = GetIdFromInterpretation(this.GetInterpretation(result));

                // Increment the version by performing a change
                this.changes.Add(new FieldChange()
                {
                    ReferenceId = id
                });

                this.currentHeap.Add(id, new LocationInfo()
                {
                    LastModifiedVersion = this.CurrentVersion
                });

                return(new HeapModelLocation(id, this.CurrentVersion));
            }
Пример #16
0
            public HeapModelLocation GetLocation(VersionedVariable reference)
            {
                int id = GetIdFromInterpretation(this.GetInterpretation(reference));

                if (this.currentHeap.TryGetValue(id, out var locationInfo) ||
                    this.inputHeap.TryGetValue(id, out locationInfo))
                {
                    return(new HeapModelLocation(id, locationInfo.LastModifiedVersion));
                }
                else
                {
                    this.inputHeap.Add(id, new LocationInfo()
                    {
                        LastModifiedVersion = 0
                    });
                    return(new HeapModelLocation(id, 0));
                }
            }
                private VariableState GetOrCreateVariableState(
                    VersionedVariable variable,
                    ISymbolicHeapContext context,
                    bool canBeNull = true)
                {
                    if (this.variableToStateIdMap.TryGetValue(variable, out var varStateId))
                    {
                        return(this.variableStates[varStateId]);
                    }
                    else
                    {
                        VariableState newState = this.CreateNewInputVariableState(variable, context, canBeNull);

                        this.MapToVariableState(variable, newState);

                        return(newState);
                    }
                }
                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);
                }
Пример #19
0
            public void ReadField(VersionedVariable reference, IFieldDefinition field)
            {
                int refId = GetIdFromInterpretation(this.GetInterpretation(reference));

                if (this.currentHeap.TryGetValue(refId, out var locationInfo))
                {
                    if (locationInfo.ContainsField(field))
                    {
                        // It was read successfully
                        return;
                    }
                    else if (refId > VariableState.NullValue)
                    {
                        // Note: This can't happen in higher level languages, because they always
                        //       initialize the fields (e.g. to zero)
                        throw new NotSupportedException(
                                  "Unable to model reading data of explicitly allocated but uninitialized objects");
                    }
                }

                // Fall back to input heap if not found in the current heap
                if (!this.inputHeap.TryGetValue(refId, out locationInfo))
                {
                    locationInfo = new LocationInfo()
                    {
                        LastModifiedVersion = 0
                    };
                    this.inputHeap.Add(refId, locationInfo);
                }

                if (!locationInfo.ContainsField(field))
                {
                    // Read the value from the particular input heap array
                    var fieldArray = this.state.GetFieldArray(field);
                    var valueIntr  = this.smtModel.GetInterpretation(fieldArray.Select(refId));

                    // Store either the reference ID or the value interpretation to the field
                    locationInfo.SetField(field, valueIntr);
                }
            }
                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);
                }
                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 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 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);
                    }
                }
Пример #24
0
            private Interpretation GetInterpretation(VersionedVariable reference)
            {
                var varState = this.state.TryGetVariableState(reference);

                if (varState == null)
                {
                    // References with no operations or constraints imposed upon them will be null
                    return((Interpretation)VariableState.Null.Representation);
                }
                else if (varState.IsInput || varState.IsInputDerived)
                {
                    Contract.Assert(varState.Representation.Expression.Kind == ExpressionKind.Variable);

                    return(this.smtModel.GetInterpretation(varState.Representation));
                }
                else
                {
                    Contract.Assert(varState.Representation.Expression.Kind == ExpressionKind.Interpretation);

                    return((Interpretation)varState.Representation);
                }
            }