langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java
changeset 29054 310b8028d7df
parent 27844 8b5d79870a2f
child 31003 c4c8cbd9b3b4
equal deleted inserted replaced
29053:5c1f1d6b40f6 29054:310b8028d7df
     1 /*
     1 /*
     2  * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
     2  * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.  Oracle designates this
     7  * published by the Free Software Foundation.  Oracle designates this
   351 
   351 
   352             PendingExit(JCTree tree) {
   352             PendingExit(JCTree tree) {
   353                 this.tree = tree;
   353                 this.tree = tree;
   354             }
   354             }
   355 
   355 
   356             void resolveJump(JCTree tree) {
   356             void resolveJump() {
   357                 //do nothing
   357                 //do nothing
   358             }
   358             }
   359         }
   359         }
   360 
   360 
   361         abstract void markDead(JCTree tree);
   361         abstract void markDead();
   362 
   362 
   363         /** Record an outward transfer of control. */
   363         /** Record an outward transfer of control. */
   364         void recordExit(JCTree tree, P pe) {
   364         void recordExit(P pe) {
   365             pendingExits.append(pe);
   365             pendingExits.append(pe);
   366             markDead(tree);
   366             markDead();
   367         }
   367         }
   368 
   368 
   369         /** Resolve all jumps of this statement. */
   369         /** Resolve all jumps of this statement. */
   370         private boolean resolveJump(JCTree tree,
   370         private boolean resolveJump(JCTree tree,
   371                         ListBuffer<P> oldPendingExits,
   371                         ListBuffer<P> oldPendingExits,
   375             pendingExits = oldPendingExits;
   375             pendingExits = oldPendingExits;
   376             for (; exits.nonEmpty(); exits = exits.tail) {
   376             for (; exits.nonEmpty(); exits = exits.tail) {
   377                 P exit = exits.head;
   377                 P exit = exits.head;
   378                 if (exit.tree.hasTag(jk.treeTag) &&
   378                 if (exit.tree.hasTag(jk.treeTag) &&
   379                         jk.getTarget(exit.tree) == tree) {
   379                         jk.getTarget(exit.tree) == tree) {
   380                     exit.resolveJump(tree);
   380                     exit.resolveJump();
   381                     resolved = true;
   381                     resolved = true;
   382                 } else {
   382                 } else {
   383                     pendingExits.append(exit);
   383                     pendingExits.append(exit);
   384                 }
   384                 }
   385             }
   385             }
   422          *  complete normally.
   422          *  complete normally.
   423          */
   423          */
   424         private boolean alive;
   424         private boolean alive;
   425 
   425 
   426         @Override
   426         @Override
   427         void markDead(JCTree tree) {
   427         void markDead() {
   428             alive = false;
   428             alive = false;
   429         }
   429         }
   430 
   430 
   431     /*************************************************************************
   431     /*************************************************************************
   432      * Visitor methods for statements and definitions
   432      * Visitor methods for statements and definitions
   690                 alive = true;
   690                 alive = true;
   691             }
   691             }
   692         }
   692         }
   693 
   693 
   694         public void visitBreak(JCBreak tree) {
   694         public void visitBreak(JCBreak tree) {
   695             recordExit(tree, new PendingExit(tree));
   695             recordExit(new PendingExit(tree));
   696         }
   696         }
   697 
   697 
   698         public void visitContinue(JCContinue tree) {
   698         public void visitContinue(JCContinue tree) {
   699             recordExit(tree, new PendingExit(tree));
   699             recordExit(new PendingExit(tree));
   700         }
   700         }
   701 
   701 
   702         public void visitReturn(JCReturn tree) {
   702         public void visitReturn(JCReturn tree) {
   703             scan(tree.expr);
   703             scan(tree.expr);
   704             recordExit(tree, new PendingExit(tree));
   704             recordExit(new PendingExit(tree));
   705         }
   705         }
   706 
   706 
   707         public void visitThrow(JCThrow tree) {
   707         public void visitThrow(JCThrow tree) {
   708             scan(tree.expr);
   708             scan(tree.expr);
   709             markDead(tree);
   709             markDead();
   710         }
   710         }
   711 
   711 
   712         public void visitApply(JCMethodInvocation tree) {
   712         public void visitApply(JCMethodInvocation tree) {
   713             scan(tree.meth);
   713             scan(tree.meth);
   714             scan(tree.args);
   714             scan(tree.args);
   801                 this.thrown = thrown;
   801                 this.thrown = thrown;
   802             }
   802             }
   803         }
   803         }
   804 
   804 
   805         @Override
   805         @Override
   806         void markDead(JCTree tree) {
   806         void markDead() {
   807             //do nothing
   807             //do nothing
   808         }
   808         }
   809 
   809 
   810         /*-------------------- Exceptions ----------------------*/
   810         /*-------------------- Exceptions ----------------------*/
   811 
   811 
  1199                 return exc.tsym == syms.throwableType.tsym ||
  1199                 return exc.tsym == syms.throwableType.tsym ||
  1200                     exc.tsym == syms.exceptionType.tsym;
  1200                     exc.tsym == syms.exceptionType.tsym;
  1201             }
  1201             }
  1202 
  1202 
  1203         public void visitBreak(JCBreak tree) {
  1203         public void visitBreak(JCBreak tree) {
  1204             recordExit(tree, new FlowPendingExit(tree, null));
  1204             recordExit(new FlowPendingExit(tree, null));
  1205         }
  1205         }
  1206 
  1206 
  1207         public void visitContinue(JCContinue tree) {
  1207         public void visitContinue(JCContinue tree) {
  1208             recordExit(tree, new FlowPendingExit(tree, null));
  1208             recordExit(new FlowPendingExit(tree, null));
  1209         }
  1209         }
  1210 
  1210 
  1211         public void visitReturn(JCReturn tree) {
  1211         public void visitReturn(JCReturn tree) {
  1212             scan(tree.expr);
  1212             scan(tree.expr);
  1213             recordExit(tree, new FlowPendingExit(tree, null));
  1213             recordExit(new FlowPendingExit(tree, null));
  1214         }
  1214         }
  1215 
  1215 
  1216         public void visitThrow(JCThrow tree) {
  1216         public void visitThrow(JCThrow tree) {
  1217             scan(tree.expr);
  1217             scan(tree.expr);
  1218             Symbol sym = TreeInfo.symbol(tree.expr);
  1218             Symbol sym = TreeInfo.symbol(tree.expr);
  1226                 }
  1226                 }
  1227             }
  1227             }
  1228             else {
  1228             else {
  1229                 markThrown(tree, tree.expr.type);
  1229                 markThrown(tree, tree.expr.type);
  1230             }
  1230             }
  1231             markDead(tree);
  1231             markDead();
  1232         }
  1232         }
  1233 
  1233 
  1234         public void visitApply(JCMethodInvocation tree) {
  1234         public void visitApply(JCMethodInvocation tree) {
  1235             scan(tree.meth);
  1235             scan(tree.meth);
  1236             scan(tree.args);
  1236             scan(tree.args);
  1373      * which ensures that no final variable is assigned more than once. This visitor
  1373      * which ensures that no final variable is assigned more than once. This visitor
  1374      * depends on the results of the liveliness analyzer. This pass is also used to mark
  1374      * depends on the results of the liveliness analyzer. This pass is also used to mark
  1375      * effectively-final local variables/parameters.
  1375      * effectively-final local variables/parameters.
  1376      */
  1376      */
  1377 
  1377 
  1378     public abstract class AbstractAssignAnalyzer<P extends AbstractAssignAnalyzer<P>.AbstractAssignPendingExit>
  1378     public class AssignAnalyzer extends BaseAnalyzer<AssignAnalyzer.AssignPendingExit> {
  1379         extends BaseAnalyzer<P> {
       
  1380 
  1379 
  1381         /** The set of definitely assigned variables.
  1380         /** The set of definitely assigned variables.
  1382          */
  1381          */
  1383         protected Bits inits;
  1382         final Bits inits;
  1384 
  1383 
  1385         /** The set of definitely unassigned variables.
  1384         /** The set of definitely unassigned variables.
  1386          */
  1385          */
  1387         final Bits uninits;
  1386         final Bits uninits;
  1388 
  1387 
  1426 
  1425 
  1427         /** The list of unreferenced automatic resources.
  1426         /** The list of unreferenced automatic resources.
  1428          */
  1427          */
  1429         WriteableScope unrefdResources;
  1428         WriteableScope unrefdResources;
  1430 
  1429 
  1431         /** Set when processing a loop body the second time for DU analysis. */
  1430         /** Modified when processing a loop body the second time for DU analysis. */
  1432         FlowKind flowKind = FlowKind.NORMAL;
  1431         FlowKind flowKind = FlowKind.NORMAL;
  1433 
  1432 
  1434         /** The starting position of the analysed tree */
  1433         /** The starting position of the analyzed tree */
  1435         int startPos;
  1434         int startPos;
  1436 
  1435 
  1437         public class AbstractAssignPendingExit extends BaseAnalyzer.PendingExit {
  1436         public class AssignPendingExit extends BaseAnalyzer.PendingExit {
  1438 
  1437 
  1439             final Bits inits;
  1438             final Bits inits;
  1440             final Bits uninits;
  1439             final Bits uninits;
  1441             final Bits exit_inits = new Bits(true);
  1440             final Bits exit_inits = new Bits(true);
  1442             final Bits exit_uninits = new Bits(true);
  1441             final Bits exit_uninits = new Bits(true);
  1443 
  1442 
  1444             public AbstractAssignPendingExit(JCTree tree, final Bits inits, final Bits uninits) {
  1443             public AssignPendingExit(JCTree tree, final Bits inits, final Bits uninits) {
  1445                 super(tree);
  1444                 super(tree);
  1446                 this.inits = inits;
  1445                 this.inits = inits;
  1447                 this.uninits = uninits;
  1446                 this.uninits = uninits;
  1448                 this.exit_inits.assign(inits);
  1447                 this.exit_inits.assign(inits);
  1449                 this.exit_uninits.assign(uninits);
  1448                 this.exit_uninits.assign(uninits);
  1450             }
  1449             }
  1451 
  1450 
  1452             @Override
  1451             @Override
  1453             public void resolveJump(JCTree tree) {
  1452             public void resolveJump() {
  1454                 inits.andSet(exit_inits);
  1453                 inits.andSet(exit_inits);
  1455                 uninits.andSet(exit_uninits);
  1454                 uninits.andSet(exit_uninits);
  1456             }
  1455             }
  1457         }
  1456         }
  1458 
  1457 
  1459         public AbstractAssignAnalyzer() {
  1458         public AssignAnalyzer() {
  1460             this.inits = new Bits();
  1459             this.inits = new Bits();
  1461             uninits = new Bits();
  1460             uninits = new Bits();
  1462             uninitsTry = new Bits();
  1461             uninitsTry = new Bits();
  1463             initsWhenTrue = new Bits(true);
  1462             initsWhenTrue = new Bits(true);
  1464             initsWhenFalse = new Bits(true);
  1463             initsWhenFalse = new Bits(true);
  1467         }
  1466         }
  1468 
  1467 
  1469         private boolean isInitialConstructor = false;
  1468         private boolean isInitialConstructor = false;
  1470 
  1469 
  1471         @Override
  1470         @Override
  1472         protected void markDead(JCTree tree) {
  1471         protected void markDead() {
  1473             if (!isInitialConstructor) {
  1472             if (!isInitialConstructor) {
  1474                 inits.inclRange(returnadr, nextadr);
  1473                 inits.inclRange(returnadr, nextadr);
  1475             } else {
  1474             } else {
  1476                 for (int address = returnadr; address < nextadr; address++) {
  1475                 for (int address = returnadr; address < nextadr; address++) {
  1477                     if (!(isFinalUninitializedStaticField(vardecls[address].sym))) {
  1476                     if (!(isFinalUninitializedStaticField(vardecls[address].sym))) {
  1514             if ((sym.flags() & FINAL) == 0) {
  1513             if ((sym.flags() & FINAL) == 0) {
  1515                 sym.flags_field |= EFFECTIVELY_FINAL;
  1514                 sym.flags_field |= EFFECTIVELY_FINAL;
  1516             }
  1515             }
  1517             sym.adr = nextadr;
  1516             sym.adr = nextadr;
  1518             vardecls[nextadr] = varDecl;
  1517             vardecls[nextadr] = varDecl;
  1519             exclVarFromInits(varDecl, nextadr);
  1518             inits.excl(nextadr);
  1520             uninits.incl(nextadr);
  1519             uninits.incl(nextadr);
  1521             nextadr++;
  1520             nextadr++;
  1522         }
  1521         }
  1523 
  1522 
  1524         protected void exclVarFromInits(JCTree tree, int adr) {
       
  1525             inits.excl(adr);
       
  1526         }
       
  1527 
       
  1528         protected void assignToInits(JCTree tree, Bits bits) {
       
  1529             inits.assign(bits);
       
  1530         }
       
  1531 
       
  1532         protected void andSetInits(JCTree tree, Bits bits) {
       
  1533             inits.andSet(bits);
       
  1534         }
       
  1535 
       
  1536         protected void orSetInits(JCTree tree, Bits bits) {
       
  1537             inits.orSet(bits);
       
  1538         }
       
  1539 
       
  1540         /** Record an initialization of a trackable variable.
  1523         /** Record an initialization of a trackable variable.
  1541          */
  1524          */
  1542         void letInit(DiagnosticPosition pos, VarSymbol sym) {
  1525         void letInit(DiagnosticPosition pos, VarSymbol sym) {
  1543             if (sym.adr >= firstadr && trackable(sym)) {
  1526             if (sym.adr >= firstadr && trackable(sym)) {
  1544                 if (uninits.isMember(sym.adr)) {
  1527                 if ((sym.flags() & EFFECTIVELY_FINAL) != 0) {
  1545                     uninit(sym);
  1528                     if (!uninits.isMember(sym.adr)) {
       
  1529                         //assignment targeting an effectively final variable
       
  1530                         //makes the variable lose its status of effectively final
       
  1531                         //if the variable is _not_ definitively unassigned
       
  1532                         sym.flags_field &= ~EFFECTIVELY_FINAL;
       
  1533                     } else {
       
  1534                         uninit(sym);
       
  1535                     }
       
  1536                 }
       
  1537                 else if ((sym.flags() & FINAL) != 0) {
       
  1538                     if ((sym.flags() & PARAMETER) != 0) {
       
  1539                         if ((sym.flags() & UNION) != 0) { //multi-catch parameter
       
  1540                             log.error(pos, "multicatch.parameter.may.not.be.assigned", sym);
       
  1541                         }
       
  1542                         else {
       
  1543                             log.error(pos, "final.parameter.may.not.be.assigned",
       
  1544                                   sym);
       
  1545                         }
       
  1546                     } else if (!uninits.isMember(sym.adr)) {
       
  1547                         log.error(pos, flowKind.errKey, sym);
       
  1548                     } else {
       
  1549                         uninit(sym);
       
  1550                     }
  1546                 }
  1551                 }
  1547                 inits.incl(sym.adr);
  1552                 inits.incl(sym.adr);
       
  1553             } else if ((sym.flags() & FINAL) != 0) {
       
  1554                 log.error(pos, "var.might.already.be.assigned", sym);
  1548             }
  1555             }
  1549         }
  1556         }
  1550         //where
  1557         //where
  1551             void uninit(VarSymbol sym) {
  1558             void uninit(VarSymbol sym) {
  1552                 if (!inits.isMember(sym.adr)) {
  1559                 if (!inits.isMember(sym.adr)) {
  1577          */
  1584          */
  1578         void checkInit(DiagnosticPosition pos, VarSymbol sym) {
  1585         void checkInit(DiagnosticPosition pos, VarSymbol sym) {
  1579             checkInit(pos, sym, "var.might.not.have.been.initialized");
  1586             checkInit(pos, sym, "var.might.not.have.been.initialized");
  1580         }
  1587         }
  1581 
  1588 
  1582         void checkInit(DiagnosticPosition pos, VarSymbol sym, String errkey) {}
  1589         void checkInit(DiagnosticPosition pos, VarSymbol sym, String errkey) {
       
  1590             if ((sym.adr >= firstadr || sym.owner.kind != TYP) &&
       
  1591                 trackable(sym) &&
       
  1592                 !inits.isMember(sym.adr)) {
       
  1593                 log.error(pos, errkey, sym);
       
  1594                 inits.incl(sym.adr);
       
  1595             }
       
  1596         }
  1583 
  1597 
  1584         /** Utility method to reset several Bits instances.
  1598         /** Utility method to reset several Bits instances.
  1585          */
  1599          */
  1586         private void resetBits(Bits... bits) {
  1600         private void resetBits(Bits... bits) {
  1587             for (Bits b : bits) {
  1601             for (Bits b : bits) {
  1601             }
  1615             }
  1602         }
  1616         }
  1603 
  1617 
  1604         /** Merge (intersect) inits/uninits from WhenTrue/WhenFalse sets.
  1618         /** Merge (intersect) inits/uninits from WhenTrue/WhenFalse sets.
  1605          */
  1619          */
  1606         protected void merge(JCTree tree) {
  1620         protected void merge() {
  1607             inits.assign(initsWhenFalse.andSet(initsWhenTrue));
  1621             inits.assign(initsWhenFalse.andSet(initsWhenTrue));
  1608             uninits.assign(uninitsWhenFalse.andSet(uninitsWhenTrue));
  1622             uninits.assign(uninitsWhenFalse.andSet(uninitsWhenTrue));
  1609         }
  1623         }
  1610 
  1624 
  1611     /* ************************************************************************
  1625     /* ************************************************************************
  1617          */
  1631          */
  1618         void scanExpr(JCTree tree) {
  1632         void scanExpr(JCTree tree) {
  1619             if (tree != null) {
  1633             if (tree != null) {
  1620                 scan(tree);
  1634                 scan(tree);
  1621                 if (inits.isReset()) {
  1635                 if (inits.isReset()) {
  1622                     merge(tree);
  1636                     merge();
  1623                 }
  1637                 }
  1624             }
  1638             }
  1625         }
  1639         }
  1626 
  1640 
  1627         /** Analyze a list of expressions.
  1641         /** Analyze a list of expressions.
  1635         /** Analyze a condition. Make sure to set (un)initsWhenTrue(WhenFalse)
  1649         /** Analyze a condition. Make sure to set (un)initsWhenTrue(WhenFalse)
  1636          *  rather than (un)inits on exit.
  1650          *  rather than (un)inits on exit.
  1637          */
  1651          */
  1638         void scanCond(JCTree tree) {
  1652         void scanCond(JCTree tree) {
  1639             if (tree.type.isFalse()) {
  1653             if (tree.type.isFalse()) {
  1640                 if (inits.isReset()) merge(tree);
  1654                 if (inits.isReset()) merge();
  1641                 initsWhenTrue.assign(inits);
  1655                 initsWhenTrue.assign(inits);
  1642                 initsWhenTrue.inclRange(firstadr, nextadr);
  1656                 initsWhenTrue.inclRange(firstadr, nextadr);
  1643                 uninitsWhenTrue.assign(uninits);
  1657                 uninitsWhenTrue.assign(uninits);
  1644                 uninitsWhenTrue.inclRange(firstadr, nextadr);
  1658                 uninitsWhenTrue.inclRange(firstadr, nextadr);
  1645                 initsWhenFalse.assign(inits);
  1659                 initsWhenFalse.assign(inits);
  1646                 uninitsWhenFalse.assign(uninits);
  1660                 uninitsWhenFalse.assign(uninits);
  1647             } else if (tree.type.isTrue()) {
  1661             } else if (tree.type.isTrue()) {
  1648                 if (inits.isReset()) merge(tree);
  1662                 if (inits.isReset()) merge();
  1649                 initsWhenFalse.assign(inits);
  1663                 initsWhenFalse.assign(inits);
  1650                 initsWhenFalse.inclRange(firstadr, nextadr);
  1664                 initsWhenFalse.inclRange(firstadr, nextadr);
  1651                 uninitsWhenFalse.assign(uninits);
  1665                 uninitsWhenFalse.assign(uninits);
  1652                 uninitsWhenFalse.inclRange(firstadr, nextadr);
  1666                 uninitsWhenFalse.inclRange(firstadr, nextadr);
  1653                 initsWhenTrue.assign(inits);
  1667                 initsWhenTrue.assign(inits);
  1662             }
  1676             }
  1663         }
  1677         }
  1664 
  1678 
  1665         /* ------------ Visitor methods for various sorts of trees -------------*/
  1679         /* ------------ Visitor methods for various sorts of trees -------------*/
  1666 
  1680 
  1667         @Override
       
  1668         public void visitClassDef(JCClassDecl tree) {
  1681         public void visitClassDef(JCClassDecl tree) {
  1669             if (tree.sym == null) {
  1682             if (tree.sym == null) {
  1670                 return;
  1683                 return;
  1671             }
  1684             }
  1672 
  1685 
  1673             JCClassDecl classDefPrev = classDef;
  1686             Lint lintPrev = lint;
  1674             int firstadrPrev = firstadr;
  1687             lint = lint.augment(tree.sym);
  1675             int nextadrPrev = nextadr;
       
  1676             ListBuffer<P> pendingExitsPrev = pendingExits;
       
  1677 
       
  1678             pendingExits = new ListBuffer<>();
       
  1679             if (tree.name != names.empty) {
       
  1680                 firstadr = nextadr;
       
  1681             }
       
  1682             classDef = tree;
       
  1683             try {
  1688             try {
  1684                 // define all the static fields
  1689                 if (tree.sym == null) {
  1685                 for (List<JCTree> l = tree.defs; l.nonEmpty(); l = l.tail) {
  1690                     return;
  1686                     if (l.head.hasTag(VARDEF)) {
  1691                 }
  1687                         JCVariableDecl def = (JCVariableDecl)l.head;
  1692 
  1688                         if ((def.mods.flags & STATIC) != 0) {
  1693                 JCClassDecl classDefPrev = classDef;
  1689                             VarSymbol sym = def.sym;
  1694                 int firstadrPrev = firstadr;
  1690                             if (trackable(sym)) {
  1695                 int nextadrPrev = nextadr;
  1691                                 newVar(def);
  1696                 ListBuffer<AssignPendingExit> pendingExitsPrev = pendingExits;
       
  1697 
       
  1698                 pendingExits = new ListBuffer<>();
       
  1699                 if (tree.name != names.empty) {
       
  1700                     firstadr = nextadr;
       
  1701                 }
       
  1702                 classDef = tree;
       
  1703                 try {
       
  1704                     // define all the static fields
       
  1705                     for (List<JCTree> l = tree.defs; l.nonEmpty(); l = l.tail) {
       
  1706                         if (l.head.hasTag(VARDEF)) {
       
  1707                             JCVariableDecl def = (JCVariableDecl)l.head;
       
  1708                             if ((def.mods.flags & STATIC) != 0) {
       
  1709                                 VarSymbol sym = def.sym;
       
  1710                                 if (trackable(sym)) {
       
  1711                                     newVar(def);
       
  1712                                 }
  1692                             }
  1713                             }
  1693                         }
  1714                         }
  1694                     }
  1715                     }
  1695                 }
  1716 
  1696 
  1717                     // process all the static initializers
  1697                 // process all the static initializers
  1718                     for (List<JCTree> l = tree.defs; l.nonEmpty(); l = l.tail) {
  1698                 for (List<JCTree> l = tree.defs; l.nonEmpty(); l = l.tail) {
  1719                         if (!l.head.hasTag(METHODDEF) &&
  1699                     if (!l.head.hasTag(METHODDEF) &&
  1720                             (TreeInfo.flags(l.head) & STATIC) != 0) {
  1700                         (TreeInfo.flags(l.head) & STATIC) != 0) {
  1721                             scan(l.head);
  1701                         scan(l.head);
  1722                         }
  1702                     }
  1723                     }
  1703                 }
  1724 
  1704 
  1725                     // define all the instance fields
  1705                 // define all the instance fields
  1726                     for (List<JCTree> l = tree.defs; l.nonEmpty(); l = l.tail) {
  1706                 for (List<JCTree> l = tree.defs; l.nonEmpty(); l = l.tail) {
  1727                         if (l.head.hasTag(VARDEF)) {
  1707                     if (l.head.hasTag(VARDEF)) {
  1728                             JCVariableDecl def = (JCVariableDecl)l.head;
  1708                         JCVariableDecl def = (JCVariableDecl)l.head;
  1729                             if ((def.mods.flags & STATIC) == 0) {
  1709                         if ((def.mods.flags & STATIC) == 0) {
  1730                                 VarSymbol sym = def.sym;
  1710                             VarSymbol sym = def.sym;
  1731                                 if (trackable(sym)) {
  1711                             if (trackable(sym)) {
  1732                                     newVar(def);
  1712                                 newVar(def);
  1733                                 }
  1713                             }
  1734                             }
  1714                         }
  1735                         }
  1715                     }
  1736                     }
  1716                 }
  1737 
  1717 
  1738                     // process all the instance initializers
  1718                 // process all the instance initializers
  1739                     for (List<JCTree> l = tree.defs; l.nonEmpty(); l = l.tail) {
  1719                 for (List<JCTree> l = tree.defs; l.nonEmpty(); l = l.tail) {
  1740                         if (!l.head.hasTag(METHODDEF) &&
  1720                     if (!l.head.hasTag(METHODDEF) &&
  1741                             (TreeInfo.flags(l.head) & STATIC) == 0) {
  1721                         (TreeInfo.flags(l.head) & STATIC) == 0) {
  1742                             scan(l.head);
  1722                         scan(l.head);
  1743                         }
  1723                     }
  1744                     }
  1724                 }
  1745 
  1725 
  1746                     // process all the methods
  1726                 // process all the methods
  1747                     for (List<JCTree> l = tree.defs; l.nonEmpty(); l = l.tail) {
  1727                 for (List<JCTree> l = tree.defs; l.nonEmpty(); l = l.tail) {
  1748                         if (l.head.hasTag(METHODDEF)) {
  1728                     if (l.head.hasTag(METHODDEF)) {
  1749                             scan(l.head);
  1729                         scan(l.head);
  1750                         }
  1730                     }
  1751                     }
       
  1752                 } finally {
       
  1753                     pendingExits = pendingExitsPrev;
       
  1754                     nextadr = nextadrPrev;
       
  1755                     firstadr = firstadrPrev;
       
  1756                     classDef = classDefPrev;
  1731                 }
  1757                 }
  1732             } finally {
  1758             } finally {
  1733                 pendingExits = pendingExitsPrev;
  1759                 lint = lintPrev;
  1734                 nextadr = nextadrPrev;
  1760             }
  1735                 firstadr = firstadrPrev;
  1761         }
  1736                 classDef = classDefPrev;
  1762 
  1737             }
       
  1738         }
       
  1739 
       
  1740         @Override
       
  1741         public void visitMethodDef(JCMethodDecl tree) {
  1763         public void visitMethodDef(JCMethodDecl tree) {
  1742             if (tree.body == null) {
  1764             if (tree.body == null) {
  1743                 return;
  1765                 return;
  1744             }
  1766             }
  1745             /*  Ignore synthetic methods, except for translated lambda methods.
  1767 
       
  1768             /*  MemberEnter can generate synthetic methods ignore them
  1746              */
  1769              */
  1747             if ((tree.sym.flags() & (SYNTHETIC | LAMBDA_METHOD)) == SYNTHETIC) {
  1770             if ((tree.sym.flags() & SYNTHETIC) != 0) {
  1748                 return;
  1771                 return;
  1749             }
  1772             }
  1750 
  1773 
  1751             final Bits initsPrev = new Bits(inits);
  1774             Lint lintPrev = lint;
  1752             final Bits uninitsPrev = new Bits(uninits);
  1775             lint = lint.augment(tree.sym);
  1753             int nextadrPrev = nextadr;
       
  1754             int firstadrPrev = firstadr;
       
  1755             int returnadrPrev = returnadr;
       
  1756 
       
  1757             Assert.check(pendingExits.isEmpty());
       
  1758             boolean lastInitialConstructor = isInitialConstructor;
       
  1759             try {
  1776             try {
  1760                 isInitialConstructor = TreeInfo.isInitialConstructor(tree);
  1777                 if (tree.body == null) {
  1761 
  1778                     return;
  1762                 if (!isInitialConstructor) {
  1779                 }
  1763                     firstadr = nextadr;
  1780                 /*  Ignore synthetic methods, except for translated lambda methods.
  1764                 }
  1781                  */
  1765                 for (List<JCVariableDecl> l = tree.params; l.nonEmpty(); l = l.tail) {
  1782                 if ((tree.sym.flags() & (SYNTHETIC | LAMBDA_METHOD)) == SYNTHETIC) {
  1766                     JCVariableDecl def = l.head;
  1783                     return;
  1767                     scan(def);
  1784                 }
  1768                     Assert.check((def.sym.flags() & PARAMETER) != 0, "Method parameter without PARAMETER flag");
  1785 
  1769                     /*  If we are executing the code from Gen, then there can be
  1786                 final Bits initsPrev = new Bits(inits);
  1770                      *  synthetic or mandated variables, ignore them.
  1787                 final Bits uninitsPrev = new Bits(uninits);
  1771                      */
  1788                 int nextadrPrev = nextadr;
  1772                     initParam(def);
  1789                 int firstadrPrev = firstadr;
  1773                 }
  1790                 int returnadrPrev = returnadr;
  1774                 // else we are in an instance initializer block;
  1791 
  1775                 // leave caught unchanged.
  1792                 Assert.check(pendingExits.isEmpty());
  1776                 scan(tree.body);
  1793                 boolean lastInitialConstructor = isInitialConstructor;
  1777 
  1794                 try {
  1778                 if (isInitialConstructor) {
  1795                     isInitialConstructor = TreeInfo.isInitialConstructor(tree);
  1779                     boolean isSynthesized = (tree.sym.flags() &
  1796 
  1780                                              GENERATEDCONSTR) != 0;
  1797                     if (!isInitialConstructor) {
  1781                     for (int i = firstadr; i < nextadr; i++) {
  1798                         firstadr = nextadr;
  1782                         JCVariableDecl vardecl = vardecls[i];
  1799                     }
  1783                         VarSymbol var = vardecl.sym;
  1800                     for (List<JCVariableDecl> l = tree.params; l.nonEmpty(); l = l.tail) {
  1784                         if (var.owner == classDef.sym) {
  1801                         JCVariableDecl def = l.head;
  1785                             // choose the diagnostic position based on whether
  1802                         scan(def);
  1786                             // the ctor is default(synthesized) or not
  1803                         Assert.check((def.sym.flags() & PARAMETER) != 0, "Method parameter without PARAMETER flag");
  1787                             if (isSynthesized) {
  1804                         /*  If we are executing the code from Gen, then there can be
  1788                                 checkInit(TreeInfo.diagnosticPositionFor(var, vardecl),
  1805                          *  synthetic or mandated variables, ignore them.
  1789                                     var, "var.not.initialized.in.default.constructor");
  1806                          */
  1790                             } else {
  1807                         initParam(def);
  1791                                 checkInit(TreeInfo.diagEndPos(tree.body), var);
  1808                     }
       
  1809                     // else we are in an instance initializer block;
       
  1810                     // leave caught unchanged.
       
  1811                     scan(tree.body);
       
  1812 
       
  1813                     if (isInitialConstructor) {
       
  1814                         boolean isSynthesized = (tree.sym.flags() &
       
  1815                                                  GENERATEDCONSTR) != 0;
       
  1816                         for (int i = firstadr; i < nextadr; i++) {
       
  1817                             JCVariableDecl vardecl = vardecls[i];
       
  1818                             VarSymbol var = vardecl.sym;
       
  1819                             if (var.owner == classDef.sym) {
       
  1820                                 // choose the diagnostic position based on whether
       
  1821                                 // the ctor is default(synthesized) or not
       
  1822                                 if (isSynthesized) {
       
  1823                                     checkInit(TreeInfo.diagnosticPositionFor(var, vardecl),
       
  1824                                         var, "var.not.initialized.in.default.constructor");
       
  1825                                 } else {
       
  1826                                     checkInit(TreeInfo.diagEndPos(tree.body), var);
       
  1827                                 }
  1792                             }
  1828                             }
  1793                         }
  1829                         }
  1794                     }
  1830                     }
  1795                 }
  1831                     List<AssignPendingExit> exits = pendingExits.toList();
  1796                 List<P> exits = pendingExits.toList();
  1832                     pendingExits = new ListBuffer<>();
  1797                 pendingExits = new ListBuffer<>();
  1833                     while (exits.nonEmpty()) {
  1798                 while (exits.nonEmpty()) {
  1834                         AssignPendingExit exit = exits.head;
  1799                     P exit = exits.head;
  1835                         exits = exits.tail;
  1800                     exits = exits.tail;
  1836                         Assert.check(exit.tree.hasTag(RETURN), exit.tree);
  1801                     Assert.check(exit.tree.hasTag(RETURN), exit.tree);
  1837                         if (isInitialConstructor) {
  1802                     if (isInitialConstructor) {
  1838                             inits.assign(exit.exit_inits);
  1803                         assignToInits(exit.tree, exit.exit_inits);
  1839                             for (int i = firstadr; i < nextadr; i++) {
  1804                         for (int i = firstadr; i < nextadr; i++) {
  1840                                 checkInit(exit.tree.pos(), vardecls[i].sym);
  1805                             checkInit(exit.tree.pos(), vardecls[i].sym);
  1841                             }
  1806                         }
  1842                         }
  1807                     }
  1843                     }
       
  1844                 } finally {
       
  1845                     inits.assign(initsPrev);
       
  1846                     uninits.assign(uninitsPrev);
       
  1847                     nextadr = nextadrPrev;
       
  1848                     firstadr = firstadrPrev;
       
  1849                     returnadr = returnadrPrev;
       
  1850                     isInitialConstructor = lastInitialConstructor;
  1808                 }
  1851                 }
  1809             } finally {
  1852             } finally {
  1810                 assignToInits(tree, initsPrev);
  1853                 lint = lintPrev;
  1811                 uninits.assign(uninitsPrev);
       
  1812                 nextadr = nextadrPrev;
       
  1813                 firstadr = firstadrPrev;
       
  1814                 returnadr = returnadrPrev;
       
  1815                 isInitialConstructor = lastInitialConstructor;
       
  1816             }
  1854             }
  1817         }
  1855         }
  1818 
  1856 
  1819         protected void initParam(JCVariableDecl def) {
  1857         protected void initParam(JCVariableDecl def) {
  1820             inits.incl(def.sym.adr);
  1858             inits.incl(def.sym.adr);
  1821             uninits.excl(def.sym.adr);
  1859             uninits.excl(def.sym.adr);
  1822             }
  1860         }
  1823 
  1861 
  1824         public void visitVarDef(JCVariableDecl tree) {
  1862         public void visitVarDef(JCVariableDecl tree) {
  1825             boolean track = trackable(tree.sym);
  1863             Lint lintPrev = lint;
  1826             if (track && tree.sym.owner.kind == MTH) {
  1864             lint = lint.augment(tree.sym);
  1827                 newVar(tree);
  1865             try{
  1828             }
  1866                 boolean track = trackable(tree.sym);
  1829             if (tree.init != null) {
  1867                 if (track && tree.sym.owner.kind == MTH) {
  1830                 scanExpr(tree.init);
  1868                     newVar(tree);
  1831                 if (track) {
  1869                 }
  1832                     letInit(tree.pos(), tree.sym);
  1870                 if (tree.init != null) {
  1833                 }
  1871                     scanExpr(tree.init);
       
  1872                     if (track) {
       
  1873                         letInit(tree.pos(), tree.sym);
       
  1874                     }
       
  1875                 }
       
  1876             } finally {
       
  1877                 lint = lintPrev;
  1834             }
  1878             }
  1835         }
  1879         }
  1836 
  1880 
  1837         public void visitBlock(JCBlock tree) {
  1881         public void visitBlock(JCBlock tree) {
  1838             int nextadrPrev = nextadr;
  1882             int nextadrPrev = nextadr;
  1839             scan(tree.stats);
  1883             scan(tree.stats);
  1840             nextadr = nextadrPrev;
  1884             nextadr = nextadrPrev;
  1841         }
  1885         }
  1842 
  1886 
  1843         int getLogNumberOfErrors() {
       
  1844             return 0;
       
  1845         }
       
  1846 
       
  1847         public void visitDoLoop(JCDoWhileLoop tree) {
  1887         public void visitDoLoop(JCDoWhileLoop tree) {
  1848             ListBuffer<P> prevPendingExits = pendingExits;
  1888             ListBuffer<AssignPendingExit> prevPendingExits = pendingExits;
  1849             FlowKind prevFlowKind = flowKind;
  1889             FlowKind prevFlowKind = flowKind;
  1850             flowKind = FlowKind.NORMAL;
  1890             flowKind = FlowKind.NORMAL;
  1851             final Bits initsSkip = new Bits(true);
  1891             final Bits initsSkip = new Bits(true);
  1852             final Bits uninitsSkip = new Bits(true);
  1892             final Bits uninitsSkip = new Bits(true);
  1853             pendingExits = new ListBuffer<>();
  1893             pendingExits = new ListBuffer<>();
  1854             int prevErrors = getLogNumberOfErrors();
  1894             int prevErrors = log.nerrors;
  1855             do {
  1895             do {
  1856                 final Bits uninitsEntry = new Bits(uninits);
  1896                 final Bits uninitsEntry = new Bits(uninits);
  1857                 uninitsEntry.excludeFrom(nextadr);
  1897                 uninitsEntry.excludeFrom(nextadr);
  1858                 scan(tree.body);
  1898                 scan(tree.body);
  1859                 resolveContinues(tree);
  1899                 resolveContinues(tree);
  1860                 scanCond(tree.cond);
  1900                 scanCond(tree.cond);
  1861                 if (!flowKind.isFinal()) {
  1901                 if (!flowKind.isFinal()) {
  1862                     initsSkip.assign(initsWhenFalse);
  1902                     initsSkip.assign(initsWhenFalse);
  1863                     uninitsSkip.assign(uninitsWhenFalse);
  1903                     uninitsSkip.assign(uninitsWhenFalse);
  1864                 }
  1904                 }
  1865                 if (getLogNumberOfErrors() !=  prevErrors ||
  1905                 if (log.nerrors !=  prevErrors ||
  1866                     flowKind.isFinal() ||
  1906                     flowKind.isFinal() ||
  1867                     new Bits(uninitsEntry).diffSet(uninitsWhenTrue).nextBit(firstadr)==-1)
  1907                     new Bits(uninitsEntry).diffSet(uninitsWhenTrue).nextBit(firstadr)==-1)
  1868                     break;
  1908                     break;
  1869                 assignToInits(tree.cond, initsWhenTrue);
  1909                 inits.assign(initsWhenTrue);
  1870                 uninits.assign(uninitsEntry.andSet(uninitsWhenTrue));
  1910                 uninits.assign(uninitsEntry.andSet(uninitsWhenTrue));
  1871                 flowKind = FlowKind.SPECULATIVE_LOOP;
  1911                 flowKind = FlowKind.SPECULATIVE_LOOP;
  1872             } while (true);
  1912             } while (true);
  1873             flowKind = prevFlowKind;
  1913             flowKind = prevFlowKind;
  1874             assignToInits(tree, initsSkip);
  1914             inits.assign(initsSkip);
  1875             uninits.assign(uninitsSkip);
  1915             uninits.assign(uninitsSkip);
  1876             resolveBreaks(tree, prevPendingExits);
  1916             resolveBreaks(tree, prevPendingExits);
  1877         }
  1917         }
  1878 
  1918 
  1879         public void visitWhileLoop(JCWhileLoop tree) {
  1919         public void visitWhileLoop(JCWhileLoop tree) {
  1880             ListBuffer<P> prevPendingExits = pendingExits;
  1920             ListBuffer<AssignPendingExit> prevPendingExits = pendingExits;
  1881             FlowKind prevFlowKind = flowKind;
  1921             FlowKind prevFlowKind = flowKind;
  1882             flowKind = FlowKind.NORMAL;
  1922             flowKind = FlowKind.NORMAL;
  1883             final Bits initsSkip = new Bits(true);
  1923             final Bits initsSkip = new Bits(true);
  1884             final Bits uninitsSkip = new Bits(true);
  1924             final Bits uninitsSkip = new Bits(true);
  1885             pendingExits = new ListBuffer<>();
  1925             pendingExits = new ListBuffer<>();
  1886             int prevErrors = getLogNumberOfErrors();
  1926             int prevErrors = log.nerrors;
  1887             final Bits uninitsEntry = new Bits(uninits);
  1927             final Bits uninitsEntry = new Bits(uninits);
  1888             uninitsEntry.excludeFrom(nextadr);
  1928             uninitsEntry.excludeFrom(nextadr);
  1889             do {
  1929             do {
  1890                 scanCond(tree.cond);
  1930                 scanCond(tree.cond);
  1891                 if (!flowKind.isFinal()) {
  1931                 if (!flowKind.isFinal()) {
  1892                     initsSkip.assign(initsWhenFalse) ;
  1932                     initsSkip.assign(initsWhenFalse) ;
  1893                     uninitsSkip.assign(uninitsWhenFalse);
  1933                     uninitsSkip.assign(uninitsWhenFalse);
  1894                 }
  1934                 }
  1895                 assignToInits(tree, initsWhenTrue);
  1935                 inits.assign(initsWhenTrue);
  1896                 uninits.assign(uninitsWhenTrue);
  1936                 uninits.assign(uninitsWhenTrue);
  1897                 scan(tree.body);
  1937                 scan(tree.body);
  1898                 resolveContinues(tree);
  1938                 resolveContinues(tree);
  1899                 if (getLogNumberOfErrors() != prevErrors ||
  1939                 if (log.nerrors != prevErrors ||
  1900                     flowKind.isFinal() ||
  1940                     flowKind.isFinal() ||
  1901                     new Bits(uninitsEntry).diffSet(uninits).nextBit(firstadr) == -1) {
  1941                     new Bits(uninitsEntry).diffSet(uninits).nextBit(firstadr) == -1) {
  1902                     break;
  1942                     break;
  1903                 }
  1943                 }
  1904                 uninits.assign(uninitsEntry.andSet(uninits));
  1944                 uninits.assign(uninitsEntry.andSet(uninits));
  1905                 flowKind = FlowKind.SPECULATIVE_LOOP;
  1945                 flowKind = FlowKind.SPECULATIVE_LOOP;
  1906             } while (true);
  1946             } while (true);
  1907             flowKind = prevFlowKind;
  1947             flowKind = prevFlowKind;
  1908             //a variable is DA/DU after the while statement, if it's DA/DU assuming the
  1948             //a variable is DA/DU after the while statement, if it's DA/DU assuming the
  1909             //branch is not taken AND if it's DA/DU before any break statement
  1949             //branch is not taken AND if it's DA/DU before any break statement
  1910             assignToInits(tree.body, initsSkip);
  1950             inits.assign(initsSkip);
  1911             uninits.assign(uninitsSkip);
  1951             uninits.assign(uninitsSkip);
  1912             resolveBreaks(tree, prevPendingExits);
  1952             resolveBreaks(tree, prevPendingExits);
  1913         }
  1953         }
  1914 
  1954 
  1915         public void visitForLoop(JCForLoop tree) {
  1955         public void visitForLoop(JCForLoop tree) {
  1916             ListBuffer<P> prevPendingExits = pendingExits;
  1956             ListBuffer<AssignPendingExit> prevPendingExits = pendingExits;
  1917             FlowKind prevFlowKind = flowKind;
  1957             FlowKind prevFlowKind = flowKind;
  1918             flowKind = FlowKind.NORMAL;
  1958             flowKind = FlowKind.NORMAL;
  1919             int nextadrPrev = nextadr;
  1959             int nextadrPrev = nextadr;
  1920             scan(tree.init);
  1960             scan(tree.init);
  1921             final Bits initsSkip = new Bits(true);
  1961             final Bits initsSkip = new Bits(true);
  1922             final Bits uninitsSkip = new Bits(true);
  1962             final Bits uninitsSkip = new Bits(true);
  1923             pendingExits = new ListBuffer<>();
  1963             pendingExits = new ListBuffer<>();
  1924             int prevErrors = getLogNumberOfErrors();
  1964             int prevErrors = log.nerrors;
  1925             do {
  1965             do {
  1926                 final Bits uninitsEntry = new Bits(uninits);
  1966                 final Bits uninitsEntry = new Bits(uninits);
  1927                 uninitsEntry.excludeFrom(nextadr);
  1967                 uninitsEntry.excludeFrom(nextadr);
  1928                 if (tree.cond != null) {
  1968                 if (tree.cond != null) {
  1929                     scanCond(tree.cond);
  1969                     scanCond(tree.cond);
  1930                     if (!flowKind.isFinal()) {
  1970                     if (!flowKind.isFinal()) {
  1931                         initsSkip.assign(initsWhenFalse);
  1971                         initsSkip.assign(initsWhenFalse);
  1932                         uninitsSkip.assign(uninitsWhenFalse);
  1972                         uninitsSkip.assign(uninitsWhenFalse);
  1933                     }
  1973                     }
  1934                     assignToInits(tree.body, initsWhenTrue);
  1974                     inits.assign(initsWhenTrue);
  1935                     uninits.assign(uninitsWhenTrue);
  1975                     uninits.assign(uninitsWhenTrue);
  1936                 } else if (!flowKind.isFinal()) {
  1976                 } else if (!flowKind.isFinal()) {
  1937                     initsSkip.assign(inits);
  1977                     initsSkip.assign(inits);
  1938                     initsSkip.inclRange(firstadr, nextadr);
  1978                     initsSkip.inclRange(firstadr, nextadr);
  1939                     uninitsSkip.assign(uninits);
  1979                     uninitsSkip.assign(uninits);
  1940                     uninitsSkip.inclRange(firstadr, nextadr);
  1980                     uninitsSkip.inclRange(firstadr, nextadr);
  1941                 }
  1981                 }
  1942                 scan(tree.body);
  1982                 scan(tree.body);
  1943                 resolveContinues(tree);
  1983                 resolveContinues(tree);
  1944                 scan(tree.step);
  1984                 scan(tree.step);
  1945                 if (getLogNumberOfErrors() != prevErrors ||
  1985                 if (log.nerrors != prevErrors ||
  1946                     flowKind.isFinal() ||
  1986                     flowKind.isFinal() ||
  1947                     new Bits(uninitsEntry).diffSet(uninits).nextBit(firstadr) == -1)
  1987                     new Bits(uninitsEntry).diffSet(uninits).nextBit(firstadr) == -1)
  1948                     break;
  1988                     break;
  1949                 uninits.assign(uninitsEntry.andSet(uninits));
  1989                 uninits.assign(uninitsEntry.andSet(uninits));
  1950                 flowKind = FlowKind.SPECULATIVE_LOOP;
  1990                 flowKind = FlowKind.SPECULATIVE_LOOP;
  1951             } while (true);
  1991             } while (true);
  1952             flowKind = prevFlowKind;
  1992             flowKind = prevFlowKind;
  1953             //a variable is DA/DU after a for loop, if it's DA/DU assuming the
  1993             //a variable is DA/DU after a for loop, if it's DA/DU assuming the
  1954             //branch is not taken AND if it's DA/DU before any break statement
  1994             //branch is not taken AND if it's DA/DU before any break statement
  1955             assignToInits(tree.body, initsSkip);
  1995             inits.assign(initsSkip);
  1956             uninits.assign(uninitsSkip);
  1996             uninits.assign(uninitsSkip);
  1957             resolveBreaks(tree, prevPendingExits);
  1997             resolveBreaks(tree, prevPendingExits);
  1958             nextadr = nextadrPrev;
  1998             nextadr = nextadrPrev;
  1959         }
  1999         }
  1960 
  2000 
  1961         public void visitForeachLoop(JCEnhancedForLoop tree) {
  2001         public void visitForeachLoop(JCEnhancedForLoop tree) {
  1962             visitVarDef(tree.var);
  2002             visitVarDef(tree.var);
  1963 
  2003 
  1964             ListBuffer<P> prevPendingExits = pendingExits;
  2004             ListBuffer<AssignPendingExit> prevPendingExits = pendingExits;
  1965             FlowKind prevFlowKind = flowKind;
  2005             FlowKind prevFlowKind = flowKind;
  1966             flowKind = FlowKind.NORMAL;
  2006             flowKind = FlowKind.NORMAL;
  1967             int nextadrPrev = nextadr;
  2007             int nextadrPrev = nextadr;
  1968             scan(tree.expr);
  2008             scan(tree.expr);
  1969             final Bits initsStart = new Bits(inits);
  2009             final Bits initsStart = new Bits(inits);
  1970             final Bits uninitsStart = new Bits(uninits);
  2010             final Bits uninitsStart = new Bits(uninits);
  1971 
  2011 
  1972             letInit(tree.pos(), tree.var.sym);
  2012             letInit(tree.pos(), tree.var.sym);
  1973             pendingExits = new ListBuffer<>();
  2013             pendingExits = new ListBuffer<>();
  1974             int prevErrors = getLogNumberOfErrors();
  2014             int prevErrors = log.nerrors;
  1975             do {
  2015             do {
  1976                 final Bits uninitsEntry = new Bits(uninits);
  2016                 final Bits uninitsEntry = new Bits(uninits);
  1977                 uninitsEntry.excludeFrom(nextadr);
  2017                 uninitsEntry.excludeFrom(nextadr);
  1978                 scan(tree.body);
  2018                 scan(tree.body);
  1979                 resolveContinues(tree);
  2019                 resolveContinues(tree);
  1980                 if (getLogNumberOfErrors() != prevErrors ||
  2020                 if (log.nerrors != prevErrors ||
  1981                     flowKind.isFinal() ||
  2021                     flowKind.isFinal() ||
  1982                     new Bits(uninitsEntry).diffSet(uninits).nextBit(firstadr) == -1)
  2022                     new Bits(uninitsEntry).diffSet(uninits).nextBit(firstadr) == -1)
  1983                     break;
  2023                     break;
  1984                 uninits.assign(uninitsEntry.andSet(uninits));
  2024                 uninits.assign(uninitsEntry.andSet(uninits));
  1985                 flowKind = FlowKind.SPECULATIVE_LOOP;
  2025                 flowKind = FlowKind.SPECULATIVE_LOOP;
  1986             } while (true);
  2026             } while (true);
  1987             flowKind = prevFlowKind;
  2027             flowKind = prevFlowKind;
  1988             assignToInits(tree.body, initsStart);
  2028             inits.assign(initsStart);
  1989             uninits.assign(uninitsStart.andSet(uninits));
  2029             uninits.assign(uninitsStart.andSet(uninits));
  1990             resolveBreaks(tree, prevPendingExits);
  2030             resolveBreaks(tree, prevPendingExits);
  1991             nextadr = nextadrPrev;
  2031             nextadr = nextadrPrev;
  1992         }
  2032         }
  1993 
  2033 
  1994         public void visitLabelled(JCLabeledStatement tree) {
  2034         public void visitLabelled(JCLabeledStatement tree) {
  1995             ListBuffer<P> prevPendingExits = pendingExits;
  2035             ListBuffer<AssignPendingExit> prevPendingExits = pendingExits;
  1996             pendingExits = new ListBuffer<>();
  2036             pendingExits = new ListBuffer<>();
  1997             scan(tree.body);
  2037             scan(tree.body);
  1998             resolveBreaks(tree, prevPendingExits);
  2038             resolveBreaks(tree, prevPendingExits);
  1999         }
  2039         }
  2000 
  2040 
  2001         public void visitSwitch(JCSwitch tree) {
  2041         public void visitSwitch(JCSwitch tree) {
  2002             ListBuffer<P> prevPendingExits = pendingExits;
  2042             ListBuffer<AssignPendingExit> prevPendingExits = pendingExits;
  2003             pendingExits = new ListBuffer<>();
  2043             pendingExits = new ListBuffer<>();
  2004             int nextadrPrev = nextadr;
  2044             int nextadrPrev = nextadr;
  2005             scanExpr(tree.selector);
  2045             scanExpr(tree.selector);
  2006             final Bits initsSwitch = new Bits(inits);
  2046             final Bits initsSwitch = new Bits(inits);
  2007             final Bits uninitsSwitch = new Bits(uninits);
  2047             final Bits uninitsSwitch = new Bits(uninits);
  2008             boolean hasDefault = false;
  2048             boolean hasDefault = false;
  2009             for (List<JCCase> l = tree.cases; l.nonEmpty(); l = l.tail) {
  2049             for (List<JCCase> l = tree.cases; l.nonEmpty(); l = l.tail) {
  2010                 assignToInits(l.head, initsSwitch);
  2050                 inits.assign(initsSwitch);
  2011                 uninits.assign(uninits.andSet(uninitsSwitch));
  2051                 uninits.assign(uninits.andSet(uninitsSwitch));
  2012                 JCCase c = l.head;
  2052                 JCCase c = l.head;
  2013                 if (c.pat == null) {
  2053                 if (c.pat == null) {
  2014                     hasDefault = true;
  2054                     hasDefault = true;
  2015                 } else {
  2055                 } else {
  2016                     scanExpr(c.pat);
  2056                     scanExpr(c.pat);
  2017                 }
  2057                 }
  2018                 if (hasDefault) {
  2058                 if (hasDefault) {
  2019                     assignToInits(null, initsSwitch);
  2059                     inits.assign(initsSwitch);
  2020                     uninits.assign(uninits.andSet(uninitsSwitch));
  2060                     uninits.assign(uninits.andSet(uninitsSwitch));
  2021                 }
  2061                 }
  2022                 scan(c.stats);
  2062                 scan(c.stats);
  2023                 addVars(c.stats, initsSwitch, uninitsSwitch);
  2063                 addVars(c.stats, initsSwitch, uninitsSwitch);
  2024                 if (!hasDefault) {
  2064                 if (!hasDefault) {
  2025                     assignToInits(l.head.stats.last(), initsSwitch);
  2065                     inits.assign(initsSwitch);
  2026                     uninits.assign(uninits.andSet(uninitsSwitch));
  2066                     uninits.assign(uninits.andSet(uninitsSwitch));
  2027                 }
  2067                 }
  2028                 // Warn about fall-through if lint switch fallthrough enabled.
  2068                 // Warn about fall-through if lint switch fallthrough enabled.
  2029             }
  2069             }
  2030             if (!hasDefault) {
  2070             if (!hasDefault) {
  2031                 andSetInits(null, initsSwitch);
  2071                 inits.andSet(initsSwitch);
  2032             }
  2072             }
  2033             resolveBreaks(tree, prevPendingExits);
  2073             resolveBreaks(tree, prevPendingExits);
  2034             nextadr = nextadrPrev;
  2074             nextadr = nextadrPrev;
  2035         }
  2075         }
  2036         // where
  2076         // where
  2045                         uninits.incl(adr);
  2085                         uninits.incl(adr);
  2046                     }
  2086                     }
  2047                 }
  2087                 }
  2048             }
  2088             }
  2049 
  2089 
  2050         boolean isEnabled(Lint.LintCategory lc) {
       
  2051             return false;
       
  2052         }
       
  2053 
       
  2054         void reportWarning(Lint.LintCategory lc, DiagnosticPosition pos, String key, Object ... args) {}
       
  2055 
       
  2056         public void visitTry(JCTry tree) {
  2090         public void visitTry(JCTry tree) {
  2057             ListBuffer<JCVariableDecl> resourceVarDecls = new ListBuffer<>();
  2091             ListBuffer<JCVariableDecl> resourceVarDecls = new ListBuffer<>();
  2058             final Bits uninitsTryPrev = new Bits(uninitsTry);
  2092             final Bits uninitsTryPrev = new Bits(uninitsTry);
  2059             ListBuffer<P> prevPendingExits = pendingExits;
  2093             ListBuffer<AssignPendingExit> prevPendingExits = pendingExits;
  2060             pendingExits = new ListBuffer<>();
  2094             pendingExits = new ListBuffer<>();
  2061             final Bits initsTry = new Bits(inits);
  2095             final Bits initsTry = new Bits(inits);
  2062             uninitsTry.assign(uninits);
  2096             uninitsTry.assign(uninits);
  2063             for (JCTree resource : tree.resources) {
  2097             for (JCTree resource : tree.resources) {
  2064                 if (resource instanceof JCVariableDecl) {
  2098                 if (resource instanceof JCVariableDecl) {
  2077             final Bits initsEnd = new Bits(inits);
  2111             final Bits initsEnd = new Bits(inits);
  2078             final Bits uninitsEnd = new Bits(uninits);
  2112             final Bits uninitsEnd = new Bits(uninits);
  2079             int nextadrCatch = nextadr;
  2113             int nextadrCatch = nextadr;
  2080 
  2114 
  2081             if (!resourceVarDecls.isEmpty() &&
  2115             if (!resourceVarDecls.isEmpty() &&
  2082                     isEnabled(Lint.LintCategory.TRY)) {
  2116                     lint.isEnabled(Lint.LintCategory.TRY)) {
  2083                 for (JCVariableDecl resVar : resourceVarDecls) {
  2117                 for (JCVariableDecl resVar : resourceVarDecls) {
  2084                     if (unrefdResources.includes(resVar.sym)) {
  2118                     if (unrefdResources.includes(resVar.sym)) {
  2085                         reportWarning(Lint.LintCategory.TRY, resVar.pos(),
  2119                         log.warning(Lint.LintCategory.TRY, resVar.pos(),
  2086                                     "try.resource.not.referenced", resVar.sym);
  2120                                     "try.resource.not.referenced", resVar.sym);
  2087                         unrefdResources.remove(resVar.sym);
  2121                         unrefdResources.remove(resVar.sym);
  2088                     }
  2122                     }
  2089                 }
  2123                 }
  2090             }
  2124             }
  2096             final Bits initsCatchPrev = new Bits(initsTry);
  2130             final Bits initsCatchPrev = new Bits(initsTry);
  2097             final Bits uninitsCatchPrev = new Bits(uninitsTry);
  2131             final Bits uninitsCatchPrev = new Bits(uninitsTry);
  2098 
  2132 
  2099             for (List<JCCatch> l = tree.catchers; l.nonEmpty(); l = l.tail) {
  2133             for (List<JCCatch> l = tree.catchers; l.nonEmpty(); l = l.tail) {
  2100                 JCVariableDecl param = l.head.param;
  2134                 JCVariableDecl param = l.head.param;
  2101                 assignToInits(tree.body, initsCatchPrev);
  2135                 inits.assign(initsCatchPrev);
  2102                 uninits.assign(uninitsCatchPrev);
  2136                 uninits.assign(uninitsCatchPrev);
  2103                 scan(param);
  2137                 scan(param);
  2104                 /* If this is a TWR and we are executing the code from Gen,
  2138                 /* If this is a TWR and we are executing the code from Gen,
  2105                  * then there can be synthetic variables, ignore them.
  2139                  * then there can be synthetic variables, ignore them.
  2106                  */
  2140                  */
  2109                 initsEnd.andSet(inits);
  2143                 initsEnd.andSet(inits);
  2110                 uninitsEnd.andSet(uninits);
  2144                 uninitsEnd.andSet(uninits);
  2111                 nextadr = nextadrCatch;
  2145                 nextadr = nextadrCatch;
  2112             }
  2146             }
  2113             if (tree.finalizer != null) {
  2147             if (tree.finalizer != null) {
  2114                 assignToInits(tree.finalizer, initsTry);
  2148                 inits.assign(initsTry);
  2115                 uninits.assign(uninitsTry);
  2149                 uninits.assign(uninitsTry);
  2116                 ListBuffer<P> exits = pendingExits;
  2150                 ListBuffer<AssignPendingExit> exits = pendingExits;
  2117                 pendingExits = prevPendingExits;
  2151                 pendingExits = prevPendingExits;
  2118                 scan(tree.finalizer);
  2152                 scan(tree.finalizer);
  2119                 if (!tree.finallyCanCompleteNormally) {
  2153                 if (!tree.finallyCanCompleteNormally) {
  2120                     // discard exits and exceptions from try and finally
  2154                     // discard exits and exceptions from try and finally
  2121                 } else {
  2155                 } else {
  2122                     uninits.andSet(uninitsEnd);
  2156                     uninits.andSet(uninitsEnd);
  2123                     // FIX: this doesn't preserve source order of exits in catch
  2157                     // FIX: this doesn't preserve source order of exits in catch
  2124                     // versus finally!
  2158                     // versus finally!
  2125                     while (exits.nonEmpty()) {
  2159                     while (exits.nonEmpty()) {
  2126                         P exit = exits.next();
  2160                         AssignPendingExit exit = exits.next();
  2127                         if (exit.exit_inits != null) {
  2161                         if (exit.exit_inits != null) {
  2128                             exit.exit_inits.orSet(inits);
  2162                             exit.exit_inits.orSet(inits);
  2129                             exit.exit_uninits.andSet(uninits);
  2163                             exit.exit_uninits.andSet(uninits);
  2130                         }
  2164                         }
  2131                         pendingExits.append(exit);
  2165                         pendingExits.append(exit);
  2132                     }
  2166                     }
  2133                     orSetInits(tree, initsEnd);
  2167                     inits.orSet(initsEnd);
  2134                 }
  2168                 }
  2135             } else {
  2169             } else {
  2136                 assignToInits(tree, initsEnd);
  2170                 inits.assign(initsEnd);
  2137                 uninits.assign(uninitsEnd);
  2171                 uninits.assign(uninitsEnd);
  2138                 ListBuffer<P> exits = pendingExits;
  2172                 ListBuffer<AssignPendingExit> exits = pendingExits;
  2139                 pendingExits = prevPendingExits;
  2173                 pendingExits = prevPendingExits;
  2140                 while (exits.nonEmpty()) pendingExits.append(exits.next());
  2174                 while (exits.nonEmpty()) pendingExits.append(exits.next());
  2141             }
  2175             }
  2142             uninitsTry.andSet(uninitsTryPrev).andSet(uninits);
  2176             uninitsTry.andSet(uninitsTryPrev).andSet(uninits);
  2143         }
  2177         }
  2144 
  2178 
  2145         public void visitConditional(JCConditional tree) {
  2179         public void visitConditional(JCConditional tree) {
  2146             scanCond(tree.cond);
  2180             scanCond(tree.cond);
  2147             final Bits initsBeforeElse = new Bits(initsWhenFalse);
  2181             final Bits initsBeforeElse = new Bits(initsWhenFalse);
  2148             final Bits uninitsBeforeElse = new Bits(uninitsWhenFalse);
  2182             final Bits uninitsBeforeElse = new Bits(uninitsWhenFalse);
  2149             assignToInits(tree.cond, initsWhenTrue);
  2183             inits.assign(initsWhenTrue);
  2150             uninits.assign(uninitsWhenTrue);
  2184             uninits.assign(uninitsWhenTrue);
  2151             if (tree.truepart.type.hasTag(BOOLEAN) &&
  2185             if (tree.truepart.type.hasTag(BOOLEAN) &&
  2152                 tree.falsepart.type.hasTag(BOOLEAN)) {
  2186                 tree.falsepart.type.hasTag(BOOLEAN)) {
  2153                 // if b and c are boolean valued, then
  2187                 // if b and c are boolean valued, then
  2154                 // v is (un)assigned after a?b:c when true iff
  2188                 // v is (un)assigned after a?b:c when true iff
  2157                 scanCond(tree.truepart);
  2191                 scanCond(tree.truepart);
  2158                 final Bits initsAfterThenWhenTrue = new Bits(initsWhenTrue);
  2192                 final Bits initsAfterThenWhenTrue = new Bits(initsWhenTrue);
  2159                 final Bits initsAfterThenWhenFalse = new Bits(initsWhenFalse);
  2193                 final Bits initsAfterThenWhenFalse = new Bits(initsWhenFalse);
  2160                 final Bits uninitsAfterThenWhenTrue = new Bits(uninitsWhenTrue);
  2194                 final Bits uninitsAfterThenWhenTrue = new Bits(uninitsWhenTrue);
  2161                 final Bits uninitsAfterThenWhenFalse = new Bits(uninitsWhenFalse);
  2195                 final Bits uninitsAfterThenWhenFalse = new Bits(uninitsWhenFalse);
  2162                 assignToInits(tree.truepart, initsBeforeElse);
  2196                 inits.assign(initsBeforeElse);
  2163                 uninits.assign(uninitsBeforeElse);
  2197                 uninits.assign(uninitsBeforeElse);
  2164                 scanCond(tree.falsepart);
  2198                 scanCond(tree.falsepart);
  2165                 initsWhenTrue.andSet(initsAfterThenWhenTrue);
  2199                 initsWhenTrue.andSet(initsAfterThenWhenTrue);
  2166                 initsWhenFalse.andSet(initsAfterThenWhenFalse);
  2200                 initsWhenFalse.andSet(initsAfterThenWhenFalse);
  2167                 uninitsWhenTrue.andSet(uninitsAfterThenWhenTrue);
  2201                 uninitsWhenTrue.andSet(uninitsAfterThenWhenTrue);
  2168                 uninitsWhenFalse.andSet(uninitsAfterThenWhenFalse);
  2202                 uninitsWhenFalse.andSet(uninitsAfterThenWhenFalse);
  2169             } else {
  2203             } else {
  2170                 scanExpr(tree.truepart);
  2204                 scanExpr(tree.truepart);
  2171                 final Bits initsAfterThen = new Bits(inits);
  2205                 final Bits initsAfterThen = new Bits(inits);
  2172                 final Bits uninitsAfterThen = new Bits(uninits);
  2206                 final Bits uninitsAfterThen = new Bits(uninits);
  2173                 assignToInits(tree.truepart, initsBeforeElse);
  2207                 inits.assign(initsBeforeElse);
  2174                 uninits.assign(uninitsBeforeElse);
  2208                 uninits.assign(uninitsBeforeElse);
  2175                 scanExpr(tree.falsepart);
  2209                 scanExpr(tree.falsepart);
  2176                 andSetInits(tree.falsepart, initsAfterThen);
  2210                 inits.andSet(initsAfterThen);
  2177                 uninits.andSet(uninitsAfterThen);
  2211                 uninits.andSet(uninitsAfterThen);
  2178             }
  2212             }
  2179         }
  2213         }
  2180 
  2214 
  2181         public void visitIf(JCIf tree) {
  2215         public void visitIf(JCIf tree) {
  2182             scanCond(tree.cond);
  2216             scanCond(tree.cond);
  2183             final Bits initsBeforeElse = new Bits(initsWhenFalse);
  2217             final Bits initsBeforeElse = new Bits(initsWhenFalse);
  2184             final Bits uninitsBeforeElse = new Bits(uninitsWhenFalse);
  2218             final Bits uninitsBeforeElse = new Bits(uninitsWhenFalse);
  2185             assignToInits(tree.cond, initsWhenTrue);
  2219             inits.assign(initsWhenTrue);
  2186             uninits.assign(uninitsWhenTrue);
  2220             uninits.assign(uninitsWhenTrue);
  2187             scan(tree.thenpart);
  2221             scan(tree.thenpart);
  2188             if (tree.elsepart != null) {
  2222             if (tree.elsepart != null) {
  2189                 final Bits initsAfterThen = new Bits(inits);
  2223                 final Bits initsAfterThen = new Bits(inits);
  2190                 final Bits uninitsAfterThen = new Bits(uninits);
  2224                 final Bits uninitsAfterThen = new Bits(uninits);
  2191                 assignToInits(tree.thenpart, initsBeforeElse);
  2225                 inits.assign(initsBeforeElse);
  2192                 uninits.assign(uninitsBeforeElse);
  2226                 uninits.assign(uninitsBeforeElse);
  2193                 scan(tree.elsepart);
  2227                 scan(tree.elsepart);
  2194                 andSetInits(tree.elsepart, initsAfterThen);
  2228                 inits.andSet(initsAfterThen);
  2195                 uninits.andSet(uninitsAfterThen);
  2229                 uninits.andSet(uninitsAfterThen);
  2196             } else {
  2230             } else {
  2197                 andSetInits(tree.thenpart, initsBeforeElse);
  2231                 inits.andSet(initsBeforeElse);
  2198                 uninits.andSet(uninitsBeforeElse);
  2232                 uninits.andSet(uninitsBeforeElse);
  2199             }
  2233             }
  2200         }
       
  2201 
       
  2202         protected P createNewPendingExit(JCTree tree, Bits inits, Bits uninits) {
       
  2203             return null;
       
  2204         }
  2234         }
  2205 
  2235 
  2206         @Override
  2236         @Override
  2207         public void visitBreak(JCBreak tree) {
  2237         public void visitBreak(JCBreak tree) {
  2208             recordExit(tree, createNewPendingExit(tree, inits, uninits));
  2238             recordExit(new AssignPendingExit(tree, inits, uninits));
  2209         }
  2239         }
  2210 
  2240 
  2211         @Override
  2241         @Override
  2212         public void visitContinue(JCContinue tree) {
  2242         public void visitContinue(JCContinue tree) {
  2213             recordExit(tree, createNewPendingExit(tree, inits, uninits));
  2243             recordExit(new AssignPendingExit(tree, inits, uninits));
  2214         }
  2244         }
  2215 
  2245 
  2216         @Override
  2246         @Override
  2217         public void visitReturn(JCReturn tree) {
  2247         public void visitReturn(JCReturn tree) {
  2218             scanExpr(tree.expr);
  2248             scanExpr(tree.expr);
  2219             recordExit(tree, createNewPendingExit(tree, inits, uninits));
  2249             recordExit(new AssignPendingExit(tree, inits, uninits));
  2220         }
  2250         }
  2221 
  2251 
  2222         public void visitThrow(JCThrow tree) {
  2252         public void visitThrow(JCThrow tree) {
  2223             scanExpr(tree.expr);
  2253             scanExpr(tree.expr);
  2224             markDead(tree.expr);
  2254             markDead();
  2225         }
  2255         }
  2226 
  2256 
  2227         public void visitApply(JCMethodInvocation tree) {
  2257         public void visitApply(JCMethodInvocation tree) {
  2228             scanExpr(tree.meth);
  2258             scanExpr(tree.meth);
  2229             scanExprs(tree.args);
  2259             scanExprs(tree.args);
  2238         @Override
  2268         @Override
  2239         public void visitLambda(JCLambda tree) {
  2269         public void visitLambda(JCLambda tree) {
  2240             final Bits prevUninits = new Bits(uninits);
  2270             final Bits prevUninits = new Bits(uninits);
  2241             final Bits prevInits = new Bits(inits);
  2271             final Bits prevInits = new Bits(inits);
  2242             int returnadrPrev = returnadr;
  2272             int returnadrPrev = returnadr;
  2243             ListBuffer<P> prevPending = pendingExits;
  2273             ListBuffer<AssignPendingExit> prevPending = pendingExits;
  2244             try {
  2274             try {
  2245                 returnadr = nextadr;
  2275                 returnadr = nextadr;
  2246                 pendingExits = new ListBuffer<>();
  2276                 pendingExits = new ListBuffer<>();
  2247                 for (List<JCVariableDecl> l = tree.params; l.nonEmpty(); l = l.tail) {
  2277                 for (List<JCVariableDecl> l = tree.params; l.nonEmpty(); l = l.tail) {
  2248                     JCVariableDecl def = l.head;
  2278                     JCVariableDecl def = l.head;
  2257                 }
  2287                 }
  2258             }
  2288             }
  2259             finally {
  2289             finally {
  2260                 returnadr = returnadrPrev;
  2290                 returnadr = returnadrPrev;
  2261                 uninits.assign(prevUninits);
  2291                 uninits.assign(prevUninits);
  2262                 assignToInits(tree, prevInits);
  2292                 inits.assign(prevInits);
  2263                 pendingExits = prevPending;
  2293                 pendingExits = prevPending;
  2264             }
  2294             }
  2265         }
  2295         }
  2266 
  2296 
  2267         public void visitNewArray(JCNewArray tree) {
  2297         public void visitNewArray(JCNewArray tree) {
  2273             final Bits initsExit = new Bits(inits);
  2303             final Bits initsExit = new Bits(inits);
  2274             final Bits uninitsExit = new Bits(uninits);
  2304             final Bits uninitsExit = new Bits(uninits);
  2275             scanCond(tree.cond);
  2305             scanCond(tree.cond);
  2276             uninitsExit.andSet(uninitsWhenTrue);
  2306             uninitsExit.andSet(uninitsWhenTrue);
  2277             if (tree.detail != null) {
  2307             if (tree.detail != null) {
  2278                 assignToInits(tree, initsWhenFalse);
  2308                 inits.assign(initsWhenFalse);
  2279                 uninits.assign(uninitsWhenFalse);
  2309                 uninits.assign(uninitsWhenFalse);
  2280                 scanExpr(tree.detail);
  2310                 scanExpr(tree.detail);
  2281             }
  2311             }
  2282             assignToInits(tree, initsExit);
  2312             inits.assign(initsExit);
  2283             uninits.assign(uninitsExit);
  2313             uninits.assign(uninitsExit);
  2284         }
  2314         }
  2285 
  2315 
  2286         public void visitAssign(JCAssign tree) {
  2316         public void visitAssign(JCAssign tree) {
  2287             JCTree lhs = TreeInfo.skipParens(tree.lhs);
  2317             JCTree lhs = TreeInfo.skipParens(tree.lhs);
  2306         public void visitSelect(JCFieldAccess tree) {
  2336         public void visitSelect(JCFieldAccess tree) {
  2307             super.visitSelect(tree);
  2337             super.visitSelect(tree);
  2308             if (enforceThisDotInit &&
  2338             if (enforceThisDotInit &&
  2309                 tree.selected.hasTag(IDENT) &&
  2339                 tree.selected.hasTag(IDENT) &&
  2310                 ((JCIdent)tree.selected).name == names._this &&
  2340                 ((JCIdent)tree.selected).name == names._this &&
  2311                 tree.sym.kind == VAR)
  2341                 tree.sym.kind == VAR) {
  2312             {
       
  2313                 checkInit(tree.pos(), (VarSymbol)tree.sym);
  2342                 checkInit(tree.pos(), (VarSymbol)tree.sym);
  2314             }
  2343             }
  2315         }
  2344         }
  2316 
  2345 
  2317         public void visitAssignop(JCAssignOp tree) {
  2346         public void visitAssignop(JCAssignOp tree) {
  2345             switch (tree.getTag()) {
  2374             switch (tree.getTag()) {
  2346             case AND:
  2375             case AND:
  2347                 scanCond(tree.lhs);
  2376                 scanCond(tree.lhs);
  2348                 final Bits initsWhenFalseLeft = new Bits(initsWhenFalse);
  2377                 final Bits initsWhenFalseLeft = new Bits(initsWhenFalse);
  2349                 final Bits uninitsWhenFalseLeft = new Bits(uninitsWhenFalse);
  2378                 final Bits uninitsWhenFalseLeft = new Bits(uninitsWhenFalse);
  2350                 assignToInits(tree.lhs, initsWhenTrue);
  2379                 inits.assign(initsWhenTrue);
  2351                 uninits.assign(uninitsWhenTrue);
  2380                 uninits.assign(uninitsWhenTrue);
  2352                 scanCond(tree.rhs);
  2381                 scanCond(tree.rhs);
  2353                 initsWhenFalse.andSet(initsWhenFalseLeft);
  2382                 initsWhenFalse.andSet(initsWhenFalseLeft);
  2354                 uninitsWhenFalse.andSet(uninitsWhenFalseLeft);
  2383                 uninitsWhenFalse.andSet(uninitsWhenFalseLeft);
  2355                 break;
  2384                 break;
  2356             case OR:
  2385             case OR:
  2357                 scanCond(tree.lhs);
  2386                 scanCond(tree.lhs);
  2358                 final Bits initsWhenTrueLeft = new Bits(initsWhenTrue);
  2387                 final Bits initsWhenTrueLeft = new Bits(initsWhenTrue);
  2359                 final Bits uninitsWhenTrueLeft = new Bits(uninitsWhenTrue);
  2388                 final Bits uninitsWhenTrueLeft = new Bits(uninitsWhenTrue);
  2360                 assignToInits(tree.lhs, initsWhenFalse);
  2389                 inits.assign(initsWhenFalse);
  2361                 uninits.assign(uninitsWhenFalse);
  2390                 uninits.assign(uninitsWhenFalse);
  2362                 scanCond(tree.rhs);
  2391                 scanCond(tree.rhs);
  2363                 initsWhenTrue.andSet(initsWhenTrueLeft);
  2392                 initsWhenTrue.andSet(initsWhenTrueLeft);
  2364                 uninitsWhenTrue.andSet(uninitsWhenTrueLeft);
  2393                 uninitsWhenTrue.andSet(uninitsWhenTrueLeft);
  2365                 break;
  2394                 break;
  2426                 unrefdResources = null;
  2455                 unrefdResources = null;
  2427             }
  2456             }
  2428         }
  2457         }
  2429     }
  2458     }
  2430 
  2459 
  2431     public class AssignAnalyzer extends AbstractAssignAnalyzer<AssignAnalyzer.AssignPendingExit> {
       
  2432 
       
  2433         public class AssignPendingExit extends AbstractAssignAnalyzer<AssignPendingExit>.AbstractAssignPendingExit {
       
  2434 
       
  2435             public AssignPendingExit(JCTree tree, final Bits inits, final Bits uninits) {
       
  2436                 super(tree, inits, uninits);
       
  2437             }
       
  2438         }
       
  2439 
       
  2440         @Override
       
  2441         protected AssignPendingExit createNewPendingExit(JCTree tree,
       
  2442             Bits inits, Bits uninits) {
       
  2443             return new AssignPendingExit(tree, inits, uninits);
       
  2444         }
       
  2445 
       
  2446         /** Record an initialization of a trackable variable.
       
  2447          */
       
  2448         @Override
       
  2449         void letInit(DiagnosticPosition pos, VarSymbol sym) {
       
  2450             if (sym.adr >= firstadr && trackable(sym)) {
       
  2451                 if ((sym.flags() & EFFECTIVELY_FINAL) != 0) {
       
  2452                     if (!uninits.isMember(sym.adr)) {
       
  2453                         //assignment targeting an effectively final variable
       
  2454                         //makes the variable lose its status of effectively final
       
  2455                         //if the variable is _not_ definitively unassigned
       
  2456                         sym.flags_field &= ~EFFECTIVELY_FINAL;
       
  2457                     } else {
       
  2458                         uninit(sym);
       
  2459                     }
       
  2460                 }
       
  2461                 else if ((sym.flags() & FINAL) != 0) {
       
  2462                     if ((sym.flags() & PARAMETER) != 0) {
       
  2463                         if ((sym.flags() & UNION) != 0) { //multi-catch parameter
       
  2464                             log.error(pos, "multicatch.parameter.may.not.be.assigned", sym);
       
  2465                         }
       
  2466                         else {
       
  2467                             log.error(pos, "final.parameter.may.not.be.assigned",
       
  2468                                   sym);
       
  2469                         }
       
  2470                     } else if (!uninits.isMember(sym.adr)) {
       
  2471                         log.error(pos, flowKind.errKey, sym);
       
  2472                     } else {
       
  2473                         uninit(sym);
       
  2474                     }
       
  2475                 }
       
  2476                 inits.incl(sym.adr);
       
  2477             } else if ((sym.flags() & FINAL) != 0) {
       
  2478                 log.error(pos, "var.might.already.be.assigned", sym);
       
  2479             }
       
  2480         }
       
  2481 
       
  2482         @Override
       
  2483         void checkInit(DiagnosticPosition pos, VarSymbol sym, String errkey) {
       
  2484             if ((sym.adr >= firstadr || sym.owner.kind != TYP) &&
       
  2485                 trackable(sym) &&
       
  2486                 !inits.isMember(sym.adr)) {
       
  2487                 log.error(pos, errkey, sym);
       
  2488                 inits.incl(sym.adr);
       
  2489             }
       
  2490         }
       
  2491 
       
  2492         @Override
       
  2493         void reportWarning(Lint.LintCategory lc, DiagnosticPosition pos,
       
  2494             String key, Object ... args) {
       
  2495             log.warning(lc, pos, key, args);
       
  2496         }
       
  2497 
       
  2498         @Override
       
  2499         int getLogNumberOfErrors() {
       
  2500             return log.nerrors;
       
  2501         }
       
  2502 
       
  2503         @Override
       
  2504         boolean isEnabled(Lint.LintCategory lc) {
       
  2505             return lint.isEnabled(lc);
       
  2506         }
       
  2507 
       
  2508         @Override
       
  2509         public void visitClassDef(JCClassDecl tree) {
       
  2510             if (tree.sym == null) {
       
  2511                 return;
       
  2512             }
       
  2513 
       
  2514             Lint lintPrev = lint;
       
  2515             lint = lint.augment(tree.sym);
       
  2516             try {
       
  2517                 super.visitClassDef(tree);
       
  2518             } finally {
       
  2519                 lint = lintPrev;
       
  2520             }
       
  2521         }
       
  2522 
       
  2523         @Override
       
  2524         public void visitMethodDef(JCMethodDecl tree) {
       
  2525             if (tree.body == null) {
       
  2526                 return;
       
  2527             }
       
  2528 
       
  2529             /*  MemberEnter can generate synthetic methods ignore them
       
  2530              */
       
  2531             if ((tree.sym.flags() & SYNTHETIC) != 0) {
       
  2532                 return;
       
  2533             }
       
  2534 
       
  2535             Lint lintPrev = lint;
       
  2536             lint = lint.augment(tree.sym);
       
  2537             try {
       
  2538                 super.visitMethodDef(tree);
       
  2539             } finally {
       
  2540                 lint = lintPrev;
       
  2541             }
       
  2542         }
       
  2543 
       
  2544         @Override
       
  2545         public void visitVarDef(JCVariableDecl tree) {
       
  2546             if (tree.init == null) {
       
  2547                 super.visitVarDef(tree);
       
  2548             } else {
       
  2549                 Lint lintPrev = lint;
       
  2550                 lint = lint.augment(tree.sym);
       
  2551                 try{
       
  2552                     super.visitVarDef(tree);
       
  2553                 } finally {
       
  2554                     lint = lintPrev;
       
  2555                 }
       
  2556             }
       
  2557         }
       
  2558 
       
  2559     }
       
  2560 
       
  2561     /**
  2460     /**
  2562      * This pass implements the last step of the dataflow analysis, namely
  2461      * This pass implements the last step of the dataflow analysis, namely
  2563      * the effectively-final analysis check. This checks that every local variable
  2462      * the effectively-final analysis check. This checks that every local variable
  2564      * reference from a lambda body/local inner class is either final or effectively final.
  2463      * reference from a lambda body/local inner class is either final or effectively final.
  2565      * Additional this also checks that every variable that is used as an operand to
  2464      * Additional this also checks that every variable that is used as an operand to
  2570     class CaptureAnalyzer extends BaseAnalyzer<BaseAnalyzer.PendingExit> {
  2469     class CaptureAnalyzer extends BaseAnalyzer<BaseAnalyzer.PendingExit> {
  2571 
  2470 
  2572         JCTree currentTree; //local class or lambda
  2471         JCTree currentTree; //local class or lambda
  2573 
  2472 
  2574         @Override
  2473         @Override
  2575         void markDead(JCTree tree) {
  2474         void markDead() {
  2576             //do nothing
  2475             //do nothing
  2577         }
  2476         }
  2578 
  2477 
  2579         @SuppressWarnings("fallthrough")
  2478         @SuppressWarnings("fallthrough")
  2580         void checkEffectivelyFinal(DiagnosticPosition pos, VarSymbol sym) {
  2479         void checkEffectivelyFinal(DiagnosticPosition pos, VarSymbol sym) {