[PATCH] [Fernflower] prevent null to be cast as short/byte

master
Alexandru-Constantin Bledea 7 years ago committed by Egor Ushakov
parent e7854376b8
commit c241278aee
  1. 2
      src/org/jetbrains/java/decompiler/modules/decompiler/ExprProcessor.java
  2. 4
      src/org/jetbrains/java/decompiler/modules/decompiler/exps/ConstExprent.java
  3. 1
      test/org/jetbrains/java/decompiler/SingleClassesTest.java
  4. BIN
      testData/classes/pkg/TestPrimitiveNarrowing.class
  5. 64
      testData/results/TestPrimitiveNarrowing.dec
  6. 24
      testData/src/pkg/TestPrimitiveNarrowing.java

@ -877,7 +877,7 @@ public class ExprProcessor implements CodeConstants {
boolean quote = cast && exprent.getPrecedence() >= FunctionExprent.getPrecedence(FunctionExprent.FUNCTION_CAST); boolean quote = cast && exprent.getPrecedence() >= FunctionExprent.getPrecedence(FunctionExprent.FUNCTION_CAST);
// cast instead to 'byte' / 'short' when int constant is used as a value for 'Byte' / 'Short' // cast instead to 'byte' / 'short' when int constant is used as a value for 'Byte' / 'Short'
if (castNarrowing && exprent.type == Exprent.EXPRENT_CONST) { if (castNarrowing && exprent.type == Exprent.EXPRENT_CONST && !((ConstExprent) exprent).isNull()) {
if (leftType.equals(VarType.VARTYPE_BYTE_OBJ)) { if (leftType.equals(VarType.VARTYPE_BYTE_OBJ)) {
leftType = VarType.VARTYPE_BYTE; leftType = VarType.VARTYPE_BYTE;
} }

@ -247,6 +247,10 @@ public class ConstExprent extends Exprent {
throw new RuntimeException("invalid constant type: " + constType); throw new RuntimeException("invalid constant type: " + constType);
} }
public boolean isNull() {
return CodeConstants.TYPE_NULL == constType.type;
}
private static String convertStringToJava(String value, boolean ascii) { private static String convertStringToJava(String value, boolean ascii) {
char[] arr = value.toCharArray(); char[] arr = value.toCharArray();
StringBuilder buffer = new StringBuilder(arr.length); StringBuilder buffer = new StringBuilder(arr.length);

@ -32,6 +32,7 @@ public class SingleClassesTest {
fixture = null; fixture = null;
} }
@Test public void testPrimitiveNarrowing() { doTest("pkg/TestPrimitiveNarrowing"); }
@Test public void testClassFields() { doTest("pkg/TestClassFields"); } @Test public void testClassFields() { doTest("pkg/TestClassFields"); }
@Test public void testInterfaceFields() { doTest("pkg/TestInterfaceFields"); } @Test public void testInterfaceFields() { doTest("pkg/TestInterfaceFields"); }
@Test public void testClassLambda() { doTest("pkg/TestClassLambda"); } @Test public void testClassLambda() { doTest("pkg/TestClassLambda"); }

@ -0,0 +1,64 @@
package pkg;
class TestPrimitiveNarrowing {
TestPrimitiveNarrowing(Short value) {
}// 6
static void invocations() {
withInteger((Integer)null);// 9
withShort((Short)null);// 10
withByte((Byte)null);// 11
new TestPrimitiveNarrowing((Short)null);// 12
}// 13
static void withByte(Byte defaultValue) {
}// 16
static void withInteger(Integer defaultValue) {
}// 19
static void withShort(Short defaultValue) {
}// 22
}
class 'pkg/TestPrimitiveNarrowing' {
method '<init> (Ljava/lang/Short;)V' {
4 4
}
method 'invocations ()V' {
0 7
1 7
4 8
5 8
8 9
9 9
10 10
15 11
}
method 'withByte (Ljava/lang/Byte;)V' {
0 14
}
method 'withInteger (Ljava/lang/Integer;)V' {
0 17
}
method 'withShort (Ljava/lang/Short;)V' {
0 20
}
}
Lines mapping:
6 <-> 5
9 <-> 8
10 <-> 9
11 <-> 10
12 <-> 11
13 <-> 12
16 <-> 15
19 <-> 18
22 <-> 21
Not mapped:
5

@ -0,0 +1,24 @@
package pkg;
class TestPrimitiveNarrowing {
TestPrimitiveNarrowing(Short value) {
}
static void invocations() {
withInteger(null);
withShort(null);
withByte(null);
new TestPrimitiveNarrowing(null);
}
static void withByte(Byte defaultValue) {
}
static void withInteger(Integer defaultValue) {
}
static void withShort(Short defaultValue) {
}
}
Loading…
Cancel
Save