Proguard removes valid code when optimizing
Java class file shrinker, optimizer, obfuscator, and preverifier
Brought to you by:
guardsquare
Consider the following piece of code:
public void check(Object1 obj1)
{
Object2 tmp = (Object2)obj1;
}
If applying the "code/removal/advanced" optimization, Proguard is removing the cast operation.
In my test case, the cast is failing and an exception is thrown : but after optimization, no more cast is done (and then no more exception is thrown) which leads to a bug at runtime.
In SideEffectInstructionChecker.visitConstantInstruction(), shouldn't we had CHECKCAST instruction to notify a side effect : if doing this, the cast operation of my example is no more removed.
I guess this falls under the ProGuard manual > Limitations > first item: "For best results, ProGuard's optimization algorithms assume that the processed code never intentionally throws NullPointerExceptions....." It may be time to reconsider these assumptions. I'll think about it.
For the time being, you can indeed change SideEffectInstructionChecker.
The same behaviour occured with code like :
public void check(byte[] buf, int i)
{
byte b = buf[i];
}
After optimizing, such code is removed : BALOAD, AALOAD, etc should be added in SideEffectInstructionChecker.visitSimpleInstruction() to notify a side effect.
The upcoming ProGuard 4.9 beta1 now has a system property "optimize.conservatively" to avoid these optimizations.