예제 #1
0
 public IfStmt(ParserRuleContext sourceLocation, IPExpr condition, IPStmt thenBranch, IPStmt elseBranch)
 {
     SourceLocation = sourceLocation;
     Condition      = condition;
     ThenBranch     = CompoundStmt.FromStatement(thenBranch);
     ElseBranch     = elseBranch == null ? null : CompoundStmt.FromStatement(elseBranch);
 }
예제 #2
0
 public IfStmt(ParserRuleContext sourceLocation, IPExpr condition, IPStmt thenBranch, IPStmt elseBranch)
 {
     SourceLocation = sourceLocation;
     Condition      = condition;
     ThenBranch     = thenBranch;
     ElseBranch     = elseBranch;
 }
예제 #3
0
        public static bool SurelyReturns(IPStmt stmt)
        {
            switch (stmt)
            {
            case CompoundStmt compoundStmt:
                return(compoundStmt.Statements.Any(SurelyReturns));

            case IfStmt ifStmt:
                return(SurelyReturns(ifStmt.ThenBranch) && SurelyReturns(ifStmt.ElseBranch));

            case ReturnStmt _:
                return(true);

            case AssertStmt assertStmt
                when(assertStmt.Assertion as BoolLiteralExpr)?.Value == false:
                return(true);

            case PopStmt _:
                return(true);

            case GotoStmt _:
                return(true);

            case RaiseStmt _:
                return(true);

            case ReceiveStmt receive:
                return(receive.Cases.Values.All(fn => SurelyReturns(fn.Body)));

            default:
                return(false);
            }
        }
예제 #4
0
 public static CompoundStmt FromStatement(IPStmt statement)
 {
     if (statement is CompoundStmt compound)
     {
         return(compound);
     }
     return(new CompoundStmt(statement.SourceLocation, new[] { statement }));
 }
예제 #5
0
        public static void SimplifyMethod(Function function)
        {
            if (function.IsForeign)
            {
                return;
            }

            IRTransformer transformer  = new IRTransformer(function);
            IPStmt        functionBody = function.Body;

            function.Body = new CompoundStmt(functionBody.SourceLocation, transformer.SimplifyStatement(functionBody));
        }
예제 #6
0
        private void CheckStmt(IPStmt stmt)
        {
            switch (stmt)
            {
            case BreakStmt breakStmt:
                throw handler.BareLoopControlFlow("break", breakStmt.SourceLocation);

            case ContinueStmt continueStmt:
                throw handler.BareLoopControlFlow("continue", continueStmt.SourceLocation);

            case CompoundStmt compoundStmt:
                foreach (IPStmt subStmt in compoundStmt.Statements)
                {
                    CheckStmt(subStmt);
                }

                break;

            case IfStmt ifStmt:
                CheckStmt(ifStmt.ThenBranch);
                CheckStmt(ifStmt.ElseBranch);
                break;

            // Any break or continue statements inside this while loop are necessarily safe
            case WhileStmt _:
                break;

            // None of the following statement types can contain child statements, so we can safely skip them
            case AddStmt _:
            case AnnounceStmt _:
            case AssertStmt _:
            case AssignStmt _:
            case CtorStmt _:
            case FunCallStmt _:
            case GotoStmt _:
            case InsertStmt _:
            case MoveAssignStmt _:
            case NoStmt _:
            case PopStmt _:
            case PrintStmt _:
            case RaiseStmt _:
            case ReceiveStmt _:
            case RemoveStmt _:
            case ReturnStmt _:
            case SendStmt _:
            case StringAssignStmt _:
            case SwapAssignStmt _:
                break;

            default:
                throw new ArgumentOutOfRangeException(nameof(stmt));
            }
        }
예제 #7
0
        private List <IPStmt> SimplifyStatement(IPStmt statement)
        {
            Antlr4.Runtime.ParserRuleContext location = statement?.SourceLocation;
            switch (statement)
            {
            case null:
                throw new ArgumentNullException(nameof(statement));

            case AnnounceStmt announceStmt:
                (IExprTerm annEvt, List <IPStmt> annEvtDeps)         = SimplifyExpression(announceStmt.PEvent);
                (IExprTerm annPayload, List <IPStmt> annPayloadDeps) = announceStmt.Payload == null
                        ? (null, new List <IPStmt>())
                        : SimplifyExpression(announceStmt.Payload);
                return(annEvtDeps.Concat(annPayloadDeps)
                       .Concat(new[]
                {
                    new AnnounceStmt(location, annEvt, annPayload)
                })
                       .ToList());

            case AssertStmt assertStmt:
                (IExprTerm assertExpr, List <IPStmt> assertDeps)   = SimplifyExpression(assertStmt.Assertion);
                (IExprTerm messageExpr, List <IPStmt> messageDeps) = SimplifyExpression(assertStmt.Message);

                return(assertDeps.Concat(messageDeps).Concat(new[]
                {
                    new AssertStmt(location, assertExpr, messageExpr)
                })
                       .ToList());

            case AssignStmt assignStmt:
                (IPExpr assignLV, List <IPStmt> assignLVDeps)    = SimplifyLvalue(assignStmt.Location);
                (IExprTerm assignRV, List <IPStmt> assignRVDeps) = SimplifyRvalue(assignStmt.Value);
                IPStmt assignment;
                // If temporary returned, then automatically move.
                if (assignRV is VariableAccessExpr variableRef &&
                    variableRef.Variable.Role.HasFlag(VariableRole.Temp))
                {
                    assignment = new MoveAssignStmt(location, assignLV, variableRef.Variable);
                }
                else
                {
                    assignment = new AssignStmt(location, assignLV, new CloneExpr(assignRV));
                }

                return(assignLVDeps.Concat(assignRVDeps).Concat(new[] { assignment }).ToList());
예제 #8
0
파일: WhileStmt.cs 프로젝트: yzhang90/P-1
 public WhileStmt(ParserRuleContext sourceLocation, IPExpr condition, IPStmt body)
 {
     SourceLocation = sourceLocation;
     Condition      = condition;
     Body           = CompoundStmt.FromStatement(body);
 }
예제 #9
0
        private ISet <Variable> ProcessStatement(ISet <Variable> unavailable, IPStmt statement)
        {
            Contract.Requires(statement != null);
            switch (statement)
            {
            case CompoundStmt compoundStmt:
                unavailable = compoundStmt.Statements.Aggregate(unavailable, ProcessStatement);
                break;

            case AssertStmt assertStmt:
                unavailable = ProcessExpr(unavailable, assertStmt.Assertion);
                break;

            case PrintStmt printStmt:
                unavailable = ProcessArgList(printStmt.Args, unavailable, ArgOptions.SwapNotAllowed);
                break;

            case ReturnStmt returnStmt:
                if (returnStmt.ReturnValue != null)
                {
                    unavailable = ProcessExpr(unavailable, returnStmt.ReturnValue);
                }

                break;

            case AssignStmt assignStmt:
                unavailable = ProcessExpr(unavailable, assignStmt.Value);
                if (assignStmt.Location is VariableAccessExpr assignAccess)
                {
                    unavailable.Remove(assignAccess.Variable);
                }
                else
                {
                    unavailable = ProcessExpr(unavailable, assignStmt.Location);
                }

                break;

            case MoveAssignStmt moveAssignStmt:
                if (moveAssignStmt.FromVariable.Role.Equals(VariableRole.Field))
                {
                    throw handler.MovedField(moveAssignStmt);
                }

                unavailable.Add(moveAssignStmt.FromVariable);

                if (moveAssignStmt.ToLocation is VariableAccessExpr moveAssignAccess)
                {
                    unavailable.Remove(moveAssignAccess.Variable);
                }
                else
                {
                    unavailable = ProcessExpr(unavailable, moveAssignStmt.ToLocation);
                }

                break;

            case SwapAssignStmt swapAssignStmt:
                if (swapAssignStmt.NewLocation is VariableAccessExpr swapAssignAccess)
                {
                    if (unavailable.Contains(swapAssignAccess.Variable))
                    {
                        throw handler.SwapAssignUnavailable(swapAssignStmt, swapAssignAccess.Variable);
                    }
                }
                else
                {
                    unavailable = ProcessExpr(unavailable, swapAssignStmt.NewLocation);
                }

                if (unavailable.Contains(swapAssignStmt.OldLocation))
                {
                    throw handler.SwapAssignUnavailable(swapAssignStmt, swapAssignStmt.OldLocation);
                }

                break;

            case InsertStmt insertStmt:
                unavailable = ProcessExpr(unavailable, insertStmt.Variable);
                unavailable = ProcessExpr(unavailable, insertStmt.Index);
                unavailable = ProcessExpr(unavailable, insertStmt.Value);
                break;

            case RemoveStmt removeStmt:
                unavailable = ProcessExpr(unavailable, removeStmt.Variable);
                unavailable = ProcessExpr(unavailable, removeStmt.Value);
                break;

            case WhileStmt whileStmt:
                unavailable = ProcessExpr(unavailable, whileStmt.Condition);
                // process running the body twice. on the first go, the loop can potentially
                // relinquish additional variables on the second go, either the body will use
                // one of these variables and throw or reach a fixed point since all paths are
                // considered simultaneously. Then, we continue our overapproximation by taking
                // the union of no runs and one or more runs.
                var bodyUnavailable =
                    ProcessStatement(new HashSet <Variable>(unavailable), whileStmt.Body);
                bodyUnavailable = ProcessExpr(bodyUnavailable, whileStmt.Condition);
                // TODO: more efficient way of doing this?
                bodyUnavailable = ProcessStatement(bodyUnavailable, whileStmt.Body);
                bodyUnavailable = ProcessExpr(bodyUnavailable, whileStmt.Condition);
                unavailable.UnionWith(bodyUnavailable);
                break;

            case IfStmt ifStmt:
                unavailable = ProcessExpr(unavailable, ifStmt.Condition);
                var thenUnavailable =
                    ProcessStatement(new HashSet <Variable>(unavailable), ifStmt.ThenBranch);
                var elseUnavailable =
                    ProcessStatement(new HashSet <Variable>(unavailable), ifStmt.ElseBranch);
                thenUnavailable.UnionWith(elseUnavailable);
                unavailable = thenUnavailable;
                break;

            case CtorStmt ctorStmt:
                unavailable = ProcessArgList(ctorStmt.Arguments, unavailable, ArgOptions.SwapNotAllowed);
                break;

            case FunCallStmt funCallStmt:
                unavailable = ProcessArgList(funCallStmt.ArgsList, unavailable);
                funCallStmts.Add(funCallStmt);
                break;

            case RaiseStmt raiseStmt:
                unavailable = ProcessExpr(unavailable, raiseStmt.PEvent);
                unavailable = ProcessArgList(raiseStmt.Payload, unavailable, ArgOptions.SwapNotAllowed);
                break;

            case SendStmt sendStmt:
                unavailable = ProcessExpr(unavailable, sendStmt.MachineExpr);
                unavailable = ProcessExpr(unavailable, sendStmt.Evt);
                unavailable = ProcessArgList(sendStmt.Arguments, unavailable, ArgOptions.SwapNotAllowed);
                break;

            case AnnounceStmt announceStmt:
                unavailable = ProcessExpr(unavailable, announceStmt.PEvent);
                if (announceStmt.Payload != null)
                {
                    unavailable = ProcessExpr(unavailable, announceStmt.Payload);
                }

                break;

            case GotoStmt gotoStmt:
                if (gotoStmt.Payload != null)
                {
                    unavailable = ProcessExpr(unavailable, gotoStmt.Payload);
                }

                break;

            case ReceiveStmt receiveStmt:
                var postUnavailable = new HashSet <Variable>();
                var caseVariables   = new HashSet <Variable>();
                foreach (var recvCase in receiveStmt.Cases)
                {
                    var caseUnavailable =
                        ProcessStatement(new HashSet <Variable>(unavailable), recvCase.Value.Body);
                    postUnavailable.UnionWith(caseUnavailable);
                    caseVariables.UnionWith(recvCase.Value.Signature.Parameters);
                }

                unavailable = postUnavailable;
                unavailable.ExceptWith(caseVariables);
                break;

            case PopStmt _:
            case NoStmt _:
                // nothing to check
                break;

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

            return(unavailable);
        }
예제 #10
0
 public WhileStmt(ParserRuleContext sourceLocation, IPExpr condition, IPStmt body)
 {
     SourceLocation = sourceLocation;
     Condition      = condition;
     Body           = body;
 }