Skip to content
This repository was archived by the owner on Sep 19, 2023. It is now read-only.

Commit 83d0573

Browse files
committed
8292756: java.lang.AssertionError at at jdk.compiler/com.sun.tools.javac.code.Scope$ScopeImpl.leave(Scope.java:386)
Reviewed-by: vromero Backport-of: 0be2b2c2f1b670bbcd3a8e17bc9b43a534909da5
1 parent 88490ec commit 83d0573

File tree

3 files changed

+119
-13
lines changed

3 files changed

+119
-13
lines changed

src/jdk.compiler/share/classes/com/sun/tools/javac/code/Scope.java

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -272,9 +272,9 @@ public static WriteableScope create(Symbol owner) {
272272
}
273273

274274
private static class ScopeImpl extends WriteableScope {
275-
/** The number of scopes that share this scope's hash table.
275+
/** true if this scope's hash table is shared with a nested scope.
276276
*/
277-
private int shared;
277+
private boolean shared;
278278

279279
/** Next enclosing scope (with whom this scope may share a hashtable)
280280
*/
@@ -339,8 +339,10 @@ public ScopeImpl(Symbol owner) {
339339
* of fresh tables.
340340
*/
341341
public WriteableScope dup(Symbol newOwner) {
342+
Assert.check(!shared);
343+
342344
ScopeImpl result = new ScopeImpl(this, newOwner, this.table, this.nelems);
343-
shared++;
345+
shared = true;
344346
// System.out.println("====> duping scope " + this.hashCode() + " owned by " + newOwner + " to " + result.hashCode());
345347
// new Error().printStackTrace(System.out);
346348
return result;
@@ -351,7 +353,7 @@ public WriteableScope dup(Symbol newOwner) {
351353
* the table of its outer scope.
352354
*/
353355
public WriteableScope dupUnshared(Symbol newOwner) {
354-
if (shared > 0) {
356+
if (shared) {
355357
//The nested Scopes might have already added something to the table, so all items
356358
//that don't originate in this Scope or any of its outer Scopes need to be cleared:
357359
Set<Scope> acceptScopes = Collections.newSetFromMap(new IdentityHashMap<>());
@@ -383,7 +385,7 @@ public WriteableScope dupUnshared(Symbol newOwner) {
383385
* with next.
384386
*/
385387
public WriteableScope leave() {
386-
Assert.check(shared == 0);
388+
Assert.check(!shared);
387389
if (table != next.table) return next;
388390
while (elems != null) {
389391
int hash = getIndex(elems.sym.name);
@@ -392,8 +394,8 @@ public WriteableScope leave() {
392394
table[hash] = elems.shadowed;
393395
elems = elems.nextSibling;
394396
}
395-
Assert.check(next.shared > 0);
396-
next.shared--;
397+
Assert.check(next.shared);
398+
next.shared = false;
397399
next.nelems = nelems;
398400
// System.out.println("====> leaving scope " + this.hashCode() + " owned by " + this.owner + " to " + next.hashCode());
399401
// new Error().printStackTrace(System.out);
@@ -403,12 +405,12 @@ public WriteableScope leave() {
403405
/** Double size of hash table.
404406
*/
405407
private void dble() {
406-
Assert.check(shared == 0);
408+
Assert.check(!shared);
407409
Entry[] oldtable = table;
408410
Entry[] newtable = new Entry[oldtable.length * 2];
409411
for (ScopeImpl s = this; s != null; s = s.next) {
410412
if (s.table == oldtable) {
411-
Assert.check(s == this || s.shared != 0);
413+
Assert.check(s == this || s.shared);
412414
s.table = newtable;
413415
s.hashMask = newtable.length - 1;
414416
}
@@ -429,7 +431,7 @@ private void dble() {
429431
/** Enter symbol sym in this scope.
430432
*/
431433
public void enter(Symbol sym) {
432-
Assert.check(shared == 0);
434+
Assert.check(!shared);
433435
if (nelems * 3 >= hashMask * 2)
434436
dble();
435437
int hash = getIndex(sym.name);
@@ -449,7 +451,7 @@ public void enter(Symbol sym) {
449451
/** Remove symbol from this scope.
450452
*/
451453
public void remove(Symbol sym) {
452-
Assert.check(shared == 0);
454+
Assert.check(!shared);
453455
Entry e = lookup(sym.name, candidate -> candidate == sym);
454456
if (e.scope == null) return;
455457

@@ -487,7 +489,7 @@ else while (true) {
487489
/** Enter symbol sym in this scope if not already there.
488490
*/
489491
public void enterIfAbsent(Symbol sym) {
490-
Assert.check(shared == 0);
492+
Assert.check(!shared);
491493
Entry e = lookup(sym.name);
492494
while (e.scope == this && e.sym.kind != sym.kind) e = e.next();
493495
if (e.scope != this) enter(sym);

src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1787,7 +1787,7 @@ private void handleSwitch(JCTree switchTree,
17871787
JCExpression guard = patternlabel.guard;
17881788
if (guard != null) {
17891789
MatchBindings afterPattern = matchBindings;
1790-
Env<AttrContext> bodyEnv = bindingEnv(env, matchBindings.bindingsWhenTrue);
1790+
Env<AttrContext> bodyEnv = bindingEnv(switchEnv, matchBindings.bindingsWhenTrue);
17911791
try {
17921792
attribExpr(guard, bodyEnv, syms.booleanType);
17931793
} finally {
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
/*
2+
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 2 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 2 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*/
23+
24+
/*
25+
* @test
26+
* @bug 8292756
27+
* @summary Verify the Scope can be safely and correctly resized to accommodate pattern binding variables
28+
* when the Scope for a guard is constructed.
29+
* @library /tools/lib /tools/javac/lib
30+
* @modules
31+
* jdk.compiler/com.sun.tools.javac.api
32+
* jdk.compiler/com.sun.tools.javac.file
33+
* jdk.compiler/com.sun.tools.javac.main
34+
* jdk.compiler/com.sun.tools.javac.util
35+
* @build toolbox.ToolBox toolbox.JavacTask
36+
* @build combo.ComboTestHelper
37+
* @compile ScopeResizeTest.java
38+
* @run main ScopeResizeTest
39+
*/
40+
41+
import combo.ComboInstance;
42+
import combo.ComboParameter;
43+
import combo.ComboTask;
44+
import combo.ComboTestHelper;
45+
import java.util.stream.Stream;
46+
import toolbox.ToolBox;
47+
48+
public class ScopeResizeTest extends ComboInstance<ScopeResizeTest> {
49+
protected ToolBox tb;
50+
51+
ScopeResizeTest() {
52+
super();
53+
tb = new ToolBox();
54+
}
55+
56+
public static void main(String... args) throws Exception {
57+
int variantsSize = 17;
58+
PredefinedVariables[] variants = Stream.iterate(0, i -> i + 1)
59+
.limit(variantsSize)
60+
.map(s -> new PredefinedVariables(s))
61+
.toArray(s -> new PredefinedVariables[s]);
62+
new ComboTestHelper<ScopeResizeTest>()
63+
.withDimension("PREDEFINED_VARIABLES", (x, predefinedVariables) -> x.predefinedVariables = predefinedVariables, variants)
64+
.run(ScopeResizeTest::new);
65+
}
66+
67+
private PredefinedVariables predefinedVariables;
68+
69+
private static final String MAIN_TEMPLATE =
70+
"""
71+
public class Test {
72+
public static void test(Object o) {
73+
#{PREDEFINED_VARIABLES}
74+
switch (o) {
75+
case String s when s.isEmpty() -> {}
76+
default -> {}
77+
}
78+
}
79+
}
80+
""";
81+
82+
@Override
83+
protected void doWork() throws Throwable {
84+
ComboTask task = newCompilationTask()
85+
.withSourceFromTemplate(MAIN_TEMPLATE, pname -> switch (pname) {
86+
case "PREDEFINED_VARIABLES" -> predefinedVariables;
87+
default -> throw new UnsupportedOperationException(pname);
88+
});
89+
90+
task.analyze(result -> {});
91+
}
92+
93+
public record PredefinedVariables(int size) implements ComboParameter {
94+
@Override
95+
public String expand(String optParameter) {
96+
StringBuilder variables = new StringBuilder();
97+
for (int i = 0; i < size(); i++) {
98+
variables.append("int i" + i + ";\n");
99+
}
100+
return variables.toString();
101+
}
102+
}
103+
104+
}

0 commit comments

Comments
 (0)