fix(core): fix primitive-to-primitive conversions (PR #2326)

This commit is contained in:
pubiqq
2024-10-28 23:33:10 +03:00
committed by GitHub
parent 982307b1ac
commit 4d8a5d6671
4 changed files with 214 additions and 33 deletions
@@ -105,27 +105,13 @@ public class TypeCompare {
}
}
if (firstPrimitive && secondPrimitive) {
PrimitiveType firstPrimitiveType = first.getPrimitiveType();
PrimitiveType secondPrimitiveType = second.getPrimitiveType();
if (firstPrimitiveType == PrimitiveType.BOOLEAN
|| secondPrimitiveType == PrimitiveType.BOOLEAN) {
return CONFLICT;
}
if (swapEquals(firstPrimitiveType, secondPrimitiveType, PrimitiveType.CHAR, PrimitiveType.BYTE)
|| swapEquals(firstPrimitiveType, secondPrimitiveType, PrimitiveType.CHAR, PrimitiveType.SHORT)) {
return CONFLICT;
}
return firstPrimitiveType.compareTo(secondPrimitiveType) > 0 ? WIDER : NARROW;
return comparePrimitives(first.getPrimitiveType(), second.getPrimitiveType());
}
LOG.warn("Type compare function not complete, can't compare {} and {}", first, second);
return TypeCompareEnum.CONFLICT;
}
private boolean swapEquals(PrimitiveType first, PrimitiveType second, PrimitiveType a, PrimitiveType b) {
return (first == a && second == b) || (first == b && second == a);
}
private TypeCompareEnum compareArrayWithOtherType(ArgType array, ArgType other) {
if (!other.isTypeKnown()) {
if (other.contains(PrimitiveType.ARRAY)) {
@@ -320,6 +306,60 @@ public class TypeCompare {
return extendTypes;
}
private TypeCompareEnum comparePrimitives(PrimitiveType type1, PrimitiveType type2) {
if (type1 == PrimitiveType.BOOLEAN || type2 == PrimitiveType.BOOLEAN) {
return type1 == type2 ? EQUAL : CONFLICT;
}
if (type1 == PrimitiveType.VOID || type2 == PrimitiveType.VOID) {
return type1 == type2 ? EQUAL : CONFLICT;
}
if (type1 == PrimitiveType.BYTE && type2 == PrimitiveType.CHAR) {
return WIDER;
}
if (type1 == PrimitiveType.SHORT && type2 == PrimitiveType.CHAR) {
return WIDER;
}
final int type1Width = getTypeWidth(type1);
final int type2Width = getTypeWidth(type2);
if (type1Width > type2Width) {
return WIDER;
} else if (type1Width < type2Width) {
return NARROW;
} else {
return EQUAL;
}
}
private byte getTypeWidth(PrimitiveType type) {
switch (type) {
case BYTE:
return 0;
case SHORT:
return 1;
case CHAR:
return 2;
case INT:
return 3;
case LONG:
return 4;
case FLOAT:
return 5;
case DOUBLE:
return 6;
case BOOLEAN:
case OBJECT:
case ARRAY:
case VOID:
throw new JadxRuntimeException("Type " + type + " should not be here");
}
throw new JadxRuntimeException("Unhandled type: " + type);
}
public Comparator<ArgType> getComparator() {
return comparator;
}