Пример #1
0
        private ISet <Variable> ProcessExpr(ISet <Variable> unavailable, IPExpr expression)
        {
            Contract.Requires(expression != null);
            switch (expression)
            {
            case CloneExpr cloneExpr:
                unavailable = ProcessExpr(unavailable, cloneExpr.Term);
                break;

            case CastExpr castExpr:
                unavailable = ProcessExpr(unavailable, castExpr.SubExpr);
                break;

            case CoerceExpr coerceExpr:
                unavailable = ProcessExpr(unavailable, coerceExpr.SubExpr);
                break;

            case ContainsKeyExpr containsKeyExpr:
                unavailable = ProcessExpr(unavailable, containsKeyExpr.Map);
                unavailable = ProcessExpr(unavailable, containsKeyExpr.Key);
                break;

            case CtorExpr ctorExpr:
                unavailable = ProcessArgList(ctorExpr.Arguments, unavailable, ArgOptions.SwapNotAllowed);
                break;

            case FunCallExpr funCallExpr:
                unavailable = ProcessArgList(funCallExpr.Arguments, unavailable);
                funCallExprs.Add(funCallExpr);
                break;

            case KeysExpr keysExpr:
                unavailable = ProcessExpr(unavailable, keysExpr.Expr);
                break;

            case LinearAccessRefExpr linearAccessRefExpr:
                if (unavailable.Contains(linearAccessRefExpr.Variable) ||
                    linearAccessRefExpr.Variable.Role.Equals(VariableRole.Field))
                {
                    throw handler.RelinquishedWithoutOwnership(linearAccessRefExpr);
                }

                if (linearAccessRefExpr.LinearType.Equals(LinearType.Move))
                {
                    unavailable.Add(linearAccessRefExpr.Variable);
                }

                break;

            case UnaryOpExpr unaryOp:
                unavailable = ProcessExpr(unavailable, unaryOp.SubExpr);
                break;

            case MapAccessExpr mapAccessExpr:
                unavailable = ProcessExpr(unavailable, mapAccessExpr.MapExpr);
                unavailable = ProcessExpr(unavailable, mapAccessExpr.IndexExpr);
                break;

            case BinOpExpr binOp:
                unavailable = ProcessExpr(unavailable, binOp.Lhs);
                unavailable = ProcessExpr(unavailable, binOp.Rhs);
                break;

            case NamedTupleAccessExpr namedTupleAccessExpr:
                unavailable = ProcessExpr(unavailable, namedTupleAccessExpr.SubExpr);
                break;

            case NamedTupleExpr namedTupleExpr:
                unavailable = ProcessArgList(namedTupleExpr.TupleFields, unavailable, ArgOptions.SwapNotAllowed);
                break;

            case SeqAccessExpr seqAccessExpr:
                unavailable = ProcessExpr(unavailable, seqAccessExpr.SeqExpr);
                unavailable = ProcessExpr(unavailable, seqAccessExpr.IndexExpr);
                break;

            case SizeofExpr sizeofExpr:
                unavailable = ProcessExpr(unavailable, sizeofExpr.Expr);
                break;

            case TupleAccessExpr tupleAccessExpr:
                unavailable = ProcessExpr(unavailable, tupleAccessExpr.SubExpr);
                break;

            case UnnamedTupleExpr unnamedTupleExpr:
                unavailable = ProcessArgList(unnamedTupleExpr.TupleFields, unavailable, ArgOptions.SwapNotAllowed);
                break;

            case ValuesExpr valuesExpr:
                unavailable = ProcessExpr(unavailable, valuesExpr.Expr);
                break;

            case VariableAccessExpr variableAccessExpr:
                if (unavailable.Contains(variableAccessExpr.Variable))
                {
                    throw handler.UseWithoutOwnership(variableAccessExpr);
                }

                break;

            case BoolLiteralExpr _:
            case DefaultExpr _:
            case EnumElemRefExpr _:
            case EventRefExpr _:
            case FairNondetExpr _:
            case FloatLiteralExpr _:
            case IntLiteralExpr _:
            case NondetExpr _:
            case NullLiteralExpr _:
            case ThisRefExpr _:
                // nothing to do
                break;

            default:
                throw handler.InternalError(expression.SourceLocation,
                                            new ArgumentOutOfRangeException(nameof(expression)));
            }

            return(unavailable);
        }