Skip to content

Commit

Permalink
Bogus null contract violation diagnostic at yield statements (#3154)
Browse files Browse the repository at this point in the history
* Fixes #2522
  • Loading branch information
srikanth-sankaran authored Oct 25, 2024
1 parent 55fbb80 commit 2e98dcb
Show file tree
Hide file tree
Showing 2 changed files with 112 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,6 @@ public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, Fl

flowInfo = this.expression.analyseCode(currentScope, flowContext, flowInfo);
this.expression.checkNPEbyUnboxing(currentScope, flowContext, flowInfo);
if (flowInfo.reachMode() == FlowInfo.REACHABLE && currentScope.compilerOptions().isAnnotationBasedNullAnalysisEnabled)
checkAgainstNullAnnotation(currentScope, flowContext, flowInfo, this.expression);

targetContext.recordAbruptExit();
targetContext.expireNullCheckedFieldInfo();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1132,4 +1132,116 @@ public static void main(String[] args) {
runner.classLibraries = this.LIBS;
runner.runConformTest();
}

// https://github.com/eclipse-jdt/eclipse.jdt.core/issues/2522
// Pattern matching on sealed classes cannot infer NonNull (JDK 21)
public void testIssue2522() {
Runner runner = getDefaultRunner();
runner.testFiles = new String[] {
"PatternMatching.java",
"""
import org.eclipse.jdt.annotation.*;
public sealed interface PatternMatching {
record Stuff() implements PatternMatching {}
@NonNull
static Stuff match(PatternMatching pm, int v) {
if (v == 0) {
Stuff r = switch (pm) {
case Stuff s -> s;
case null -> throw new NullPointerException();
};
return r; // no error here - good
} else if (v == 1) {
Stuff r = switch (pm) {
case Stuff s -> s;
case null -> throw new NullPointerException();
};
return null; // get error here - good
} else if (v == 2) {
Stuff r = switch (pm) {
case Stuff s -> s;
};
return r; // no error here -- good
} else if (v == 3) {
Stuff r = switch (pm) {
case Stuff s -> null; // <<<<<---------------------------- Line 28 - error Why ???
};
return r; // get error here - good
} else if (v == 4) {
Stuff r = switch (pm) {
case Stuff s -> s;
case null -> null; // <<<-------------------------------- Line 34 - error Why ??
};
return new Stuff(); // no error here // good
}
return new Stuff();
}
}
"""
};
runner.expectedCompilerLog =
"""
----------
1. ERROR in PatternMatching.java (at line 20)
return null; // get error here - good
^^^^
Null type mismatch: required 'PatternMatching.@NonNull Stuff' but the provided value is null
----------
2. ERROR in PatternMatching.java (at line 30)
return r; // get error here - good
^
Null type mismatch: required 'PatternMatching.@NonNull Stuff' but the provided value is null
----------
""";
runner.runNegativeTest();
}

// https://github.com/eclipse-jdt/eclipse.jdt.core/issues/2522
// Pattern matching on sealed classes cannot infer NonNull (JDK 21)
public void testIssue2522_2() {
Runner runner = getDefaultRunner();
runner.testFiles = new String[] {
"PatternMatching.java",
"""
import org.eclipse.jdt.annotation.*;
public sealed interface PatternMatching {
record Stuff() implements PatternMatching {}
@NonNull
static Stuff match(PatternMatching pm, int v) {
if (v == 0) {
return switch (pm) {
case Stuff s -> s;
case null -> throw new NullPointerException();
}; // no error here - good
} else if (v == 2) {
return switch (pm) {
case Stuff s -> s;
}; // no error here -- good
} else if (v == 3) {
return switch (pm) {
case Stuff s -> null; // get error here - good
};
}
return new Stuff();
}
}
"""
};
runner.expectedCompilerLog =
"""
----------
1. ERROR in PatternMatching.java (at line 20)
case Stuff s -> null; // get error here - good
^^^^
Null type mismatch: required 'PatternMatching.@NonNull Stuff' but the provided value is null
----------
""";
runner.runNegativeTest();
}
}

0 comments on commit 2e98dcb

Please sign in to comment.