Issue details
Reading a generic field through a raw instance type and null-checking it emits == 0 instead of == null, with a type inference failed warning.
It affects both a plain type-variable field (T) and an array of one (T[]).
TypeBoundFieldGetAssign.getResultType (TypeBoundFieldGetAssign.java:42): when the field's type cannot be resolved from the (raw) instance type, replaceClassGenerics returns null and the fallback returns the field type unchanged (the existing // TODO: check if this type is allowed in current scope, line 47).
That leaves an out-of-scope type variable owned by another class; type propagation rejects it (TypeUpdate.checkForUnknownTypeVars), so the compared 0 literal keeps its unknown type and TypeGen renders it as 0.
The bound is built for any field whose type contains a type variable (TypeInferenceVisitor.java:271, containsTypeVariable()), so T[] is affected too.
Sample
Compile with javac and run jadx on the .class files:
public class GenBug {
public static class Box<T extends Number> {
public T value;
public T[] arr;
}
public static boolean isNull(Box box) { // raw Box
return box.value == null;
}
public static boolean arrNull(Box box) {
return box.arr == null;
}
}
Current output on master (8c28a85):
public static boolean isNull(Box box) {
return box.value == 0; // expected: == null
}
public static boolean arrNull(Box box) {
return box.arr == 0; // expected: == null
}
Jadx version
master 8c28a85 (current HEAD)
Issue details
Reading a generic field through a raw instance type and null-checking it emits
== 0instead of== null, with atype inference failedwarning.It affects both a plain type-variable field (
T) and an array of one (T[]).TypeBoundFieldGetAssign.getResultType(TypeBoundFieldGetAssign.java:42): when the field's type cannot be resolved from the (raw) instance type,replaceClassGenericsreturns null and the fallback returns the field type unchanged (the existing// TODO: check if this type is allowed in current scope, line 47).That leaves an out-of-scope type variable owned by another class; type propagation rejects it (TypeUpdate.checkForUnknownTypeVars), so the compared
0literal keeps its unknown type and TypeGen renders it as0.The bound is built for any field whose type contains a type variable (TypeInferenceVisitor.java:271,
containsTypeVariable()), soT[]is affected too.Sample
Compile with
javacand run jadx on the.classfiles:Current output on master (8c28a85):
Jadx version
master
8c28a85(current HEAD)