1337 final Bits uninitsWhenTrue; |
1337 final Bits uninitsWhenTrue; |
1338 final Bits uninitsWhenFalse; |
1338 final Bits uninitsWhenFalse; |
1339 |
1339 |
1340 /** A mapping from addresses to variable symbols. |
1340 /** A mapping from addresses to variable symbols. |
1341 */ |
1341 */ |
1342 VarSymbol[] vars; |
1342 JCVariableDecl[] vardecls; |
1343 |
1343 |
1344 /** The current class being defined. |
1344 /** The current class being defined. |
1345 */ |
1345 */ |
1346 JCClassDecl classDef; |
1346 JCClassDecl classDef; |
1347 |
1347 |
1415 |
1415 |
1416 /** Initialize new trackable variable by setting its address field |
1416 /** Initialize new trackable variable by setting its address field |
1417 * to the next available sequence number and entering it under that |
1417 * to the next available sequence number and entering it under that |
1418 * index into the vars array. |
1418 * index into the vars array. |
1419 */ |
1419 */ |
1420 void newVar(VarSymbol sym) { |
1420 void newVar(JCVariableDecl varDecl) { |
1421 vars = ArrayUtils.ensureCapacity(vars, nextadr); |
1421 VarSymbol sym = varDecl.sym; |
|
1422 vardecls = ArrayUtils.ensureCapacity(vardecls, nextadr); |
1422 if ((sym.flags() & FINAL) == 0) { |
1423 if ((sym.flags() & FINAL) == 0) { |
1423 sym.flags_field |= EFFECTIVELY_FINAL; |
1424 sym.flags_field |= EFFECTIVELY_FINAL; |
1424 } |
1425 } |
1425 sym.adr = nextadr; |
1426 sym.adr = nextadr; |
1426 vars[nextadr] = sym; |
1427 vardecls[nextadr] = varDecl; |
1427 inits.excl(nextadr); |
1428 inits.excl(nextadr); |
1428 uninits.incl(nextadr); |
1429 uninits.incl(nextadr); |
1429 nextadr++; |
1430 nextadr++; |
1430 } |
1431 } |
1431 |
1432 |
1491 } |
1492 } |
1492 |
1493 |
1493 /** Check that trackable variable is initialized. |
1494 /** Check that trackable variable is initialized. |
1494 */ |
1495 */ |
1495 void checkInit(DiagnosticPosition pos, VarSymbol sym) { |
1496 void checkInit(DiagnosticPosition pos, VarSymbol sym) { |
|
1497 checkInit(pos, sym, "var.might.not.have.been.initialized"); |
|
1498 } |
|
1499 void checkInit(DiagnosticPosition pos, VarSymbol sym, String errkey) { |
1496 if ((sym.adr >= firstadr || sym.owner.kind != TYP) && |
1500 if ((sym.adr >= firstadr || sym.owner.kind != TYP) && |
1497 trackable(sym) && |
1501 trackable(sym) && |
1498 !inits.isMember(sym.adr)) { |
1502 !inits.isMember(sym.adr)) { |
1499 log.error(pos, "var.might.not.have.been.initialized", |
1503 log.error(pos, errkey, sym); |
1500 sym); |
|
1501 inits.incl(sym.adr); |
1504 inits.incl(sym.adr); |
1502 } |
1505 } |
1503 } |
1506 } |
1504 |
1507 |
1505 /** Split (duplicate) inits/uninits into WhenTrue/WhenFalse sets |
1508 /** Split (duplicate) inits/uninits into WhenTrue/WhenFalse sets |
1597 if (l.head.hasTag(VARDEF)) { |
1600 if (l.head.hasTag(VARDEF)) { |
1598 JCVariableDecl def = (JCVariableDecl)l.head; |
1601 JCVariableDecl def = (JCVariableDecl)l.head; |
1599 if ((def.mods.flags & STATIC) != 0) { |
1602 if ((def.mods.flags & STATIC) != 0) { |
1600 VarSymbol sym = def.sym; |
1603 VarSymbol sym = def.sym; |
1601 if (trackable(sym)) |
1604 if (trackable(sym)) |
1602 newVar(sym); |
1605 newVar(def); |
1603 } |
1606 } |
1604 } |
1607 } |
1605 } |
1608 } |
1606 |
1609 |
1607 // process all the static initializers |
1610 // process all the static initializers |
1617 if (l.head.hasTag(VARDEF)) { |
1620 if (l.head.hasTag(VARDEF)) { |
1618 JCVariableDecl def = (JCVariableDecl)l.head; |
1621 JCVariableDecl def = (JCVariableDecl)l.head; |
1619 if ((def.mods.flags & STATIC) == 0) { |
1622 if ((def.mods.flags & STATIC) == 0) { |
1620 VarSymbol sym = def.sym; |
1623 VarSymbol sym = def.sym; |
1621 if (trackable(sym)) |
1624 if (trackable(sym)) |
1622 newVar(sym); |
1625 newVar(def); |
1623 } |
1626 } |
1624 } |
1627 } |
1625 } |
1628 } |
1626 |
1629 |
1627 // process all the instance initializers |
1630 // process all the instance initializers |
1676 // else we are in an instance initializer block; |
1679 // else we are in an instance initializer block; |
1677 // leave caught unchanged. |
1680 // leave caught unchanged. |
1678 scan(tree.body); |
1681 scan(tree.body); |
1679 |
1682 |
1680 if (isInitialConstructor) { |
1683 if (isInitialConstructor) { |
1681 for (int i = firstadr; i < nextadr; i++) |
1684 boolean isSynthesized = (tree.sym.flags() & |
1682 if (vars[i].owner == classDef.sym) |
1685 GENERATEDCONSTR) != 0; |
1683 checkInit(TreeInfo.diagEndPos(tree.body), vars[i]); |
1686 for (int i = firstadr; i < nextadr; i++) { |
|
1687 JCVariableDecl vardecl = vardecls[i]; |
|
1688 VarSymbol var = vardecl.sym; |
|
1689 if (var.owner == classDef.sym) { |
|
1690 // choose the diagnostic position based on whether |
|
1691 // the ctor is default(synthesized) or not |
|
1692 if (isSynthesized) { |
|
1693 checkInit(TreeInfo.diagnosticPositionFor(var, vardecl), |
|
1694 var, "var.not.initialized.in.default.constructor"); |
|
1695 } else { |
|
1696 checkInit(TreeInfo.diagEndPos(tree.body), var); |
|
1697 } |
|
1698 } |
|
1699 } |
1684 } |
1700 } |
1685 List<AssignPendingExit> exits = pendingExits.toList(); |
1701 List<AssignPendingExit> exits = pendingExits.toList(); |
1686 pendingExits = new ListBuffer<AssignPendingExit>(); |
1702 pendingExits = new ListBuffer<AssignPendingExit>(); |
1687 while (exits.nonEmpty()) { |
1703 while (exits.nonEmpty()) { |
1688 AssignPendingExit exit = exits.head; |
1704 AssignPendingExit exit = exits.head; |
1689 exits = exits.tail; |
1705 exits = exits.tail; |
1690 Assert.check(exit.tree.hasTag(RETURN), exit.tree); |
1706 Assert.check(exit.tree.hasTag(RETURN), exit.tree); |
1691 if (isInitialConstructor) { |
1707 if (isInitialConstructor) { |
1692 inits.assign(exit.exit_inits); |
1708 inits.assign(exit.exit_inits); |
1693 for (int i = firstadr; i < nextadr; i++) |
1709 for (int i = firstadr; i < nextadr; i++) |
1694 checkInit(exit.tree.pos(), vars[i]); |
1710 checkInit(exit.tree.pos(), vardecls[i].sym); |
1695 } |
1711 } |
1696 } |
1712 } |
1697 } finally { |
1713 } finally { |
1698 inits.assign(initsPrev); |
1714 inits.assign(initsPrev); |
1699 uninits.assign(uninitsPrev); |
1715 uninits.assign(uninitsPrev); |
1704 } |
1720 } |
1705 } |
1721 } |
1706 |
1722 |
1707 public void visitVarDef(JCVariableDecl tree) { |
1723 public void visitVarDef(JCVariableDecl tree) { |
1708 boolean track = trackable(tree.sym); |
1724 boolean track = trackable(tree.sym); |
1709 if (track && tree.sym.owner.kind == MTH) newVar(tree.sym); |
1725 if (track && tree.sym.owner.kind == MTH) newVar(tree); |
1710 if (tree.init != null) { |
1726 if (tree.init != null) { |
1711 Lint lintPrev = lint; |
1727 Lint lintPrev = lint; |
1712 lint = lint.augment(tree.sym); |
1728 lint = lint.augment(tree.sym); |
1713 try{ |
1729 try{ |
1714 scanExpr(tree.init); |
1730 scanExpr(tree.init); |
2237 try { |
2253 try { |
2238 attrEnv = env; |
2254 attrEnv = env; |
2239 Flow.this.make = make; |
2255 Flow.this.make = make; |
2240 startPos = tree.pos().getStartPosition(); |
2256 startPos = tree.pos().getStartPosition(); |
2241 |
2257 |
2242 if (vars == null) |
2258 if (vardecls == null) |
2243 vars = new VarSymbol[32]; |
2259 vardecls = new JCVariableDecl[32]; |
2244 else |
2260 else |
2245 for (int i=0; i<vars.length; i++) |
2261 for (int i=0; i<vardecls.length; i++) |
2246 vars[i] = null; |
2262 vardecls[i] = null; |
2247 firstadr = 0; |
2263 firstadr = 0; |
2248 nextadr = 0; |
2264 nextadr = 0; |
2249 pendingExits = new ListBuffer<AssignPendingExit>(); |
2265 pendingExits = new ListBuffer<AssignPendingExit>(); |
2250 this.classDef = null; |
2266 this.classDef = null; |
2251 unrefdResources = new Scope(env.enclClass.sym); |
2267 unrefdResources = new Scope(env.enclClass.sym); |
2253 } finally { |
2269 } finally { |
2254 // note that recursive invocations of this method fail hard |
2270 // note that recursive invocations of this method fail hard |
2255 startPos = -1; |
2271 startPos = -1; |
2256 resetBits(inits, uninits, uninitsTry, initsWhenTrue, |
2272 resetBits(inits, uninits, uninitsTry, initsWhenTrue, |
2257 initsWhenFalse, uninitsWhenTrue, uninitsWhenFalse); |
2273 initsWhenFalse, uninitsWhenTrue, uninitsWhenFalse); |
2258 if (vars != null) for (int i=0; i<vars.length; i++) |
2274 if (vardecls != null) for (int i=0; i<vardecls.length; i++) |
2259 vars[i] = null; |
2275 vardecls[i] = null; |
2260 firstadr = 0; |
2276 firstadr = 0; |
2261 nextadr = 0; |
2277 nextadr = 0; |
2262 pendingExits = null; |
2278 pendingExits = null; |
2263 Flow.this.make = null; |
2279 Flow.this.make = null; |
2264 this.classDef = null; |
2280 this.classDef = null; |