changeset 57025:a898dc684456 patterns

Improving fallthrough handling in switches with patterns.
author jlahoda
date Wed, 21 Aug 2019 13:28:16 +0200
parents c91c71a053ad
children 00dece45a5de e80040658b50
files src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TransPatterns.java
diffstat 1 files changed, 14 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TransPatterns.java	Tue Aug 20 15:59:21 2019 +0200
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TransPatterns.java	Wed Aug 21 13:28:16 2019 +0200
@@ -294,9 +294,10 @@
                 pendingMatchLabel = make.Labelled(names.fromString("match$" + tree.pos), null);
                 VarSymbol fallthroughSym = new VarSymbol(0, names.fromString("fallthrough$" + tree.pos), syms.booleanType, currentMethodSym);
 
-                JCStatement fallthroughInit = make.at(tree.pos).VarDef(fallthroughSym, make.Literal(BOOLEAN, 0).setType(syms.booleanType));
+                boolean hasFallThrough = false;
+                boolean wasFallThrough = false;
 
-                List<JCStatement> resultStatements = List.of(fallthroughInit);
+                List<JCStatement> resultStatements = List.nil();
 
                 for (JCCase clause : tree.cases) {
                     Assert.check(clause.pats.size() <= 1);
@@ -311,12 +312,20 @@
                     JCStatement translatedIf = translate(make.If(jcMatches, body, null));
                     JCIf testStatement = translatedIf.hasTag(Tag.IF) ? (JCIf)translatedIf : (JCIf) ((JCBlock)translatedIf).stats.tail.head;
 
-                    testStatement.cond = makeBinary(Tag.OR,
-                            make.Ident(fallthroughSym),
-                            testStatement.cond);
+                    if (wasFallThrough) {
+                        testStatement.cond = makeBinary(Tag.OR,
+                                make.Ident(fallthroughSym),
+                                testStatement.cond);
+                    }
 
+                    hasFallThrough |= wasFallThrough = clause.completesNormally;
                     resultStatements = resultStatements.append(translatedIf);
                 }
+                if (hasFallThrough) {
+                    resultStatements = resultStatements.prepend(make.at(tree.pos)
+                                                                    .VarDef(fallthroughSym,
+                                                                            make.Literal(BOOLEAN, 0).setType(syms.booleanType)));
+                }
                 pendingMatchLabel.body = make.Block(0, resultStatements);
                 result = pendingMatchLabel;
             } finally {