Throw a loud exception if switch encounters unexpected enum value

Previously each of these `switch` statements would implicitly do
nothing if an unanticipated `enum` value came along.  My impression is
that each of these `switch` statements is supposed to be exhaustive,
such that an unexpected (unhandled) value should never appear.  If one
does, we should recognize it and complain loudly.

Of course, sometimes the right behavior for previously-unhandled
values is to do nothing.  It may not always be clear whether an
exception or doing nothing is the right choice.  For this commit,
WALA's regression tests still pass even with the possibility of
throwing an exception for unexpected values.  If we assume that the
test suite is thorough, that tells me that throwing an exception is
the right policy for each `switch` statement that I'm changing here.
This commit is contained in:
Ben Liblit 2017-08-06 14:50:05 -05:00 committed by Manu Sridharan
parent cbcfb40435
commit ab791f8c41
12 changed files with 44 additions and 13 deletions

View File

@ -167,6 +167,8 @@ public class ArrayBoundsGraphBuilder {
this.upperBoundGraph.addEdge(piParent, piVar);
break;
default:
throw new UnsupportedOperationException(String.format("unexpected operator %s", op));
}
}

View File

@ -159,7 +159,8 @@ public class Util {
*/
public static <I, T extends IBasicBlock<I>> T resolveBranch(ControlFlowGraph<I, T> G, T bb, int c1, int c2) {
SSAConditionalBranchInstruction c = (SSAConditionalBranchInstruction) getLastInstruction(G, bb);
switch ((ConditionalBranchInstruction.Operator) c.getOperator()) {
final ConditionalBranchInstruction.Operator operator = (ConditionalBranchInstruction.Operator) c.getOperator();
switch (operator) {
case EQ:
if (c1 == c2)
return getTakenSuccessor(G, bb);
@ -190,10 +191,9 @@ public class Util {
return getTakenSuccessor(G, bb);
else
return getNotTakenSuccessor(G, bb);
default:
throw new UnsupportedOperationException(String.format("unexpected operator %s", operator));
}
Assertions.UNREACHABLE();
return null;
}
/**

View File

@ -84,6 +84,8 @@ public class ParameterState extends AbstractVariable<ParameterState> {
throw new IllegalArgumentException("Try to set " + prev + " to " + state);
}
break;
default:
throw new UnsupportedOperationException(String.format("unexpected previous state %s", prev));
}
}
params.put(varNum, state);

View File

@ -317,7 +317,8 @@ public final class TypeName implements Serializable {
boolean isPrimitive = (dim==-1) || (dim&ElementMask)==PrimitiveMask;
if (dim != -1) {
for (int d = (dim&ElementMask) == PrimitiveMask? dim>>ElementBits: dim; d != 0; d>>=ElementBits) {
switch (d&ElementMask) {
final int masked = d&ElementMask;
switch (masked) {
case ArrayMask:
result.append("[");
break;
@ -327,6 +328,8 @@ public final class TypeName implements Serializable {
case ReferenceMask:
result.append("&");
break;
default:
throw new UnsupportedOperationException(String.format("unexpected masked type-name component %X", masked));
}
}
}

View File

@ -138,8 +138,10 @@ public class Intent implements ContextItem, Comparable<Intent> {
explicit = Explicit.EXPLICIT;
break;
case EXPLICIT:
unbind();
break;
default:
throw new UnsupportedOperationException(String.format("unexpected explicitness setting %s", explicit));
}
}

View File

@ -20,7 +20,7 @@ org.eclipse.jdt.core.compiler.debug.sourceFile=generate
org.eclipse.jdt.core.compiler.doc.comment.support=enabled
org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=error
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.autoboxing=error
org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
org.eclipse.jdt.core.compiler.problem.comparingIdentical=error
org.eclipse.jdt.core.compiler.problem.deadCode=error
org.eclipse.jdt.core.compiler.problem.deprecation=warning

View File

@ -77,7 +77,8 @@ public class JavaEclipseProjectPath extends EclipseProjectPath<IClasspathEntry,
@Override
protected void resolveClasspathEntry(IJavaProject project, IClasspathEntry entry, ILoader loader, boolean includeSource, boolean cpeFromMainProject) {
entry = JavaCore.getResolvedClasspathEntry(entry);
switch (entry.getEntryKind()) {
final int entryKind = entry.getEntryKind();
switch (entryKind) {
case IClasspathEntry.CPE_SOURCE: {
resolveSourcePathEntry(includeSource? JavaSourceLoader.SOURCE: Loader.APPLICATION, includeSource, cpeFromMainProject, entry.getPath(), entry.getOutputLocation(), entry.getExclusionPatterns()
, "java");
@ -101,7 +102,10 @@ public class JavaEclipseProjectPath extends EclipseProjectPath<IClasspathEntry,
System.err.println(e);
Assertions.UNREACHABLE();
}
break;
}
default:
throw new UnsupportedOperationException(String.format("unexpected classpath entry kind %s", entryKind));
}
}

View File

@ -102,9 +102,13 @@ public class JavaScriptEclipseProjectPath extends EclipseProjectPath<IIncludePat
ILoader loader,
boolean includeSource, boolean cpeFromMainProject) {
IIncludePathEntry e = JavaScriptCore.getResolvedIncludepathEntry(entry);
switch (e.getEntryKind()) {
final int entryKind = e.getEntryKind();
switch (entryKind) {
case IIncludePathEntry.CPE_SOURCE:
resolveSourcePathEntry(JSLoader.JAVASCRIPT, true, cpeFromMainProject, e.getPath(), null, e.getExclusionPatterns(), "js");
break;
default:
throw new UnsupportedOperationException(String.format("unexpected classpath entry kind %s", entryKind));
}
}

View File

@ -276,7 +276,8 @@ public class OfflineDynamicCallGraph {
{
ConstantPoolParser p = r.getCP();
for(int i = 1; i < p.getItemCount(); i++) {
switch (p.getItemType(i)) {
final byte itemType = p.getItemType(i);
switch (itemType) {
case CONSTANT_Integer:
entries.put(new Integer(p.getCPInt(i)), i);
break;
@ -301,6 +302,9 @@ public class OfflineDynamicCallGraph {
case CONSTANT_MethodHandle:
case CONSTANT_MethodType:
case CONSTANT_InvokeDynamic:
break;
default:
throw new UnsupportedOperationException(String.format("unexpected constant-pool item type %s", itemType));
}
}
}

View File

@ -293,7 +293,8 @@ public class CopyWriter {
int CPCount = cp.getItemCount();
if (1 < CPCount) {
switch (cp.getItemType(1)) {
final byte itemType = cp.getItemType(1);
switch (itemType) {
case ClassConstants.CONSTANT_Long:
case ClassConstants.CONSTANT_Double:
// item 1 is a double-word item, so the next real item is at 3
@ -303,6 +304,8 @@ public class CopyWriter {
if (r != 2)
throw new Error("Invalid constant pool index for dummy: " + r);
break;
default:
throw new UnsupportedOperationException(String.format("unexpected constant-pool item type %s", itemType));
}
}
for (int i = 2; i < CPCount; i++) {

View File

@ -1009,6 +1009,8 @@ public abstract class Compiler implements Constants {
writeShort(curOffset, allocateConstantPoolClassType(((InstanceofInstruction) instr).getType()));
curOffset += 2;
break;
default:
throw new UnsupportedOperationException(String.format("unexpected instruction opcode %s", opcode));
}
} else {
stackLenRef[0] = stackLen;

View File

@ -262,6 +262,8 @@ public class ClassWriter implements ClassConstants {
case CONSTANT_Utf8:
cachedCPEntries.put(cp.getCPUtf8(i), new Integer(i));
break;
default:
throw new UnsupportedOperationException(String.format("unexpected constant-pool item type %s", t));
}
}
}
@ -763,8 +765,9 @@ public class ClassWriter implements ClassConstants {
case CONSTANT_MethodHandle: {
offset = reserveBuf(4);
CWHandle handle = (CWHandle) item;
setUByte(buf, offset + 1, handle.getKind());
switch (handle.getKind()) {
final byte kind = handle.getKind();
setUByte(buf, offset + 1, kind);
switch (kind) {
case REF_getStatic:
case REF_getField:
case REF_putField:
@ -790,6 +793,8 @@ public class ClassWriter implements ClassConstants {
setUShort(buf, offset + 2, x);
break;
}
default:
throw new UnsupportedOperationException(String.format("unexpected ref kind %s", kind));
}
break;
}