Skip to content
Permalink
Browse files
8222850: jshell tool: Misleading cascade compiler error in switch exp…
…ression with undefined vars

Reviewed-by: vromero
  • Loading branch information
Jan Lahoda committed Feb 3, 2021
1 parent 91e6c75 commit 90376156be1a2d93dac612ef77d1c0f267e72c60
@@ -1650,6 +1650,7 @@ private void handleSwitch(JCTree switchTree,
try {
boolean enumSwitch = (seltype.tsym.flags() & Flags.ENUM) != 0;
boolean stringSwitch = types.isSameType(seltype, syms.stringType);
boolean errorEnumSwitch = TreeInfo.isErrorEnumSwitch(selector, cases);
if (!enumSwitch && !stringSwitch)
seltype = chk.checkType(selector.pos(), seltype, syms.intType);

@@ -1680,6 +1681,17 @@ private void handleSwitch(JCTree switchTree,
} else if (!labels.add(sym)) {
log.error(c.pos(), Errors.DuplicateCaseLabel);
}
} else if (errorEnumSwitch) {
//error recovery: the selector is erroneous, and all the case labels
//are identifiers. This could be an enum switch - don't report resolve
//error for the case label:
var prevResolveHelper = rs.basicLogResolveHelper;
try {
rs.basicLogResolveHelper = rs.silentLogResolveHelper;
attribExpr(pat, switchEnv, seltype);
} finally {
rs.basicLogResolveHelper = prevResolveHelper;
}
} else {
Type pattype = attribExpr(pat, switchEnv, seltype);
if (!pattype.hasTag(ERROR)) {
@@ -3796,7 +3808,7 @@ public void visitParens(JCParens tree) {
Type owntype = attribTree(tree.expr, env, resultInfo);
result = check(tree, owntype, pkind(), resultInfo);
Symbol sym = TreeInfo.symbol(tree);
if (sym != null && sym.kind.matches(KindSelector.TYP_PCK))
if (sym != null && sym.kind.matches(KindSelector.TYP_PCK) && sym.kind != Kind.ERR)
log.error(tree.pos(), Errors.IllegalParenthesizedExpression);
}

@@ -1,5 +1,5 @@
/*
* Copyright (c) 1999, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1999, 2021, 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
@@ -736,7 +736,8 @@ public void visitSwitchExpression(JCSwitchExpression tree) {
}
c.completesNormally = alive != Liveness.DEAD;
}
if ((constants == null || !constants.isEmpty()) && !hasDefault) {
if ((constants == null || !constants.isEmpty()) && !hasDefault &&
!TreeInfo.isErrorEnumSwitch(tree.selector, tree.cases)) {
log.error(tree, Errors.NotExhaustive);
}
alive = prevAlive;
@@ -2629,6 +2629,15 @@ public boolean resolveDiagnosticNeeded(Type site, List<Type> argtypes, List<Type
}
};

LogResolveHelper silentLogResolveHelper = new LogResolveHelper() {
public boolean resolveDiagnosticNeeded(Type site, List<Type> argtypes, List<Type> typeargtypes) {
return false;
}
public List<Type> getArgumentTypes(ResolveError errSym, Symbol accessedSym, Name name, List<Type> argtypes) {
return argtypes;
}
};

LogResolveHelper methodLogResolveHelper = new LogResolveHelper() {
public boolean resolveDiagnosticNeeded(Type site, List<Type> argtypes, List<Type> typeargtypes) {
return !site.isErroneous() &&
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1999, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1999, 2021, 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
@@ -1324,4 +1324,9 @@ public static boolean isPackageInfo(JCCompilationUnit tree) {
return tree.sourcefile.isNameCompatible("package-info", JavaFileObject.Kind.SOURCE);
}

public static boolean isErrorEnumSwitch(JCExpression selector, List<JCCase> cases) {
return selector.type.tsym.kind == Kinds.Kind.ERR &&
cases.stream().flatMap(c -> c.pats.stream())
.allMatch(p -> p.hasTag(IDENT));
}
}
@@ -0,0 +1,26 @@
/**
* @test /nodynamiccopyright/
* @bug 8222850
* @summary Check error recovery for switch over undefined variables.
* @compile/fail/ref=SwitchUndefinedSelector.out -XDrawDiagnostics --should-stop=at=FLOW SwitchUndefinedSelector.java
*/

public class SwitchUndefinedSelector {
private static final Object D = null;
public void switchTest() {
switch (undefined) {
case A -> {}
case B, C -> {}
case D -> {}
}
var v = switch (undefined) {
case A -> 0;
case B, C -> 0;
case D -> 0;
};
switch (undefined) {
case SwitchUndefinedSelector.D -> {}
case SwitchUndefinedSelector.UNDEF -> {}
}
}
}
@@ -0,0 +1,6 @@
SwitchUndefinedSelector.java:11:17: compiler.err.cant.resolve.location: kindname.variable, undefined, , , (compiler.misc.location: kindname.class, SwitchUndefinedSelector, null)
SwitchUndefinedSelector.java:16:25: compiler.err.cant.resolve.location: kindname.variable, undefined, , , (compiler.misc.location: kindname.class, SwitchUndefinedSelector, null)
SwitchUndefinedSelector.java:21:17: compiler.err.cant.resolve.location: kindname.variable, undefined, , , (compiler.misc.location: kindname.class, SwitchUndefinedSelector, null)
SwitchUndefinedSelector.java:22:41: compiler.err.string.const.req
SwitchUndefinedSelector.java:23:41: compiler.err.cant.resolve.location: kindname.variable, UNDEF, , , (compiler.misc.location: kindname.class, SwitchUndefinedSelector, null)
5 errors

1 comment on commit 9037615

@openjdk-notifier

This comment has been minimized.

Copy link

@openjdk-notifier openjdk-notifier bot commented on 9037615 Feb 3, 2021

Please sign in to comment.