1712:3c02d2f1a421 | 1713:2ca9e7d50136 |
---|---|
33 import com.sun.tools.javac.tree.*; | 33 import com.sun.tools.javac.tree.*; |
34 import com.sun.tools.javac.util.*; | 34 import com.sun.tools.javac.util.*; |
35 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition; | 35 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition; |
36 | 36 |
37 import com.sun.tools.javac.code.Symbol.*; | 37 import com.sun.tools.javac.code.Symbol.*; |
38 import com.sun.tools.javac.comp.Resolve; | |
39 import com.sun.tools.javac.tree.JCTree.*; | 38 import com.sun.tools.javac.tree.JCTree.*; |
40 | 39 |
41 import static com.sun.tools.javac.code.Flags.*; | 40 import static com.sun.tools.javac.code.Flags.*; |
42 import static com.sun.tools.javac.code.Flags.BLOCK; | 41 import static com.sun.tools.javac.code.Flags.BLOCK; |
43 import static com.sun.tools.javac.code.Kinds.*; | 42 import static com.sun.tools.javac.code.Kinds.*; |
275 allowImprovedCatchAnalysis = source.allowImprovedCatchAnalysis(); | 274 allowImprovedCatchAnalysis = source.allowImprovedCatchAnalysis(); |
276 allowEffectivelyFinalInInnerClasses = source.allowEffectivelyFinalInInnerClasses(); | 275 allowEffectivelyFinalInInnerClasses = source.allowEffectivelyFinalInInnerClasses(); |
277 } | 276 } |
278 | 277 |
279 /** | 278 /** |
279 * Utility method to reset several Bits instances. | |
280 */ | |
281 private void resetBits(Bits... bits) { | |
282 for (Bits b : bits) { | |
283 b.reset(); | |
284 } | |
285 } | |
286 | |
287 /** | |
280 * Base visitor class for all visitors implementing dataflow analysis logic. | 288 * Base visitor class for all visitors implementing dataflow analysis logic. |
281 * This class define the shared logic for handling jumps (break/continue statements). | 289 * This class define the shared logic for handling jumps (break/continue statements). |
282 */ | 290 */ |
283 static abstract class BaseAnalyzer<P extends BaseAnalyzer.PendingExit> extends TreeScanner { | 291 static abstract class BaseAnalyzer<P extends BaseAnalyzer.PendingExit> extends TreeScanner { |
284 | 292 |
1292 */ | 1300 */ |
1293 class AssignAnalyzer extends BaseAnalyzer<AssignAnalyzer.AssignPendingExit> { | 1301 class AssignAnalyzer extends BaseAnalyzer<AssignAnalyzer.AssignPendingExit> { |
1294 | 1302 |
1295 /** The set of definitely assigned variables. | 1303 /** The set of definitely assigned variables. |
1296 */ | 1304 */ |
1297 Bits inits; | 1305 final Bits inits; |
1298 | 1306 |
1299 /** The set of definitely unassigned variables. | 1307 /** The set of definitely unassigned variables. |
1300 */ | 1308 */ |
1301 Bits uninits; | 1309 final Bits uninits; |
1302 | 1310 |
1303 /** The set of variables that are definitely unassigned everywhere | 1311 /** The set of variables that are definitely unassigned everywhere |
1304 * in current try block. This variable is maintained lazily; it is | 1312 * in current try block. This variable is maintained lazily; it is |
1305 * updated only when something gets removed from uninits, | 1313 * updated only when something gets removed from uninits, |
1306 * typically by being assigned in reachable code. To obtain the | 1314 * typically by being assigned in reachable code. To obtain the |
1307 * correct set of variables which are definitely unassigned | 1315 * correct set of variables which are definitely unassigned |
1308 * anywhere in current try block, intersect uninitsTry and | 1316 * anywhere in current try block, intersect uninitsTry and |
1309 * uninits. | 1317 * uninits. |
1310 */ | 1318 */ |
1311 Bits uninitsTry; | 1319 final Bits uninitsTry; |
1312 | 1320 |
1313 /** When analyzing a condition, inits and uninits are null. | 1321 /** When analyzing a condition, inits and uninits are null. |
1314 * Instead we have: | 1322 * Instead we have: |
1315 */ | 1323 */ |
1316 Bits initsWhenTrue; | 1324 final Bits initsWhenTrue; |
1317 Bits initsWhenFalse; | 1325 final Bits initsWhenFalse; |
1318 Bits uninitsWhenTrue; | 1326 final Bits uninitsWhenTrue; |
1319 Bits uninitsWhenFalse; | 1327 final Bits uninitsWhenFalse; |
1320 | 1328 |
1321 /** A mapping from addresses to variable symbols. | 1329 /** A mapping from addresses to variable symbols. |
1322 */ | 1330 */ |
1323 VarSymbol[] vars; | 1331 VarSymbol[] vars; |
1324 | 1332 |
1346 FlowKind flowKind = FlowKind.NORMAL; | 1354 FlowKind flowKind = FlowKind.NORMAL; |
1347 | 1355 |
1348 /** The starting position of the analysed tree */ | 1356 /** The starting position of the analysed tree */ |
1349 int startPos; | 1357 int startPos; |
1350 | 1358 |
1359 AssignAnalyzer() { | |
1360 inits = new Bits(); | |
1361 uninits = new Bits(); | |
1362 uninitsTry = new Bits(); | |
1363 initsWhenTrue = new Bits(true); | |
1364 initsWhenFalse = new Bits(true); | |
1365 uninitsWhenTrue = new Bits(true); | |
1366 uninitsWhenFalse = new Bits(true); | |
1367 } | |
1368 | |
1351 class AssignPendingExit extends BaseAnalyzer.PendingExit { | 1369 class AssignPendingExit extends BaseAnalyzer.PendingExit { |
1352 | 1370 |
1353 Bits exit_inits; | 1371 final Bits exit_inits = new Bits(true); |
1354 Bits exit_uninits; | 1372 final Bits exit_uninits = new Bits(true); |
1355 | 1373 |
1356 AssignPendingExit(JCTree tree, Bits inits, Bits uninits) { | 1374 AssignPendingExit(JCTree tree, final Bits inits, final Bits uninits) { |
1357 super(tree); | 1375 super(tree); |
1358 this.exit_inits = inits.dup(); | 1376 this.exit_inits.assign(inits); |
1359 this.exit_uninits = uninits.dup(); | 1377 this.exit_uninits.assign(uninits); |
1360 } | 1378 } |
1361 | 1379 |
1362 void resolveJump() { | 1380 void resolveJump() { |
1363 inits.andSet(exit_inits); | 1381 inits.andSet(exit_inits); |
1364 uninits.andSet(exit_uninits); | 1382 uninits.andSet(exit_uninits); |
1474 } | 1492 } |
1475 | 1493 |
1476 /** Split (duplicate) inits/uninits into WhenTrue/WhenFalse sets | 1494 /** Split (duplicate) inits/uninits into WhenTrue/WhenFalse sets |
1477 */ | 1495 */ |
1478 void split(boolean setToNull) { | 1496 void split(boolean setToNull) { |
1479 initsWhenFalse = inits.dup(); | 1497 initsWhenFalse.assign(inits); |
1480 uninitsWhenFalse = uninits.dup(); | 1498 uninitsWhenFalse.assign(uninits); |
1481 initsWhenTrue = inits; | 1499 initsWhenTrue.assign(inits); |
1482 uninitsWhenTrue = uninits; | 1500 uninitsWhenTrue.assign(uninits); |
1483 if (setToNull) | 1501 if (setToNull) { |
1484 inits = uninits = null; | 1502 resetBits(inits, uninits); |
1503 } | |
1485 } | 1504 } |
1486 | 1505 |
1487 /** Merge (intersect) inits/uninits from WhenTrue/WhenFalse sets. | 1506 /** Merge (intersect) inits/uninits from WhenTrue/WhenFalse sets. |
1488 */ | 1507 */ |
1489 void merge() { | 1508 void merge() { |
1490 inits = initsWhenFalse.andSet(initsWhenTrue); | 1509 inits.assign(initsWhenFalse.andSet(initsWhenTrue)); |
1491 uninits = uninitsWhenFalse.andSet(uninitsWhenTrue); | 1510 uninits.assign(uninitsWhenFalse.andSet(uninitsWhenTrue)); |
1492 } | 1511 } |
1493 | 1512 |
1494 /* ************************************************************************ | 1513 /* ************************************************************************ |
1495 * Visitor methods for statements and definitions | 1514 * Visitor methods for statements and definitions |
1496 *************************************************************************/ | 1515 *************************************************************************/ |
1499 * (un)initsWhenTrue(WhenFalse) on exit. | 1518 * (un)initsWhenTrue(WhenFalse) on exit. |
1500 */ | 1519 */ |
1501 void scanExpr(JCTree tree) { | 1520 void scanExpr(JCTree tree) { |
1502 if (tree != null) { | 1521 if (tree != null) { |
1503 scan(tree); | 1522 scan(tree); |
1504 if (inits == null) merge(); | 1523 if (inits.isReset()) merge(); |
1505 } | 1524 } |
1506 } | 1525 } |
1507 | 1526 |
1508 /** Analyze a list of expressions. | 1527 /** Analyze a list of expressions. |
1509 */ | 1528 */ |
1516 /** Analyze a condition. Make sure to set (un)initsWhenTrue(WhenFalse) | 1535 /** Analyze a condition. Make sure to set (un)initsWhenTrue(WhenFalse) |
1517 * rather than (un)inits on exit. | 1536 * rather than (un)inits on exit. |
1518 */ | 1537 */ |
1519 void scanCond(JCTree tree) { | 1538 void scanCond(JCTree tree) { |
1520 if (tree.type.isFalse()) { | 1539 if (tree.type.isFalse()) { |
1521 if (inits == null) merge(); | 1540 if (inits.isReset()) merge(); |
1522 initsWhenTrue = inits.dup(); | 1541 initsWhenTrue.assign(inits); |
1523 initsWhenTrue.inclRange(firstadr, nextadr); | 1542 initsWhenTrue.inclRange(firstadr, nextadr); |
1524 uninitsWhenTrue = uninits.dup(); | 1543 uninitsWhenTrue.assign(uninits); |
1525 uninitsWhenTrue.inclRange(firstadr, nextadr); | 1544 uninitsWhenTrue.inclRange(firstadr, nextadr); |
1526 initsWhenFalse = inits; | 1545 initsWhenFalse.assign(inits); |
1527 uninitsWhenFalse = uninits; | 1546 uninitsWhenFalse.assign(uninits); |
1528 } else if (tree.type.isTrue()) { | 1547 } else if (tree.type.isTrue()) { |
1529 if (inits == null) merge(); | 1548 if (inits.isReset()) merge(); |
1530 initsWhenFalse = inits.dup(); | 1549 initsWhenFalse.assign(inits); |
1531 initsWhenFalse.inclRange(firstadr, nextadr); | 1550 initsWhenFalse.inclRange(firstadr, nextadr); |
1532 uninitsWhenFalse = uninits.dup(); | 1551 uninitsWhenFalse.assign(uninits); |
1533 uninitsWhenFalse.inclRange(firstadr, nextadr); | 1552 uninitsWhenFalse.inclRange(firstadr, nextadr); |
1534 initsWhenTrue = inits; | 1553 initsWhenTrue.assign(inits); |
1535 uninitsWhenTrue = uninits; | 1554 uninitsWhenTrue.assign(uninits); |
1536 } else { | 1555 } else { |
1537 scan(tree); | 1556 scan(tree); |
1538 if (inits != null) | 1557 if (!inits.isReset()) |
1539 split(tree.type != syms.unknownType); | 1558 split(tree.type != syms.unknownType); |
1540 } | 1559 } |
1541 if (tree.type != syms.unknownType) | 1560 if (tree.type != syms.unknownType) { |
1542 inits = uninits = null; | 1561 resetBits(inits, uninits); |
1562 } | |
1543 } | 1563 } |
1544 | 1564 |
1545 /* ------------ Visitor methods for various sorts of trees -------------*/ | 1565 /* ------------ Visitor methods for various sorts of trees -------------*/ |
1546 | 1566 |
1547 public void visitClassDef(JCClassDecl tree) { | 1567 public void visitClassDef(JCClassDecl tree) { |
1617 } | 1637 } |
1618 | 1638 |
1619 public void visitMethodDef(JCMethodDecl tree) { | 1639 public void visitMethodDef(JCMethodDecl tree) { |
1620 if (tree.body == null) return; | 1640 if (tree.body == null) return; |
1621 | 1641 |
1622 Bits initsPrev = inits.dup(); | 1642 final Bits initsPrev = new Bits(inits); |
1623 Bits uninitsPrev = uninits.dup(); | 1643 final Bits uninitsPrev = new Bits(uninits); |
1624 int nextadrPrev = nextadr; | 1644 int nextadrPrev = nextadr; |
1625 int firstadrPrev = firstadr; | 1645 int firstadrPrev = firstadr; |
1626 int returnadrPrev = returnadr; | 1646 int returnadrPrev = returnadr; |
1627 Lint lintPrev = lint; | 1647 Lint lintPrev = lint; |
1628 | 1648 |
1656 while (exits.nonEmpty()) { | 1676 while (exits.nonEmpty()) { |
1657 AssignPendingExit exit = exits.head; | 1677 AssignPendingExit exit = exits.head; |
1658 exits = exits.tail; | 1678 exits = exits.tail; |
1659 Assert.check(exit.tree.hasTag(RETURN), exit.tree); | 1679 Assert.check(exit.tree.hasTag(RETURN), exit.tree); |
1660 if (isInitialConstructor) { | 1680 if (isInitialConstructor) { |
1661 inits = exit.exit_inits; | 1681 inits.assign(exit.exit_inits); |
1662 for (int i = firstadr; i < nextadr; i++) | 1682 for (int i = firstadr; i < nextadr; i++) |
1663 checkInit(exit.tree.pos(), vars[i]); | 1683 checkInit(exit.tree.pos(), vars[i]); |
1664 } | 1684 } |
1665 } | 1685 } |
1666 } finally { | 1686 } finally { |
1667 inits = initsPrev; | 1687 inits.assign(initsPrev); |
1668 uninits = uninitsPrev; | 1688 uninits.assign(uninitsPrev); |
1669 nextadr = nextadrPrev; | 1689 nextadr = nextadrPrev; |
1670 firstadr = firstadrPrev; | 1690 firstadr = firstadrPrev; |
1671 returnadr = returnadrPrev; | 1691 returnadr = returnadrPrev; |
1672 lint = lintPrev; | 1692 lint = lintPrev; |
1673 } | 1693 } |
1696 | 1716 |
1697 public void visitDoLoop(JCDoWhileLoop tree) { | 1717 public void visitDoLoop(JCDoWhileLoop tree) { |
1698 ListBuffer<AssignPendingExit> prevPendingExits = pendingExits; | 1718 ListBuffer<AssignPendingExit> prevPendingExits = pendingExits; |
1699 FlowKind prevFlowKind = flowKind; | 1719 FlowKind prevFlowKind = flowKind; |
1700 flowKind = FlowKind.NORMAL; | 1720 flowKind = FlowKind.NORMAL; |
1701 Bits initsSkip = null; | 1721 final Bits initsSkip = new Bits(true); |
1702 Bits uninitsSkip = null; | 1722 final Bits uninitsSkip = new Bits(true); |
1703 pendingExits = new ListBuffer<AssignPendingExit>(); | 1723 pendingExits = new ListBuffer<AssignPendingExit>(); |
1704 int prevErrors = log.nerrors; | 1724 int prevErrors = log.nerrors; |
1705 do { | 1725 do { |
1706 Bits uninitsEntry = uninits.dup(); | 1726 final Bits uninitsEntry = new Bits(uninits); |
1707 uninitsEntry.excludeFrom(nextadr); | 1727 uninitsEntry.excludeFrom(nextadr); |
1708 scan(tree.body); | 1728 scan(tree.body); |
1709 resolveContinues(tree); | 1729 resolveContinues(tree); |
1710 scanCond(tree.cond); | 1730 scanCond(tree.cond); |
1711 if (!flowKind.isFinal()) { | 1731 if (!flowKind.isFinal()) { |
1712 initsSkip = initsWhenFalse; | 1732 initsSkip.assign(initsWhenFalse); |
1713 uninitsSkip = uninitsWhenFalse; | 1733 uninitsSkip.assign(uninitsWhenFalse); |
1714 } | 1734 } |
1715 if (log.nerrors != prevErrors || | 1735 if (log.nerrors != prevErrors || |
1716 flowKind.isFinal() || | 1736 flowKind.isFinal() || |
1717 uninitsEntry.dup().diffSet(uninitsWhenTrue).nextBit(firstadr)==-1) | 1737 new Bits(uninitsEntry).diffSet(uninitsWhenTrue).nextBit(firstadr)==-1) |
1718 break; | 1738 break; |
1719 inits = initsWhenTrue; | 1739 inits.assign(initsWhenTrue); |
1720 uninits = uninitsEntry.andSet(uninitsWhenTrue); | 1740 uninits.assign(uninitsEntry.andSet(uninitsWhenTrue)); |
1721 flowKind = FlowKind.SPECULATIVE_LOOP; | 1741 flowKind = FlowKind.SPECULATIVE_LOOP; |
1722 } while (true); | 1742 } while (true); |
1723 flowKind = prevFlowKind; | 1743 flowKind = prevFlowKind; |
1724 inits = initsSkip; | 1744 inits.assign(initsSkip); |
1725 uninits = uninitsSkip; | 1745 uninits.assign(uninitsSkip); |
1726 resolveBreaks(tree, prevPendingExits); | 1746 resolveBreaks(tree, prevPendingExits); |
1727 } | 1747 } |
1728 | 1748 |
1729 public void visitWhileLoop(JCWhileLoop tree) { | 1749 public void visitWhileLoop(JCWhileLoop tree) { |
1730 ListBuffer<AssignPendingExit> prevPendingExits = pendingExits; | 1750 ListBuffer<AssignPendingExit> prevPendingExits = pendingExits; |
1731 FlowKind prevFlowKind = flowKind; | 1751 FlowKind prevFlowKind = flowKind; |
1732 flowKind = FlowKind.NORMAL; | 1752 flowKind = FlowKind.NORMAL; |
1733 Bits initsSkip = null; | 1753 final Bits initsSkip = new Bits(true); |
1734 Bits uninitsSkip = null; | 1754 final Bits uninitsSkip = new Bits(true); |
1735 pendingExits = new ListBuffer<AssignPendingExit>(); | 1755 pendingExits = new ListBuffer<AssignPendingExit>(); |
1736 int prevErrors = log.nerrors; | 1756 int prevErrors = log.nerrors; |
1737 Bits uninitsEntry = uninits.dup(); | 1757 final Bits uninitsEntry = new Bits(uninits); |
1738 uninitsEntry.excludeFrom(nextadr); | 1758 uninitsEntry.excludeFrom(nextadr); |
1739 do { | 1759 do { |
1740 scanCond(tree.cond); | 1760 scanCond(tree.cond); |
1741 if (!flowKind.isFinal()) { | 1761 if (!flowKind.isFinal()) { |
1742 initsSkip = initsWhenFalse; | 1762 initsSkip.assign(initsWhenFalse) ; |
1743 uninitsSkip = uninitsWhenFalse; | 1763 uninitsSkip.assign(uninitsWhenFalse); |
1744 } | 1764 } |
1745 inits = initsWhenTrue; | 1765 inits.assign(initsWhenTrue); |
1746 uninits = uninitsWhenTrue; | 1766 uninits.assign(uninitsWhenTrue); |
1747 scan(tree.body); | 1767 scan(tree.body); |
1748 resolveContinues(tree); | 1768 resolveContinues(tree); |
1749 if (log.nerrors != prevErrors || | 1769 if (log.nerrors != prevErrors || |
1750 flowKind.isFinal() || | 1770 flowKind.isFinal() || |
1751 uninitsEntry.dup().diffSet(uninits).nextBit(firstadr) == -1) | 1771 new Bits(uninitsEntry).diffSet(uninits).nextBit(firstadr) == -1) |
1752 break; | 1772 break; |
1753 uninits = uninitsEntry.andSet(uninits); | 1773 uninits.assign(uninitsEntry.andSet(uninits)); |
1754 flowKind = FlowKind.SPECULATIVE_LOOP; | 1774 flowKind = FlowKind.SPECULATIVE_LOOP; |
1755 } while (true); | 1775 } while (true); |
1756 flowKind = prevFlowKind; | 1776 flowKind = prevFlowKind; |
1757 //a variable is DA/DU after the while statement, if it's DA/DU assuming the | 1777 //a variable is DA/DU after the while statement, if it's DA/DU assuming the |
1758 //branch is not taken AND if it's DA/DU before any break statement | 1778 //branch is not taken AND if it's DA/DU before any break statement |
1759 inits = initsSkip; | 1779 inits.assign(initsSkip); |
1760 uninits = uninitsSkip; | 1780 uninits.assign(uninitsSkip); |
1761 resolveBreaks(tree, prevPendingExits); | 1781 resolveBreaks(tree, prevPendingExits); |
1762 } | 1782 } |
1763 | 1783 |
1764 public void visitForLoop(JCForLoop tree) { | 1784 public void visitForLoop(JCForLoop tree) { |
1765 ListBuffer<AssignPendingExit> prevPendingExits = pendingExits; | 1785 ListBuffer<AssignPendingExit> prevPendingExits = pendingExits; |
1766 FlowKind prevFlowKind = flowKind; | 1786 FlowKind prevFlowKind = flowKind; |
1767 flowKind = FlowKind.NORMAL; | 1787 flowKind = FlowKind.NORMAL; |
1768 int nextadrPrev = nextadr; | 1788 int nextadrPrev = nextadr; |
1769 scan(tree.init); | 1789 scan(tree.init); |
1770 Bits initsSkip = null; | 1790 final Bits initsSkip = new Bits(true); |
1771 Bits uninitsSkip = null; | 1791 final Bits uninitsSkip = new Bits(true); |
1772 pendingExits = new ListBuffer<AssignPendingExit>(); | 1792 pendingExits = new ListBuffer<AssignPendingExit>(); |
1773 int prevErrors = log.nerrors; | 1793 int prevErrors = log.nerrors; |
1774 do { | 1794 do { |
1775 Bits uninitsEntry = uninits.dup(); | 1795 final Bits uninitsEntry = new Bits(uninits); |
1776 uninitsEntry.excludeFrom(nextadr); | 1796 uninitsEntry.excludeFrom(nextadr); |
1777 if (tree.cond != null) { | 1797 if (tree.cond != null) { |
1778 scanCond(tree.cond); | 1798 scanCond(tree.cond); |
1779 if (!flowKind.isFinal()) { | 1799 if (!flowKind.isFinal()) { |
1780 initsSkip = initsWhenFalse; | 1800 initsSkip.assign(initsWhenFalse); |
1781 uninitsSkip = uninitsWhenFalse; | 1801 uninitsSkip.assign(uninitsWhenFalse); |
1782 } | 1802 } |
1783 inits = initsWhenTrue; | 1803 inits.assign(initsWhenTrue); |
1784 uninits = uninitsWhenTrue; | 1804 uninits.assign(uninitsWhenTrue); |
1785 } else if (!flowKind.isFinal()) { | 1805 } else if (!flowKind.isFinal()) { |
1786 initsSkip = inits.dup(); | 1806 initsSkip.assign(inits); |
1787 initsSkip.inclRange(firstadr, nextadr); | 1807 initsSkip.inclRange(firstadr, nextadr); |
1788 uninitsSkip = uninits.dup(); | 1808 uninitsSkip.assign(uninits); |
1789 uninitsSkip.inclRange(firstadr, nextadr); | 1809 uninitsSkip.inclRange(firstadr, nextadr); |
1790 } | 1810 } |
1791 scan(tree.body); | 1811 scan(tree.body); |
1792 resolveContinues(tree); | 1812 resolveContinues(tree); |
1793 scan(tree.step); | 1813 scan(tree.step); |
1794 if (log.nerrors != prevErrors || | 1814 if (log.nerrors != prevErrors || |
1795 flowKind.isFinal() || | 1815 flowKind.isFinal() || |
1796 uninitsEntry.dup().diffSet(uninits).nextBit(firstadr) == -1) | 1816 new Bits(uninitsEntry).diffSet(uninits).nextBit(firstadr) == -1) |
1797 break; | 1817 break; |
1798 uninits = uninitsEntry.andSet(uninits); | 1818 uninits.assign(uninitsEntry.andSet(uninits)); |
1799 flowKind = FlowKind.SPECULATIVE_LOOP; | 1819 flowKind = FlowKind.SPECULATIVE_LOOP; |
1800 } while (true); | 1820 } while (true); |
1801 flowKind = prevFlowKind; | 1821 flowKind = prevFlowKind; |
1802 //a variable is DA/DU after a for loop, if it's DA/DU assuming the | 1822 //a variable is DA/DU after a for loop, if it's DA/DU assuming the |
1803 //branch is not taken AND if it's DA/DU before any break statement | 1823 //branch is not taken AND if it's DA/DU before any break statement |
1804 inits = initsSkip; | 1824 inits.assign(initsSkip); |
1805 uninits = uninitsSkip; | 1825 uninits.assign(uninitsSkip); |
1806 resolveBreaks(tree, prevPendingExits); | 1826 resolveBreaks(tree, prevPendingExits); |
1807 nextadr = nextadrPrev; | 1827 nextadr = nextadrPrev; |
1808 } | 1828 } |
1809 | 1829 |
1810 public void visitForeachLoop(JCEnhancedForLoop tree) { | 1830 public void visitForeachLoop(JCEnhancedForLoop tree) { |
1813 ListBuffer<AssignPendingExit> prevPendingExits = pendingExits; | 1833 ListBuffer<AssignPendingExit> prevPendingExits = pendingExits; |
1814 FlowKind prevFlowKind = flowKind; | 1834 FlowKind prevFlowKind = flowKind; |
1815 flowKind = FlowKind.NORMAL; | 1835 flowKind = FlowKind.NORMAL; |
1816 int nextadrPrev = nextadr; | 1836 int nextadrPrev = nextadr; |
1817 scan(tree.expr); | 1837 scan(tree.expr); |
1818 Bits initsStart = inits.dup(); | 1838 final Bits initsStart = new Bits(inits); |
1819 Bits uninitsStart = uninits.dup(); | 1839 final Bits uninitsStart = new Bits(uninits); |
1820 | 1840 |
1821 letInit(tree.pos(), tree.var.sym); | 1841 letInit(tree.pos(), tree.var.sym); |
1822 pendingExits = new ListBuffer<AssignPendingExit>(); | 1842 pendingExits = new ListBuffer<AssignPendingExit>(); |
1823 int prevErrors = log.nerrors; | 1843 int prevErrors = log.nerrors; |
1824 do { | 1844 do { |
1825 Bits uninitsEntry = uninits.dup(); | 1845 final Bits uninitsEntry = new Bits(uninits); |
1826 uninitsEntry.excludeFrom(nextadr); | 1846 uninitsEntry.excludeFrom(nextadr); |
1827 scan(tree.body); | 1847 scan(tree.body); |
1828 resolveContinues(tree); | 1848 resolveContinues(tree); |
1829 if (log.nerrors != prevErrors || | 1849 if (log.nerrors != prevErrors || |
1830 flowKind.isFinal() || | 1850 flowKind.isFinal() || |
1831 uninitsEntry.dup().diffSet(uninits).nextBit(firstadr) == -1) | 1851 new Bits(uninitsEntry).diffSet(uninits).nextBit(firstadr) == -1) |
1832 break; | 1852 break; |
1833 uninits = uninitsEntry.andSet(uninits); | 1853 uninits.assign(uninitsEntry.andSet(uninits)); |
1834 flowKind = FlowKind.SPECULATIVE_LOOP; | 1854 flowKind = FlowKind.SPECULATIVE_LOOP; |
1835 } while (true); | 1855 } while (true); |
1836 flowKind = prevFlowKind; | 1856 flowKind = prevFlowKind; |
1837 inits = initsStart; | 1857 inits.assign(initsStart); |
1838 uninits = uninitsStart.andSet(uninits); | 1858 uninits.assign(uninitsStart.andSet(uninits)); |
1839 resolveBreaks(tree, prevPendingExits); | 1859 resolveBreaks(tree, prevPendingExits); |
1840 nextadr = nextadrPrev; | 1860 nextadr = nextadrPrev; |
1841 } | 1861 } |
1842 | 1862 |
1843 public void visitLabelled(JCLabeledStatement tree) { | 1863 public void visitLabelled(JCLabeledStatement tree) { |
1850 public void visitSwitch(JCSwitch tree) { | 1870 public void visitSwitch(JCSwitch tree) { |
1851 ListBuffer<AssignPendingExit> prevPendingExits = pendingExits; | 1871 ListBuffer<AssignPendingExit> prevPendingExits = pendingExits; |
1852 pendingExits = new ListBuffer<AssignPendingExit>(); | 1872 pendingExits = new ListBuffer<AssignPendingExit>(); |
1853 int nextadrPrev = nextadr; | 1873 int nextadrPrev = nextadr; |
1854 scanExpr(tree.selector); | 1874 scanExpr(tree.selector); |
1855 Bits initsSwitch = inits; | 1875 final Bits initsSwitch = new Bits(inits); |
1856 Bits uninitsSwitch = uninits.dup(); | 1876 final Bits uninitsSwitch = new Bits(uninits); |
1857 boolean hasDefault = false; | 1877 boolean hasDefault = false; |
1858 for (List<JCCase> l = tree.cases; l.nonEmpty(); l = l.tail) { | 1878 for (List<JCCase> l = tree.cases; l.nonEmpty(); l = l.tail) { |
1859 inits = initsSwitch.dup(); | 1879 inits.assign(initsSwitch); |
1860 uninits = uninits.andSet(uninitsSwitch); | 1880 uninits.assign(uninits.andSet(uninitsSwitch)); |
1861 JCCase c = l.head; | 1881 JCCase c = l.head; |
1862 if (c.pat == null) | 1882 if (c.pat == null) |
1863 hasDefault = true; | 1883 hasDefault = true; |
1864 else | 1884 else |
1865 scanExpr(c.pat); | 1885 scanExpr(c.pat); |
1873 resolveBreaks(tree, prevPendingExits); | 1893 resolveBreaks(tree, prevPendingExits); |
1874 nextadr = nextadrPrev; | 1894 nextadr = nextadrPrev; |
1875 } | 1895 } |
1876 // where | 1896 // where |
1877 /** Add any variables defined in stats to inits and uninits. */ | 1897 /** Add any variables defined in stats to inits and uninits. */ |
1878 private void addVars(List<JCStatement> stats, Bits inits, | 1898 private void addVars(List<JCStatement> stats, final Bits inits, |
1879 Bits uninits) { | 1899 final Bits uninits) { |
1880 for (;stats.nonEmpty(); stats = stats.tail) { | 1900 for (;stats.nonEmpty(); stats = stats.tail) { |
1881 JCTree stat = stats.head; | 1901 JCTree stat = stats.head; |
1882 if (stat.hasTag(VARDEF)) { | 1902 if (stat.hasTag(VARDEF)) { |
1883 int adr = ((JCVariableDecl) stat).sym.adr; | 1903 int adr = ((JCVariableDecl) stat).sym.adr; |
1884 inits.excl(adr); | 1904 inits.excl(adr); |
1887 } | 1907 } |
1888 } | 1908 } |
1889 | 1909 |
1890 public void visitTry(JCTry tree) { | 1910 public void visitTry(JCTry tree) { |
1891 ListBuffer<JCVariableDecl> resourceVarDecls = ListBuffer.lb(); | 1911 ListBuffer<JCVariableDecl> resourceVarDecls = ListBuffer.lb(); |
1892 Bits uninitsTryPrev = uninitsTry; | 1912 final Bits uninitsTryPrev = new Bits(uninitsTry); |
1893 ListBuffer<AssignPendingExit> prevPendingExits = pendingExits; | 1913 ListBuffer<AssignPendingExit> prevPendingExits = pendingExits; |
1894 pendingExits = new ListBuffer<AssignPendingExit>(); | 1914 pendingExits = new ListBuffer<AssignPendingExit>(); |
1895 Bits initsTry = inits.dup(); | 1915 final Bits initsTry = new Bits(inits); |
1896 uninitsTry = uninits.dup(); | 1916 uninitsTry.assign(uninits); |
1897 for (JCTree resource : tree.resources) { | 1917 for (JCTree resource : tree.resources) { |
1898 if (resource instanceof JCVariableDecl) { | 1918 if (resource instanceof JCVariableDecl) { |
1899 JCVariableDecl vdecl = (JCVariableDecl) resource; | 1919 JCVariableDecl vdecl = (JCVariableDecl) resource; |
1900 visitVarDef(vdecl); | 1920 visitVarDef(vdecl); |
1901 unrefdResources.enter(vdecl.sym); | 1921 unrefdResources.enter(vdecl.sym); |
1906 throw new AssertionError(tree); // parser error | 1926 throw new AssertionError(tree); // parser error |
1907 } | 1927 } |
1908 } | 1928 } |
1909 scan(tree.body); | 1929 scan(tree.body); |
1910 uninitsTry.andSet(uninits); | 1930 uninitsTry.andSet(uninits); |
1911 Bits initsEnd = inits; | 1931 final Bits initsEnd = new Bits(inits); |
1912 Bits uninitsEnd = uninits; | 1932 final Bits uninitsEnd = new Bits(uninits); |
1913 int nextadrCatch = nextadr; | 1933 int nextadrCatch = nextadr; |
1914 | 1934 |
1915 if (!resourceVarDecls.isEmpty() && | 1935 if (!resourceVarDecls.isEmpty() && |
1916 lint.isEnabled(Lint.LintCategory.TRY)) { | 1936 lint.isEnabled(Lint.LintCategory.TRY)) { |
1917 for (JCVariableDecl resVar : resourceVarDecls) { | 1937 for (JCVariableDecl resVar : resourceVarDecls) { |
1923 } | 1943 } |
1924 } | 1944 } |
1925 | 1945 |
1926 for (List<JCCatch> l = tree.catchers; l.nonEmpty(); l = l.tail) { | 1946 for (List<JCCatch> l = tree.catchers; l.nonEmpty(); l = l.tail) { |
1927 JCVariableDecl param = l.head.param; | 1947 JCVariableDecl param = l.head.param; |
1928 inits = initsTry.dup(); | 1948 inits.assign(initsTry); |
1929 uninits = uninitsTry.dup(); | 1949 uninits.assign(uninitsTry); |
1930 scan(param); | 1950 scan(param); |
1931 inits.incl(param.sym.adr); | 1951 inits.incl(param.sym.adr); |
1932 uninits.excl(param.sym.adr); | 1952 uninits.excl(param.sym.adr); |
1933 scan(l.head.body); | 1953 scan(l.head.body); |
1934 initsEnd.andSet(inits); | 1954 initsEnd.andSet(inits); |
1935 uninitsEnd.andSet(uninits); | 1955 uninitsEnd.andSet(uninits); |
1936 nextadr = nextadrCatch; | 1956 nextadr = nextadrCatch; |
1937 } | 1957 } |
1938 if (tree.finalizer != null) { | 1958 if (tree.finalizer != null) { |
1939 inits = initsTry.dup(); | 1959 inits.assign(initsTry); |
1940 uninits = uninitsTry.dup(); | 1960 uninits.assign(uninitsTry); |
1941 ListBuffer<AssignPendingExit> exits = pendingExits; | 1961 ListBuffer<AssignPendingExit> exits = pendingExits; |
1942 pendingExits = prevPendingExits; | 1962 pendingExits = prevPendingExits; |
1943 scan(tree.finalizer); | 1963 scan(tree.finalizer); |
1944 if (!tree.finallyCanCompleteNormally) { | 1964 if (!tree.finallyCanCompleteNormally) { |
1945 // discard exits and exceptions from try and finally | 1965 // discard exits and exceptions from try and finally |
1956 pendingExits.append(exit); | 1976 pendingExits.append(exit); |
1957 } | 1977 } |
1958 inits.orSet(initsEnd); | 1978 inits.orSet(initsEnd); |
1959 } | 1979 } |
1960 } else { | 1980 } else { |
1961 inits = initsEnd; | 1981 inits.assign(initsEnd); |
1962 uninits = uninitsEnd; | 1982 uninits.assign(uninitsEnd); |
1963 ListBuffer<AssignPendingExit> exits = pendingExits; | 1983 ListBuffer<AssignPendingExit> exits = pendingExits; |
1964 pendingExits = prevPendingExits; | 1984 pendingExits = prevPendingExits; |
1965 while (exits.nonEmpty()) pendingExits.append(exits.next()); | 1985 while (exits.nonEmpty()) pendingExits.append(exits.next()); |
1966 } | 1986 } |
1967 uninitsTry.andSet(uninitsTryPrev).andSet(uninits); | 1987 uninitsTry.andSet(uninitsTryPrev).andSet(uninits); |
1968 } | 1988 } |
1969 | 1989 |
1970 public void visitConditional(JCConditional tree) { | 1990 public void visitConditional(JCConditional tree) { |
1971 scanCond(tree.cond); | 1991 scanCond(tree.cond); |
1972 Bits initsBeforeElse = initsWhenFalse; | 1992 final Bits initsBeforeElse = new Bits(initsWhenFalse); |
1973 Bits uninitsBeforeElse = uninitsWhenFalse; | 1993 final Bits uninitsBeforeElse = new Bits(uninitsWhenFalse); |
1974 inits = initsWhenTrue; | 1994 inits.assign(initsWhenTrue); |
1975 uninits = uninitsWhenTrue; | 1995 uninits.assign(uninitsWhenTrue); |
1976 if (tree.truepart.type.hasTag(BOOLEAN) && | 1996 if (tree.truepart.type.hasTag(BOOLEAN) && |
1977 tree.falsepart.type.hasTag(BOOLEAN)) { | 1997 tree.falsepart.type.hasTag(BOOLEAN)) { |
1978 // if b and c are boolean valued, then | 1998 // if b and c are boolean valued, then |
1979 // v is (un)assigned after a?b:c when true iff | 1999 // v is (un)assigned after a?b:c when true iff |
1980 // v is (un)assigned after b when true and | 2000 // v is (un)assigned after b when true and |
1981 // v is (un)assigned after c when true | 2001 // v is (un)assigned after c when true |
1982 scanCond(tree.truepart); | 2002 scanCond(tree.truepart); |
1983 Bits initsAfterThenWhenTrue = initsWhenTrue.dup(); | 2003 final Bits initsAfterThenWhenTrue = new Bits(initsWhenTrue); |
1984 Bits initsAfterThenWhenFalse = initsWhenFalse.dup(); | 2004 final Bits initsAfterThenWhenFalse = new Bits(initsWhenFalse); |
1985 Bits uninitsAfterThenWhenTrue = uninitsWhenTrue.dup(); | 2005 final Bits uninitsAfterThenWhenTrue = new Bits(uninitsWhenTrue); |
1986 Bits uninitsAfterThenWhenFalse = uninitsWhenFalse.dup(); | 2006 final Bits uninitsAfterThenWhenFalse = new Bits(uninitsWhenFalse); |
1987 inits = initsBeforeElse; | 2007 inits.assign(initsBeforeElse); |
1988 uninits = uninitsBeforeElse; | 2008 uninits.assign(uninitsBeforeElse); |
1989 scanCond(tree.falsepart); | 2009 scanCond(tree.falsepart); |
1990 initsWhenTrue.andSet(initsAfterThenWhenTrue); | 2010 initsWhenTrue.andSet(initsAfterThenWhenTrue); |
1991 initsWhenFalse.andSet(initsAfterThenWhenFalse); | 2011 initsWhenFalse.andSet(initsAfterThenWhenFalse); |
1992 uninitsWhenTrue.andSet(uninitsAfterThenWhenTrue); | 2012 uninitsWhenTrue.andSet(uninitsAfterThenWhenTrue); |
1993 uninitsWhenFalse.andSet(uninitsAfterThenWhenFalse); | 2013 uninitsWhenFalse.andSet(uninitsAfterThenWhenFalse); |
1994 } else { | 2014 } else { |
1995 scanExpr(tree.truepart); | 2015 scanExpr(tree.truepart); |
1996 Bits initsAfterThen = inits.dup(); | 2016 final Bits initsAfterThen = new Bits(inits); |
1997 Bits uninitsAfterThen = uninits.dup(); | 2017 final Bits uninitsAfterThen = new Bits(uninits); |
1998 inits = initsBeforeElse; | 2018 inits.assign(initsBeforeElse); |
1999 uninits = uninitsBeforeElse; | 2019 uninits.assign(uninitsBeforeElse); |
2000 scanExpr(tree.falsepart); | 2020 scanExpr(tree.falsepart); |
2001 inits.andSet(initsAfterThen); | 2021 inits.andSet(initsAfterThen); |
2002 uninits.andSet(uninitsAfterThen); | 2022 uninits.andSet(uninitsAfterThen); |
2003 } | 2023 } |
2004 } | 2024 } |
2005 | 2025 |
2006 public void visitIf(JCIf tree) { | 2026 public void visitIf(JCIf tree) { |
2007 scanCond(tree.cond); | 2027 scanCond(tree.cond); |
2008 Bits initsBeforeElse = initsWhenFalse; | 2028 final Bits initsBeforeElse = new Bits(initsWhenFalse); |
2009 Bits uninitsBeforeElse = uninitsWhenFalse; | 2029 final Bits uninitsBeforeElse = new Bits(uninitsWhenFalse); |
2010 inits = initsWhenTrue; | 2030 inits.assign(initsWhenTrue); |
2011 uninits = uninitsWhenTrue; | 2031 uninits.assign(uninitsWhenTrue); |
2012 scan(tree.thenpart); | 2032 scan(tree.thenpart); |
2013 if (tree.elsepart != null) { | 2033 if (tree.elsepart != null) { |
2014 Bits initsAfterThen = inits.dup(); | 2034 final Bits initsAfterThen = new Bits(inits); |
2015 Bits uninitsAfterThen = uninits.dup(); | 2035 final Bits uninitsAfterThen = new Bits(uninits); |
2016 inits = initsBeforeElse; | 2036 inits.assign(initsBeforeElse); |
2017 uninits = uninitsBeforeElse; | 2037 uninits.assign(uninitsBeforeElse); |
2018 scan(tree.elsepart); | 2038 scan(tree.elsepart); |
2019 inits.andSet(initsAfterThen); | 2039 inits.andSet(initsAfterThen); |
2020 uninits.andSet(uninitsAfterThen); | 2040 uninits.andSet(uninitsAfterThen); |
2021 } else { | 2041 } else { |
2022 inits.andSet(initsBeforeElse); | 2042 inits.andSet(initsBeforeElse); |
2053 scan(tree.def); | 2073 scan(tree.def); |
2054 } | 2074 } |
2055 | 2075 |
2056 @Override | 2076 @Override |
2057 public void visitLambda(JCLambda tree) { | 2077 public void visitLambda(JCLambda tree) { |
2058 Bits prevUninits = uninits; | 2078 final Bits prevUninits = new Bits(uninits); |
2059 Bits prevInits = inits; | 2079 final Bits prevInits = new Bits(inits); |
2060 int returnadrPrev = returnadr; | 2080 int returnadrPrev = returnadr; |
2061 ListBuffer<AssignPendingExit> prevPending = pendingExits; | 2081 ListBuffer<AssignPendingExit> prevPending = pendingExits; |
2062 try { | 2082 try { |
2063 returnadr = nextadr; | 2083 returnadr = nextadr; |
2064 pendingExits = new ListBuffer<AssignPendingExit>(); | 2084 pendingExits = new ListBuffer<AssignPendingExit>(); |
2074 scan(tree.body); | 2094 scan(tree.body); |
2075 } | 2095 } |
2076 } | 2096 } |
2077 finally { | 2097 finally { |
2078 returnadr = returnadrPrev; | 2098 returnadr = returnadrPrev; |
2079 uninits = prevUninits; | 2099 uninits.assign(prevUninits); |
2080 inits = prevInits; | 2100 inits.assign(prevInits); |
2081 pendingExits = prevPending; | 2101 pendingExits = prevPending; |
2082 } | 2102 } |
2083 } | 2103 } |
2084 | 2104 |
2085 public void visitNewArray(JCNewArray tree) { | 2105 public void visitNewArray(JCNewArray tree) { |
2086 scanExprs(tree.dims); | 2106 scanExprs(tree.dims); |
2087 scanExprs(tree.elems); | 2107 scanExprs(tree.elems); |
2088 } | 2108 } |
2089 | 2109 |
2090 public void visitAssert(JCAssert tree) { | 2110 public void visitAssert(JCAssert tree) { |
2091 Bits initsExit = inits.dup(); | 2111 final Bits initsExit = new Bits(inits); |
2092 Bits uninitsExit = uninits.dup(); | 2112 final Bits uninitsExit = new Bits(uninits); |
2093 scanCond(tree.cond); | 2113 scanCond(tree.cond); |
2094 uninitsExit.andSet(uninitsWhenTrue); | 2114 uninitsExit.andSet(uninitsWhenTrue); |
2095 if (tree.detail != null) { | 2115 if (tree.detail != null) { |
2096 inits = initsWhenFalse; | 2116 inits.assign(initsWhenFalse); |
2097 uninits = uninitsWhenFalse; | 2117 uninits.assign(uninitsWhenFalse); |
2098 scanExpr(tree.detail); | 2118 scanExpr(tree.detail); |
2099 } | 2119 } |
2100 inits = initsExit; | 2120 inits.assign(initsExit); |
2101 uninits = uninitsExit; | 2121 uninits.assign(uninitsExit); |
2102 } | 2122 } |
2103 | 2123 |
2104 public void visitAssign(JCAssign tree) { | 2124 public void visitAssign(JCAssign tree) { |
2105 JCTree lhs = TreeInfo.skipParens(tree.lhs); | 2125 JCTree lhs = TreeInfo.skipParens(tree.lhs); |
2106 if (!(lhs instanceof JCIdent)) { | 2126 if (!(lhs instanceof JCIdent)) { |
2118 | 2138 |
2119 public void visitUnary(JCUnary tree) { | 2139 public void visitUnary(JCUnary tree) { |
2120 switch (tree.getTag()) { | 2140 switch (tree.getTag()) { |
2121 case NOT: | 2141 case NOT: |
2122 scanCond(tree.arg); | 2142 scanCond(tree.arg); |
2123 Bits t = initsWhenFalse; | 2143 final Bits t = new Bits(initsWhenFalse); |
2124 initsWhenFalse = initsWhenTrue; | 2144 initsWhenFalse.assign(initsWhenTrue); |
2125 initsWhenTrue = t; | 2145 initsWhenTrue.assign(t); |
2126 t = uninitsWhenFalse; | 2146 t.assign(uninitsWhenFalse); |
2127 uninitsWhenFalse = uninitsWhenTrue; | 2147 uninitsWhenFalse.assign(uninitsWhenTrue); |
2128 uninitsWhenTrue = t; | 2148 uninitsWhenTrue.assign(t); |
2129 break; | 2149 break; |
2130 case PREINC: case POSTINC: | 2150 case PREINC: case POSTINC: |
2131 case PREDEC: case POSTDEC: | 2151 case PREDEC: case POSTDEC: |
2132 scanExpr(tree.arg); | 2152 scanExpr(tree.arg); |
2133 letInit(tree.arg); | 2153 letInit(tree.arg); |
2139 | 2159 |
2140 public void visitBinary(JCBinary tree) { | 2160 public void visitBinary(JCBinary tree) { |
2141 switch (tree.getTag()) { | 2161 switch (tree.getTag()) { |
2142 case AND: | 2162 case AND: |
2143 scanCond(tree.lhs); | 2163 scanCond(tree.lhs); |
2144 Bits initsWhenFalseLeft = initsWhenFalse; | 2164 final Bits initsWhenFalseLeft = new Bits(initsWhenFalse); |
2145 Bits uninitsWhenFalseLeft = uninitsWhenFalse; | 2165 final Bits uninitsWhenFalseLeft = new Bits(uninitsWhenFalse); |
2146 inits = initsWhenTrue; | 2166 inits.assign(initsWhenTrue); |
2147 uninits = uninitsWhenTrue; | 2167 uninits.assign(uninitsWhenTrue); |
2148 scanCond(tree.rhs); | 2168 scanCond(tree.rhs); |
2149 initsWhenFalse.andSet(initsWhenFalseLeft); | 2169 initsWhenFalse.andSet(initsWhenFalseLeft); |
2150 uninitsWhenFalse.andSet(uninitsWhenFalseLeft); | 2170 uninitsWhenFalse.andSet(uninitsWhenFalseLeft); |
2151 break; | 2171 break; |
2152 case OR: | 2172 case OR: |
2153 scanCond(tree.lhs); | 2173 scanCond(tree.lhs); |
2154 Bits initsWhenTrueLeft = initsWhenTrue; | 2174 final Bits initsWhenTrueLeft = new Bits(initsWhenTrue); |
2155 Bits uninitsWhenTrueLeft = uninitsWhenTrue; | 2175 final Bits uninitsWhenTrueLeft = new Bits(uninitsWhenTrue); |
2156 inits = initsWhenFalse; | 2176 inits.assign(initsWhenFalse); |
2157 uninits = uninitsWhenFalse; | 2177 uninits.assign(uninitsWhenFalse); |
2158 scanCond(tree.rhs); | 2178 scanCond(tree.rhs); |
2159 initsWhenTrue.andSet(initsWhenTrueLeft); | 2179 initsWhenTrue.andSet(initsWhenTrueLeft); |
2160 uninitsWhenTrue.andSet(uninitsWhenTrueLeft); | 2180 uninitsWhenTrue.andSet(uninitsWhenTrueLeft); |
2161 break; | 2181 break; |
2162 default: | 2182 default: |
2198 public void analyzeTree(Env<AttrContext> env, JCTree tree, TreeMaker make) { | 2218 public void analyzeTree(Env<AttrContext> env, JCTree tree, TreeMaker make) { |
2199 try { | 2219 try { |
2200 attrEnv = env; | 2220 attrEnv = env; |
2201 Flow.this.make = make; | 2221 Flow.this.make = make; |
2202 startPos = tree.pos().getStartPosition(); | 2222 startPos = tree.pos().getStartPosition(); |
2203 inits = new Bits(); | 2223 |
2204 uninits = new Bits(); | |
2205 uninitsTry = new Bits(); | |
2206 initsWhenTrue = initsWhenFalse = | |
2207 uninitsWhenTrue = uninitsWhenFalse = null; | |
2208 if (vars == null) | 2224 if (vars == null) |
2209 vars = new VarSymbol[32]; | 2225 vars = new VarSymbol[32]; |
2210 else | 2226 else |
2211 for (int i=0; i<vars.length; i++) | 2227 for (int i=0; i<vars.length; i++) |
2212 vars[i] = null; | 2228 vars[i] = null; |
2217 unrefdResources = new Scope(env.enclClass.sym); | 2233 unrefdResources = new Scope(env.enclClass.sym); |
2218 scan(tree); | 2234 scan(tree); |
2219 } finally { | 2235 } finally { |
2220 // note that recursive invocations of this method fail hard | 2236 // note that recursive invocations of this method fail hard |
2221 startPos = -1; | 2237 startPos = -1; |
2222 inits = uninits = uninitsTry = null; | 2238 resetBits(inits, uninits, uninitsTry, initsWhenTrue, |
2223 initsWhenTrue = initsWhenFalse = | 2239 initsWhenFalse, uninitsWhenTrue, uninitsWhenFalse); |
2224 uninitsWhenTrue = uninitsWhenFalse = null; | |
2225 if (vars != null) for (int i=0; i<vars.length; i++) | 2240 if (vars != null) for (int i=0; i<vars.length; i++) |
2226 vars[i] = null; | 2241 vars[i] = null; |
2227 firstadr = 0; | 2242 firstadr = 0; |
2228 nextadr = 0; | 2243 nextadr = 0; |
2229 pendingExits = null; | 2244 pendingExits = null; |