From d512729a283e5e3d02594d5ad1efbdb9914abee1 Mon Sep 17 00:00:00 2001 From: Michael Ernst Date: Wed, 4 Sep 2024 19:46:48 -0700 Subject: [PATCH 1/2] Handle conditional expressions like `x.isEmpty() ? null : null` --- .../dataflow/cfg/builder/CFGTranslationPhaseOne.java | 6 ++++-- framework/tests/all-systems/Issue6785.java | 5 +++++ 2 files changed, 9 insertions(+), 2 deletions(-) create mode 100644 framework/tests/all-systems/Issue6785.java diff --git a/dataflow/src/main/java/org/checkerframework/dataflow/cfg/builder/CFGTranslationPhaseOne.java b/dataflow/src/main/java/org/checkerframework/dataflow/cfg/builder/CFGTranslationPhaseOne.java index bd03929758f..ad8d5b47730 100644 --- a/dataflow/src/main/java/org/checkerframework/dataflow/cfg/builder/CFGTranslationPhaseOne.java +++ b/dataflow/src/main/java/org/checkerframework/dataflow/cfg/builder/CFGTranslationPhaseOne.java @@ -2723,11 +2723,13 @@ public Node visitConditionalExpression(ConditionalExpressionTree tree, Void p) { // see JLS 15.25 TypeMirror exprType = TreeUtils.typeOf(tree); if (exprType.getKind() == TypeKind.NULL) { - // Happens when the 2nd and 3rd operands are both null, i.e. b ? null : null. + // Happens when the 2nd and 3rd operands are both null, e.g.: b ? null : null Tree parent = TreePathUtil.getContextForPolyExpression(getCurrentPath()); if (parent != null) { exprType = TreeUtils.typeOf(parent); - } else { + // exprType is null when the condition is non-atomic, e.g.: x.isEmpty() ? null : null + } + if (parent == null || exprType == null) { exprType = TypesUtils.getObjectTypeMirror(env); } } diff --git a/framework/tests/all-systems/Issue6785.java b/framework/tests/all-systems/Issue6785.java new file mode 100644 index 00000000000..00bfc8141f5 --- /dev/null +++ b/framework/tests/all-systems/Issue6785.java @@ -0,0 +1,5 @@ +public class Issue6785 { + String foo2(String x) { + return x.isEmpty() ? null : null; + } +} From 65ca74d81598e00e108f27f00c09638d833e9011 Mon Sep 17 00:00:00 2001 From: Michael Ernst Date: Wed, 4 Sep 2024 21:20:34 -0700 Subject: [PATCH 2/2] Add `@Nullable` annotation --- framework/tests/all-systems/Issue6785.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/framework/tests/all-systems/Issue6785.java b/framework/tests/all-systems/Issue6785.java index 00bfc8141f5..52f0f08ec1d 100644 --- a/framework/tests/all-systems/Issue6785.java +++ b/framework/tests/all-systems/Issue6785.java @@ -1,5 +1,7 @@ +import org.checkerframework.checker.nullness.qual.Nullable; + public class Issue6785 { - String foo2(String x) { + @Nullable String foo2(String x) { return x.isEmpty() ? null : null; } }