From 6a32c6ab1b74d24f9cf167e10740e19db8fe2cb3 Mon Sep 17 00:00:00 2001 From: Manu Sridharan Date: Wed, 18 Dec 2024 21:12:04 -0800 Subject: [PATCH 1/2] fix --- .../main/java/com/uber/nullaway/NullAway.java | 7 ++++++- .../jspecify/NullMarkednessTests.java | 21 +++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/nullaway/src/main/java/com/uber/nullaway/NullAway.java b/nullaway/src/main/java/com/uber/nullaway/NullAway.java index 9964550754..6c44c8c2f1 100644 --- a/nullaway/src/main/java/com/uber/nullaway/NullAway.java +++ b/nullaway/src/main/java/com/uber/nullaway/NullAway.java @@ -485,6 +485,12 @@ public Description matchAssignment(AssignmentTree tree, VisitorState state) { if (lhsType != null && lhsType.isPrimitive()) { doUnboxingCheck(state, tree.getExpression()); } + Symbol assigned = ASTHelpers.getSymbol(tree.getVariable()); + if (assigned != null && codeAnnotationInfo.isSymbolUnannotated(assigned, config, handler)) { + // assigning to symbol that is unannotated + return Description.NO_MATCH; + } + // TODO add test that we skip generics check if lhs symbol is unannotated // generics check if (lhsType != null && config.isJSpecifyMode()) { GenericsChecks.checkTypeParameterNullnessForAssignability(tree, this, state); @@ -508,7 +514,6 @@ public Description matchAssignment(AssignmentTree tree, VisitorState state) { } } - Symbol assigned = ASTHelpers.getSymbol(tree.getVariable()); if (assigned == null || assigned.getKind() != ElementKind.FIELD) { // not a field of nullable type return Description.NO_MATCH; diff --git a/nullaway/src/test/java/com/uber/nullaway/jspecify/NullMarkednessTests.java b/nullaway/src/test/java/com/uber/nullaway/jspecify/NullMarkednessTests.java index 705aa8180d..34feb6f7e5 100644 --- a/nullaway/src/test/java/com/uber/nullaway/jspecify/NullMarkednessTests.java +++ b/nullaway/src/test/java/com/uber/nullaway/jspecify/NullMarkednessTests.java @@ -1173,4 +1173,25 @@ public void nullUnmarkedOnConstructorSuppressesInitializerWarnings() { "}") .doTest(); } + + @Test + public void writeToNullUnmarkedField() { + defaultCompilationHelper + .addSourceLines( + "Test.java", + "package com.unannotated;", + "import org.jspecify.annotations.NullMarked;", + "public class Test {", + " static Object foo;", + " @NullMarked", + " static class Inner {", + " String bar() {", + " // expecting no errors since foo is in @NullUnmarked code", + " foo = null;", + " return foo.toString();", + " }", + " }", + "}") + .doTest(); + } } From 1a1c04230cd067f2246bf06c159ebadb16f535ff Mon Sep 17 00:00:00 2001 From: Manu Sridharan Date: Thu, 19 Dec 2024 07:44:11 -0800 Subject: [PATCH 2/2] another test --- .../main/java/com/uber/nullaway/NullAway.java | 1 - .../uber/nullaway/jspecify/GenericsTests.java | 24 +++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/nullaway/src/main/java/com/uber/nullaway/NullAway.java b/nullaway/src/main/java/com/uber/nullaway/NullAway.java index 6c44c8c2f1..9e27d42c0a 100644 --- a/nullaway/src/main/java/com/uber/nullaway/NullAway.java +++ b/nullaway/src/main/java/com/uber/nullaway/NullAway.java @@ -490,7 +490,6 @@ public Description matchAssignment(AssignmentTree tree, VisitorState state) { // assigning to symbol that is unannotated return Description.NO_MATCH; } - // TODO add test that we skip generics check if lhs symbol is unannotated // generics check if (lhsType != null && config.isJSpecifyMode()) { GenericsChecks.checkTypeParameterNullnessForAssignability(tree, this, state); diff --git a/nullaway/src/test/java/com/uber/nullaway/jspecify/GenericsTests.java b/nullaway/src/test/java/com/uber/nullaway/jspecify/GenericsTests.java index 7585c85657..ac749a7afc 100644 --- a/nullaway/src/test/java/com/uber/nullaway/jspecify/GenericsTests.java +++ b/nullaway/src/test/java/com/uber/nullaway/jspecify/GenericsTests.java @@ -2045,6 +2045,30 @@ public void issue1093() { .doTest(); } + @Test + public void nullUnmarkedGenericField() { + makeHelper() + .addSourceLines( + "Test.java", + "package com.unannotated;", + "import org.jspecify.annotations.*;", + "import java.util.function.Function;", + "public class Test {", + " static Function<@Nullable String, @Nullable String> foo;", + " @NullMarked", + " static class Inner {", + " static @Nullable Function<@Nullable String, @Nullable String> bar;", + " void bar(Function f) {", + " // no error since foo is in @NullUnmarked code", + " foo = f;", + " // BUG: Diagnostic contains: Cannot assign from type Function", + " bar = f;", + " }", + " }", + "}") + .doTest(); + } + private CompilationTestHelper makeHelper() { return makeTestHelperWithArgs( Arrays.asList(