提交 da351bac 编写于 作者: A asaha

Merge

...@@ -440,3 +440,4 @@ e7e42c79861ea1ab7495de5f238c01f98035a8a8 jdk8u60-b18 ...@@ -440,3 +440,4 @@ e7e42c79861ea1ab7495de5f238c01f98035a8a8 jdk8u60-b18
0366d7f1faa12ed35694571c151524e0847f05ff jdk8u60-b19 0366d7f1faa12ed35694571c151524e0847f05ff jdk8u60-b19
976523f1d5626bdb6dd47883e2734614b64a5e61 jdk8u60-b20 976523f1d5626bdb6dd47883e2734614b64a5e61 jdk8u60-b20
97328f3e2aa2c713931edf471270a1208980b963 jdk8u60-b21 97328f3e2aa2c713931edf471270a1208980b963 jdk8u60-b21
d1febf79ce5ea41fb4b818ffd3589cf923e6de5f jdk8u60-b22
...@@ -1140,37 +1140,6 @@ included with JRE 8, JDK 8, and OpenJDK 8. ...@@ -1140,37 +1140,6 @@ included with JRE 8, JDK 8, and OpenJDK 8.
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
%% This notice is provided with respect to JSON, which may be included
with JRE 8 & JDK 8.
--- begin of LICENSE ---
Copyright (c) 2002 JSON.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
The Software shall be used for Good, not Evil.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
--- end of LICENSE ---
-------------------------------------------------------------------------------
%% This notice is provided with respect to Kerberos functionality, which %% This notice is provided with respect to Kerberos functionality, which
which may be included with JRE 8, JDK 8, and OpenJDK 8. which may be included with JRE 8, JDK 8, and OpenJDK 8.
...@@ -1250,7 +1219,7 @@ included with JDK 8 and OpenJDK 8 source distributions. ...@@ -1250,7 +1219,7 @@ included with JDK 8 and OpenJDK 8 source distributions.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
%% This notice is provided with respect to libpng 1.6.16, which may be %% This notice is provided with respect to libpng 1.6.16, which may be
included with JRE 8, JDK 8, and OpenJDK 8. included with JRE 8, JDK 8, and OpenJDK 8.
--- begin of LICENSE --- --- begin of LICENSE ---
...@@ -1370,7 +1339,7 @@ December 22, 2014 ...@@ -1370,7 +1339,7 @@ December 22, 2014
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
%% This notice is provided with respect to libungif 4.1.3, which may be %% This notice is provided with respect to GIFLIB 5.1.1 & libungif 4.1.3, which may be
included with JRE 8, JDK 8, and OpenJDK 8. included with JRE 8, JDK 8, and OpenJDK 8.
--- begin of LICENSE --- --- begin of LICENSE ---
...@@ -1399,13 +1368,13 @@ THE SOFTWARE. ...@@ -1399,13 +1368,13 @@ THE SOFTWARE.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
%% This notice is provided with respect to Little CMS 2.5, which may be %% This notice is provided with respect to Little CMS 2.7, which may be
included with JRE 8, JDK 8, and OpenJDK 8. included with JRE 8, JDK 8, and OpenJDK 8.
--- begin of LICENSE --- --- begin of LICENSE ---
Little CMS Little CMS
Copyright (c) 1998-2011 Marti Maria Saguer Copyright (c) 1998-2015 Marti Maria Saguer
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
......
/* /*
* Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -353,17 +353,17 @@ public class Flow { ...@@ -353,17 +353,17 @@ public class Flow {
this.tree = tree; this.tree = tree;
} }
void resolveJump(JCTree tree) { void resolveJump() {
//do nothing //do nothing
} }
} }
abstract void markDead(JCTree tree); abstract void markDead();
/** Record an outward transfer of control. */ /** Record an outward transfer of control. */
void recordExit(JCTree tree, P pe) { void recordExit(P pe) {
pendingExits.append(pe); pendingExits.append(pe);
markDead(tree); markDead();
} }
/** Resolve all jumps of this statement. */ /** Resolve all jumps of this statement. */
...@@ -377,7 +377,7 @@ public class Flow { ...@@ -377,7 +377,7 @@ public class Flow {
P exit = exits.head; P exit = exits.head;
if (exit.tree.hasTag(jk.treeTag) && if (exit.tree.hasTag(jk.treeTag) &&
jk.getTarget(exit.tree) == tree) { jk.getTarget(exit.tree) == tree) {
exit.resolveJump(tree); exit.resolveJump();
resolved = true; resolved = true;
} else { } else {
pendingExits.append(exit); pendingExits.append(exit);
...@@ -420,7 +420,7 @@ public class Flow { ...@@ -420,7 +420,7 @@ public class Flow {
private boolean alive; private boolean alive;
@Override @Override
void markDead(JCTree tree) { void markDead() {
alive = false; alive = false;
} }
...@@ -464,7 +464,7 @@ public class Flow { ...@@ -464,7 +464,7 @@ public class Flow {
ListBuffer<PendingExit> pendingExitsPrev = pendingExits; ListBuffer<PendingExit> pendingExitsPrev = pendingExits;
Lint lintPrev = lint; Lint lintPrev = lint;
pendingExits = new ListBuffer<PendingExit>(); pendingExits = new ListBuffer<>();
lint = lint.augment(tree.sym); lint = lint.augment(tree.sym);
try { try {
...@@ -513,7 +513,7 @@ public class Flow { ...@@ -513,7 +513,7 @@ public class Flow {
log.error(TreeInfo.diagEndPos(tree.body), "missing.ret.stmt"); log.error(TreeInfo.diagEndPos(tree.body), "missing.ret.stmt");
List<PendingExit> exits = pendingExits.toList(); List<PendingExit> exits = pendingExits.toList();
pendingExits = new ListBuffer<PendingExit>(); pendingExits = new ListBuffer<>();
while (exits.nonEmpty()) { while (exits.nonEmpty()) {
PendingExit exit = exits.head; PendingExit exit = exits.head;
exits = exits.tail; exits = exits.tail;
...@@ -542,7 +542,7 @@ public class Flow { ...@@ -542,7 +542,7 @@ public class Flow {
public void visitDoLoop(JCDoWhileLoop tree) { public void visitDoLoop(JCDoWhileLoop tree) {
ListBuffer<PendingExit> prevPendingExits = pendingExits; ListBuffer<PendingExit> prevPendingExits = pendingExits;
pendingExits = new ListBuffer<PendingExit>(); pendingExits = new ListBuffer<>();
scanStat(tree.body); scanStat(tree.body);
alive |= resolveContinues(tree); alive |= resolveContinues(tree);
scan(tree.cond); scan(tree.cond);
...@@ -552,7 +552,7 @@ public class Flow { ...@@ -552,7 +552,7 @@ public class Flow {
public void visitWhileLoop(JCWhileLoop tree) { public void visitWhileLoop(JCWhileLoop tree) {
ListBuffer<PendingExit> prevPendingExits = pendingExits; ListBuffer<PendingExit> prevPendingExits = pendingExits;
pendingExits = new ListBuffer<PendingExit>(); pendingExits = new ListBuffer<>();
scan(tree.cond); scan(tree.cond);
alive = !tree.cond.type.isFalse(); alive = !tree.cond.type.isFalse();
scanStat(tree.body); scanStat(tree.body);
...@@ -564,7 +564,7 @@ public class Flow { ...@@ -564,7 +564,7 @@ public class Flow {
public void visitForLoop(JCForLoop tree) { public void visitForLoop(JCForLoop tree) {
ListBuffer<PendingExit> prevPendingExits = pendingExits; ListBuffer<PendingExit> prevPendingExits = pendingExits;
scanStats(tree.init); scanStats(tree.init);
pendingExits = new ListBuffer<PendingExit>(); pendingExits = new ListBuffer<>();
if (tree.cond != null) { if (tree.cond != null) {
scan(tree.cond); scan(tree.cond);
alive = !tree.cond.type.isFalse(); alive = !tree.cond.type.isFalse();
...@@ -582,7 +582,7 @@ public class Flow { ...@@ -582,7 +582,7 @@ public class Flow {
visitVarDef(tree.var); visitVarDef(tree.var);
ListBuffer<PendingExit> prevPendingExits = pendingExits; ListBuffer<PendingExit> prevPendingExits = pendingExits;
scan(tree.expr); scan(tree.expr);
pendingExits = new ListBuffer<PendingExit>(); pendingExits = new ListBuffer<>();
scanStat(tree.body); scanStat(tree.body);
alive |= resolveContinues(tree); alive |= resolveContinues(tree);
resolveBreaks(tree, prevPendingExits); resolveBreaks(tree, prevPendingExits);
...@@ -591,14 +591,14 @@ public class Flow { ...@@ -591,14 +591,14 @@ public class Flow {
public void visitLabelled(JCLabeledStatement tree) { public void visitLabelled(JCLabeledStatement tree) {
ListBuffer<PendingExit> prevPendingExits = pendingExits; ListBuffer<PendingExit> prevPendingExits = pendingExits;
pendingExits = new ListBuffer<PendingExit>(); pendingExits = new ListBuffer<>();
scanStat(tree.body); scanStat(tree.body);
alive |= resolveBreaks(tree, prevPendingExits); alive |= resolveBreaks(tree, prevPendingExits);
} }
public void visitSwitch(JCSwitch tree) { public void visitSwitch(JCSwitch tree) {
ListBuffer<PendingExit> prevPendingExits = pendingExits; ListBuffer<PendingExit> prevPendingExits = pendingExits;
pendingExits = new ListBuffer<PendingExit>(); pendingExits = new ListBuffer<>();
scan(tree.selector); scan(tree.selector);
boolean hasDefault = false; boolean hasDefault = false;
for (List<JCCase> l = tree.cases; l.nonEmpty(); l = l.tail) { for (List<JCCase> l = tree.cases; l.nonEmpty(); l = l.tail) {
...@@ -625,7 +625,7 @@ public class Flow { ...@@ -625,7 +625,7 @@ public class Flow {
public void visitTry(JCTry tree) { public void visitTry(JCTry tree) {
ListBuffer<PendingExit> prevPendingExits = pendingExits; ListBuffer<PendingExit> prevPendingExits = pendingExits;
pendingExits = new ListBuffer<PendingExit>(); pendingExits = new ListBuffer<>();
for (JCTree resource : tree.resources) { for (JCTree resource : tree.resources) {
if (resource instanceof JCVariableDecl) { if (resource instanceof JCVariableDecl) {
JCVariableDecl vdecl = (JCVariableDecl) resource; JCVariableDecl vdecl = (JCVariableDecl) resource;
...@@ -688,21 +688,21 @@ public class Flow { ...@@ -688,21 +688,21 @@ public class Flow {
} }
public void visitBreak(JCBreak tree) { public void visitBreak(JCBreak tree) {
recordExit(tree, new PendingExit(tree)); recordExit(new PendingExit(tree));
} }
public void visitContinue(JCContinue tree) { public void visitContinue(JCContinue tree) {
recordExit(tree, new PendingExit(tree)); recordExit(new PendingExit(tree));
} }
public void visitReturn(JCReturn tree) { public void visitReturn(JCReturn tree) {
scan(tree.expr); scan(tree.expr);
recordExit(tree, new PendingExit(tree)); recordExit(new PendingExit(tree));
} }
public void visitThrow(JCThrow tree) { public void visitThrow(JCThrow tree) {
scan(tree.expr); scan(tree.expr);
markDead(tree); markDead();
} }
public void visitApply(JCMethodInvocation tree) { public void visitApply(JCMethodInvocation tree) {
...@@ -756,7 +756,7 @@ public class Flow { ...@@ -756,7 +756,7 @@ public class Flow {
try { try {
attrEnv = env; attrEnv = env;
Flow.this.make = make; Flow.this.make = make;
pendingExits = new ListBuffer<PendingExit>(); pendingExits = new ListBuffer<>();
alive = true; alive = true;
scan(tree); scan(tree);
} finally { } finally {
...@@ -803,7 +803,7 @@ public class Flow { ...@@ -803,7 +803,7 @@ public class Flow {
} }
@Override @Override
void markDead(JCTree tree) { void markDead() {
//do nothing //do nothing
} }
...@@ -1201,16 +1201,16 @@ public class Flow { ...@@ -1201,16 +1201,16 @@ public class Flow {
} }
public void visitBreak(JCBreak tree) { public void visitBreak(JCBreak tree) {
recordExit(tree, new FlowPendingExit(tree, null)); recordExit(new FlowPendingExit(tree, null));
} }
public void visitContinue(JCContinue tree) { public void visitContinue(JCContinue tree) {
recordExit(tree, new FlowPendingExit(tree, null)); recordExit(new FlowPendingExit(tree, null));
} }
public void visitReturn(JCReturn tree) { public void visitReturn(JCReturn tree) {
scan(tree.expr); scan(tree.expr);
recordExit(tree, new FlowPendingExit(tree, null)); recordExit(new FlowPendingExit(tree, null));
} }
public void visitThrow(JCThrow tree) { public void visitThrow(JCThrow tree) {
...@@ -1228,7 +1228,7 @@ public class Flow { ...@@ -1228,7 +1228,7 @@ public class Flow {
else { else {
markThrown(tree, tree.expr.type); markThrown(tree, tree.expr.type);
} }
markDead(tree); markDead();
} }
public void visitApply(JCMethodInvocation tree) { public void visitApply(JCMethodInvocation tree) {
...@@ -1379,12 +1379,10 @@ public class Flow { ...@@ -1379,12 +1379,10 @@ public class Flow {
* effectively-final local variables/parameters. * effectively-final local variables/parameters.
*/ */
public abstract class AbstractAssignAnalyzer<P extends AbstractAssignAnalyzer<P>.AbstractAssignPendingExit> public class AssignAnalyzer extends BaseAnalyzer<AssignAnalyzer.AssignPendingExit> {
extends BaseAnalyzer<P> {
/** The set of definitely assigned variables. /** The set of definitely assigned variables.
*/ */
protected Bits inits; final Bits inits;
/** The set of definitely unassigned variables. /** The set of definitely unassigned variables.
*/ */
...@@ -1432,20 +1430,20 @@ public class Flow { ...@@ -1432,20 +1430,20 @@ public class Flow {
*/ */
Scope unrefdResources; Scope unrefdResources;
/** Set when processing a loop body the second time for DU analysis. */ /** Modified when processing a loop body the second time for DU analysis. */
FlowKind flowKind = FlowKind.NORMAL; FlowKind flowKind = FlowKind.NORMAL;
/** The starting position of the analysed tree */ /** The starting position of the analyzed tree */
int startPos; int startPos;
public class AbstractAssignPendingExit extends BaseAnalyzer.PendingExit { public class AssignPendingExit extends BaseAnalyzer.PendingExit {
final Bits inits; final Bits inits;
final Bits uninits; final Bits uninits;
final Bits exit_inits = new Bits(true); final Bits exit_inits = new Bits(true);
final Bits exit_uninits = new Bits(true); final Bits exit_uninits = new Bits(true);
public AbstractAssignPendingExit(JCTree tree, final Bits inits, final Bits uninits) { public AssignPendingExit(JCTree tree, final Bits inits, final Bits uninits) {
super(tree); super(tree);
this.inits = inits; this.inits = inits;
this.uninits = uninits; this.uninits = uninits;
...@@ -1454,13 +1452,13 @@ public class Flow { ...@@ -1454,13 +1452,13 @@ public class Flow {
} }
@Override @Override
public void resolveJump(JCTree tree) { void resolveJump() {
inits.andSet(exit_inits); inits.andSet(exit_inits);
uninits.andSet(exit_uninits); uninits.andSet(exit_uninits);
} }
} }
public AbstractAssignAnalyzer() { public AssignAnalyzer() {
this.inits = new Bits(); this.inits = new Bits();
uninits = new Bits(); uninits = new Bits();
uninitsTry = new Bits(); uninitsTry = new Bits();
...@@ -1473,7 +1471,7 @@ public class Flow { ...@@ -1473,7 +1471,7 @@ public class Flow {
private boolean isInitialConstructor = false; private boolean isInitialConstructor = false;
@Override @Override
protected void markDead(JCTree tree) { void markDead() {
if (!isInitialConstructor) { if (!isInitialConstructor) {
inits.inclRange(returnadr, nextadr); inits.inclRange(returnadr, nextadr);
} else { } else {
...@@ -1520,35 +1518,41 @@ public class Flow { ...@@ -1520,35 +1518,41 @@ public class Flow {
} }
sym.adr = nextadr; sym.adr = nextadr;
vardecls[nextadr] = varDecl; vardecls[nextadr] = varDecl;
exclVarFromInits(varDecl, nextadr); inits.excl(nextadr);
uninits.incl(nextadr); uninits.incl(nextadr);
nextadr++; nextadr++;
} }
protected void exclVarFromInits(JCTree tree, int adr) {
inits.excl(adr);
}
protected void assignToInits(JCTree tree, Bits bits) {
inits.assign(bits);
}
protected void andSetInits(JCTree tree, Bits bits) {
inits.andSet(bits);
}
protected void orSetInits(JCTree tree, Bits bits) {
inits.orSet(bits);
}
/** Record an initialization of a trackable variable. /** Record an initialization of a trackable variable.
*/ */
void letInit(DiagnosticPosition pos, VarSymbol sym) { void letInit(DiagnosticPosition pos, VarSymbol sym) {
if (sym.adr >= firstadr && trackable(sym)) { if (sym.adr >= firstadr && trackable(sym)) {
if (uninits.isMember(sym.adr)) { if ((sym.flags() & EFFECTIVELY_FINAL) != 0) {
uninit(sym); if (!uninits.isMember(sym.adr)) {
//assignment targeting an effectively final variable
//makes the variable lose its status of effectively final
//if the variable is _not_ definitively unassigned
sym.flags_field &= ~EFFECTIVELY_FINAL;
} else {
uninit(sym);
}
} else if ((sym.flags() & FINAL) != 0) {
if ((sym.flags() & PARAMETER) != 0) {
if ((sym.flags() & UNION) != 0) { //multi-catch parameter
log.error(pos, "multicatch.parameter.may.not.be.assigned", sym);
} else {
log.error(pos, "final.parameter.may.not.be.assigned",
sym);
}
} else if (!uninits.isMember(sym.adr)) {
log.error(pos, flowKind.errKey, sym);
} else {
uninit(sym);
}
} }
inits.incl(sym.adr); inits.incl(sym.adr);
} else if ((sym.flags() & FINAL) != 0) {
log.error(pos, "var.might.already.be.assigned", sym);
} }
} }
//where //where
...@@ -1583,7 +1587,14 @@ public class Flow { ...@@ -1583,7 +1587,14 @@ public class Flow {
checkInit(pos, sym, "var.might.not.have.been.initialized"); checkInit(pos, sym, "var.might.not.have.been.initialized");
} }
void checkInit(DiagnosticPosition pos, VarSymbol sym, String errkey) {} void checkInit(DiagnosticPosition pos, VarSymbol sym, String errkey) {
if ((sym.adr >= firstadr || sym.owner.kind != TYP) &&
trackable(sym) &&
!inits.isMember(sym.adr)) {
log.error(pos, errkey, sym);
inits.incl(sym.adr);
}
}
/** Utility method to reset several Bits instances. /** Utility method to reset several Bits instances.
*/ */
...@@ -1607,7 +1618,7 @@ public class Flow { ...@@ -1607,7 +1618,7 @@ public class Flow {
/** Merge (intersect) inits/uninits from WhenTrue/WhenFalse sets. /** Merge (intersect) inits/uninits from WhenTrue/WhenFalse sets.
*/ */
protected void merge(JCTree tree) { protected void merge() {
inits.assign(initsWhenFalse.andSet(initsWhenTrue)); inits.assign(initsWhenFalse.andSet(initsWhenTrue));
uninits.assign(uninitsWhenFalse.andSet(uninitsWhenTrue)); uninits.assign(uninitsWhenFalse.andSet(uninitsWhenTrue));
} }
...@@ -1623,7 +1634,7 @@ public class Flow { ...@@ -1623,7 +1634,7 @@ public class Flow {
if (tree != null) { if (tree != null) {
scan(tree); scan(tree);
if (inits.isReset()) { if (inits.isReset()) {
merge(tree); merge();
} }
} }
} }
...@@ -1641,7 +1652,7 @@ public class Flow { ...@@ -1641,7 +1652,7 @@ public class Flow {
*/ */
void scanCond(JCTree tree) { void scanCond(JCTree tree) {
if (tree.type.isFalse()) { if (tree.type.isFalse()) {
if (inits.isReset()) merge(tree); if (inits.isReset()) merge();
initsWhenTrue.assign(inits); initsWhenTrue.assign(inits);
initsWhenTrue.inclRange(firstadr, nextadr); initsWhenTrue.inclRange(firstadr, nextadr);
uninitsWhenTrue.assign(uninits); uninitsWhenTrue.assign(uninits);
...@@ -1649,7 +1660,7 @@ public class Flow { ...@@ -1649,7 +1660,7 @@ public class Flow {
initsWhenFalse.assign(inits); initsWhenFalse.assign(inits);
uninitsWhenFalse.assign(uninits); uninitsWhenFalse.assign(uninits);
} else if (tree.type.isTrue()) { } else if (tree.type.isTrue()) {
if (inits.isReset()) merge(tree); if (inits.isReset()) merge();
initsWhenFalse.assign(inits); initsWhenFalse.assign(inits);
initsWhenFalse.inclRange(firstadr, nextadr); initsWhenFalse.inclRange(firstadr, nextadr);
uninitsWhenFalse.assign(uninits); uninitsWhenFalse.assign(uninits);
...@@ -1668,173 +1679,202 @@ public class Flow { ...@@ -1668,173 +1679,202 @@ public class Flow {
/* ------------ Visitor methods for various sorts of trees -------------*/ /* ------------ Visitor methods for various sorts of trees -------------*/
@Override
public void visitClassDef(JCClassDecl tree) { public void visitClassDef(JCClassDecl tree) {
if (tree.sym == null) { if (tree.sym == null) {
return; return;
} }
JCClassDecl classDefPrev = classDef; Lint lintPrev = lint;
int firstadrPrev = firstadr; lint = lint.augment(tree.sym);
int nextadrPrev = nextadr;
ListBuffer<P> pendingExitsPrev = pendingExits;
pendingExits = new ListBuffer<P>();
if (tree.name != names.empty) {
firstadr = nextadr;
}
classDef = tree;
try { try {
// define all the static fields if (tree.sym == null) {
for (List<JCTree> l = tree.defs; l.nonEmpty(); l = l.tail) { return;
if (l.head.hasTag(VARDEF)) { }
JCVariableDecl def = (JCVariableDecl)l.head;
if ((def.mods.flags & STATIC) != 0) { JCClassDecl classDefPrev = classDef;
VarSymbol sym = def.sym; int firstadrPrev = firstadr;
if (trackable(sym)) { int nextadrPrev = nextadr;
newVar(def); ListBuffer<AssignPendingExit> pendingExitsPrev = pendingExits;
pendingExits = new ListBuffer<>();
if (tree.name != names.empty) {
firstadr = nextadr;
}
classDef = tree;
try {
// define all the static fields
for (List<JCTree> l = tree.defs; l.nonEmpty(); l = l.tail) {
if (l.head.hasTag(VARDEF)) {
JCVariableDecl def = (JCVariableDecl)l.head;
if ((def.mods.flags & STATIC) != 0) {
VarSymbol sym = def.sym;
if (trackable(sym)) {
newVar(def);
}
} }
} }
} }
}
// process all the static initializers // process all the static initializers
for (List<JCTree> l = tree.defs; l.nonEmpty(); l = l.tail) { for (List<JCTree> l = tree.defs; l.nonEmpty(); l = l.tail) {
if (!l.head.hasTag(METHODDEF) && if (!l.head.hasTag(METHODDEF) &&
(TreeInfo.flags(l.head) & STATIC) != 0) { (TreeInfo.flags(l.head) & STATIC) != 0) {
scan(l.head); scan(l.head);
}
} }
}
// define all the instance fields // define all the instance fields
for (List<JCTree> l = tree.defs; l.nonEmpty(); l = l.tail) { for (List<JCTree> l = tree.defs; l.nonEmpty(); l = l.tail) {
if (l.head.hasTag(VARDEF)) { if (l.head.hasTag(VARDEF)) {
JCVariableDecl def = (JCVariableDecl)l.head; JCVariableDecl def = (JCVariableDecl)l.head;
if ((def.mods.flags & STATIC) == 0) { if ((def.mods.flags & STATIC) == 0) {
VarSymbol sym = def.sym; VarSymbol sym = def.sym;
if (trackable(sym)) { if (trackable(sym)) {
newVar(def); newVar(def);
}
} }
} }
} }
} // process all the instance initializers
for (List<JCTree> l = tree.defs; l.nonEmpty(); l = l.tail) {
// process all the instance initializers if (!l.head.hasTag(METHODDEF) &&
for (List<JCTree> l = tree.defs; l.nonEmpty(); l = l.tail) { (TreeInfo.flags(l.head) & STATIC) == 0) {
if (!l.head.hasTag(METHODDEF) && scan(l.head);
(TreeInfo.flags(l.head) & STATIC) == 0) { }
scan(l.head);
} }
}
// process all the methods // process all the methods
for (List<JCTree> l = tree.defs; l.nonEmpty(); l = l.tail) { for (List<JCTree> l = tree.defs; l.nonEmpty(); l = l.tail) {
if (l.head.hasTag(METHODDEF)) { if (l.head.hasTag(METHODDEF)) {
scan(l.head); scan(l.head);
}
} }
} finally {
pendingExits = pendingExitsPrev;
nextadr = nextadrPrev;
firstadr = firstadrPrev;
classDef = classDefPrev;
} }
} finally { } finally {
pendingExits = pendingExitsPrev; lint = lintPrev;
nextadr = nextadrPrev;
firstadr = firstadrPrev;
classDef = classDefPrev;
} }
} }
@Override
public void visitMethodDef(JCMethodDecl tree) { public void visitMethodDef(JCMethodDecl tree) {
if (tree.body == null) { if (tree.body == null) {
return; return;
} }
/* Ignore synthetic methods, except for translated lambda methods.
/* MemberEnter can generate synthetic methods ignore them
*/ */
if ((tree.sym.flags() & (SYNTHETIC | LAMBDA_METHOD)) == SYNTHETIC) { if ((tree.sym.flags() & SYNTHETIC) != 0) {
return; return;
} }
final Bits initsPrev = new Bits(inits); Lint lintPrev = lint;
final Bits uninitsPrev = new Bits(uninits); lint = lint.augment(tree.sym);
int nextadrPrev = nextadr;
int firstadrPrev = firstadr;
int returnadrPrev = returnadr;
Assert.check(pendingExits.isEmpty());
boolean lastInitialConstructor = isInitialConstructor;
try { try {
isInitialConstructor = TreeInfo.isInitialConstructor(tree); if (tree.body == null) {
return;
if (!isInitialConstructor) {
firstadr = nextadr;
} }
for (List<JCVariableDecl> l = tree.params; l.nonEmpty(); l = l.tail) { /* Ignore synthetic methods, except for translated lambda methods.
JCVariableDecl def = l.head; */
scan(def); if ((tree.sym.flags() & (SYNTHETIC | LAMBDA_METHOD)) == SYNTHETIC) {
Assert.check((def.sym.flags() & PARAMETER) != 0, "Method parameter without PARAMETER flag"); return;
/* If we are executing the code from Gen, then there can be
* synthetic or mandated variables, ignore them.
*/
initParam(def);
} }
// else we are in an instance initializer block;
// leave caught unchanged.
scan(tree.body);
if (isInitialConstructor) { final Bits initsPrev = new Bits(inits);
boolean isSynthesized = (tree.sym.flags() & final Bits uninitsPrev = new Bits(uninits);
GENERATEDCONSTR) != 0; int nextadrPrev = nextadr;
for (int i = firstadr; i < nextadr; i++) { int firstadrPrev = firstadr;
JCVariableDecl vardecl = vardecls[i]; int returnadrPrev = returnadr;
VarSymbol var = vardecl.sym;
if (var.owner == classDef.sym) { Assert.check(pendingExits.isEmpty());
// choose the diagnostic position based on whether boolean lastInitialConstructor = isInitialConstructor;
// the ctor is default(synthesized) or not try {
if (isSynthesized) { isInitialConstructor = TreeInfo.isInitialConstructor(tree);
checkInit(TreeInfo.diagnosticPositionFor(var, vardecl),
var, "var.not.initialized.in.default.constructor"); if (!isInitialConstructor) {
} else { firstadr = nextadr;
checkInit(TreeInfo.diagEndPos(tree.body), var);
}
}
} }
} for (List<JCVariableDecl> l = tree.params; l.nonEmpty(); l = l.tail) {
List<P> exits = pendingExits.toList(); JCVariableDecl def = l.head;
pendingExits = new ListBuffer<>(); scan(def);
while (exits.nonEmpty()) { Assert.check((def.sym.flags() & PARAMETER) != 0, "Method parameter without PARAMETER flag");
P exit = exits.head; /* If we are executing the code from Gen, then there can be
exits = exits.tail; * synthetic or mandated variables, ignore them.
Assert.check(exit.tree.hasTag(RETURN), exit.tree); */
initParam(def);
}
// else we are in an instance initializer block;
// leave caught unchanged.
scan(tree.body);
if (isInitialConstructor) { if (isInitialConstructor) {
assignToInits(exit.tree, exit.exit_inits); boolean isSynthesized = (tree.sym.flags() &
GENERATEDCONSTR) != 0;
for (int i = firstadr; i < nextadr; i++) { for (int i = firstadr; i < nextadr; i++) {
checkInit(exit.tree.pos(), vardecls[i].sym); JCVariableDecl vardecl = vardecls[i];
VarSymbol var = vardecl.sym;
if (var.owner == classDef.sym) {
// choose the diagnostic position based on whether
// the ctor is default(synthesized) or not
if (isSynthesized) {
checkInit(TreeInfo.diagnosticPositionFor(var, vardecl),
var, "var.not.initialized.in.default.constructor");
} else {
checkInit(TreeInfo.diagEndPos(tree.body), var);
}
}
}
}
List<AssignPendingExit> exits = pendingExits.toList();
pendingExits = new ListBuffer<>();
while (exits.nonEmpty()) {
AssignPendingExit exit = exits.head;
exits = exits.tail;
Assert.check(exit.tree.hasTag(RETURN), exit.tree);
if (isInitialConstructor) {
inits.assign(exit.exit_inits);
for (int i = firstadr; i < nextadr; i++) {
checkInit(exit.tree.pos(), vardecls[i].sym);
}
} }
} }
} finally {
inits.assign(initsPrev);
uninits.assign(uninitsPrev);
nextadr = nextadrPrev;
firstadr = firstadrPrev;
returnadr = returnadrPrev;
isInitialConstructor = lastInitialConstructor;
} }
} finally { } finally {
assignToInits(tree, initsPrev); lint = lintPrev;
uninits.assign(uninitsPrev);
nextadr = nextadrPrev;
firstadr = firstadrPrev;
returnadr = returnadrPrev;
isInitialConstructor = lastInitialConstructor;
} }
} }
protected void initParam(JCVariableDecl def) { protected void initParam(JCVariableDecl def) {
inits.incl(def.sym.adr); inits.incl(def.sym.adr);
uninits.excl(def.sym.adr); uninits.excl(def.sym.adr);
} }
public void visitVarDef(JCVariableDecl tree) { public void visitVarDef(JCVariableDecl tree) {
boolean track = trackable(tree.sym); Lint lintPrev = lint;
if (track && tree.sym.owner.kind == MTH) { lint = lint.augment(tree.sym);
newVar(tree); try{
} boolean track = trackable(tree.sym);
if (tree.init != null) { if (track && tree.sym.owner.kind == MTH) {
scanExpr(tree.init); newVar(tree);
if (track) { }
letInit(tree.pos(), tree.sym); if (tree.init != null) {
scanExpr(tree.init);
if (track) {
letInit(tree.pos(), tree.sym);
}
} }
} finally {
lint = lintPrev;
} }
} }
...@@ -1844,18 +1884,14 @@ public class Flow { ...@@ -1844,18 +1884,14 @@ public class Flow {
nextadr = nextadrPrev; nextadr = nextadrPrev;
} }
int getLogNumberOfErrors() {
return 0;
}
public void visitDoLoop(JCDoWhileLoop tree) { public void visitDoLoop(JCDoWhileLoop tree) {
ListBuffer<P> prevPendingExits = pendingExits; ListBuffer<AssignPendingExit> prevPendingExits = pendingExits;
FlowKind prevFlowKind = flowKind; FlowKind prevFlowKind = flowKind;
flowKind = FlowKind.NORMAL; flowKind = FlowKind.NORMAL;
final Bits initsSkip = new Bits(true); final Bits initsSkip = new Bits(true);
final Bits uninitsSkip = new Bits(true); final Bits uninitsSkip = new Bits(true);
pendingExits = new ListBuffer<P>(); pendingExits = new ListBuffer<>();
int prevErrors = getLogNumberOfErrors(); int prevErrors = log.nerrors;
do { do {
final Bits uninitsEntry = new Bits(uninits); final Bits uninitsEntry = new Bits(uninits);
uninitsEntry.excludeFrom(nextadr); uninitsEntry.excludeFrom(nextadr);
...@@ -1866,28 +1902,28 @@ public class Flow { ...@@ -1866,28 +1902,28 @@ public class Flow {
initsSkip.assign(initsWhenFalse); initsSkip.assign(initsWhenFalse);
uninitsSkip.assign(uninitsWhenFalse); uninitsSkip.assign(uninitsWhenFalse);
} }
if (getLogNumberOfErrors() != prevErrors || if (log.nerrors != prevErrors ||
flowKind.isFinal() || flowKind.isFinal() ||
new Bits(uninitsEntry).diffSet(uninitsWhenTrue).nextBit(firstadr)==-1) new Bits(uninitsEntry).diffSet(uninitsWhenTrue).nextBit(firstadr)==-1)
break; break;
assignToInits(tree.cond, initsWhenTrue); inits.assign(initsWhenTrue);
uninits.assign(uninitsEntry.andSet(uninitsWhenTrue)); uninits.assign(uninitsEntry.andSet(uninitsWhenTrue));
flowKind = FlowKind.SPECULATIVE_LOOP; flowKind = FlowKind.SPECULATIVE_LOOP;
} while (true); } while (true);
flowKind = prevFlowKind; flowKind = prevFlowKind;
assignToInits(tree, initsSkip); inits.assign(initsSkip);
uninits.assign(uninitsSkip); uninits.assign(uninitsSkip);
resolveBreaks(tree, prevPendingExits); resolveBreaks(tree, prevPendingExits);
} }
public void visitWhileLoop(JCWhileLoop tree) { public void visitWhileLoop(JCWhileLoop tree) {
ListBuffer<P> prevPendingExits = pendingExits; ListBuffer<AssignPendingExit> prevPendingExits = pendingExits;
FlowKind prevFlowKind = flowKind; FlowKind prevFlowKind = flowKind;
flowKind = FlowKind.NORMAL; flowKind = FlowKind.NORMAL;
final Bits initsSkip = new Bits(true); final Bits initsSkip = new Bits(true);
final Bits uninitsSkip = new Bits(true); final Bits uninitsSkip = new Bits(true);
pendingExits = new ListBuffer<>(); pendingExits = new ListBuffer<>();
int prevErrors = getLogNumberOfErrors(); int prevErrors = log.nerrors;
final Bits uninitsEntry = new Bits(uninits); final Bits uninitsEntry = new Bits(uninits);
uninitsEntry.excludeFrom(nextadr); uninitsEntry.excludeFrom(nextadr);
do { do {
...@@ -1896,11 +1932,11 @@ public class Flow { ...@@ -1896,11 +1932,11 @@ public class Flow {
initsSkip.assign(initsWhenFalse) ; initsSkip.assign(initsWhenFalse) ;
uninitsSkip.assign(uninitsWhenFalse); uninitsSkip.assign(uninitsWhenFalse);
} }
assignToInits(tree, initsWhenTrue); inits.assign(initsWhenTrue);
uninits.assign(uninitsWhenTrue); uninits.assign(uninitsWhenTrue);
scan(tree.body); scan(tree.body);
resolveContinues(tree); resolveContinues(tree);
if (getLogNumberOfErrors() != prevErrors || if (log.nerrors != prevErrors ||
flowKind.isFinal() || flowKind.isFinal() ||
new Bits(uninitsEntry).diffSet(uninits).nextBit(firstadr) == -1) { new Bits(uninitsEntry).diffSet(uninits).nextBit(firstadr) == -1) {
break; break;
...@@ -1911,21 +1947,21 @@ public class Flow { ...@@ -1911,21 +1947,21 @@ public class Flow {
flowKind = prevFlowKind; flowKind = prevFlowKind;
//a variable is DA/DU after the while statement, if it's DA/DU assuming the //a variable is DA/DU after the while statement, if it's DA/DU assuming the
//branch is not taken AND if it's DA/DU before any break statement //branch is not taken AND if it's DA/DU before any break statement
assignToInits(tree.body, initsSkip); inits.assign(initsSkip);
uninits.assign(uninitsSkip); uninits.assign(uninitsSkip);
resolveBreaks(tree, prevPendingExits); resolveBreaks(tree, prevPendingExits);
} }
public void visitForLoop(JCForLoop tree) { public void visitForLoop(JCForLoop tree) {
ListBuffer<P> prevPendingExits = pendingExits; ListBuffer<AssignPendingExit> prevPendingExits = pendingExits;
FlowKind prevFlowKind = flowKind; FlowKind prevFlowKind = flowKind;
flowKind = FlowKind.NORMAL; flowKind = FlowKind.NORMAL;
int nextadrPrev = nextadr; int nextadrPrev = nextadr;
scan(tree.init); scan(tree.init);
final Bits initsSkip = new Bits(true); final Bits initsSkip = new Bits(true);
final Bits uninitsSkip = new Bits(true); final Bits uninitsSkip = new Bits(true);
pendingExits = new ListBuffer<P>(); pendingExits = new ListBuffer<>();
int prevErrors = getLogNumberOfErrors(); int prevErrors = log.nerrors;
do { do {
final Bits uninitsEntry = new Bits(uninits); final Bits uninitsEntry = new Bits(uninits);
uninitsEntry.excludeFrom(nextadr); uninitsEntry.excludeFrom(nextadr);
...@@ -1935,7 +1971,7 @@ public class Flow { ...@@ -1935,7 +1971,7 @@ public class Flow {
initsSkip.assign(initsWhenFalse); initsSkip.assign(initsWhenFalse);
uninitsSkip.assign(uninitsWhenFalse); uninitsSkip.assign(uninitsWhenFalse);
} }
assignToInits(tree.body, initsWhenTrue); inits.assign(initsWhenTrue);
uninits.assign(uninitsWhenTrue); uninits.assign(uninitsWhenTrue);
} else if (!flowKind.isFinal()) { } else if (!flowKind.isFinal()) {
initsSkip.assign(inits); initsSkip.assign(inits);
...@@ -1946,7 +1982,7 @@ public class Flow { ...@@ -1946,7 +1982,7 @@ public class Flow {
scan(tree.body); scan(tree.body);
resolveContinues(tree); resolveContinues(tree);
scan(tree.step); scan(tree.step);
if (getLogNumberOfErrors() != prevErrors || if (log.nerrors != prevErrors ||
flowKind.isFinal() || flowKind.isFinal() ||
new Bits(uninitsEntry).diffSet(uninits).nextBit(firstadr) == -1) new Bits(uninitsEntry).diffSet(uninits).nextBit(firstadr) == -1)
break; break;
...@@ -1956,7 +1992,7 @@ public class Flow { ...@@ -1956,7 +1992,7 @@ public class Flow {
flowKind = prevFlowKind; flowKind = prevFlowKind;
//a variable is DA/DU after a for loop, if it's DA/DU assuming the //a variable is DA/DU after a for loop, if it's DA/DU assuming the
//branch is not taken AND if it's DA/DU before any break statement //branch is not taken AND if it's DA/DU before any break statement
assignToInits(tree.body, initsSkip); inits.assign(initsSkip);
uninits.assign(uninitsSkip); uninits.assign(uninitsSkip);
resolveBreaks(tree, prevPendingExits); resolveBreaks(tree, prevPendingExits);
nextadr = nextadrPrev; nextadr = nextadrPrev;
...@@ -1965,7 +2001,7 @@ public class Flow { ...@@ -1965,7 +2001,7 @@ public class Flow {
public void visitForeachLoop(JCEnhancedForLoop tree) { public void visitForeachLoop(JCEnhancedForLoop tree) {
visitVarDef(tree.var); visitVarDef(tree.var);
ListBuffer<P> prevPendingExits = pendingExits; ListBuffer<AssignPendingExit> prevPendingExits = pendingExits;
FlowKind prevFlowKind = flowKind; FlowKind prevFlowKind = flowKind;
flowKind = FlowKind.NORMAL; flowKind = FlowKind.NORMAL;
int nextadrPrev = nextadr; int nextadrPrev = nextadr;
...@@ -1974,14 +2010,14 @@ public class Flow { ...@@ -1974,14 +2010,14 @@ public class Flow {
final Bits uninitsStart = new Bits(uninits); final Bits uninitsStart = new Bits(uninits);
letInit(tree.pos(), tree.var.sym); letInit(tree.pos(), tree.var.sym);
pendingExits = new ListBuffer<P>(); pendingExits = new ListBuffer<>();
int prevErrors = getLogNumberOfErrors(); int prevErrors = log.nerrors;
do { do {
final Bits uninitsEntry = new Bits(uninits); final Bits uninitsEntry = new Bits(uninits);
uninitsEntry.excludeFrom(nextadr); uninitsEntry.excludeFrom(nextadr);
scan(tree.body); scan(tree.body);
resolveContinues(tree); resolveContinues(tree);
if (getLogNumberOfErrors() != prevErrors || if (log.nerrors != prevErrors ||
flowKind.isFinal() || flowKind.isFinal() ||
new Bits(uninitsEntry).diffSet(uninits).nextBit(firstadr) == -1) new Bits(uninitsEntry).diffSet(uninits).nextBit(firstadr) == -1)
break; break;
...@@ -1989,21 +2025,21 @@ public class Flow { ...@@ -1989,21 +2025,21 @@ public class Flow {
flowKind = FlowKind.SPECULATIVE_LOOP; flowKind = FlowKind.SPECULATIVE_LOOP;
} while (true); } while (true);
flowKind = prevFlowKind; flowKind = prevFlowKind;
assignToInits(tree.body, initsStart); inits.assign(initsStart);
uninits.assign(uninitsStart.andSet(uninits)); uninits.assign(uninitsStart.andSet(uninits));
resolveBreaks(tree, prevPendingExits); resolveBreaks(tree, prevPendingExits);
nextadr = nextadrPrev; nextadr = nextadrPrev;
} }
public void visitLabelled(JCLabeledStatement tree) { public void visitLabelled(JCLabeledStatement tree) {
ListBuffer<P> prevPendingExits = pendingExits; ListBuffer<AssignPendingExit> prevPendingExits = pendingExits;
pendingExits = new ListBuffer<P>(); pendingExits = new ListBuffer<>();
scan(tree.body); scan(tree.body);
resolveBreaks(tree, prevPendingExits); resolveBreaks(tree, prevPendingExits);
} }
public void visitSwitch(JCSwitch tree) { public void visitSwitch(JCSwitch tree) {
ListBuffer<P> prevPendingExits = pendingExits; ListBuffer<AssignPendingExit> prevPendingExits = pendingExits;
pendingExits = new ListBuffer<>(); pendingExits = new ListBuffer<>();
int nextadrPrev = nextadr; int nextadrPrev = nextadr;
scanExpr(tree.selector); scanExpr(tree.selector);
...@@ -2011,7 +2047,7 @@ public class Flow { ...@@ -2011,7 +2047,7 @@ public class Flow {
final Bits uninitsSwitch = new Bits(uninits); final Bits uninitsSwitch = new Bits(uninits);
boolean hasDefault = false; boolean hasDefault = false;
for (List<JCCase> l = tree.cases; l.nonEmpty(); l = l.tail) { for (List<JCCase> l = tree.cases; l.nonEmpty(); l = l.tail) {
assignToInits(l.head, initsSwitch); inits.assign(initsSwitch);
uninits.assign(uninits.andSet(uninitsSwitch)); uninits.assign(uninits.andSet(uninitsSwitch));
JCCase c = l.head; JCCase c = l.head;
if (c.pat == null) { if (c.pat == null) {
...@@ -2020,19 +2056,19 @@ public class Flow { ...@@ -2020,19 +2056,19 @@ public class Flow {
scanExpr(c.pat); scanExpr(c.pat);
} }
if (hasDefault) { if (hasDefault) {
assignToInits(null, initsSwitch); inits.assign(initsSwitch);
uninits.assign(uninits.andSet(uninitsSwitch)); uninits.assign(uninits.andSet(uninitsSwitch));
} }
scan(c.stats); scan(c.stats);
addVars(c.stats, initsSwitch, uninitsSwitch); addVars(c.stats, initsSwitch, uninitsSwitch);
if (!hasDefault) { if (!hasDefault) {
assignToInits(l.head.stats.last(), initsSwitch); inits.assign(initsSwitch);
uninits.assign(uninits.andSet(uninitsSwitch)); uninits.assign(uninits.andSet(uninitsSwitch));
} }
// Warn about fall-through if lint switch fallthrough enabled. // Warn about fall-through if lint switch fallthrough enabled.
} }
if (!hasDefault) { if (!hasDefault) {
andSetInits(null, initsSwitch); inits.andSet(initsSwitch);
} }
resolveBreaks(tree, prevPendingExits); resolveBreaks(tree, prevPendingExits);
nextadr = nextadrPrev; nextadr = nextadrPrev;
...@@ -2051,16 +2087,10 @@ public class Flow { ...@@ -2051,16 +2087,10 @@ public class Flow {
} }
} }
boolean isEnabled(Lint.LintCategory lc) {
return false;
}
void reportWarning(Lint.LintCategory lc, DiagnosticPosition pos, String key, Object ... args) {}
public void visitTry(JCTry tree) { public void visitTry(JCTry tree) {
ListBuffer<JCVariableDecl> resourceVarDecls = new ListBuffer<>(); ListBuffer<JCVariableDecl> resourceVarDecls = new ListBuffer<>();
final Bits uninitsTryPrev = new Bits(uninitsTry); final Bits uninitsTryPrev = new Bits(uninitsTry);
ListBuffer<P> prevPendingExits = pendingExits; ListBuffer<AssignPendingExit> prevPendingExits = pendingExits;
pendingExits = new ListBuffer<>(); pendingExits = new ListBuffer<>();
final Bits initsTry = new Bits(inits); final Bits initsTry = new Bits(inits);
uninitsTry.assign(uninits); uninitsTry.assign(uninits);
...@@ -2083,10 +2113,10 @@ public class Flow { ...@@ -2083,10 +2113,10 @@ public class Flow {
int nextadrCatch = nextadr; int nextadrCatch = nextadr;
if (!resourceVarDecls.isEmpty() && if (!resourceVarDecls.isEmpty() &&
isEnabled(Lint.LintCategory.TRY)) { lint.isEnabled(Lint.LintCategory.TRY)) {
for (JCVariableDecl resVar : resourceVarDecls) { for (JCVariableDecl resVar : resourceVarDecls) {
if (unrefdResources.includes(resVar.sym)) { if (unrefdResources.includes(resVar.sym)) {
reportWarning(Lint.LintCategory.TRY, resVar.pos(), log.warning(Lint.LintCategory.TRY, resVar.pos(),
"try.resource.not.referenced", resVar.sym); "try.resource.not.referenced", resVar.sym);
unrefdResources.remove(resVar.sym); unrefdResources.remove(resVar.sym);
} }
...@@ -2102,7 +2132,7 @@ public class Flow { ...@@ -2102,7 +2132,7 @@ public class Flow {
for (List<JCCatch> l = tree.catchers; l.nonEmpty(); l = l.tail) { for (List<JCCatch> l = tree.catchers; l.nonEmpty(); l = l.tail) {
JCVariableDecl param = l.head.param; JCVariableDecl param = l.head.param;
assignToInits(tree.body, initsCatchPrev); inits.assign(initsCatchPrev);
uninits.assign(uninitsCatchPrev); uninits.assign(uninitsCatchPrev);
scan(param); scan(param);
/* If this is a TWR and we are executing the code from Gen, /* If this is a TWR and we are executing the code from Gen,
...@@ -2115,9 +2145,9 @@ public class Flow { ...@@ -2115,9 +2145,9 @@ public class Flow {
nextadr = nextadrCatch; nextadr = nextadrCatch;
} }
if (tree.finalizer != null) { if (tree.finalizer != null) {
assignToInits(tree.finalizer, initsTry); inits.assign(initsTry);
uninits.assign(uninitsTry); uninits.assign(uninitsTry);
ListBuffer<P> exits = pendingExits; ListBuffer<AssignPendingExit> exits = pendingExits;
pendingExits = prevPendingExits; pendingExits = prevPendingExits;
scan(tree.finalizer); scan(tree.finalizer);
if (!tree.finallyCanCompleteNormally) { if (!tree.finallyCanCompleteNormally) {
...@@ -2127,19 +2157,19 @@ public class Flow { ...@@ -2127,19 +2157,19 @@ public class Flow {
// FIX: this doesn't preserve source order of exits in catch // FIX: this doesn't preserve source order of exits in catch
// versus finally! // versus finally!
while (exits.nonEmpty()) { while (exits.nonEmpty()) {
P exit = exits.next(); AssignPendingExit exit = exits.next();
if (exit.exit_inits != null) { if (exit.exit_inits != null) {
exit.exit_inits.orSet(inits); exit.exit_inits.orSet(inits);
exit.exit_uninits.andSet(uninits); exit.exit_uninits.andSet(uninits);
} }
pendingExits.append(exit); pendingExits.append(exit);
} }
orSetInits(tree, initsEnd); inits.orSet(initsEnd);
} }
} else { } else {
assignToInits(tree, initsEnd); inits.assign(initsEnd);
uninits.assign(uninitsEnd); uninits.assign(uninitsEnd);
ListBuffer<P> exits = pendingExits; ListBuffer<AssignPendingExit> exits = pendingExits;
pendingExits = prevPendingExits; pendingExits = prevPendingExits;
while (exits.nonEmpty()) pendingExits.append(exits.next()); while (exits.nonEmpty()) pendingExits.append(exits.next());
} }
...@@ -2150,7 +2180,7 @@ public class Flow { ...@@ -2150,7 +2180,7 @@ public class Flow {
scanCond(tree.cond); scanCond(tree.cond);
final Bits initsBeforeElse = new Bits(initsWhenFalse); final Bits initsBeforeElse = new Bits(initsWhenFalse);
final Bits uninitsBeforeElse = new Bits(uninitsWhenFalse); final Bits uninitsBeforeElse = new Bits(uninitsWhenFalse);
assignToInits(tree.cond, initsWhenTrue); inits.assign(initsWhenTrue);
uninits.assign(uninitsWhenTrue); uninits.assign(uninitsWhenTrue);
if (tree.truepart.type.hasTag(BOOLEAN) && if (tree.truepart.type.hasTag(BOOLEAN) &&
tree.falsepart.type.hasTag(BOOLEAN)) { tree.falsepart.type.hasTag(BOOLEAN)) {
...@@ -2163,7 +2193,7 @@ public class Flow { ...@@ -2163,7 +2193,7 @@ public class Flow {
final Bits initsAfterThenWhenFalse = new Bits(initsWhenFalse); final Bits initsAfterThenWhenFalse = new Bits(initsWhenFalse);
final Bits uninitsAfterThenWhenTrue = new Bits(uninitsWhenTrue); final Bits uninitsAfterThenWhenTrue = new Bits(uninitsWhenTrue);
final Bits uninitsAfterThenWhenFalse = new Bits(uninitsWhenFalse); final Bits uninitsAfterThenWhenFalse = new Bits(uninitsWhenFalse);
assignToInits(tree.truepart, initsBeforeElse); inits.assign(initsBeforeElse);
uninits.assign(uninitsBeforeElse); uninits.assign(uninitsBeforeElse);
scanCond(tree.falsepart); scanCond(tree.falsepart);
initsWhenTrue.andSet(initsAfterThenWhenTrue); initsWhenTrue.andSet(initsAfterThenWhenTrue);
...@@ -2174,10 +2204,10 @@ public class Flow { ...@@ -2174,10 +2204,10 @@ public class Flow {
scanExpr(tree.truepart); scanExpr(tree.truepart);
final Bits initsAfterThen = new Bits(inits); final Bits initsAfterThen = new Bits(inits);
final Bits uninitsAfterThen = new Bits(uninits); final Bits uninitsAfterThen = new Bits(uninits);
assignToInits(tree.truepart, initsBeforeElse); inits.assign(initsBeforeElse);
uninits.assign(uninitsBeforeElse); uninits.assign(uninitsBeforeElse);
scanExpr(tree.falsepart); scanExpr(tree.falsepart);
andSetInits(tree.falsepart, initsAfterThen); inits.andSet(initsAfterThen);
uninits.andSet(uninitsAfterThen); uninits.andSet(uninitsAfterThen);
} }
} }
...@@ -2186,46 +2216,42 @@ public class Flow { ...@@ -2186,46 +2216,42 @@ public class Flow {
scanCond(tree.cond); scanCond(tree.cond);
final Bits initsBeforeElse = new Bits(initsWhenFalse); final Bits initsBeforeElse = new Bits(initsWhenFalse);
final Bits uninitsBeforeElse = new Bits(uninitsWhenFalse); final Bits uninitsBeforeElse = new Bits(uninitsWhenFalse);
assignToInits(tree.cond, initsWhenTrue); inits.assign(initsWhenTrue);
uninits.assign(uninitsWhenTrue); uninits.assign(uninitsWhenTrue);
scan(tree.thenpart); scan(tree.thenpart);
if (tree.elsepart != null) { if (tree.elsepart != null) {
final Bits initsAfterThen = new Bits(inits); final Bits initsAfterThen = new Bits(inits);
final Bits uninitsAfterThen = new Bits(uninits); final Bits uninitsAfterThen = new Bits(uninits);
assignToInits(tree.thenpart, initsBeforeElse); inits.assign(initsBeforeElse);
uninits.assign(uninitsBeforeElse); uninits.assign(uninitsBeforeElse);
scan(tree.elsepart); scan(tree.elsepart);
andSetInits(tree.elsepart, initsAfterThen); inits.andSet(initsAfterThen);
uninits.andSet(uninitsAfterThen); uninits.andSet(uninitsAfterThen);
} else { } else {
andSetInits(tree.thenpart, initsBeforeElse); inits.andSet(initsBeforeElse);
uninits.andSet(uninitsBeforeElse); uninits.andSet(uninitsBeforeElse);
} }
} }
protected P createNewPendingExit(JCTree tree, Bits inits, Bits uninits) {
return null;
}
@Override @Override
public void visitBreak(JCBreak tree) { public void visitBreak(JCBreak tree) {
recordExit(tree, createNewPendingExit(tree, inits, uninits)); recordExit(new AssignPendingExit(tree, inits, uninits));
} }
@Override @Override
public void visitContinue(JCContinue tree) { public void visitContinue(JCContinue tree) {
recordExit(tree, createNewPendingExit(tree, inits, uninits)); recordExit(new AssignPendingExit(tree, inits, uninits));
} }
@Override @Override
public void visitReturn(JCReturn tree) { public void visitReturn(JCReturn tree) {
scanExpr(tree.expr); scanExpr(tree.expr);
recordExit(tree, createNewPendingExit(tree, inits, uninits)); recordExit(new AssignPendingExit(tree, inits, uninits));
} }
public void visitThrow(JCThrow tree) { public void visitThrow(JCThrow tree) {
scanExpr(tree.expr); scanExpr(tree.expr);
markDead(tree.expr); markDead();
} }
public void visitApply(JCMethodInvocation tree) { public void visitApply(JCMethodInvocation tree) {
...@@ -2244,10 +2270,10 @@ public class Flow { ...@@ -2244,10 +2270,10 @@ public class Flow {
final Bits prevUninits = new Bits(uninits); final Bits prevUninits = new Bits(uninits);
final Bits prevInits = new Bits(inits); final Bits prevInits = new Bits(inits);
int returnadrPrev = returnadr; int returnadrPrev = returnadr;
ListBuffer<P> prevPending = pendingExits; ListBuffer<AssignPendingExit> prevPending = pendingExits;
try { try {
returnadr = nextadr; returnadr = nextadr;
pendingExits = new ListBuffer<P>(); pendingExits = new ListBuffer<>();
for (List<JCVariableDecl> l = tree.params; l.nonEmpty(); l = l.tail) { for (List<JCVariableDecl> l = tree.params; l.nonEmpty(); l = l.tail) {
JCVariableDecl def = l.head; JCVariableDecl def = l.head;
scan(def); scan(def);
...@@ -2263,7 +2289,7 @@ public class Flow { ...@@ -2263,7 +2289,7 @@ public class Flow {
finally { finally {
returnadr = returnadrPrev; returnadr = returnadrPrev;
uninits.assign(prevUninits); uninits.assign(prevUninits);
assignToInits(tree, prevInits); inits.assign(prevInits);
pendingExits = prevPending; pendingExits = prevPending;
} }
} }
...@@ -2279,11 +2305,11 @@ public class Flow { ...@@ -2279,11 +2305,11 @@ public class Flow {
scanCond(tree.cond); scanCond(tree.cond);
uninitsExit.andSet(uninitsWhenTrue); uninitsExit.andSet(uninitsWhenTrue);
if (tree.detail != null) { if (tree.detail != null) {
assignToInits(tree, initsWhenFalse); inits.assign(initsWhenFalse);
uninits.assign(uninitsWhenFalse); uninits.assign(uninitsWhenFalse);
scanExpr(tree.detail); scanExpr(tree.detail);
} }
assignToInits(tree, initsExit); inits.assign(initsExit);
uninits.assign(uninitsExit); uninits.assign(uninitsExit);
} }
...@@ -2351,7 +2377,7 @@ public class Flow { ...@@ -2351,7 +2377,7 @@ public class Flow {
scanCond(tree.lhs); scanCond(tree.lhs);
final Bits initsWhenFalseLeft = new Bits(initsWhenFalse); final Bits initsWhenFalseLeft = new Bits(initsWhenFalse);
final Bits uninitsWhenFalseLeft = new Bits(uninitsWhenFalse); final Bits uninitsWhenFalseLeft = new Bits(uninitsWhenFalse);
assignToInits(tree.lhs, initsWhenTrue); inits.assign(initsWhenTrue);
uninits.assign(uninitsWhenTrue); uninits.assign(uninitsWhenTrue);
scanCond(tree.rhs); scanCond(tree.rhs);
initsWhenFalse.andSet(initsWhenFalseLeft); initsWhenFalse.andSet(initsWhenFalseLeft);
...@@ -2361,7 +2387,7 @@ public class Flow { ...@@ -2361,7 +2387,7 @@ public class Flow {
scanCond(tree.lhs); scanCond(tree.lhs);
final Bits initsWhenTrueLeft = new Bits(initsWhenTrue); final Bits initsWhenTrueLeft = new Bits(initsWhenTrue);
final Bits uninitsWhenTrueLeft = new Bits(uninitsWhenTrue); final Bits uninitsWhenTrueLeft = new Bits(uninitsWhenTrue);
assignToInits(tree.lhs, initsWhenFalse); inits.assign(initsWhenFalse);
uninits.assign(uninitsWhenFalse); uninits.assign(uninitsWhenFalse);
scanCond(tree.rhs); scanCond(tree.rhs);
initsWhenTrue.andSet(initsWhenTrueLeft); initsWhenTrue.andSet(initsWhenTrueLeft);
...@@ -2436,136 +2462,6 @@ public class Flow { ...@@ -2436,136 +2462,6 @@ public class Flow {
} }
} }
public class AssignAnalyzer extends AbstractAssignAnalyzer<AssignAnalyzer.AssignPendingExit> {
public class AssignPendingExit extends AbstractAssignAnalyzer<AssignPendingExit>.AbstractAssignPendingExit {
public AssignPendingExit(JCTree tree, final Bits inits, final Bits uninits) {
super(tree, inits, uninits);
}
}
@Override
protected AssignPendingExit createNewPendingExit(JCTree tree,
Bits inits, Bits uninits) {
return new AssignPendingExit(tree, inits, uninits);
}
/** Record an initialization of a trackable variable.
*/
@Override
void letInit(DiagnosticPosition pos, VarSymbol sym) {
if (sym.adr >= firstadr && trackable(sym)) {
if ((sym.flags() & EFFECTIVELY_FINAL) != 0) {
if (!uninits.isMember(sym.adr)) {
//assignment targeting an effectively final variable
//makes the variable lose its status of effectively final
//if the variable is _not_ definitively unassigned
sym.flags_field &= ~EFFECTIVELY_FINAL;
} else {
uninit(sym);
}
}
else if ((sym.flags() & FINAL) != 0) {
if ((sym.flags() & PARAMETER) != 0) {
if ((sym.flags() & UNION) != 0) { //multi-catch parameter
log.error(pos, "multicatch.parameter.may.not.be.assigned", sym);
}
else {
log.error(pos, "final.parameter.may.not.be.assigned",
sym);
}
} else if (!uninits.isMember(sym.adr)) {
log.error(pos, flowKind.errKey, sym);
} else {
uninit(sym);
}
}
inits.incl(sym.adr);
} else if ((sym.flags() & FINAL) != 0) {
log.error(pos, "var.might.already.be.assigned", sym);
}
}
@Override
void checkInit(DiagnosticPosition pos, VarSymbol sym, String errkey) {
if ((sym.adr >= firstadr || sym.owner.kind != TYP) &&
trackable(sym) &&
!inits.isMember(sym.adr)) {
log.error(pos, errkey, sym);
inits.incl(sym.adr);
}
}
@Override
void reportWarning(Lint.LintCategory lc, DiagnosticPosition pos,
String key, Object ... args) {
log.warning(lc, pos, key, args);
}
@Override
int getLogNumberOfErrors() {
return log.nerrors;
}
@Override
boolean isEnabled(Lint.LintCategory lc) {
return lint.isEnabled(lc);
}
@Override
public void visitClassDef(JCClassDecl tree) {
if (tree.sym == null) {
return;
}
Lint lintPrev = lint;
lint = lint.augment(tree.sym);
try {
super.visitClassDef(tree);
} finally {
lint = lintPrev;
}
}
@Override
public void visitMethodDef(JCMethodDecl tree) {
if (tree.body == null) {
return;
}
/* MemberEnter can generate synthetic methods ignore them
*/
if ((tree.sym.flags() & SYNTHETIC) != 0) {
return;
}
Lint lintPrev = lint;
lint = lint.augment(tree.sym);
try {
super.visitMethodDef(tree);
} finally {
lint = lintPrev;
}
}
@Override
public void visitVarDef(JCVariableDecl tree) {
if (tree.init == null) {
super.visitVarDef(tree);
} else {
Lint lintPrev = lint;
lint = lint.augment(tree.sym);
try{
super.visitVarDef(tree);
} finally {
lint = lintPrev;
}
}
}
}
/** /**
* This pass implements the last step of the dataflow analysis, namely * This pass implements the last step of the dataflow analysis, namely
* the effectively-final analysis check. This checks that every local variable * the effectively-final analysis check. This checks that every local variable
...@@ -2578,7 +2474,7 @@ public class Flow { ...@@ -2578,7 +2474,7 @@ public class Flow {
JCTree currentTree; //local class or lambda JCTree currentTree; //local class or lambda
@Override @Override
void markDead(JCTree tree) { void markDead() {
//do nothing //do nothing
} }
...@@ -2715,7 +2611,7 @@ public class Flow { ...@@ -2715,7 +2611,7 @@ public class Flow {
try { try {
attrEnv = env; attrEnv = env;
Flow.this.make = make; Flow.this.make = make;
pendingExits = new ListBuffer<PendingExit>(); pendingExits = new ListBuffer<>();
scan(tree); scan(tree);
} finally { } finally {
pendingExits = null; pendingExits = null;
......
/* /*
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -84,20 +84,6 @@ public class Bits { ...@@ -84,20 +84,6 @@ public class Bits {
} }
public enum BitsOpKind {
INIT,
CLEAR,
INCL_BIT,
EXCL_BIT,
ASSIGN,
AND_SET,
OR_SET,
DIFF_SET,
XOR_SET,
INCL_RANGE,
EXCL_RANGE,
}
private final static int wordlen = 32; private final static int wordlen = 32;
private final static int wordshift = 5; private final static int wordshift = 5;
private final static int wordmask = wordlen - 1; private final static int wordmask = wordlen - 1;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册