Bug 576329 - [14][switch expression] null analysis on case expression fails for QualifiedNameReference for <array>.length
Summary: [14][switch expression] null analysis on case expression fails for QualifiedN...
Status: CLOSED DUPLICATE of bug 576026
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 4.21   Edit
Hardware: All All
: P3 normal (vote)
Target Milestone: ---   Edit
Assignee: JDT-Core-Inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2021-09-29 09:17 EDT by Jesper Moller CLA
Modified: 2021-09-29 16:06 EDT (History)
0 users

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Jesper Moller CLA 2021-09-29 09:17:15 EDT
The following valid code gives an NPE when compiling:

public class Main {
    int length;
    public String switchOnArray(Object argv[]) {
        return switch(argv.length) {
        case 0 -> "0";
        default -> "x";
        };
    }
}

The error is:
Internal compiler error: java.lang.NullPointerException at org.eclipse.jdt.internal.compiler.flow.UnconditionalFlowInfo.markAsDefinitelyNonNull(UnconditionalFlowInfo.java:1376)

This happens because the QualifiedNameReference of argv.length claims to be a Binding.LOCAL type, and so UnconditionalFlowInfo tries to resolve the QNR's localVariableBinding(), which is currently always null (doesn't override Expression).  

The check happens in org.eclipse.jdt.internal.compiler.ast.SwitchStatement.analyseCode, line 195.

If the expression was instead "switch(this.length) ...", then it would have been a Binding.FIELD, and so wouldn't have triggered the request for markAsDefinitelyNonNull.

This seems fixable by overriding QualifiedNameReference.localVariableBinding like this:

/**
 * Returns the local variable referenced by this node, if expression is an array.length reference
 */
@Override
public LocalVariableBinding localVariableBinding() {
	if ((this.bits & ASTNode.RestrictiveFlagMASK) == Binding.LOCAL) {
		return (LocalVariableBinding) this.binding; // as guaranteed by resolveType()
	}
	return null;
}
Comment 1 Jesper Moller CLA 2021-09-29 16:06:31 EDT
Oops, forgot to check master. Already fixed.

*** This bug has been marked as a duplicate of bug 576026 ***