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); }
public IfStmt(ParserRuleContext sourceLocation, IPExpr condition, IPStmt thenBranch, IPStmt elseBranch) { SourceLocation = sourceLocation; Condition = condition; ThenBranch = thenBranch; ElseBranch = elseBranch; }
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); } }
public static CompoundStmt FromStatement(IPStmt statement) { if (statement is CompoundStmt compound) { return(compound); } return(new CompoundStmt(statement.SourceLocation, new[] { statement })); }
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)); }
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)); } }
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());
public WhileStmt(ParserRuleContext sourceLocation, IPExpr condition, IPStmt body) { SourceLocation = sourceLocation; Condition = condition; Body = CompoundStmt.FromStatement(body); }
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); }
public WhileStmt(ParserRuleContext sourceLocation, IPExpr condition, IPStmt body) { SourceLocation = sourceLocation; Condition = condition; Body = body; }