Skip to content

Remove redundant null check for instanceof patterns#383

Closed
Marcono1234 wants to merge 1 commit into
leibnitz27:masterfrom
Marcono1234:instanceof-null-check
Closed

Remove redundant null check for instanceof patterns#383
Marcono1234 wants to merge 1 commit into
leibnitz27:masterfrom
Marcono1234:instanceof-null-check

Conversation

@Marcono1234

Copy link
Copy Markdown
Contributor

CondenseConditionals#condenseInstanceOfAssign introduces a redundant null-check (apparently to lift the assignment into the if condition?) which ends up in the decompiled output:

// Absorb: create null != (b = (T)o) as a ConditionalExpression
Expression assignExpr = assign.getInliningExpression();
ConditionalExpression nullCheck = new ComparisonOperation(
BytecodeLoc.NONE, Literal.NULL, assignExpr, CompOp.NE);

This PR here tries to detect that and remove it again.

Example (JDK 21):

class InstanceOfTest {
    int m(Object o1, Object o2) {
        if (o1 instanceof String s1 && o2 instanceof String s2) {
            return s1.compareTo(s2);
        }
        return 0;
    }
}

Decompiled:

- if (object instanceof String var3_3 && null != var3_3 && object2 instanceof String) {
+ if (object instanceof String var3_3 && object2 instanceof String) {

@Marcono1234 Marcono1234 marked this pull request as draft May 12, 2026 09:17
@Marcono1234

Copy link
Copy Markdown
Contributor Author

Have marked this as Draft again. This is really not an ideal solution; ideally CondenseConditionals#condenseInstanceOfAssign would not introduce the null-check in the first place, but I don't know if that is possible.

What do you think? Though after all, the null-check is not 'incorrect' (and is probably side-effect free); it is just redundant. So I could understand if you decide to keep it as it is and close this PR unmerged.

Even with the changes of this PR this will only remove the null-check if an instanceof pattern is emitted, otherwise the null-check remains. For example if you negate the example from above:

class InstanceOfTest {
    int m(Object o1, Object o2) {
        if (!(o1 instanceof String s1 && o2 instanceof String s2)) {
            return 1;
        }
        return 0;
    }
}

Decompiled:

if (!(object instanceof String) || null == (string = (String)object) || !(object2 instanceof String)) {

@leibnitz27

Copy link
Copy Markdown
Owner

Hey - I have a fairly large pipeline change which is continuing to improve most of this, will look again after merged.

@leibnitz27

Copy link
Copy Markdown
Owner

we're good now (Added this as an explicit test)

@leibnitz27 leibnitz27 closed this May 14, 2026
@Marcono1234 Marcono1234 deleted the instanceof-null-check branch May 14, 2026 22:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants