Skip to content

Commit 2eb9a9b

Browse files
authored
Fix for issue eclipse-jdt#3535 on unboxing and widening primitive conversion with (eclipse-jdt#3744)
exact conversion check - case UNBOXING_AND_WIDENING_PRIMITIVE_CONVERSION
1 parent c21d1f9 commit 2eb9a9b

File tree

2 files changed

+64
-3
lines changed

2 files changed

+64
-3
lines changed

org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/IGenerateTypeCheck.java

+30-2
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
package org.eclipse.jdt.internal.compiler.ast;
1515

1616
import org.eclipse.jdt.internal.compiler.ast.Pattern.PrimitiveConversionRoute;
17+
import org.eclipse.jdt.internal.compiler.codegen.BranchLabel;
1718
import org.eclipse.jdt.internal.compiler.codegen.CodeStream;
1819
import org.eclipse.jdt.internal.compiler.lookup.BaseTypeBinding;
1920
import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
@@ -52,11 +53,38 @@ default void generateTypeCheck(TypeBinding providedType, TypeReference expectedT
5253
TypeBinding boxType = scope.environment().computeBoxingType(expectedTypeRef.resolvedType);
5354
codeStream.instance_of(expectedTypeRef, boxType);
5455
}
55-
case UNBOXING_CONVERSION,
56-
UNBOXING_AND_WIDENING_PRIMITIVE_CONVERSION -> {
56+
case UNBOXING_CONVERSION -> {
5757
codeStream.instance_of(scope.getJavaLangObject());
5858
setPatternIsTotalType();
5959
}
60+
case UNBOXING_AND_WIDENING_PRIMITIVE_CONVERSION -> {
61+
codeStream.dup();
62+
codeStream.instance_of(providedType);
63+
BranchLabel iLabel = new BranchLabel(codeStream);
64+
BranchLabel postCheck = new BranchLabel(codeStream);
65+
66+
codeStream.ifne(iLabel);
67+
codeStream.pop();
68+
codeStream.iconst_0();
69+
codeStream.goto_(postCheck);
70+
71+
iLabel.place();
72+
codeStream.checkcast(providedType);
73+
TypeBinding unboxedType = scope.environment().computeBoxingType(providedType);
74+
codeStream.generateUnboxingConversion(unboxedType.id);
75+
int expectedTypeId = expectedTypeRef.resolvedType.id;
76+
int unboxedProvidedTypeId = unboxedType.id;
77+
if (BaseTypeBinding.isExactWidening(expectedTypeId, unboxedProvidedTypeId)) {
78+
codeStream.pop();
79+
codeStream.iconst_1();
80+
} else {
81+
codeStream.invokeExactConversionsSupport(BaseTypeBinding.getRightToLeft(expectedTypeId, unboxedProvidedTypeId));
82+
}
83+
84+
codeStream.goto_(postCheck);
85+
postCheck.place();
86+
setPatternIsTotalType();
87+
}
6088
case NO_CONVERSION_ROUTE -> {
6189
codeStream.instance_of(expectedTypeRef, expectedTypeRef.resolvedType);
6290
break;

org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/PrimitiveInPatternsTest.java

+34-1
Original file line numberDiff line numberDiff line change
@@ -7416,7 +7416,7 @@ public T get() {
74167416
"1");
74177417
}
74187418

7419-
public void testIssue3535() {
7419+
public void testIssue3535_001() {
74207420
runConformTest(new String[] {
74217421
"X.java",
74227422
"""
@@ -7449,6 +7449,39 @@ void put( T t) {
74497449
},
74507450
"3");
74517451
}
7452+
public void testIssue3535_002() {
7453+
runConformTest(new String[] {
7454+
"X.java",
7455+
"""
7456+
public class X {
7457+
7458+
static Integer getInteger() {
7459+
return Integer.MAX_VALUE;
7460+
}
7461+
public int foo() {
7462+
Integer i = 10;
7463+
Y<Integer> f = new Y<>();
7464+
f.put(X.getInteger()); // This makes all the difference
7465+
return f.get() instanceof float ? 3 : 2;
7466+
}
7467+
public static void main(String[] args) {
7468+
System.out.println(new X().foo());
7469+
}
7470+
7471+
}
7472+
class Y <T> {
7473+
T t;
7474+
T get() {
7475+
return t;
7476+
}
7477+
void put( T t) {
7478+
this.t = t;
7479+
}
7480+
}
7481+
"""
7482+
},
7483+
"2");
7484+
}
74527485
public void testIssue3536() {
74537486
runConformTest(new String[] {
74547487
"X.java",

0 commit comments

Comments
 (0)