Thu, 03 Mar 2011 17:32:35 +0000
7023703: Valid code doesn't compile
Summary: leftovers cause problems when analyzing loops in Flow.java
Reviewed-by: jjg
1.1 --- a/src/share/classes/com/sun/tools/javac/comp/Flow.java Thu Mar 03 09:43:24 2011 +0000 1.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Flow.java Thu Mar 03 17:32:35 2011 +0000 1.3 @@ -804,14 +804,16 @@ 1.4 ListBuffer<PendingExit> prevPendingExits = pendingExits; 1.5 boolean prevLoopPassTwo = loopPassTwo; 1.6 pendingExits = new ListBuffer<PendingExit>(); 1.7 + int prevErrors = log.nerrors; 1.8 do { 1.9 Bits uninitsEntry = uninits.dup(); 1.10 + uninitsEntry.excludeFrom(nextadr); 1.11 scanStat(tree.body); 1.12 alive |= resolveContinues(tree); 1.13 scanCond(tree.cond); 1.14 - if (log.nerrors != 0 || 1.15 + if (log.nerrors != prevErrors || 1.16 loopPassTwo || 1.17 - uninitsEntry.diffSet(uninitsWhenTrue).nextBit(firstadr)==-1) 1.18 + uninitsEntry.dup().diffSet(uninitsWhenTrue).nextBit(firstadr)==-1) 1.19 break; 1.20 inits = initsWhenTrue; 1.21 uninits = uninitsEntry.andSet(uninitsWhenTrue); 1.22 @@ -831,8 +833,10 @@ 1.23 Bits initsCond; 1.24 Bits uninitsCond; 1.25 pendingExits = new ListBuffer<PendingExit>(); 1.26 + int prevErrors = log.nerrors; 1.27 do { 1.28 Bits uninitsEntry = uninits.dup(); 1.29 + uninitsEntry.excludeFrom(nextadr); 1.30 scanCond(tree.cond); 1.31 initsCond = initsWhenFalse; 1.32 uninitsCond = uninitsWhenFalse; 1.33 @@ -841,9 +845,9 @@ 1.34 alive = !tree.cond.type.isFalse(); 1.35 scanStat(tree.body); 1.36 alive |= resolveContinues(tree); 1.37 - if (log.nerrors != 0 || 1.38 + if (log.nerrors != prevErrors || 1.39 loopPassTwo || 1.40 - uninitsEntry.diffSet(uninits).nextBit(firstadr) == -1) 1.41 + uninitsEntry.dup().diffSet(uninits).nextBit(firstadr) == -1) 1.42 break; 1.43 uninits = uninitsEntry.andSet(uninits); 1.44 loopPassTwo = true; 1.45 @@ -864,8 +868,10 @@ 1.46 Bits initsCond; 1.47 Bits uninitsCond; 1.48 pendingExits = new ListBuffer<PendingExit>(); 1.49 + int prevErrors = log.nerrors; 1.50 do { 1.51 Bits uninitsEntry = uninits.dup(); 1.52 + uninitsEntry.excludeFrom(nextadr); 1.53 if (tree.cond != null) { 1.54 scanCond(tree.cond); 1.55 initsCond = initsWhenFalse; 1.56 @@ -883,7 +889,7 @@ 1.57 scanStat(tree.body); 1.58 alive |= resolveContinues(tree); 1.59 scan(tree.step); 1.60 - if (log.nerrors != 0 || 1.61 + if (log.nerrors != prevErrors || 1.62 loopPassTwo || 1.63 uninitsEntry.dup().diffSet(uninits).nextBit(firstadr) == -1) 1.64 break; 1.65 @@ -897,8 +903,6 @@ 1.66 alive = resolveBreaks(tree, prevPendingExits) || 1.67 tree.cond != null && !tree.cond.type.isTrue(); 1.68 nextadr = nextadrPrev; 1.69 - inits.excludeFrom(nextadr); 1.70 - uninits.excludeFrom(nextadr); 1.71 } 1.72 1.73 public void visitForeachLoop(JCEnhancedForLoop tree) { 1.74 @@ -913,13 +917,15 @@ 1.75 1.76 letInit(tree.pos(), tree.var.sym); 1.77 pendingExits = new ListBuffer<PendingExit>(); 1.78 + int prevErrors = log.nerrors; 1.79 do { 1.80 Bits uninitsEntry = uninits.dup(); 1.81 + uninitsEntry.excludeFrom(nextadr); 1.82 scanStat(tree.body); 1.83 alive |= resolveContinues(tree); 1.84 - if (log.nerrors != 0 || 1.85 + if (log.nerrors != prevErrors || 1.86 loopPassTwo || 1.87 - uninitsEntry.diffSet(uninits).nextBit(firstadr) == -1) 1.88 + uninitsEntry.dup().diffSet(uninits).nextBit(firstadr) == -1) 1.89 break; 1.90 uninits = uninitsEntry.andSet(uninits); 1.91 loopPassTwo = true;
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 2.2 +++ b/test/tools/javac/7023703/T7023703neg.java Thu Mar 03 17:32:35 2011 +0000 2.3 @@ -0,0 +1,71 @@ 2.4 +/* 2.5 + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. 2.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 2.7 + * 2.8 + * This code is free software; you can redistribute it and/or modify it 2.9 + * under the terms of the GNU General Public License version 2 only, as 2.10 + * published by the Free Software Foundation. 2.11 + * 2.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 2.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 2.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 2.15 + * version 2 for more details (a copy is included in the LICENSE file that 2.16 + * accompanied this code). 2.17 + * 2.18 + * You should have received a copy of the GNU General Public License version 2.19 + * 2 along with this work; if not, write to the Free Software Foundation, 2.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 2.21 + * 2.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2.23 + * or visit www.oracle.com if you need additional information or have any 2.24 + * questions. 2.25 + */ 2.26 + 2.27 +/* @test 2.28 + * @bug 7023703 2.29 + * @summary Valid code doesn't compile 2.30 + * @compile/fail/ref=T7023703neg.out -XDrawDiagnostics T7023703neg.java 2.31 + */ 2.32 + 2.33 +class T7023703neg { 2.34 + 2.35 + void testForLoop(boolean cond) { 2.36 + final int bug; 2.37 + final int bug2; 2.38 + for (;cond;) { 2.39 + final int item = 0; 2.40 + bug2 = 1; //error 2.41 + } 2.42 + bug = 0; //ok 2.43 + } 2.44 + 2.45 + void testForEachLoop(java.util.Collection<Integer> c) { 2.46 + final int bug; 2.47 + final int bug2; 2.48 + for (Integer i : c) { 2.49 + final int item = 0; 2.50 + bug2 = 1; //error 2.51 + } 2.52 + bug = 0; //ok 2.53 + } 2.54 + 2.55 + void testWhileLoop(boolean cond) { 2.56 + final int bug; 2.57 + final int bug2; 2.58 + while (cond) { 2.59 + final int item = 0; 2.60 + bug2 = 1; //error 2.61 + } 2.62 + bug = 0; //ok 2.63 + } 2.64 + 2.65 + void testDoWhileLoop(boolean cond) { 2.66 + final int bug; 2.67 + final int bug2; 2.68 + do { 2.69 + final int item = 0; 2.70 + bug2 = 1; //error 2.71 + } while (cond); 2.72 + bug = 0; //ok 2.73 + } 2.74 +}
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 3.2 +++ b/test/tools/javac/7023703/T7023703neg.out Thu Mar 03 17:32:35 2011 +0000 3.3 @@ -0,0 +1,5 @@ 3.4 +T7023703neg.java:37:13: compiler.err.var.might.be.assigned.in.loop: bug2 3.5 +T7023703neg.java:47:13: compiler.err.var.might.be.assigned.in.loop: bug2 3.6 +T7023703neg.java:57:13: compiler.err.var.might.be.assigned.in.loop: bug2 3.7 +T7023703neg.java:67:13: compiler.err.var.might.be.assigned.in.loop: bug2 3.8 +4 errors
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 4.2 +++ b/test/tools/javac/7023703/T7023703pos.java Thu Mar 03 17:32:35 2011 +0000 4.3 @@ -0,0 +1,73 @@ 4.4 +/* 4.5 + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. 4.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4.7 + * 4.8 + * This code is free software; you can redistribute it and/or modify it 4.9 + * under the terms of the GNU General Public License version 2 only, as 4.10 + * published by the Free Software Foundation. 4.11 + * 4.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 4.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 4.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 4.15 + * version 2 for more details (a copy is included in the LICENSE file that 4.16 + * accompanied this code). 4.17 + * 4.18 + * You should have received a copy of the GNU General Public License version 4.19 + * 2 along with this work; if not, write to the Free Software Foundation, 4.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 4.21 + * 4.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 4.23 + * or visit www.oracle.com if you need additional information or have any 4.24 + * questions. 4.25 + */ 4.26 + 4.27 +/* @test 4.28 + * @bug 7023703 4.29 + * @summary Valid code doesn't compile 4.30 + * @compile T7023703pos.java 4.31 + */ 4.32 + 4.33 +class T7023703pos { 4.34 + 4.35 + void testForLoop() { 4.36 + final int bug; 4.37 + for (;"a".equals("b");) { 4.38 + final int item = 0; 4.39 + } 4.40 + bug = 0; //ok 4.41 + } 4.42 + 4.43 + void testForEachLoop(boolean cond, java.util.Collection<Integer> c) { 4.44 + final int bug; 4.45 + for (Integer i : c) { 4.46 + if (cond) { 4.47 + final int item = 0; 4.48 + } 4.49 + } 4.50 + bug = 0; //ok 4.51 + } 4.52 + 4.53 + void testWhileLoop() { 4.54 + final int bug; 4.55 + while ("a".equals("b")) { 4.56 + final int item = 0; 4.57 + } 4.58 + bug = 0; //ok 4.59 + } 4.60 + 4.61 + void testDoWhileLoop() { 4.62 + final int bug; 4.63 + do { 4.64 + final int item = 0; 4.65 + } while ("a".equals("b")); 4.66 + bug = 0; //ok 4.67 + } 4.68 + 4.69 + private static class Inner { 4.70 + private final int a, b, c, d, e; 4.71 + 4.72 + public Inner() { 4.73 + a = b = c = d = e = 0; 4.74 + } 4.75 + } 4.76 +}