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); } } }
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); }
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); }