Skip to content

Commit

Permalink
8309336: Incorrect switch in enum not reported properly
Browse files Browse the repository at this point in the history
Reviewed-by: vromero
  • Loading branch information
lahodaj committed Jun 5, 2023
1 parent 08c91c2 commit 05fb6c6
Show file tree
Hide file tree
Showing 7 changed files with 120 additions and 9 deletions.
18 changes: 12 additions & 6 deletions src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java
Original file line number Diff line number Diff line change
Expand Up @@ -1657,9 +1657,9 @@ private void handleSwitch(JCTree switchTree,
boolean enumSwitch = (seltype.tsym.flags() & Flags.ENUM) != 0;
boolean stringSwitch = types.isSameType(seltype, syms.stringType);
boolean errorEnumSwitch = TreeInfo.isErrorEnumSwitch(selector, cases);
boolean intSwitch = types.isAssignable(seltype, syms.intType);
boolean patternSwitch;
if (!enumSwitch && !stringSwitch && !errorEnumSwitch &&
!types.isAssignable(seltype, syms.intType)) {
if (!enumSwitch && !stringSwitch && !errorEnumSwitch && !intSwitch) {
preview.checkSourceLevel(selector.pos(), Feature.PATTERN_SWITCH);
patternSwitch = true;
} else {
Expand Down Expand Up @@ -1706,6 +1706,10 @@ private void handleSwitch(JCTree switchTree,
if (sym == null) {
if (allowPatternSwitch) {
attribTree(expr, switchEnv, caseLabelResultInfo(seltype));
Symbol enumSym = TreeInfo.symbol(expr);
if (enumSym == null || !enumSym.isEnum() || enumSym.kind != VAR) {
log.error(expr.pos(), Errors.EnumLabelMustBeEnumConstant);
}
} else {
log.error(expr.pos(), Errors.EnumLabelMustBeUnqualifiedEnum);
}
Expand All @@ -1728,14 +1732,16 @@ private void handleSwitch(JCTree switchTree,
if (!pattype.hasTag(ERROR)) {
if (pattype.constValue() == null) {
Symbol s = TreeInfo.symbol(expr);
if (s != null && s.kind == TYP && allowPatternSwitch) {
if (s != null && s.kind == TYP) {
log.error(expr.pos(),
Errors.PatternExpected);
} else if ((s != null && !s.isEnum()) || !allowPatternSwitch) {
} else if (s == null || !s.isEnum()) {
log.error(expr.pos(),
(stringSwitch ? Errors.StringConstReq : Errors.ConstExprReq));
(stringSwitch ? Errors.StringConstReq
: intSwitch ? Errors.ConstExprReq
: Errors.PatternOrEnumReq));
}
} else if (!stringSwitch && !types.isAssignable(seltype, syms.intType)) {
} else if (!stringSwitch && !intSwitch) {
log.error(label.pos(), Errors.ConstantLabelNotCompatible(pattype, seltype));
} else if (!constants.add(pattype.constValue())) {
log.error(c.pos(), Errors.DuplicateCaseLabel);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -411,6 +411,9 @@ compiler.err.class.not.allowed=\
compiler.err.const.expr.req=\
constant expression required

compiler.err.pattern.or.enum.req=\
pattern or enum constant required

compiler.err.cont.outside.loop=\
continue outside of loop

Expand Down Expand Up @@ -576,6 +579,9 @@ compiler.err.enum.cant.be.instantiated=\
compiler.err.enum.label.must.be.unqualified.enum=\
an enum switch case label must be the unqualified name of an enumeration constant

compiler.err.enum.label.must.be.enum.constant=\
an enum switch constant case label must be an enumeration constant

compiler.err.enum.no.subclassing=\
classes cannot directly extend java.lang.Enum

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* Copyright (c) 2023, 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.enum.label.must.be.enum.constant

class EnumLabelMustBeEnumConstant {
enum E { A };

void m(E e) {
switch (e) {
case EA -> {}
default -> {}
}
}

static final E EA;
}
37 changes: 37 additions & 0 deletions test/langtools/tools/javac/diags/examples/PatternOrEnumReq.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* Copyright (c) 2023, 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.pattern.or.enum.req

class PatternOrEnumReq {
enum E { A };

void m(Object o) {
switch (o) {
case EA -> {}
default -> {}
}
}

static final E EA;
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
PatternErrorRecovery.java:12:18: compiler.err.feature.not.supported.in.source.plural: (compiler.misc.feature.pattern.switch), 20, 21
PatternErrorRecovery.java:11:18: compiler.err.const.expr.req
PatternErrorRecovery.java:11:18: compiler.err.pattern.expected
2 errors
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@

/**
* @test
* @bug 8300543
* @bug 8300543 8309336
* @summary Check switches work correctly with qualified enum constants
* @compile/fail/ref=EnumSwitchQualifiedErrors.out -XDrawDiagnostics EnumSwitchQualifiedErrors.java
*/
Expand Down Expand Up @@ -51,8 +51,27 @@ int testPatternMatchingSwitch3(Number n) {
};
}

int testPatternMatchingSwitch4(E1 e) {
return switch(e) {
case E1A -> 1;
case (E1) null -> 1;
case E1 -> 1;
default -> {}
};
}

int testPatternMatchingSwitch5(Object e) {
return switch(e) {
case E1A -> 1;
case (E1) null -> 1;
case E1 -> 1;
default -> {}
};
}

sealed interface I {}
enum E1 implements I { A; }
enum E2 { A; }

static final E1 E1A = null;
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,10 @@ EnumSwitchQualifiedErrors.java:36:20: compiler.err.prob.found.req: (compiler.mis
EnumSwitchQualifiedErrors.java:43:20: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: EnumSwitchQualifiedErrors.E2, EnumSwitchQualifiedErrors.E1)
EnumSwitchQualifiedErrors.java:49:20: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: EnumSwitchQualifiedErrors.E1, java.lang.Number)
EnumSwitchQualifiedErrors.java:50:20: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: EnumSwitchQualifiedErrors.E2, java.lang.Number)
4 errors
EnumSwitchQualifiedErrors.java:56:18: compiler.err.enum.label.must.be.enum.constant
EnumSwitchQualifiedErrors.java:57:18: compiler.err.enum.label.must.be.enum.constant
EnumSwitchQualifiedErrors.java:58:18: compiler.err.enum.label.must.be.enum.constant
EnumSwitchQualifiedErrors.java:65:18: compiler.err.pattern.or.enum.req
EnumSwitchQualifiedErrors.java:66:18: compiler.err.pattern.or.enum.req
EnumSwitchQualifiedErrors.java:67:18: compiler.err.pattern.expected
10 errors

1 comment on commit 05fb6c6

@openjdk-notifier
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.