fix: keep wide upcast for arith instructions (#2730)

This commit is contained in:
Skylot
2026-01-12 18:40:01 +00:00
parent add11dff1d
commit 018c20187d
2 changed files with 55 additions and 0 deletions
@@ -231,6 +231,9 @@ public class SimplifyVisitor extends AbstractVisitor {
}
ArgType castToType = (ArgType) castInsn.getIndex();
if (isArithWideUpCast(parentInsn, argType, castToType)) {
return null;
}
if (!ArgType.isCastNeeded(mth.root(), argType, castToType)
|| isCastDuplicate(castInsn)
|| shadowedByOuterCast(mth.root(), castToType, parentInsn)) {
@@ -243,6 +246,21 @@ public class SimplifyVisitor extends AbstractVisitor {
return null;
}
/**
* Keep cast to wide types in arith instructions,
* because arguments type determine instruction used in result bytecode.
* Example: (long) i << 32 - without 'long' cast will be used 'int shift' instruction and result
* will be incorrect
*/
private static boolean isArithWideUpCast(@Nullable InsnNode parentInsn, ArgType argType, ArgType castToType) {
if (parentInsn != null
&& parentInsn.getType() == InsnType.ARITH
&& argType.isPrimitive() && castToType.isPrimitive()) {
return castToType.getRegCount() > argType.getRegCount();
}
return false;
}
private static boolean isCastDuplicate(IndexInsnNode castInsn) {
InsnArg arg = castInsn.getArg(0);
if (arg.isRegister()) {
@@ -0,0 +1,37 @@
package jadx.tests.integration.types;
import org.junit.jupiter.api.Test;
import jadx.tests.api.IntegrationTest;
import static jadx.tests.api.utils.assertj.JadxAssertions.assertThat;
import static org.assertj.core.api.Assertions.assertThat;
public class TestLongCast extends IntegrationTest {
public static class TestCls {
public long test(char c) {
return (long) c << 32;
}
public int test2(long l) {
return (int) l >> 2;
}
public void check() {
assertThat(test((char) 22)).isEqualTo(94489280512L);
assertThat(test2((1L << 32) + 8)).isEqualTo(2);
}
}
@Test
public void test() {
noDebugInfo();
assertThat(getClassNode(TestCls.class))
.code()
.containsOneOf(
"return (long) c << 32;",
"return ((long) c) << 32;");
}
}