Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOlivier Thomann2019-02-08 06:36:54 +0000
committerManoj Palat2019-02-08 09:36:11 +0000
commit08aa694adff3d4944bc34c2d3eb33d85d876198a (patch)
tree1ef057c73c55de8bb45d67a339a3886b215a9585
parent818d36828a5ccc4ac75608bef6bd668c71a80f29 (diff)
downloadeclipse.jdt.core-08aa694adff3d4944bc34c2d3eb33d85d876198a.tar.gz
eclipse.jdt.core-08aa694adff3d4944bc34c2d3eb33d85d876198a.tar.xz
eclipse.jdt.core-08aa694adff3d4944bc34c2d3eb33d85d876198a.zip
Bug 544223 - [12][codegen] StackMapFrame.addStackItem IOOBEY20190208-0505
-rw-r--r--org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/SwitchExpressionTest.java70
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SwitchStatement.java10
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/StackMapFrameCodeStream.java17
3 files changed, 96 insertions, 1 deletions
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/SwitchExpressionTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/SwitchExpressionTest.java
index 9124a849a4..fbc2ac18e9 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/SwitchExpressionTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/SwitchExpressionTest.java
@@ -1605,4 +1605,74 @@ public class SwitchExpressionTest extends AbstractRegressionTest {
new String[] { "--enable-preview"},
options);
}
+ public void testBug544204() {
+ runConformTest(
+ new String[] {
+ "X.java",
+ "public class X {\n" +
+ " public void foo(int i) {\n" +
+ " int j = switch (i) {\n" +
+ " case 1 -> i;\n" +
+ " default -> i;\n" +
+ " };\n" +
+ " System.out.println(j);\n" +
+ " }\n" +
+ " \n" +
+ " public static void main(String[] args) {\n" +
+ " new X().foo(1);\n" +
+ " }\n" +
+ "}"
+ },
+ "1",
+ null,
+ new String[] {"--enable-preview"});
+ }
+ public void testBug544204_2() {
+ runConformTest(
+ new String[] {
+ "X.java",
+ "public class X {\n" +
+ " public void foo(int i) {\n" +
+ " long j = switch (i) {\n" +
+ " case 1 -> 10L;\n" +
+ " default -> 20L;\n" +
+ " };\n" +
+ " System.out.println(j);\n" +
+ " }\n" +
+ " \n" +
+ " public static void main(String[] args) {\n" +
+ " new X().foo(1);\n" +
+ " }\n" +
+ "}"
+ },
+ "10",
+ null,
+ new String[] {"--enable-preview"});
+ }
+ public void testBug544223() {
+ runConformTest(
+ new String[] {
+ "X.java",
+ "public class X {\n" +
+ " public int foo(String s) throws Exception {\n" +
+ " int i = switch (s) {\n" +
+ " case \"hello\" -> 1;\n" +
+ " default -> throw new Exception();\n" +
+ " };\n" +
+ " return i;\n" +
+ " }\n" +
+ "\n" +
+ " public static void main(String[] argv) {\n" +
+ " try {\n" +
+ " System.out.print(new X().foo(\"hello\"));\n" +
+ " } catch (Exception e) {\n" +
+ " //\n" +
+ " }\n" +
+ " }\n" +
+ "}"
+ },
+ "1",
+ null,
+ new String[] {"--enable-preview"});
+ }
} \ No newline at end of file
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SwitchStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SwitchStatement.java
index 4f5b7503d1..6c6bfcd939 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SwitchStatement.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SwitchStatement.java
@@ -353,6 +353,14 @@ public class SwitchStatement extends Expression {
defaultCaseLabel.place();
defaultBranchLabel.place();
}
+ if (this.expectedType() != null) {
+ TypeBinding expectedType = this.expectedType().erasure();
+ /*
+ * is the last goto was optimized the lastAbruptCompletion is equal to -1 which means there is already some value on the
+ * stack so we don't need to add one.
+ */
+ codeStream.recordExpressionType(expectedType, codeStream.lastAbruptCompletion != -1 ? 1 : 0);
+ }
codeStream.recordPositionsFrom(pc, this.sourceStart);
} finally {
if (this.scope != null) this.scope.enclosingCase = null; // no longer inside switch case block
@@ -507,7 +515,7 @@ public class SwitchStatement extends Expression {
codeStream.recordPositionsFrom(codeStream.position, this.sourceEnd, true);
defaultLabel.place();
}
- if (valueRequired && this.expectedType() != null) {
+ if (this.expectedType() != null) {
TypeBinding expectedType = this.expectedType().erasure();
/*
* is the last goto was optimized the lastAbruptCompletion is equal to -1 which means there is already some value on the
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/StackMapFrameCodeStream.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/StackMapFrameCodeStream.java
index df03ec309c..b73023a00e 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/StackMapFrameCodeStream.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/StackMapFrameCodeStream.java
@@ -251,6 +251,7 @@ public void removeStackMapMarkers(int markerOldPosition) {
StackDepthMarker marker = (StackDepthMarker) this.stackDepthMarkers.get(i);
if (marker.pc == markerOldPosition) {
this.stackDepthMarkers.remove(i);
+ break;
}
}
}
@@ -305,6 +306,22 @@ public void recordExpressionType(TypeBinding typeBinding) {
@Override
public void recordExpressionType(TypeBinding typeBinding, int delta) {
addStackDepthMarker(this.position, delta, typeBinding);
+ if (delta == 0) {
+ // optimized goto
+ // the break label already adjusted the stack depth (-1 or -2 depending on the return type)
+ // we need to adjust back to what it was
+ switch(typeBinding.id) {
+ case TypeIds.T_long :
+ case TypeIds.T_double :
+ this.stackDepth+=2;
+ break;
+ case TypeIds.T_void :
+ break;
+ default :
+ this.stackDepth++;
+ break;
+ }
+ }
}
/**
* Macro for building a class descriptor object

Back to the top