diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/ASTNode.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/ASTNode.java index 1adf20c1bc7..5bf0ebf7436 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/ASTNode.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/ASTNode.java @@ -224,7 +224,7 @@ public abstract class ASTNode implements TypeConstants, TypeIds { public static final int IsUsefulEmptyStatement = Bit1; // for block and method declaration - public static final int SwitchRuleBlock = Bit1; + public static final int BlockShouldEndDead = Bit1; public static final int UndocumentedEmptyBlock = Bit4; public static final int OverridingMethodWithSupercall = Bit5; public static final int CanBeStatic = Bit9; // used to flag a method that can be declared static diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/Block.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/Block.java index 711a57707f4..68fd1cec2e9 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/Block.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/Block.java @@ -74,10 +74,16 @@ public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, Fl } } } - if ((this.bits & ASTNode.SwitchRuleBlock) != 0) { // switch rule blocks don't fall through + if ((this.bits & ASTNode.BlockShouldEndDead) != 0) { // switch rule blocks don't fall through if (flowInfo != FlowInfo.DEAD_END) { - flowContext.recordBreakFrom(flowInfo); - return FlowInfo.DEAD_END; + if (flowContext.associatedNode instanceof SwitchExpression) { // ... demand that for expression switch ... + currentScope.problemReporter().switchExpressionBlockCompletesNormally(this); + } else { // ... enforce that for statement switch, by having the code generator inject an automagic break ... + flowContext.recordBreakFrom(flowInfo); + return FlowInfo.DEAD_END; + } + } else { + this.bits &= ~ASTNode.BlockShouldEndDead; // Already dead-ends; nothing special needed from code generator } } return flowInfo; @@ -182,17 +188,4 @@ public boolean completesByContinue() { int length = this.statements == null ? 0 : this.statements.length; return length > 0 && this.statements[length - 1].completesByContinue(); } - -@Override -public boolean canCompleteNormally() { - int length = this.statements == null ? 0 : this.statements.length; - return length == 0 || this.statements[length - 1].canCompleteNormally(); -} - -@Override -public boolean continueCompletes() { - int length = this.statements == null ? 0 : this.statements.length; - return length > 0 && this.statements[length - 1].continueCompletes(); -} - } diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/BreakStatement.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/BreakStatement.java index c219bd09c2a..3754c4f3d78 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/BreakStatement.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/BreakStatement.java @@ -109,9 +109,4 @@ public void traverse(ASTVisitor visitor, BlockScope blockscope) { public boolean doesNotCompleteNormally() { return true; } - -@Override -public boolean canCompleteNormally() { - return false; -} } diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/ContinueStatement.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/ContinueStatement.java index 4e439c0c39f..58e6bec74fa 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/ContinueStatement.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/ContinueStatement.java @@ -118,14 +118,4 @@ public boolean doesNotCompleteNormally() { public boolean completesByContinue() { return true; } - -@Override -public boolean canCompleteNormally() { - return false; -} - -@Override -public boolean continueCompletes() { - return true; -} } diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/DoStatement.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/DoStatement.java index 1b7c6de4ab6..51e511949c7 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/DoStatement.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/DoStatement.java @@ -273,28 +273,4 @@ public boolean doesNotCompleteNormally() { public boolean completesByContinue() { return this.action.continuesAtOuterLabel(); } - -@Override -public boolean canCompleteNormally() { - Constant cst = this.condition.constant; - boolean isConditionTrue = cst == null || cst != Constant.NotAConstant && cst.booleanValue() == true; - cst = this.condition.optimizedBooleanConstant(); - boolean isConditionOptimizedTrue = cst == null ? true : cst != Constant.NotAConstant && cst.booleanValue() == true; - - if (!(isConditionTrue || isConditionOptimizedTrue)) { - if (this.action == null || this.action.canCompleteNormally()) - return true; - if (this.action != null && this.action.continueCompletes()) - return true; - } - if (this.action != null && this.action.breaksOut(null)) - return true; - - return false; -} -@Override -public boolean continueCompletes() { - return this.action.continuesAtOuterLabel(); -} - } diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/ForStatement.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/ForStatement.java index e962a1df4b6..6092110dcff 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/ForStatement.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/ForStatement.java @@ -489,23 +489,4 @@ public boolean doesNotCompleteNormally() { public boolean completesByContinue() { return this.action.continuesAtOuterLabel(); } - @Override - public boolean canCompleteNormally() { - Constant cst = this.condition == null ? null : this.condition.constant; - boolean isConditionTrue = cst == null || cst != Constant.NotAConstant && cst.booleanValue() == true; - cst = this.condition == null ? null : this.condition.optimizedBooleanConstant(); - boolean isConditionOptimizedTrue = cst == null ? true : cst != Constant.NotAConstant && cst.booleanValue() == true; - - if (!(isConditionTrue || isConditionOptimizedTrue)) - return true; - if (this.action != null && this.action.breaksOut(null)) - return true; - return false; - } - - @Override - public boolean continueCompletes() { - return this.action.continuesAtOuterLabel(); - } - } diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/ForeachStatement.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/ForeachStatement.java index 4786165f015..58d929fdaca 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/ForeachStatement.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/ForeachStatement.java @@ -688,10 +688,4 @@ public void traverse( public boolean doesNotCompleteNormally() { return false; // may not be entered at all. } - - @Override - public boolean canCompleteNormally() { - return true; - } - } diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/IfStatement.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/IfStatement.java index 3091758ec68..c5b4eadaa04 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/IfStatement.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/IfStatement.java @@ -340,14 +340,4 @@ public boolean doesNotCompleteNormally() { public boolean completesByContinue() { return this.thenStatement != null && this.thenStatement.completesByContinue() || this.elseStatement != null && this.elseStatement.completesByContinue(); } -@Override -public boolean canCompleteNormally() { - return ((this.thenStatement == null || this.thenStatement.canCompleteNormally()) || - (this.elseStatement == null || this.elseStatement.canCompleteNormally())); -} -@Override -public boolean continueCompletes() { - return this.thenStatement != null && this.thenStatement.continueCompletes() || - this.elseStatement != null && this.elseStatement.continueCompletes(); -} } diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/LabeledStatement.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/LabeledStatement.java index 682dc0249e4..6cceb950492 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/LabeledStatement.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/LabeledStatement.java @@ -165,17 +165,4 @@ public boolean doesNotCompleteNormally() { public boolean completesByContinue() { return this.statement instanceof ContinueStatement; // NOT this.statement.continuesAtOuterLabel } - - @Override - public boolean canCompleteNormally() { - if (this.statement.canCompleteNormally()) - return true; - return this.statement.breaksOut(this.label); - } - - @Override - public boolean continueCompletes() { - return this.statement instanceof ContinueStatement; // NOT this.statement.continuesAtOuterLabel - } - } diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/ReturnStatement.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/ReturnStatement.java index 77bc1e47472..6c20ca42192 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/ReturnStatement.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/ReturnStatement.java @@ -217,13 +217,8 @@ public boolean doesNotCompleteNormally() { return true; } -@Override -public boolean canCompleteNormally() { - return false; -} - /** - * Retrun statement code generation + * Return statement code generation * * generate the finallyInvocationSequence. * diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/Statement.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/Statement.java index a8b1db7c524..e6173aa37cd 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/Statement.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/Statement.java @@ -104,23 +104,6 @@ public boolean completesByContinue() { return false; } -/** - * Switch Expression analysis: *Assuming* this is reachable, analyze if this completes normally - * i.e control flow can reach the textually next statement, as per JLS 14 Sec 14.22 - * For blocks, we don't perform intra-reachability analysis. - * Note: delinking this from a similar (opposite) {@link #doesNotCompleteNormally()} since that was - * coded for a specific purpose of Lambda Shape Analysis. - */ -public boolean canCompleteNormally() { - return true; -} -/** - * The equivalent function of completesByContinue - implements both the rules concerning continue with - * and without a label. - */ -public boolean continueCompletes() { - return false; -} public static final int NOT_COMPLAINED = 0; public static final int COMPLAINED_FAKE_REACHABLE = 1; public static final int COMPLAINED_UNREACHABLE = 2; diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/SwitchExpression.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/SwitchExpression.java index 811ebee69d8..53019b7a616 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/SwitchExpression.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/SwitchExpression.java @@ -376,16 +376,6 @@ private TypeBinding resolveAsType(TypeBinding switchType) { @Override public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) { flowInfo = super.analyseCode(currentScope, flowContext, flowInfo); - if ((this.switchBits & LabeledRules) != 0) { // 15.28.1 - for (Statement stmt : this.statements) { - if (stmt instanceof Block && stmt.canCompleteNormally()) - currentScope.problemReporter().switchExpressionBlockCompletesNormally(stmt); - } - } else { - Statement ultimateStmt = this.statements[this.statements.length - 1]; // length guaranteed > 0 - if (ultimateStmt.canCompleteNormally()) - currentScope.problemReporter().switchExpressionBlockCompletesNormally(ultimateStmt); - } if (currentScope.compilerOptions().enableSyntacticNullAnalysisForFields) flowContext.expireNullCheckedFieldInfo(); // wipe information that was meant only for this result expression: diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/SwitchStatement.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/SwitchStatement.java index 1099e0bf112..b02f9ca12c8 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/SwitchStatement.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/SwitchStatement.java @@ -105,6 +105,7 @@ public static record SingletonBootstrap(String id, char[] selector, char[] signa public final static int Exhaustive = ASTNode.Bit3; public final static int QualifiedEnum = ASTNode.Bit4; public final static int LabeledBlockStatementGroup = ASTNode.Bit5; + public final static int BarricadeInjectedDefault = ASTNode.Bit6; // for switch on strings private static final char[] SecretSelectorVariableName = " selector".toCharArray(); //$NON-NLS-1$ @@ -438,6 +439,12 @@ else if ((statement.bits & ASTNode.DocumentedFallthrough) == 0) // the case is n } } } + if (caseInits != FlowInfo.DEAD_END) { + if (isTrulyExpression()) + currentScope.problemReporter().switchExpressionBlockCompletesNormally(this.statements[this.statements.length - 1]); + if (this.defaultCase == null) + this.switchBits |= BarricadeInjectedDefault; + } final TypeBinding resolvedTypeBinding = this.expression.resolvedType; if (resolvedTypeBinding.isEnum() && !needPatternDispatchCopy()) { @@ -607,7 +614,7 @@ public String toString() { defaultCaseLabel.place(); // branch label gets placed by generateCode below. } statement.generateCode(this.scope, codeStream); - if ((this.switchBits & LabeledRules) != 0 && statement instanceof Block && statement.canCompleteNormally()) + if (statement instanceof Block block && (block.bits & BlockShouldEndDead) != 0) codeStream.goto_(this.breakLabel); } } @@ -759,7 +766,7 @@ public void generateCode(BlockScope currentScope, CodeStream codeStream) { codeStream.removeNotDefinitelyAssignedVariables(currentScope, this.preSwitchInitStateIndex); } statement.generateCode(this.scope, codeStream); - if ((this.switchBits & LabeledRules) != 0 && statement instanceof Block && statement.canCompleteNormally()) + if (statement instanceof Block block && (block.bits & BlockShouldEndDead) != 0) codeStream.goto_(this.breakLabel); } } @@ -782,7 +789,7 @@ public void generateCode(BlockScope currentScope, CodeStream codeStream) { */ if (this.scope.compilerOptions().complianceLevel >= ClassFileConstants.JDK19) { // since 19 we have MatchException for this - if (this.statements.length > 0 && this.statements[this.statements.length - 1].canCompleteNormally()) + if ((this.switchBits & BarricadeInjectedDefault) != 0) codeStream.goto_(this.breakLabel); // hop, skip and jump over match exception throw. defaultLabel.place(); codeStream.newJavaLangMatchException(); @@ -1355,55 +1362,6 @@ public boolean completesByContinue() { return false; } - @Override - public boolean canCompleteNormally() { - if (this.statements == null || this.statements.length == 0) - return true; - if ((this.switchBits & LabeledRules) == 0) { // switch labeled statement group - if (this.statements[this.statements.length - 1].canCompleteNormally()) - return true; // last statement as well as last switch label after blocks if exists. - if (this.totalPattern == null && this.defaultCase == null) - return true; - for (Statement statement : this.statements) { - if (statement.breaksOut(null)) - return true; - } - } else { - // switch block consists of switch rules - for (Statement stmt : this.statements) { - if (stmt instanceof CaseStatement) - continue; // skip case - if (this.totalPattern == null && this.defaultCase == null) - return true; - if (stmt instanceof Expression) - return true; - if (stmt.canCompleteNormally()) - return true; - if (stmt instanceof YieldStatement && ((YieldStatement) stmt).isImplicit) // note: artificially introduced - return true; - if (stmt instanceof Block) { - Block block = (Block) stmt; - if (block.canCompleteNormally()) - return true; - if (block.breaksOut(null)) - return true; - } - } - } - return false; - } - - @Override - public boolean continueCompletes() { - if (this.statements == null || this.statements.length == 0) - return false; - for (Statement statement : this.statements) { - if (statement.continueCompletes()) - return true; - } - return false; - } - @Override public StringBuilder printExpression(int indent, StringBuilder output) { return printStatement(indent, output); diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/SynchronizedStatement.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/SynchronizedStatement.java index 24e5b024559..2ad5d2895eb 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/SynchronizedStatement.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/SynchronizedStatement.java @@ -248,14 +248,4 @@ public boolean doesNotCompleteNormally() { public boolean completesByContinue() { return this.block.completesByContinue(); } - -@Override -public boolean canCompleteNormally() { - return this.block.canCompleteNormally(); -} - -@Override -public boolean continueCompletes() { - return this.block.continueCompletes(); -} } diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/ThrowStatement.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/ThrowStatement.java index bfa0da9ba7a..c510de8d41b 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/ThrowStatement.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/ThrowStatement.java @@ -99,10 +99,4 @@ public void traverse(ASTVisitor visitor, BlockScope blockScope) { public boolean doesNotCompleteNormally() { return true; } - -@Override -public boolean canCompleteNormally() { - return false; -} - } diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/TryStatement.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/TryStatement.java index 228388b1a3a..632f903810b 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/TryStatement.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/TryStatement.java @@ -1270,34 +1270,4 @@ public boolean completesByContinue() { } return this.finallyBlock != null && this.finallyBlock.completesByContinue(); } -@Override -public boolean canCompleteNormally() { - if (this.tryBlock.canCompleteNormally()) { - return (this.finallyBlock != null) ? this.finallyBlock.canCompleteNormally() : true; - } - if (this.catchBlocks != null) { - for (Block catchBlock : this.catchBlocks) { - if (catchBlock.canCompleteNormally()) { - return (this.finallyBlock != null) ? this.finallyBlock.canCompleteNormally() : true; - } - } - } - return false; -} -@Override -public boolean continueCompletes() { - if (this.tryBlock.continueCompletes()) { - return (this.finallyBlock == null) ? true : - this.finallyBlock.canCompleteNormally() || this.finallyBlock.continueCompletes(); - } - if (this.catchBlocks != null) { - for (Block catchBlock : this.catchBlocks) { - if (catchBlock.continueCompletes()) { - return (this.finallyBlock == null) ? true : - this.finallyBlock.canCompleteNormally() || this.finallyBlock.continueCompletes(); - } - } - } - return this.finallyBlock != null && this.finallyBlock.continueCompletes(); -} } diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/WhileStatement.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/WhileStatement.java index 81332ae0997..9154521f122 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/WhileStatement.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/WhileStatement.java @@ -339,20 +339,4 @@ public boolean doesNotCompleteNormally() { public boolean completesByContinue() { return this.action.continuesAtOuterLabel(); } - - @Override - public boolean canCompleteNormally() { - Constant cst = this.condition.constant; - boolean isConditionTrue = cst == null || cst != Constant.NotAConstant && cst.booleanValue() == true; - cst = this.condition.optimizedBooleanConstant(); - boolean isConditionOptimizedTrue = cst == null ? true : cst != Constant.NotAConstant && cst.booleanValue() == true; - if (!(isConditionTrue || isConditionOptimizedTrue)) - return true; - return this.action != null && this.action.breaksOut(null); - } - - @Override - public boolean continueCompletes() { - return this.action.continuesAtOuterLabel(); - } } diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/YieldStatement.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/YieldStatement.java index 4508678c981..e5cc1bb233b 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/YieldStatement.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/YieldStatement.java @@ -187,9 +187,4 @@ public void traverse(ASTVisitor visitor, BlockScope blockscope) { public boolean doesNotCompleteNormally() { return true; } - -@Override -public boolean canCompleteNormally() { - return false; -} } \ No newline at end of file diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/parser/Parser.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/parser/Parser.java index f2a4d85db6d..a412a0433cb 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/parser/Parser.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/parser/Parser.java @@ -9443,7 +9443,7 @@ protected void consumeSwitchRule(SwitchRuleKind kind) { this.astStack[this.astPtr] = yieldStatement; } else if (kind == SwitchRuleKind.BLOCK) { Block block = (Block) this.astStack[this.astPtr]; - block.bits |= ASTNode.SwitchRuleBlock; + block.bits |= ASTNode.BlockShouldEndDead; } concatNodeLists(); } diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/problem/messages.properties b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/problem/messages.properties index f928348c096..93e3c443f13 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/problem/messages.properties +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/problem/messages.properties @@ -1035,7 +1035,7 @@ 1700 = Incompatible results expressions in switch ###[obsolete] 1701 = A switch expression should have a non-empty switch block 1702 = A switch expression should have at least one result expression -1703 = A switch labeled block in a switch expression should not complete normally +1703 = A switch labeled block in a switch expression must yield a value or throw an an exception ###[obsolete] 1704 = The last statement of a switch block in a switch expression should not complete normally ###[obsolete] 1705 = Trailing switch labels are not allowed in a switch expression. 1706 = Mixing of '->' and ':' case statement styles is not allowed within a switch diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullAnnotationTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullAnnotationTest.java index 766b7322421..e1c648a34e2 100644 --- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullAnnotationTest.java +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullAnnotationTest.java @@ -10931,7 +10931,12 @@ public void testBug548418_001a() { " ^^^^^^^^\n" + "Breaking out of switch expressions not permitted\n" + "----------\n" + - "3. ERROR in X.java (at line 15)\n" + + "3. ERROR in X.java (at line 14)\n" + + " }\n" + + " ^^\n" + + "A switch labeled block in a switch expression must yield a value or throw an an exception\n" + + "----------\n" + + "4. ERROR in X.java (at line 15)\n" + " default -> null;\n" + " ^^^^\n" + "Null type mismatch: required '@NonNull X' but the provided value is null\n" + diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/SwitchExpressionsYieldTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/SwitchExpressionsYieldTest.java index 2f9c460523d..d8706501487 100644 --- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/SwitchExpressionsYieldTest.java +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/SwitchExpressionsYieldTest.java @@ -486,7 +486,7 @@ public void testBug544073_014() { "1. ERROR in X.java (at line 8)\n" + " default :v = 2;\n" + " ^^\n" + - "A switch labeled block in a switch expression should not complete normally\n" + + "A switch labeled block in a switch expression must yield a value or throw an an exception\n" + "----------\n"; this.runNegativeTest( testFiles, @@ -2127,6 +2127,11 @@ public void testBug544073_076() { " continue;\n" + " ^^^^^^^^^\n" + "Continue out of switch expressions not permitted\n" + + "----------\n" + + "2. ERROR in X.java (at line 11)\n" + + " continue;\n" + + " ^^\n" + + "A switch labeled block in a switch expression must yield a value or throw an an exception\n" + "----------\n"); } public void testBug544073_077() { @@ -4989,7 +4994,7 @@ public void testBug562728_005() { "1. ERROR in X.java (at line 9)\n" + " default :v = 2;\n" + " ^^\n" + - "A switch labeled block in a switch expression should not complete normally\n" + + "A switch labeled block in a switch expression must yield a value or throw an an exception\n" + "----------\n"); } public void testBug562728_006() { @@ -5021,12 +5026,12 @@ public void testBug562728_006() { "1. ERROR in X.java (at line 8)\n" + " case 2 ->{v = 2;}\n" + " ^^\n" + - "A switch labeled block in a switch expression should not complete normally\n" + + "A switch labeled block in a switch expression must yield a value or throw an an exception\n" + "----------\n" + "2. ERROR in X.java (at line 9)\n" + " default ->{v = 2;}\n" + " ^^\n" + - "A switch labeled block in a switch expression should not complete normally\n" + + "A switch labeled block in a switch expression must yield a value or throw an an exception\n" + "----------\n"); } public void testBug562728_007() { @@ -5113,7 +5118,7 @@ public void testBug563023_002() { "1. ERROR in X.java (at line 13)\n" + " }\n" + " ^^\n" + - "A switch labeled block in a switch expression should not complete normally\n" + + "A switch labeled block in a switch expression must yield a value or throw an an exception\n" + "----------\n"); } public void testBug563023_003() { @@ -5142,7 +5147,7 @@ public void testBug563023_003() { "1. ERROR in X.java (at line 10)\n" + " }\n" + " ^^\n" + - "A switch labeled block in a switch expression should not complete normally\n" + + "A switch labeled block in a switch expression must yield a value or throw an an exception\n" + "----------\n"); } public void testBug563023_004() { @@ -5202,7 +5207,7 @@ public void testBug563023_005() { "1. ERROR in X.java (at line 11)\n" + " }\n" + " ^^\n" + - "A switch labeled block in a switch expression should not complete normally\n" + + "A switch labeled block in a switch expression must yield a value or throw an an exception\n" + "----------\n"); } public void testBug563023_006() { @@ -5269,7 +5274,7 @@ public void testBug563023_007() { "2. ERROR in X.java (at line 10)\n" + " }\n" + " ^^\n" + - "A switch labeled block in a switch expression should not complete normally\n" + + "A switch labeled block in a switch expression must yield a value or throw an an exception\n" + "----------\n"); } public void testBug563147_001() { diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/SwitchPatternTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/SwitchPatternTest.java index 1a6a52cd3f5..eeb4c248931 100644 --- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/SwitchPatternTest.java +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/SwitchPatternTest.java @@ -1850,7 +1850,7 @@ public void testBug573940_5() { "1. ERROR in X.java (at line 6)\n" + " }\n" + " ^^\n" + - "A switch labeled block in a switch expression should not complete normally\n" + + "A switch labeled block in a switch expression must yield a value or throw an an exception\n" + "----------\n"); } public void testBug574564_001() { @@ -4911,7 +4911,7 @@ public void testBug578568_3() { "1. ERROR in X.java (at line 11)\n" + " }\n" + " ^^\n" + - "A switch labeled block in a switch expression should not complete normally\n" + + "A switch labeled block in a switch expression must yield a value or throw an an exception\n" + "----------\n"); } public void testBug578416() {