langtools/src/share/classes/com/sun/tools/javac/comp/Flow.java
changeset 22163 3651128c74eb
parent 22150 af8945f58fc6
child 22165 ec53c8946fc2
equal deleted inserted replaced
22162:3b3e23e67329 22163:3651128c74eb
   179  *  If you write code that depends on this, you do so at your own risk.
   179  *  If you write code that depends on this, you do so at your own risk.
   180  *  This code and its internal interfaces are subject to change or
   180  *  This code and its internal interfaces are subject to change or
   181  *  deletion without notice.</b>
   181  *  deletion without notice.</b>
   182  */
   182  */
   183 public class Flow {
   183 public class Flow {
   184     protected static final Context.Key<Flow> flowKey =
   184     protected static final Context.Key<Flow> flowKey = new Context.Key<>();
   185         new Context.Key<Flow>();
       
   186 
   185 
   187     private final Names names;
   186     private final Names names;
   188     private final Log log;
   187     private final Log log;
   189     private final Symtab syms;
   188     private final Symtab syms;
   190     private final Types types;
   189     private final Types types;
   371             return resolved;
   370             return resolved;
   372         }
   371         }
   373 
   372 
   374         /** Resolve all continues of this statement. */
   373         /** Resolve all continues of this statement. */
   375         boolean resolveContinues(JCTree tree) {
   374         boolean resolveContinues(JCTree tree) {
   376             return resolveJump(tree, new ListBuffer<P>(), JumpKind.CONTINUE);
   375             return resolveJump(tree, new ListBuffer<>(), JumpKind.CONTINUE);
   377         }
   376         }
   378 
   377 
   379         /** Resolve all breaks of this statement. */
   378         /** Resolve all breaks of this statement. */
   380         boolean resolveBreaks(JCTree tree, ListBuffer<P> oldPendingExits) {
   379         boolean resolveBreaks(JCTree tree, ListBuffer<P> oldPendingExits) {
   381             return resolveJump(tree, oldPendingExits, JumpKind.BREAK);
   380             return resolveJump(tree, oldPendingExits, JumpKind.BREAK);
   447             if (tree.sym == null) return;
   446             if (tree.sym == null) return;
   448             boolean alivePrev = alive;
   447             boolean alivePrev = alive;
   449             ListBuffer<PendingExit> pendingExitsPrev = pendingExits;
   448             ListBuffer<PendingExit> pendingExitsPrev = pendingExits;
   450             Lint lintPrev = lint;
   449             Lint lintPrev = lint;
   451 
   450 
   452             pendingExits = new ListBuffer<PendingExit>();
   451             pendingExits = new ListBuffer<>();
   453             lint = lint.augment(tree.sym);
   452             lint = lint.augment(tree.sym);
   454 
   453 
   455             try {
   454             try {
   456                 // process all the static initializers
   455                 // process all the static initializers
   457                 for (List<JCTree> l = tree.defs; l.nonEmpty(); l = l.tail) {
   456                 for (List<JCTree> l = tree.defs; l.nonEmpty(); l = l.tail) {
   496 
   495 
   497                 if (alive && !tree.sym.type.getReturnType().hasTag(VOID))
   496                 if (alive && !tree.sym.type.getReturnType().hasTag(VOID))
   498                     log.error(TreeInfo.diagEndPos(tree.body), "missing.ret.stmt");
   497                     log.error(TreeInfo.diagEndPos(tree.body), "missing.ret.stmt");
   499 
   498 
   500                 List<PendingExit> exits = pendingExits.toList();
   499                 List<PendingExit> exits = pendingExits.toList();
   501                 pendingExits = new ListBuffer<PendingExit>();
   500                 pendingExits = new ListBuffer<>();
   502                 while (exits.nonEmpty()) {
   501                 while (exits.nonEmpty()) {
   503                     PendingExit exit = exits.head;
   502                     PendingExit exit = exits.head;
   504                     exits = exits.tail;
   503                     exits = exits.tail;
   505                     Assert.check(exit.tree.hasTag(RETURN));
   504                     Assert.check(exit.tree.hasTag(RETURN));
   506                 }
   505                 }
   525             scanStats(tree.stats);
   524             scanStats(tree.stats);
   526         }
   525         }
   527 
   526 
   528         public void visitDoLoop(JCDoWhileLoop tree) {
   527         public void visitDoLoop(JCDoWhileLoop tree) {
   529             ListBuffer<PendingExit> prevPendingExits = pendingExits;
   528             ListBuffer<PendingExit> prevPendingExits = pendingExits;
   530             pendingExits = new ListBuffer<PendingExit>();
   529             pendingExits = new ListBuffer<>();
   531             scanStat(tree.body);
   530             scanStat(tree.body);
   532             alive |= resolveContinues(tree);
   531             alive |= resolveContinues(tree);
   533             scan(tree.cond);
   532             scan(tree.cond);
   534             alive = alive && !tree.cond.type.isTrue();
   533             alive = alive && !tree.cond.type.isTrue();
   535             alive |= resolveBreaks(tree, prevPendingExits);
   534             alive |= resolveBreaks(tree, prevPendingExits);
   536         }
   535         }
   537 
   536 
   538         public void visitWhileLoop(JCWhileLoop tree) {
   537         public void visitWhileLoop(JCWhileLoop tree) {
   539             ListBuffer<PendingExit> prevPendingExits = pendingExits;
   538             ListBuffer<PendingExit> prevPendingExits = pendingExits;
   540             pendingExits = new ListBuffer<PendingExit>();
   539             pendingExits = new ListBuffer<>();
   541             scan(tree.cond);
   540             scan(tree.cond);
   542             alive = !tree.cond.type.isFalse();
   541             alive = !tree.cond.type.isFalse();
   543             scanStat(tree.body);
   542             scanStat(tree.body);
   544             alive |= resolveContinues(tree);
   543             alive |= resolveContinues(tree);
   545             alive = resolveBreaks(tree, prevPendingExits) ||
   544             alive = resolveBreaks(tree, prevPendingExits) ||
   547         }
   546         }
   548 
   547 
   549         public void visitForLoop(JCForLoop tree) {
   548         public void visitForLoop(JCForLoop tree) {
   550             ListBuffer<PendingExit> prevPendingExits = pendingExits;
   549             ListBuffer<PendingExit> prevPendingExits = pendingExits;
   551             scanStats(tree.init);
   550             scanStats(tree.init);
   552             pendingExits = new ListBuffer<PendingExit>();
   551             pendingExits = new ListBuffer<>();
   553             if (tree.cond != null) {
   552             if (tree.cond != null) {
   554                 scan(tree.cond);
   553                 scan(tree.cond);
   555                 alive = !tree.cond.type.isFalse();
   554                 alive = !tree.cond.type.isFalse();
   556             } else {
   555             } else {
   557                 alive = true;
   556                 alive = true;
   565 
   564 
   566         public void visitForeachLoop(JCEnhancedForLoop tree) {
   565         public void visitForeachLoop(JCEnhancedForLoop tree) {
   567             visitVarDef(tree.var);
   566             visitVarDef(tree.var);
   568             ListBuffer<PendingExit> prevPendingExits = pendingExits;
   567             ListBuffer<PendingExit> prevPendingExits = pendingExits;
   569             scan(tree.expr);
   568             scan(tree.expr);
   570             pendingExits = new ListBuffer<PendingExit>();
   569             pendingExits = new ListBuffer<>();
   571             scanStat(tree.body);
   570             scanStat(tree.body);
   572             alive |= resolveContinues(tree);
   571             alive |= resolveContinues(tree);
   573             resolveBreaks(tree, prevPendingExits);
   572             resolveBreaks(tree, prevPendingExits);
   574             alive = true;
   573             alive = true;
   575         }
   574         }
   576 
   575 
   577         public void visitLabelled(JCLabeledStatement tree) {
   576         public void visitLabelled(JCLabeledStatement tree) {
   578             ListBuffer<PendingExit> prevPendingExits = pendingExits;
   577             ListBuffer<PendingExit> prevPendingExits = pendingExits;
   579             pendingExits = new ListBuffer<PendingExit>();
   578             pendingExits = new ListBuffer<>();
   580             scanStat(tree.body);
   579             scanStat(tree.body);
   581             alive |= resolveBreaks(tree, prevPendingExits);
   580             alive |= resolveBreaks(tree, prevPendingExits);
   582         }
   581         }
   583 
   582 
   584         public void visitSwitch(JCSwitch tree) {
   583         public void visitSwitch(JCSwitch tree) {
   585             ListBuffer<PendingExit> prevPendingExits = pendingExits;
   584             ListBuffer<PendingExit> prevPendingExits = pendingExits;
   586             pendingExits = new ListBuffer<PendingExit>();
   585             pendingExits = new ListBuffer<>();
   587             scan(tree.selector);
   586             scan(tree.selector);
   588             boolean hasDefault = false;
   587             boolean hasDefault = false;
   589             for (List<JCCase> l = tree.cases; l.nonEmpty(); l = l.tail) {
   588             for (List<JCCase> l = tree.cases; l.nonEmpty(); l = l.tail) {
   590                 alive = true;
   589                 alive = true;
   591                 JCCase c = l.head;
   590                 JCCase c = l.head;
   608             alive |= resolveBreaks(tree, prevPendingExits);
   607             alive |= resolveBreaks(tree, prevPendingExits);
   609         }
   608         }
   610 
   609 
   611         public void visitTry(JCTry tree) {
   610         public void visitTry(JCTry tree) {
   612             ListBuffer<PendingExit> prevPendingExits = pendingExits;
   611             ListBuffer<PendingExit> prevPendingExits = pendingExits;
   613             pendingExits = new ListBuffer<PendingExit>();
   612             pendingExits = new ListBuffer<>();
   614             for (JCTree resource : tree.resources) {
   613             for (JCTree resource : tree.resources) {
   615                 if (resource instanceof JCVariableDecl) {
   614                 if (resource instanceof JCVariableDecl) {
   616                     JCVariableDecl vdecl = (JCVariableDecl) resource;
   615                     JCVariableDecl vdecl = (JCVariableDecl) resource;
   617                     visitVarDef(vdecl);
   616                     visitVarDef(vdecl);
   618                 } else if (resource instanceof JCExpression) {
   617                 } else if (resource instanceof JCExpression) {
   739         }
   738         }
   740         public void analyzeTree(Env<AttrContext> env, JCTree tree, TreeMaker make) {
   739         public void analyzeTree(Env<AttrContext> env, JCTree tree, TreeMaker make) {
   741             try {
   740             try {
   742                 attrEnv = env;
   741                 attrEnv = env;
   743                 Flow.this.make = make;
   742                 Flow.this.make = make;
   744                 pendingExits = new ListBuffer<PendingExit>();
   743                 pendingExits = new ListBuffer<>();
   745                 alive = true;
   744                 alive = true;
   746                 scan(tree);
   745                 scan(tree);
   747             } finally {
   746             } finally {
   748                 pendingExits = null;
   747                 pendingExits = null;
   749                 Flow.this.make = null;
   748                 Flow.this.make = null;
   844             List<Type> thrownPrev = thrown;
   843             List<Type> thrownPrev = thrown;
   845             List<Type> caughtPrev = caught;
   844             List<Type> caughtPrev = caught;
   846             ListBuffer<FlowPendingExit> pendingExitsPrev = pendingExits;
   845             ListBuffer<FlowPendingExit> pendingExitsPrev = pendingExits;
   847             Lint lintPrev = lint;
   846             Lint lintPrev = lint;
   848 
   847 
   849             pendingExits = new ListBuffer<FlowPendingExit>();
   848             pendingExits = new ListBuffer<>();
   850             if (tree.name != names.empty) {
   849             if (tree.name != names.empty) {
   851                 caught = List.nil();
   850                 caught = List.nil();
   852             }
   851             }
   853             classDef = tree;
   852             classDef = tree;
   854             thrown = List.nil();
   853             thrown = List.nil();
   949                 // leave caught unchanged.
   948                 // leave caught unchanged.
   950 
   949 
   951                 scan(tree.body);
   950                 scan(tree.body);
   952 
   951 
   953                 List<FlowPendingExit> exits = pendingExits.toList();
   952                 List<FlowPendingExit> exits = pendingExits.toList();
   954                 pendingExits = new ListBuffer<FlowPendingExit>();
   953                 pendingExits = new ListBuffer<>();
   955                 while (exits.nonEmpty()) {
   954                 while (exits.nonEmpty()) {
   956                     FlowPendingExit exit = exits.head;
   955                     FlowPendingExit exit = exits.head;
   957                     exits = exits.tail;
   956                     exits = exits.tail;
   958                     if (exit.thrown == null) {
   957                     if (exit.thrown == null) {
   959                         Assert.check(exit.tree.hasTag(RETURN));
   958                         Assert.check(exit.tree.hasTag(RETURN));
   984             scan(tree.stats);
   983             scan(tree.stats);
   985         }
   984         }
   986 
   985 
   987         public void visitDoLoop(JCDoWhileLoop tree) {
   986         public void visitDoLoop(JCDoWhileLoop tree) {
   988             ListBuffer<FlowPendingExit> prevPendingExits = pendingExits;
   987             ListBuffer<FlowPendingExit> prevPendingExits = pendingExits;
   989             pendingExits = new ListBuffer<FlowPendingExit>();
   988             pendingExits = new ListBuffer<>();
   990             scan(tree.body);
   989             scan(tree.body);
   991             resolveContinues(tree);
   990             resolveContinues(tree);
   992             scan(tree.cond);
   991             scan(tree.cond);
   993             resolveBreaks(tree, prevPendingExits);
   992             resolveBreaks(tree, prevPendingExits);
   994         }
   993         }
   995 
   994 
   996         public void visitWhileLoop(JCWhileLoop tree) {
   995         public void visitWhileLoop(JCWhileLoop tree) {
   997             ListBuffer<FlowPendingExit> prevPendingExits = pendingExits;
   996             ListBuffer<FlowPendingExit> prevPendingExits = pendingExits;
   998             pendingExits = new ListBuffer<FlowPendingExit>();
   997             pendingExits = new ListBuffer<>();
   999             scan(tree.cond);
   998             scan(tree.cond);
  1000             scan(tree.body);
   999             scan(tree.body);
  1001             resolveContinues(tree);
  1000             resolveContinues(tree);
  1002             resolveBreaks(tree, prevPendingExits);
  1001             resolveBreaks(tree, prevPendingExits);
  1003         }
  1002         }
  1004 
  1003 
  1005         public void visitForLoop(JCForLoop tree) {
  1004         public void visitForLoop(JCForLoop tree) {
  1006             ListBuffer<FlowPendingExit> prevPendingExits = pendingExits;
  1005             ListBuffer<FlowPendingExit> prevPendingExits = pendingExits;
  1007             scan(tree.init);
  1006             scan(tree.init);
  1008             pendingExits = new ListBuffer<FlowPendingExit>();
  1007             pendingExits = new ListBuffer<>();
  1009             if (tree.cond != null) {
  1008             if (tree.cond != null) {
  1010                 scan(tree.cond);
  1009                 scan(tree.cond);
  1011             }
  1010             }
  1012             scan(tree.body);
  1011             scan(tree.body);
  1013             resolveContinues(tree);
  1012             resolveContinues(tree);
  1017 
  1016 
  1018         public void visitForeachLoop(JCEnhancedForLoop tree) {
  1017         public void visitForeachLoop(JCEnhancedForLoop tree) {
  1019             visitVarDef(tree.var);
  1018             visitVarDef(tree.var);
  1020             ListBuffer<FlowPendingExit> prevPendingExits = pendingExits;
  1019             ListBuffer<FlowPendingExit> prevPendingExits = pendingExits;
  1021             scan(tree.expr);
  1020             scan(tree.expr);
  1022             pendingExits = new ListBuffer<FlowPendingExit>();
  1021             pendingExits = new ListBuffer<>();
  1023             scan(tree.body);
  1022             scan(tree.body);
  1024             resolveContinues(tree);
  1023             resolveContinues(tree);
  1025             resolveBreaks(tree, prevPendingExits);
  1024             resolveBreaks(tree, prevPendingExits);
  1026         }
  1025         }
  1027 
  1026 
  1028         public void visitLabelled(JCLabeledStatement tree) {
  1027         public void visitLabelled(JCLabeledStatement tree) {
  1029             ListBuffer<FlowPendingExit> prevPendingExits = pendingExits;
  1028             ListBuffer<FlowPendingExit> prevPendingExits = pendingExits;
  1030             pendingExits = new ListBuffer<FlowPendingExit>();
  1029             pendingExits = new ListBuffer<>();
  1031             scan(tree.body);
  1030             scan(tree.body);
  1032             resolveBreaks(tree, prevPendingExits);
  1031             resolveBreaks(tree, prevPendingExits);
  1033         }
  1032         }
  1034 
  1033 
  1035         public void visitSwitch(JCSwitch tree) {
  1034         public void visitSwitch(JCSwitch tree) {
  1036             ListBuffer<FlowPendingExit> prevPendingExits = pendingExits;
  1035             ListBuffer<FlowPendingExit> prevPendingExits = pendingExits;
  1037             pendingExits = new ListBuffer<FlowPendingExit>();
  1036             pendingExits = new ListBuffer<>();
  1038             scan(tree.selector);
  1037             scan(tree.selector);
  1039             for (List<JCCase> l = tree.cases; l.nonEmpty(); l = l.tail) {
  1038             for (List<JCCase> l = tree.cases; l.nonEmpty(); l = l.tail) {
  1040                 JCCase c = l.head;
  1039                 JCCase c = l.head;
  1041                 if (c.pat != null) {
  1040                 if (c.pat != null) {
  1042                     scan(c.pat);
  1041                     scan(c.pat);
  1058                     caught = chk.incl(ct.type, caught);
  1057                     caught = chk.incl(ct.type, caught);
  1059                 }
  1058                 }
  1060             }
  1059             }
  1061 
  1060 
  1062             ListBuffer<FlowPendingExit> prevPendingExits = pendingExits;
  1061             ListBuffer<FlowPendingExit> prevPendingExits = pendingExits;
  1063             pendingExits = new ListBuffer<FlowPendingExit>();
  1062             pendingExits = new ListBuffer<>();
  1064             for (JCTree resource : tree.resources) {
  1063             for (JCTree resource : tree.resources) {
  1065                 if (resource instanceof JCVariableDecl) {
  1064                 if (resource instanceof JCVariableDecl) {
  1066                     JCVariableDecl vdecl = (JCVariableDecl) resource;
  1065                     JCVariableDecl vdecl = (JCVariableDecl) resource;
  1067                     visitVarDef(vdecl);
  1066                     visitVarDef(vdecl);
  1068                 } else if (resource instanceof JCExpression) {
  1067                 } else if (resource instanceof JCExpression) {
  1268                 pendingExits = new ListBuffer<>();
  1267                 pendingExits = new ListBuffer<>();
  1269                 caught = tree.getDescriptorType(types).getThrownTypes();
  1268                 caught = tree.getDescriptorType(types).getThrownTypes();
  1270                 thrown = List.nil();
  1269                 thrown = List.nil();
  1271                 scan(tree.body);
  1270                 scan(tree.body);
  1272                 List<FlowPendingExit> exits = pendingExits.toList();
  1271                 List<FlowPendingExit> exits = pendingExits.toList();
  1273                 pendingExits = new ListBuffer<FlowPendingExit>();
  1272                 pendingExits = new ListBuffer<>();
  1274                 while (exits.nonEmpty()) {
  1273                 while (exits.nonEmpty()) {
  1275                     FlowPendingExit exit = exits.head;
  1274                     FlowPendingExit exit = exits.head;
  1276                     exits = exits.tail;
  1275                     exits = exits.tail;
  1277                     if (exit.thrown == null) {
  1276                     if (exit.thrown == null) {
  1278                         Assert.check(exit.tree.hasTag(RETURN));
  1277                         Assert.check(exit.tree.hasTag(RETURN));
  1305         }
  1304         }
  1306         public void analyzeTree(Env<AttrContext> env, JCTree tree, TreeMaker make) {
  1305         public void analyzeTree(Env<AttrContext> env, JCTree tree, TreeMaker make) {
  1307             try {
  1306             try {
  1308                 attrEnv = env;
  1307                 attrEnv = env;
  1309                 Flow.this.make = make;
  1308                 Flow.this.make = make;
  1310                 pendingExits = new ListBuffer<FlowPendingExit>();
  1309                 pendingExits = new ListBuffer<>();
  1311                 preciseRethrowTypes = new HashMap<Symbol, List<Type>>();
  1310                 preciseRethrowTypes = new HashMap<>();
  1312                 this.thrown = this.caught = null;
  1311                 this.thrown = this.caught = null;
  1313                 this.classDef = null;
  1312                 this.classDef = null;
  1314                 scan(tree);
  1313                 scan(tree);
  1315             } finally {
  1314             } finally {
  1316                 pendingExits = null;
  1315                 pendingExits = null;
  1649             JCClassDecl classDefPrev = classDef;
  1648             JCClassDecl classDefPrev = classDef;
  1650             int firstadrPrev = firstadr;
  1649             int firstadrPrev = firstadr;
  1651             int nextadrPrev = nextadr;
  1650             int nextadrPrev = nextadr;
  1652             ListBuffer<P> pendingExitsPrev = pendingExits;
  1651             ListBuffer<P> pendingExitsPrev = pendingExits;
  1653 
  1652 
  1654             pendingExits = new ListBuffer<P>();
  1653             pendingExits = new ListBuffer<>();
  1655             if (tree.name != names.empty) {
  1654             if (tree.name != names.empty) {
  1656                 firstadr = nextadr;
  1655                 firstadr = nextadr;
  1657             }
  1656             }
  1658             classDef = tree;
  1657             classDef = tree;
  1659             try {
  1658             try {
  1824             ListBuffer<P> prevPendingExits = pendingExits;
  1823             ListBuffer<P> prevPendingExits = pendingExits;
  1825             FlowKind prevFlowKind = flowKind;
  1824             FlowKind prevFlowKind = flowKind;
  1826             flowKind = FlowKind.NORMAL;
  1825             flowKind = FlowKind.NORMAL;
  1827             final Bits initsSkip = new Bits(true);
  1826             final Bits initsSkip = new Bits(true);
  1828             final Bits uninitsSkip = new Bits(true);
  1827             final Bits uninitsSkip = new Bits(true);
  1829             pendingExits = new ListBuffer<P>();
  1828             pendingExits = new ListBuffer<>();
  1830             int prevErrors = getLogNumberOfErrors();
  1829             int prevErrors = getLogNumberOfErrors();
  1831             do {
  1830             do {
  1832                 final Bits uninitsEntry = new Bits(uninits);
  1831                 final Bits uninitsEntry = new Bits(uninits);
  1833                 uninitsEntry.excludeFrom(nextadr);
  1832                 uninitsEntry.excludeFrom(nextadr);
  1834                 scan(tree.body);
  1833                 scan(tree.body);
  1894             flowKind = FlowKind.NORMAL;
  1893             flowKind = FlowKind.NORMAL;
  1895             int nextadrPrev = nextadr;
  1894             int nextadrPrev = nextadr;
  1896             scan(tree.init);
  1895             scan(tree.init);
  1897             final Bits initsSkip = new Bits(true);
  1896             final Bits initsSkip = new Bits(true);
  1898             final Bits uninitsSkip = new Bits(true);
  1897             final Bits uninitsSkip = new Bits(true);
  1899             pendingExits = new ListBuffer<P>();
  1898             pendingExits = new ListBuffer<>();
  1900             int prevErrors = getLogNumberOfErrors();
  1899             int prevErrors = getLogNumberOfErrors();
  1901             do {
  1900             do {
  1902                 final Bits uninitsEntry = new Bits(uninits);
  1901                 final Bits uninitsEntry = new Bits(uninits);
  1903                 uninitsEntry.excludeFrom(nextadr);
  1902                 uninitsEntry.excludeFrom(nextadr);
  1904                 if (tree.cond != null) {
  1903                 if (tree.cond != null) {
  1944             scan(tree.expr);
  1943             scan(tree.expr);
  1945             final Bits initsStart = new Bits(inits);
  1944             final Bits initsStart = new Bits(inits);
  1946             final Bits uninitsStart = new Bits(uninits);
  1945             final Bits uninitsStart = new Bits(uninits);
  1947 
  1946 
  1948             letInit(tree.pos(), tree.var.sym);
  1947             letInit(tree.pos(), tree.var.sym);
  1949             pendingExits = new ListBuffer<P>();
  1948             pendingExits = new ListBuffer<>();
  1950             int prevErrors = getLogNumberOfErrors();
  1949             int prevErrors = getLogNumberOfErrors();
  1951             do {
  1950             do {
  1952                 final Bits uninitsEntry = new Bits(uninits);
  1951                 final Bits uninitsEntry = new Bits(uninits);
  1953                 uninitsEntry.excludeFrom(nextadr);
  1952                 uninitsEntry.excludeFrom(nextadr);
  1954                 scan(tree.body);
  1953                 scan(tree.body);
  1967             nextadr = nextadrPrev;
  1966             nextadr = nextadrPrev;
  1968         }
  1967         }
  1969 
  1968 
  1970         public void visitLabelled(JCLabeledStatement tree) {
  1969         public void visitLabelled(JCLabeledStatement tree) {
  1971             ListBuffer<P> prevPendingExits = pendingExits;
  1970             ListBuffer<P> prevPendingExits = pendingExits;
  1972             pendingExits = new ListBuffer<P>();
  1971             pendingExits = new ListBuffer<>();
  1973             scan(tree.body);
  1972             scan(tree.body);
  1974             resolveBreaks(tree, prevPendingExits);
  1973             resolveBreaks(tree, prevPendingExits);
  1975         }
  1974         }
  1976 
  1975 
  1977         public void visitSwitch(JCSwitch tree) {
  1976         public void visitSwitch(JCSwitch tree) {
  2217             final Bits prevInits = new Bits(inits);
  2216             final Bits prevInits = new Bits(inits);
  2218             int returnadrPrev = returnadr;
  2217             int returnadrPrev = returnadr;
  2219             ListBuffer<P> prevPending = pendingExits;
  2218             ListBuffer<P> prevPending = pendingExits;
  2220             try {
  2219             try {
  2221                 returnadr = nextadr;
  2220                 returnadr = nextadr;
  2222                 pendingExits = new ListBuffer<P>();
  2221                 pendingExits = new ListBuffer<>();
  2223                 for (List<JCVariableDecl> l = tree.params; l.nonEmpty(); l = l.tail) {
  2222                 for (List<JCVariableDecl> l = tree.params; l.nonEmpty(); l = l.tail) {
  2224                     JCVariableDecl def = l.head;
  2223                     JCVariableDecl def = l.head;
  2225                     scan(def);
  2224                     scan(def);
  2226                     inits.incl(def.sym.adr);
  2225                     inits.incl(def.sym.adr);
  2227                     uninits.excl(def.sym.adr);
  2226                     uninits.excl(def.sym.adr);
  2674         }
  2673         }
  2675         public void analyzeTree(Env<AttrContext> env, JCTree tree, TreeMaker make) {
  2674         public void analyzeTree(Env<AttrContext> env, JCTree tree, TreeMaker make) {
  2676             try {
  2675             try {
  2677                 attrEnv = env;
  2676                 attrEnv = env;
  2678                 Flow.this.make = make;
  2677                 Flow.this.make = make;
  2679                 pendingExits = new ListBuffer<PendingExit>();
  2678                 pendingExits = new ListBuffer<>();
  2680                 scan(tree);
  2679                 scan(tree);
  2681             } finally {
  2680             } finally {
  2682                 pendingExits = null;
  2681                 pendingExits = null;
  2683                 Flow.this.make = null;
  2682                 Flow.this.make = null;
  2684             }
  2683             }