8286797: Guards of constant value false are not permitted

Reviewed-by: vromero
This commit is contained in:
Aggelos Biboudis 2022-05-19 16:11:24 +00:00 committed by Vicente Romero
parent fa1b56ede6
commit fd36f3730e
9 changed files with 106 additions and 6 deletions
src/jdk.compiler/share/classes/com/sun/tools/javac
test/langtools/tools/javac

@ -1798,6 +1798,10 @@ public class Attr extends JCTree.Visitor {
bodyEnv.info.scope.leave();
}
matchBindings = matchBindingsComputer.caseGuard(c, afterPattern, matchBindings);
if (TreeInfo.isBooleanWithValue(guard, 0)) {
log.error(guard.pos(), Errors.GuardHasConstantExpressionFalse);
}
}
boolean unguarded = TreeInfo.unguardedCaseLabel(pat);
boolean unconditional =

@ -512,6 +512,9 @@ compiler.err.duplicate.unconditional.pattern=\
compiler.err.unconditional.pattern.and.default=\
switch has both an unconditional pattern and a default label
compiler.err.guard.has.constant.expression.false=\
this case label has a guard that is a constant expression with value ''false''
# 0: type, 1: type
compiler.err.constant.label.not.compatible=\
constant label of type {0} is not compatible with switch selector type {1}

@ -1337,9 +1337,13 @@ public class TreeInfo {
if (guard == null) {
return true;
}
return isBooleanWithValue(guard, 1);
}
public static boolean isBooleanWithValue(JCExpression guard, int value) {
var constValue = guard.type.constValue();
return constValue != null &&
guard.type.hasTag(BOOLEAN) &&
((int) constValue) == 1;
guard.type.hasTag(BOOLEAN) &&
((int) constValue) == value;
}
}

@ -0,0 +1,47 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8286797
* @summary Guards of constant value false are not permitted
* @compile/fail/ref=T8286797.out --enable-preview -source ${jdk.version} -XDrawDiagnostics -XDshould-stop.at=FLOW T8286797.java
*/
public class T8286797 {
public void testWithConstant(Object o) {
switch (o) {
case String s when false -> {}
default -> {}
}
}
public void testWithSimpleName(Object o) {
final int x = 0;
switch (o) {
case String s when x == 42 -> {}
default -> {}
}
}
}

@ -0,0 +1,5 @@
T8286797.java:35:32: compiler.err.guard.has.constant.expression.false
T8286797.java:43:34: compiler.err.guard.has.constant.expression.false
- compiler.note.preview.filename: T8286797.java, DEFAULT
- compiler.note.preview.recompile
2 errors

@ -0,0 +1,36 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
// key: compiler.err.guard.has.constant.expression.false
// key: compiler.misc.feature.pattern.switch
// key: compiler.warn.preview.feature.use.plural
// options: --enable-preview -source ${jdk.version} -Xlint:preview
class GuardHasConstantFalse {
private void doSwitch(Object o) {
switch (o) {
case String s when false -> {}
default -> {}
}
}
}

@ -64,7 +64,7 @@ public class EnumTypeChanges {
switch (e) {
case A -> { return "A"; }
case B -> { return "B"; }
case EnumTypeChangesEnum e1 when false -> throw new AssertionError();
case EnumTypeChangesEnum e1 when e1 == null -> throw new AssertionError();
default -> { return "D"; }
}
}
@ -73,7 +73,7 @@ public class EnumTypeChanges {
return switch (e) {
case A -> "A";
case B -> "B";
case EnumTypeChangesEnum e1 when false -> throw new AssertionError();
case EnumTypeChangesEnum e1 when e1 == null -> throw new AssertionError();
default -> "D";
};
}

@ -276,10 +276,11 @@ public class Exhaustiveness extends TestRunner {
}
}
""",
"Test.java:6:27: compiler.err.guard.has.constant.expression.false",
"Test.java:5:16: compiler.err.not.exhaustive",
"- compiler.note.preview.filename: Test.java, DEFAULT",
"- compiler.note.preview.recompile",
"1 error");
"2 errors");
}
@Test

@ -18,7 +18,7 @@ public class RawTypeBindingWarning<T> {
default -> {}
}
switch (o) {
case RawTypeBindingWarning w when false -> {}
case RawTypeBindingWarning w when w == null -> {}
default -> {}
}
}