Skip to content

Commit 6429ac7

Browse files
committed
Align behavior about a null candidate
1 parent 345e2d2 commit 6429ac7

File tree

2 files changed

+26
-10
lines changed

2 files changed

+26
-10
lines changed

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

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1170,6 +1170,7 @@ public void visitMatch(JCTree.JCMatch tree) {
11701170
* (where <pattern> is a record pattern) is translated to:
11711171
*
11721172
* <pre>{@code
1173+
* if (<expression> == null) throw new NullPointerException();
11731174
* if (!(<expression> instanceof(<pattern>)) {
11741175
* throw new MatchException(null, null);
11751176
* }
@@ -1178,21 +1179,39 @@ public void visitMatch(JCTree.JCMatch tree) {
11781179
*/
11791180
bindingContext = new BasicBindingContext();
11801181
try {
1182+
JCExpression expr = translate(tree.expr);
1183+
1184+
// synthetic temp to hold RHS
1185+
VarSymbol letBoundCandidate = new VarSymbol(Flags.FINAL | Flags.SYNTHETIC,
1186+
names.fromString("match" + tree.pos + target.syntheticNameChar() + "temp"),
1187+
expr.type,
1188+
currentMethodSym);
1189+
JCStatement letBoundCandidateRef =
1190+
make.at(tree.pos).VarDef(letBoundCandidate, expr).setType(expr.type);
1191+
1192+
// npe logic
1193+
JCIf ifNPEstatement = make.If(makeBinary(Tag.EQ, make.Ident(letBoundCandidate).setType(expr.type), makeNull()).setType(syms.booleanType),
1194+
make.Throw(makeNewClass(syms.nullPointerExceptionType, List.of(makeNull()))),
1195+
null);
1196+
1197+
// match statement logic
11811198
List<JCExpression> nestedNPEParams = List.of(makeNull());
11821199
JCNewClass nestedNPE = makeNewClass(syms.nullPointerExceptionType, nestedNPEParams);
11831200

11841201
List<JCExpression> matchExParams = List.of(makeNull(), nestedNPE);
11851202
JCTree.JCThrow thr = make.Throw(makeNewClass(syms.matchExceptionType, matchExParams));
11861203

1187-
JCExpression expr = translate(tree.expr);
1188-
1189-
JCInstanceOf instanceOfTree = make.TypeTest(expr, tree.pattern);
1204+
JCInstanceOf instanceOfTree = make.TypeTest(make.Ident(letBoundCandidate).setType(expr.type), tree.pattern);
11901205
tree.type = syms.booleanType;
11911206

11921207
JCIf ifNode = make.If(makeUnary(Tag.NOT,
11931208
translate(instanceOfTree)).setType(syms.booleanType), thr, null);
11941209

1195-
result = bindingContext.decorateStatement(ifNode);
1210+
// concatenate all
1211+
result = make.Block(0,
1212+
List.of(letBoundCandidateRef,
1213+
ifNPEstatement,
1214+
bindingContext.decorateStatement(ifNode)));
11961215
} finally {
11971216
bindingContext.pop();
11981217
}
@@ -1217,7 +1236,6 @@ public void visitForeachLoop(JCTree.JCEnhancedForLoop tree) {
12171236
* for (<type-of-coll-item> N$temp : coll) {
12181237
* switch (N$temp) {
12191238
* case <pattern>: stmt;
1220-
* case null: throw new MatchException();
12211239
* }
12221240
* }</pre>
12231241
*
@@ -1238,8 +1256,6 @@ public void visitForeachLoop(JCTree.JCEnhancedForLoop tree) {
12381256
List<JCExpression> matchExParams = List.of(makeNull(), nestedNPE);
12391257
JCTree.JCThrow thr = make.Throw(makeNewClass(syms.matchExceptionType, matchExParams));
12401258

1241-
JCCase caseNull = make.Case(JCCase.STATEMENT, List.of(make.ConstantCaseLabel(makeNull())), null, List.of(thr), null);
1242-
12431259
JCCase casePattern = make.Case(CaseTree.CaseKind.STATEMENT,
12441260
List.of(make.PatternCaseLabel(jcRecordPattern)),
12451261
null,
@@ -1248,7 +1264,7 @@ public void visitForeachLoop(JCTree.JCEnhancedForLoop tree) {
12481264

12491265
JCSwitch switchBody =
12501266
make.Switch(make.Ident(currentValue).setType(selectorType),
1251-
List.of(caseNull, casePattern));
1267+
List.of(casePattern));
12521268

12531269
switchBody.patternSwitch = true;
12541270

test/langtools/tools/javac/patterns/PatternAssignmentEnhancedForTest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,12 @@ public static void main(String[] args) {
3232
assertEquals(8, arrayEnhancedFor(inArray));
3333
assertEquals(8, simpleDecostructionPatternWithAccesses(in));
3434
assertEx(PatternAssignmentEnhancedForTest::simpleDecostructionPatternWithAccesses, null, NullPointerException.class);
35-
assertMatchExceptionWithNested(PatternAssignmentEnhancedForTest::simpleDecostructionPatternWithAccesses, inWithNull, NullPointerException.class);
35+
assertEx(PatternAssignmentEnhancedForTest::simpleDecostructionPatternWithAccesses, inWithNull, NullPointerException.class);
3636
assertEx(PatternAssignmentEnhancedForTest::simpleDecostructionPatternWithAccesses, inWithNullComponent, NullPointerException.class);
3737
assertMatchExceptionWithNested(PatternAssignmentEnhancedForTest::simpleDecostructionPatternException, inWithPointEx, TestPatternFailed.class);
3838
assertEx(PatternAssignmentEnhancedForTest::simpleDecostructionPatternWithAccesses, (List<Point>) inRaw, ClassCastException.class);
3939
assertEquals(2, simpleDecostructionPatternNoComponentAccess(in));
40-
assertMatchExceptionWithNested(PatternAssignmentEnhancedForTest::simpleDecostructionPatternNoComponentAccess, inWithNull, NullPointerException.class);
40+
assertEx(PatternAssignmentEnhancedForTest::simpleDecostructionPatternNoComponentAccess, inWithNull, NullPointerException.class);
4141
assertEquals(2, simpleDecostructionPatternNoComponentAccess(inWithNullComponent));
4242
assertEquals(8, varAndConcrete(in));
4343
assertEquals(3, returnFromEnhancedFor(in));

0 commit comments

Comments
 (0)