/// <summary> /// Refines the given state according to the knowledge stored in the egraph about sv /// /// In addition, the state can be null when the knowledge is inconsistent. /// </summary> /// <param name="cv">symbolic value we assume to be non-null (true)</param> /// <param name="state">state if sv is non-null (true)</param> private static void AssumeTrue(ISymValue cv, ref NonNullState state) { if (state == null) return; if (state.IsNull(cv)) { // infeasible state = null; return; } if (state.IsNonNull(cv)) return; state.egraph[cv] = Lattice.AVal.NonNull; foreach(EGraphTerm t in state.egraph.EqTerms(cv)) { if (t.Function == NonNullState.EqNullId) { ISymValue op = t.Args[0]; AssumeFalse(op, ref state); } if (t.Function == NonNullState.NeNullId) { ISymValue op = t.Args[0]; AssumeTrue(op, ref state); } if (t.Function == NonNullState.LogicalNegId) { ISymValue op = t.Args[0]; AssumeFalse(op, ref state); } if (t.Function == NonNullState.IsInstId) { ISymValue op = t.Args[0]; AssumeTrue(op, ref state); } } }
private void CheckPointerUse(Statement stat, Variable v, NonNullState nn, string purpose) { if (v == null) return; if(nn.IsNull(v)) { HandleError(stat, v, Error.UseOfNullPointer, purpose); nn.AssignNonNull(v); } else if(!nn.IsNonNull(v)) { HandleError(stat, v, Error.UseOfPossiblyNullPointer, purpose); nn.AssumeNonNull(v); } }
/// <summary> /// Refines the given state according to the knowledge stored in the egraph about sv /// /// In addition, the state can be null when the knowledge is inconsistent. /// </summary> /// <param name="cv">symbolic value we assume to be null (false)</param> private static void AssumeFalse(ISymValue cv, ref NonNullState state) { if (state == null) return; if (state.IsNonNull(cv)) { // infeasible // but we still want to go on analyzing this branch. state = null; return; } if (state.IsNull(cv)) return; foreach(EGraphTerm t in state.egraph.EqTerms(cv)) { if (t.Function == NonNullState.EqNullId) { // EqNull(op) == false, therefore op != null ISymValue op = t.Args[0]; AssumeTrue(op, ref state); } if (t.Function == NonNullState.NeNullId) { // NeNull(op) == false, therefore op == null ISymValue op = t.Args[0]; AssumeFalse(op, ref state); } if (t.Function == NonNullState.LogicalNegId) { // Not(op) == false, therefore op == true ISymValue op = t.Args[0]; AssumeTrue(op, ref state); } if (t.Function == NonNullState.IsInstId) { // IsInst(op) == null, cannot deduce anything about op } } // needs to be after we check EqTerms, as they verify mapping is current. if (state != null) state.AssumeNull(cv); }
private void CheckReceiver(Statement stat, Variable v, NonNullState nn, Node node) { Node offendingNode = v; if (v == null) return; if (v.Type.IsValueType) return; // Create a better source context for receiver null errors. offendingNode = new Statement(NodeType.Nop); offendingNode.SourceContext = v.SourceContext; // offendingNode.SourceContext.StartPos = offendingNode.SourceContext.EndPos; // offendingNode.SourceContext.EndPos++; if(nn.IsNull(v)) { HandleError(stat, offendingNode, Error.ReceiverCannotBeNull, this.ts.GetTypeName(v.Type)); nn.AssignNonNull(v); } else if(!nn.IsNonNull(v)) { HandleError(stat, offendingNode, Error.ReceiverMightBeNull, this.ts.GetTypeName(v.Type)); nn.AssumeNonNull(v); } }