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