8289894: A NullPointerException thrown from guard expression
Reviewed-by: vromero
This commit is contained in:
parent
b542bcba57
commit
25f4b04365
src/jdk.compiler/share/classes/com/sun/tools/javac/comp
test/langtools/tools/javac/patterns
@ -4348,6 +4348,9 @@ public class Check {
|
||||
wasDefault = true;
|
||||
} else {
|
||||
JCPattern pat = ((JCPatternCaseLabel) label).pat;
|
||||
while (pat instanceof JCParenthesizedPattern parenthesized) {
|
||||
pat = parenthesized.pattern;
|
||||
}
|
||||
boolean isTypePattern = pat.hasTag(BINDINGPATTERN);
|
||||
if (wasPattern || wasConstant || wasDefault ||
|
||||
(wasNullPattern && (!isTypePattern || wasNonEmptyFallThrough))) {
|
||||
|
@ -531,7 +531,21 @@ public class TransPatterns extends TreeTranslator {
|
||||
currentValue = temp;
|
||||
JCExpression test = (JCExpression) this.<JCTree>translate(label.pat);
|
||||
if (label.guard != null) {
|
||||
test = makeBinary(Tag.AND, test, translate(label.guard));
|
||||
JCExpression guard = translate(label.guard);
|
||||
if (hasJoinedNull) {
|
||||
JCPattern pattern = label.pat;
|
||||
while (pattern instanceof JCParenthesizedPattern parenthesized) {
|
||||
pattern = parenthesized.pattern;
|
||||
}
|
||||
Assert.check(pattern.hasTag(Tag.BINDINGPATTERN));
|
||||
VarSymbol binding = ((JCBindingPattern) pattern).var.sym;
|
||||
guard = makeBinary(Tag.OR,
|
||||
makeBinary(Tag.EQ,
|
||||
make.Ident(binding),
|
||||
makeNull()),
|
||||
guard);
|
||||
}
|
||||
test = makeBinary(Tag.AND, test, guard);
|
||||
}
|
||||
c.stats = translate(c.stats);
|
||||
JCContinue continueSwitch = make.at(clearedPatterns.head.pos()).Continue(null);
|
||||
|
@ -95,7 +95,7 @@ public class CaseStructureTest extends ComboInstance<CaseStructureTest> {
|
||||
task.generate(result -> {
|
||||
boolean shouldPass = true;
|
||||
long patternCases = Arrays.stream(caseLabels).filter(l -> l == CaseLabel.TYPE_PATTERN || l == CaseLabel.PARENTHESIZED_PATTERN).count();
|
||||
long typePatternCases = Arrays.stream(caseLabels).filter(l -> l == CaseLabel.TYPE_PATTERN).count();
|
||||
long typePatternCases = Arrays.stream(caseLabels).filter(l -> l == CaseLabel.TYPE_PATTERN || l == CaseLabel.PARENTHESIZED_PATTERN).count();
|
||||
long constantCases = Arrays.stream(caseLabels).filter(l -> l == CaseLabel.CONSTANT).count();
|
||||
long nullCases = Arrays.stream(caseLabels).filter(l -> l == CaseLabel.NULL).count();
|
||||
long defaultCases = Arrays.stream(caseLabels).filter(l -> l == CaseLabel.DEFAULT).count();
|
||||
|
@ -23,7 +23,7 @@
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8262891 8268663
|
||||
* @bug 8262891 8268663 8289894
|
||||
* @summary Check guards implementation.
|
||||
* @compile --enable-preview -source ${jdk.version} Guards.java
|
||||
* @run main/othervm --enable-preview Guards
|
||||
@ -164,18 +164,18 @@ public class Guards {
|
||||
}
|
||||
|
||||
void testGuardNPE() {
|
||||
assertEquals("empty", guardNPE(""));
|
||||
assertEquals("A", guardNPE("A"));
|
||||
assertEquals("other", guardNPE(1));
|
||||
try {
|
||||
guardNPE(null);
|
||||
throw new AssertionError("Expected exception missing.");
|
||||
} catch (NullPointerException ex) {
|
||||
//expected
|
||||
}
|
||||
doTestGuardNPE(this::guardNPE1);
|
||||
doTestGuardNPE(this::guardNPE2);
|
||||
}
|
||||
|
||||
String guardNPE(Object o) {
|
||||
void doTestGuardNPE(Function<Object, String> test) {
|
||||
assertEquals("empty", test.apply(""));
|
||||
assertEquals("A", test.apply("A"));
|
||||
assertEquals("other", test.apply(1));
|
||||
assertEquals("empty", test.apply(null));
|
||||
}
|
||||
|
||||
String guardNPE1(Object o) {
|
||||
return switch (o) {
|
||||
case null, String s when s.isEmpty() -> "empty";
|
||||
case String s -> s;
|
||||
@ -183,6 +183,14 @@ public class Guards {
|
||||
};
|
||||
}
|
||||
|
||||
String guardNPE2(Object o) {
|
||||
return switch (o) {
|
||||
case null, ((((String s)))) when s.isEmpty() -> "empty";
|
||||
case ((((String s)))) -> s;
|
||||
case Object x -> "other";
|
||||
};
|
||||
}
|
||||
|
||||
record Box(Object o) {}
|
||||
|
||||
void assertEquals(String expected, String actual) {
|
||||
|
@ -254,4 +254,32 @@ public class SwitchErrors {
|
||||
case int j: break;
|
||||
}
|
||||
}
|
||||
void nullAndParenthesized1(Object o) {
|
||||
record R(Object o) {}
|
||||
switch (o) {
|
||||
case null, ((R r)): break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
void nullAndParenthesized2(Object o) {
|
||||
record R(Object o) {}
|
||||
switch (o) {
|
||||
case null, ((R(var v))): break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
void nullAndParenthesized3(Object o) {
|
||||
record R(Object o) {}
|
||||
switch (o) {
|
||||
case ((R r)): case null: break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
void nullAndParenthesized4(Object o) {
|
||||
record R(Object o) {}
|
||||
switch (o) {
|
||||
case ((R(var v))): case null: break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -41,6 +41,8 @@ SwitchErrors.java:232:47: compiler.err.flows.through.from.pattern
|
||||
SwitchErrors.java:244:18: compiler.err.duplicate.unconditional.pattern
|
||||
SwitchErrors.java:249:18: compiler.err.prob.found.req: (compiler.misc.not.applicable.types: int, java.lang.Integer)
|
||||
SwitchErrors.java:254:18: compiler.err.type.found.req: int, (compiler.misc.type.req.class.array)
|
||||
SwitchErrors.java:267:24: compiler.err.flows.through.to.pattern
|
||||
SwitchErrors.java:281:37: compiler.err.flows.through.from.pattern
|
||||
SwitchErrors.java:9:9: compiler.err.not.exhaustive.statement
|
||||
SwitchErrors.java:15:9: compiler.err.not.exhaustive.statement
|
||||
SwitchErrors.java:21:9: compiler.err.not.exhaustive.statement
|
||||
@ -55,4 +57,4 @@ SwitchErrors.java:164:9: compiler.err.not.exhaustive.statement
|
||||
SwitchErrors.java:237:9: compiler.err.not.exhaustive.statement
|
||||
- compiler.note.preview.filename: SwitchErrors.java, DEFAULT
|
||||
- compiler.note.preview.recompile
|
||||
55 errors
|
||||
57 errors
|
Loading…
x
Reference in New Issue
Block a user