Skip to content

Commit af056c1

Browse files
committedMay 24, 2024
8332106: VerifyError when using switch pattern in this(...) or super(...)
Reviewed-by: abimpoudis, vromero
1 parent da3001d commit af056c1

File tree

3 files changed

+450
-15
lines changed

3 files changed

+450
-15
lines changed
 

‎src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Gen.java

+50-15
Original file line numberDiff line numberDiff line change
@@ -172,8 +172,8 @@ protected Gen(Context context) {
172172
Chain switchExpressionFalseChain;
173173
List<LocalItem> stackBeforeSwitchExpression;
174174
LocalItem switchResult;
175-
Set<JCMethodInvocation> invocationsWithPatternMatchingCatch = Set.of();
176-
ListBuffer<int[]> patternMatchingInvocationRanges;
175+
PatternMatchingCatchConfiguration patternMatchingCatchConfiguration =
176+
new PatternMatchingCatchConfiguration(Set.of(), null, null, null);
177177

178178
/** Cache the symbol to reflect the qualifying type.
179179
* key: corresponding type
@@ -1087,21 +1087,31 @@ public void visitBlock(JCBlock tree) {
10871087
}
10881088

10891089
private void visitBlockWithPatterns(JCBlock tree) {
1090-
Set<JCMethodInvocation> prevInvocationsWithPatternMatchingCatch = invocationsWithPatternMatchingCatch;
1091-
ListBuffer<int[]> prevRanges = patternMatchingInvocationRanges;
1092-
State startState = code.state.dup();
1090+
PatternMatchingCatchConfiguration prevConfiguration = patternMatchingCatchConfiguration;
10931091
try {
1094-
invocationsWithPatternMatchingCatch = tree.patternMatchingCatch.calls2Handle();
1095-
patternMatchingInvocationRanges = new ListBuffer<>();
1092+
patternMatchingCatchConfiguration =
1093+
new PatternMatchingCatchConfiguration(tree.patternMatchingCatch.calls2Handle(),
1094+
new ListBuffer<int[]>(),
1095+
tree.patternMatchingCatch.handler(),
1096+
code.state.dup());
10961097
internalVisitBlock(tree);
10971098
} finally {
1099+
generatePatternMatchingCatch(env);
1100+
patternMatchingCatchConfiguration = prevConfiguration;
1101+
}
1102+
}
1103+
1104+
private void generatePatternMatchingCatch(Env<GenContext> env) {
1105+
if (patternMatchingCatchConfiguration.handler != null &&
1106+
!patternMatchingCatchConfiguration.ranges.isEmpty()) {
10981107
Chain skipCatch = code.branch(goto_);
1099-
JCCatch handler = tree.patternMatchingCatch.handler();
1100-
code.entryPoint(startState, handler.param.sym.type);
1101-
genPatternMatchingCatch(handler, env, patternMatchingInvocationRanges.toList());
1108+
JCCatch handler = patternMatchingCatchConfiguration.handler();
1109+
code.entryPoint(patternMatchingCatchConfiguration.startState(),
1110+
handler.param.sym.type);
1111+
genPatternMatchingCatch(handler,
1112+
env,
1113+
patternMatchingCatchConfiguration.ranges.toList());
11021114
code.resolve(skipCatch);
1103-
invocationsWithPatternMatchingCatch = prevInvocationsWithPatternMatchingCatch;
1104-
patternMatchingInvocationRanges = prevRanges;
11051115
}
11061116
}
11071117

@@ -1926,12 +1936,26 @@ public void visitApply(JCMethodInvocation tree) {
19261936
if (!msym.isDynamic()) {
19271937
code.statBegin(tree.pos);
19281938
}
1929-
if (invocationsWithPatternMatchingCatch.contains(tree)) {
1939+
if (patternMatchingCatchConfiguration.invocations().contains(tree)) {
19301940
int start = code.curCP();
19311941
result = m.invoke();
1932-
patternMatchingInvocationRanges.add(new int[] {start, code.curCP()});
1942+
patternMatchingCatchConfiguration.ranges().add(new int[] {start, code.curCP()});
19331943
} else {
1934-
result = m.invoke();
1944+
if (msym.isConstructor() && TreeInfo.isConstructorCall(tree)) {
1945+
//if this is a this(...) or super(...) call, there is a pending
1946+
//"uninitialized this" before this call. One catch handler cannot
1947+
//handle exceptions that may come from places with "uninitialized this"
1948+
//and (initialized) this, hence generate one set of handlers here
1949+
//for the "uninitialized this" case, and another set of handlers
1950+
//will be generated at the end of the method for the initialized this,
1951+
//if needed:
1952+
generatePatternMatchingCatch(env);
1953+
result = m.invoke();
1954+
patternMatchingCatchConfiguration =
1955+
patternMatchingCatchConfiguration.restart(code.state.dup());
1956+
} else {
1957+
result = m.invoke();
1958+
}
19351959
}
19361960
}
19371961

@@ -2555,4 +2579,15 @@ void addCont(Chain c) {
25552579
}
25562580
}
25572581

2582+
record PatternMatchingCatchConfiguration(Set<JCMethodInvocation> invocations,
2583+
ListBuffer<int[]> ranges,
2584+
JCCatch handler,
2585+
State startState) {
2586+
public PatternMatchingCatchConfiguration restart(State newState) {
2587+
return new PatternMatchingCatchConfiguration(invocations(),
2588+
new ListBuffer<int[]>(),
2589+
handler(),
2590+
newState);
2591+
}
2592+
}
25582593
}

‎src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java

+10
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,16 @@ public void visitLambda(JCLambda tree) {
303303
}
304304
}
305305

306+
/**
307+
* Is the given method invocation an invocation of this(...) or super(...)?
308+
*/
309+
public static boolean isConstructorCall(JCMethodInvocation invoke) {
310+
Name name = TreeInfo.name(invoke.meth);
311+
Names names = name.table.names;
312+
313+
return (name == names._this || name == names._super);
314+
}
315+
306316
/** Finds super() invocations and translates them using the given mapping.
307317
*/
308318
public static void mapSuperCalls(JCBlock block, Function<? super JCExpressionStatement, ? extends JCStatement> mapper) {

0 commit comments

Comments
 (0)