Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix static field access #7

Open
wants to merge 30 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
083ee1e
first attempt
Ao-senXiong Aug 13, 2023
cfa9c3a
finish TODO
Ao-senXiong Aug 13, 2023
0f09989
refine javadoc
Ao-senXiong Aug 13, 2023
a485100
refine javadoc
Ao-senXiong Aug 13, 2023
eb30d7b
add error message
Ao-senXiong Aug 13, 2023
7a4d0e7
edit the changelog
Ao-senXiong Aug 13, 2023
49fb417
add header to test case
Ao-senXiong Aug 13, 2023
3ceea9d
modify the cfg of issue5174
Ao-senXiong Aug 13, 2023
9ce4e76
Merge branch 'master' into fix-static-field-access
Ao-senXiong Aug 17, 2023
ff70a68
resume comments
Ao-senXiong Aug 17, 2023
4171e30
add extra test for static method invocation
Ao-senXiong Aug 17, 2023
ca1f4c6
rename file name
Ao-senXiong Aug 17, 2023
47670f5
Merge branch 'master' into fix-static-field-access
Ao-senXiong Aug 18, 2023
46a237b
Merge branch 'master' into fix-static-field-access
Ao-senXiong Sep 1, 2023
7a40c0a
Merge branch 'master' into fix-static-field-access
Ao-senXiong Sep 10, 2023
ecf9daa
Merge branch 'master' into fix-static-field-access
Ao-senXiong Sep 25, 2023
e7e15d0
Merge branch 'master' into dummy
Ao-senXiong Sep 26, 2023
1e1e8cc
Merge branch 'fix-static-field-access' into dummy
Ao-senXiong Sep 26, 2023
a0a1bcd
change expected output
Ao-senXiong Sep 27, 2023
812a58b
Merge branch 'dummy' of https://github.com/Ao-senXiong/checker-framew…
Ao-senXiong Sep 27, 2023
2c21b7c
Merge pull request #6 from Ao-senXiong/dummy
Ao-senXiong Sep 27, 2023
3b6d85f
Apply suggestions from code review
Ao-senXiong Sep 28, 2023
5eb6847
Apply suggestions from code review
Ao-senXiong Sep 28, 2023
0f49b43
address comments
Ao-senXiong Sep 28, 2023
ecf238f
Merge branch 'fix-static-field-access' of https://github.com/Ao-senXi…
Ao-senXiong Sep 28, 2023
1d05f52
Apply suggestions from code review
Ao-senXiong Sep 28, 2023
4393d6e
Merge branch 'fix-static-field-access' of https://github.com/Ao-senXi…
Ao-senXiong Sep 28, 2023
41a02ee
Merge branch 'master' into fix-static-field-access
Ao-senXiong Sep 30, 2023
1639bce
Reword changelog
wmdietl Sep 30, 2023
a952621
Merge branch 'master' into fix-static-field-access
wmdietl Sep 30, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -361,9 +361,11 @@ public TransferResult<NullnessNoInitValue, NullnessNoInitStore> visitMethodAcces
MethodAccessNode n, TransferInput<NullnessNoInitValue, NullnessNoInitStore> p) {
TransferResult<NullnessNoInitValue, NullnessNoInitStore> result =
super.visitMethodAccess(n, p);
// In contrast to the conditional makeNonNull in visitMethodInvocation, this
// makeNonNull is unconditional, as the receiver is definitely non-null after the access.
makeNonNull(result, n.getReceiver());
// The receiver of an instance method access is non-null. A static method access does not
// ensure that the receiver is non-null.
if (!n.isStatic()) {
makeNonNull(result, n.getReceiver());
}
return result;
}

Expand All @@ -372,7 +374,11 @@ public TransferResult<NullnessNoInitValue, NullnessNoInitStore> visitFieldAccess
FieldAccessNode n, TransferInput<NullnessNoInitValue, NullnessNoInitStore> p) {
TransferResult<NullnessNoInitValue, NullnessNoInitStore> result =
super.visitFieldAccess(n, p);
makeNonNull(result, n.getReceiver());
// The receiver of an instance field access is non-null. A static field access does not
// ensure that the receiver is non-null.
if (!n.isStatic()) {
makeNonNull(result, n.getReceiver());
}
return result;
}

Expand Down
16 changes: 0 additions & 16 deletions checker/tests/nullness-extra/issue5174/Issue5174.out
Original file line number Diff line number Diff line change
Expand Up @@ -1215,7 +1215,6 @@ Before: NullnessNoInitStore#326(
55:
Before: NullnessNoInitStore#333(
o > NV{@NonNull, Object, poly nn/n=f/f}
Issue5174Super.class > NV{@NonNull, Issue5174Super, poly nn/n=f/f}
isPolyNullNonNull = false
isPolyNullNull = false)
~~~~~~~~~
Expand All @@ -1224,7 +1223,6 @@ Issue5174Sub [ ClassName ] > NV{@NonNull, Issue5174Sub, poly nn/n=f/f}
56:
Before: NullnessNoInitStore#334(
o > NV{@NonNull, Object, poly nn/n=f/f}
Issue5174Super.class > NV{@NonNull, Issue5174Super, poly nn/n=f/f}
isPolyNullNonNull = false
isPolyNullNull = false)
~~~~~~~~~
Expand All @@ -1236,8 +1234,6 @@ o [ LocalVariable ]
57:
Before: NullnessNoInitStore#343(
o > NV{@NonNull, Object, poly nn/n=f/f}
Issue5174Sub.class > NV{@NonNull, Issue5174Sub, poly nn/n=f/f}
Issue5174Super.class > NV{@NonNull, Issue5174Super, poly nn/n=f/f}
isPolyNullNonNull = false
isPolyNullNull = false)
~~~~~~~~~
Expand All @@ -1246,8 +1242,6 @@ Issue5174Super [ ClassName ] > NV{@NonNull, Issue5174Super, poly nn/n=f/f}
58:
Before: NullnessNoInitStore#344(
o > NV{@NonNull, Object, poly nn/n=f/f}
Issue5174Sub.class > NV{@NonNull, Issue5174Sub, poly nn/n=f/f}
Issue5174Super.class > NV{@NonNull, Issue5174Super, poly nn/n=f/f}
isPolyNullNonNull = false
isPolyNullNull = false)
~~~~~~~~~
Expand All @@ -1258,8 +1252,6 @@ expression statement o = Issue5174Super.sf [ ExpressionStatement ]
49:
Before: NullnessNoInitStore#353(
o > NV{@NonNull, Object, poly nn/n=f/f}
Issue5174Sub.class > NV{@NonNull, Issue5174Sub, poly nn/n=f/f}
Issue5174Super.class > NV{@NonNull, Issue5174Super, poly nn/n=f/f}
isPolyNullNonNull = false
isPolyNullNull = false)
~~~~~~~~~
Expand Down Expand Up @@ -1667,7 +1659,6 @@ Before: NullnessNoInitStore#456(
109:
Before: NullnessNoInitStore#463(
o > NV{@NonNull, Object, poly nn/n=f/f}
Issue5174Super.class > NV{@NonNull, Issue5174Super, poly nn/n=f/f}
isPolyNullNonNull = false
isPolyNullNull = false)
~~~~~~~~~
Expand All @@ -1676,7 +1667,6 @@ Issue5174Sub [ ClassName ] > NV{@NonNull, Issue5174Sub, poly nn/n=f/f}
110:
Before: NullnessNoInitStore#464(
o > NV{@NonNull, Object, poly nn/n=f/f}
Issue5174Super.class > NV{@NonNull, Issue5174Super, poly nn/n=f/f}
isPolyNullNonNull = false
isPolyNullNull = false)
~~~~~~~~~
Expand All @@ -1688,8 +1678,6 @@ o [ LocalVariable ]
111:
Before: NullnessNoInitStore#473(
o > NV{@NonNull, Object, poly nn/n=f/f}
Issue5174Sub.class > NV{@NonNull, Issue5174Sub, poly nn/n=f/f}
Issue5174Super.class > NV{@NonNull, Issue5174Super, poly nn/n=f/f}
isPolyNullNonNull = false
isPolyNullNull = false)
~~~~~~~~~
Expand All @@ -1698,8 +1686,6 @@ Issue5174Super [ ClassName ] > NV{@NonNull, Issue5174Super, poly nn/n=f/f}
112:
Before: NullnessNoInitStore#474(
o > NV{@NonNull, Object, poly nn/n=f/f}
Issue5174Sub.class > NV{@NonNull, Issue5174Sub, poly nn/n=f/f}
Issue5174Super.class > NV{@NonNull, Issue5174Super, poly nn/n=f/f}
isPolyNullNonNull = false
isPolyNullNull = false)
~~~~~~~~~
Expand All @@ -1710,8 +1696,6 @@ expression statement o = Issue5174Super.sf [ ExpressionStatement ]
103:
Before: NullnessNoInitStore#483(
o > NV{@NonNull, Object, poly nn/n=f/f}
Issue5174Sub.class > NV{@NonNull, Issue5174Sub, poly nn/n=f/f}
Issue5174Super.class > NV{@NonNull, Issue5174Super, poly nn/n=f/f}
isPolyNullNonNull = false
isPolyNullNull = false)
~~~~~~~~~
Expand Down
25 changes: 25 additions & 0 deletions checker/tests/nullness/flow/EisopIssue553.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Test case for EISOP Issue 553:
// https://github.com/eisop/checker-framework/issues/553
import org.checkerframework.checker.nullness.qual.Nullable;

public class EisopIssue553 {
static @Nullable Object sfield = "";
Object field = "";

static void n(Object o) {
sfield = null;
}

public static void main(String[] args) {
EisopIssue553 x = null;
Object o = x.sfield;
// :: error: (dereference.of.nullable)
o = x.field;
if (x.sfield == null) {
return;
}
x.n(x.sfield);
// :: error: (dereference.of.nullable)
x.sfield.toString();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,17 @@
* </pre>
*/
public class FieldAccessNode extends Node {

/** The tree of the field access. */
protected final Tree tree;

/** The element of the accessed field. */
protected final VariableElement element;

/** The name of the accessed field. */
protected final String field;
protected final Node receiver;

// TODO: add method to get modifiers (static, access level, ..)
/** The receiver node of the field access. */
protected final Node receiver;

/**
* Creates a new FieldAccessNode.
Expand Down Expand Up @@ -93,7 +97,11 @@ public String toString() {
return getReceiver() + "." + field;
}

/** Is this a static field? */
/**
* Determine whether the field is static or not.
*
* @return whether the field is static or not
*/
public boolean isStatic() {
return ElementUtils.isStatic(getElement());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import org.checkerframework.checker.nullness.qual.Nullable;
import org.checkerframework.dataflow.qual.SideEffectFree;
import org.checkerframework.javacutil.BugInCF;
import org.checkerframework.javacutil.ElementUtils;
import org.checkerframework.javacutil.TreeUtils;

import java.util.Collection;
Expand All @@ -22,12 +23,14 @@
* </pre>
*/
public class MethodAccessNode extends Node {

/** The tree of the method access. */
protected final ExpressionTree tree;

/** The element of the accessed method. */
protected final ExecutableElement method;
protected final Node receiver;

// TODO: add method to get modifiers (static, access level, ..)
/** The receiver node of the method access. */
protected final Node receiver;

/**
* Create a new MethodAccessNode.
Expand Down Expand Up @@ -90,4 +93,13 @@ public int hashCode() {
public Collection<Node> getOperands() {
return Collections.singletonList(receiver);
}

/**
* Determine whether the method is static or not.
*
* @return whether the method is static or not
*/
public boolean isStatic() {
return ElementUtils.isStatic(getMethod());
}
}
7 changes: 5 additions & 2 deletions docs/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ In this release, `nullness` continues to suppress warnings from the Initializati
`nullnessnoinit` may be used to suppress warnings from the Nullness Checker only. A future release
will make suppression behavior consistent with other checkers.

Fixed a bug in the Nullness Checker where an instance receiver is incorrectly marked non-null after
a static method or field access. This could lead to new nullness errors. The static access should be
changed to be through a class name.

**Implementation details:**

Corrected the arguments to an `ObjectCreationNode` when the node refers to an
Expand All @@ -32,8 +36,7 @@ Changed the return types of

**Closed issues:**

eisop#297, eisop#376, eisop#400, eisop#532, typetools#1590.

eisop#297, eisop#376, eisop#400, eisop#532, eisop#533, typetools#1590.

Version 3.34.0-eisop1 (May 9, 2023)
-----------------------------------
Expand Down
Loading