diff options
author | Manu Sridharan <msridhar@gmail.com> | 2022-01-12 09:19:44 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-01-12 09:19:44 -0800 |
commit | 876b0c0d62688169eeba6b127f6421969d1c3263 (patch) | |
tree | 216115cc32c89b75061941d535d2863d48ce6850 | |
parent | 63ec845dc23a5c909ba6c52cb19dcc92d75d4391 (diff) | |
download | nullaway-876b0c0d62688169eeba6b127f6421969d1c3263.tar.gz |
Small tweaks to handling of assignments in dataflow (#547)
We add two small tweaks to assignment handling (found while reading the code):
1. If we see an assignment `e.f = ...`, treat `e` as non-null on the non-exceptional successor (since the dereference succeeded), if it's an access path that we can track. We already did this for assignments to array elements; we should do the same for field assignments, for consistency.
2. Don't track nullability for variables and fields of primitive type, as they can never be de-referenced. This is an optimization that could reduce the size of the stores we propagate around. I didn't measure the impact, but it seems like an obvious, if small, win.
I put the new test input in the same place as other similar ones in `NullAwayPositiveCases`, for consistency.
-rw-r--r-- | nullaway/src/main/java/com/uber/nullaway/dataflow/AccessPathNullnessPropagation.java | 7 | ||||
-rw-r--r-- | nullaway/src/test/resources/com/uber/nullaway/testdata/NullAwayPositiveCases.java | 6 |
2 files changed, 11 insertions, 2 deletions
diff --git a/nullaway/src/main/java/com/uber/nullaway/dataflow/AccessPathNullnessPropagation.java b/nullaway/src/main/java/com/uber/nullaway/dataflow/AccessPathNullnessPropagation.java index 81e434e..b4184ac 100644 --- a/nullaway/src/main/java/com/uber/nullaway/dataflow/AccessPathNullnessPropagation.java +++ b/nullaway/src/main/java/com/uber/nullaway/dataflow/AccessPathNullnessPropagation.java @@ -505,7 +505,8 @@ public class AccessPathNullnessPropagation Nullness value = values(input).valueOfSubNode(node.getExpression()); Node target = node.getTarget(); - if (target instanceof LocalVariableNode) { + if (target instanceof LocalVariableNode + && !ASTHelpers.getType(target.getTree()).isPrimitive()) { updates.set((LocalVariableNode) target, value); } @@ -518,8 +519,10 @@ public class AccessPathNullnessPropagation // here we still require an access of a field of this, or a static field FieldAccessNode fieldAccessNode = (FieldAccessNode) target; Node receiver = fieldAccessNode.getReceiver(); + setNonnullIfAnalyzeable(updates, receiver); if ((receiver instanceof ThisNode || fieldAccessNode.isStatic()) - && fieldAccessNode.getElement().getKind().equals(ElementKind.FIELD)) { + && fieldAccessNode.getElement().getKind().equals(ElementKind.FIELD) + && !ASTHelpers.getType(target.getTree()).isPrimitive()) { updates.set(fieldAccessNode, value); } } diff --git a/nullaway/src/test/resources/com/uber/nullaway/testdata/NullAwayPositiveCases.java b/nullaway/src/test/resources/com/uber/nullaway/testdata/NullAwayPositiveCases.java index 8d5d2ae..d7316b1 100644 --- a/nullaway/src/test/resources/com/uber/nullaway/testdata/NullAwayPositiveCases.java +++ b/nullaway/src/test/resources/com/uber/nullaway/testdata/NullAwayPositiveCases.java @@ -283,6 +283,12 @@ public class NullAwayPositiveCases { arr.toString(); } + static void onlyReportOneField(@Nullable Inner i) { + // BUG: Diagnostic contains: dereferenced expression + i.f1 = null; + i.toString(); + } + static void testCast(@Nullable Object o) { String x = (String) o; // BUG: Diagnostic contains: dereferenced expression |