Infer Nullable when >=1 Nullable argument is passed and Nonnull when only Nonnull arguments are passed.
Prioritized in that order and both are overridden by an unchecked dereference. This does not yet implement the flagging of a conflict between an unchecked dereference and a Nullable argument being passed.
PiperOrigin-RevId: 549106061
Change-Id: Ida239943543b073513ffe15543176c3e806e172a
diff --git a/nullability/inference/merge.cc b/nullability/inference/merge.cc
index 7603338..1e3c31e 100644
--- a/nullability/inference/merge.cc
+++ b/nullability/inference/merge.cc
@@ -24,7 +24,7 @@
if (LHS.location_size() >= Limit) break;
// Linear scan is fine because Limit is tiny.
if (!llvm::is_contained(LHS.location(), Loc)) LHS.add_location(Loc);
- };
+ }
}
static void mergeSlotPartials(Partial::SlotPartial &LHS,
@@ -103,9 +103,13 @@
// Mandatory inference rules, required by type-checking.
// TODO: report conflicts between these.
if (Counts[Evidence::UNCHECKED_DEREFERENCE]) return {Inference::NONNULL};
+ if (Counts[Evidence::NULLABLE_ARGUMENT]) return {Inference::NULLABLE};
- // TODO: Optional "soft" inference heuristics.
+ // Optional "soft" inference heuristics.
// These do not report conflicts.
+ if (!Counts[Evidence::NULLABLE_ARGUMENT] &&
+ !Counts[Evidence::UNKNOWN_ARGUMENT] && Counts[Evidence::NONNULL_ARGUMENT])
+ return {Inference::NONNULL};
return {Inference::UNKNOWN};
}
diff --git a/nullability/inference/merge_test.cc b/nullability/inference/merge_test.cc
index 2d89577..b477fb2 100644
--- a/nullability/inference/merge_test.cc
+++ b/nullability/inference/merge_test.cc
@@ -206,5 +206,27 @@
EXPECT_EQ(Inference::NONNULL, infer());
}
+TEST_F(InferTest, NullableArgumentPassed) {
+ add(Evidence::NULLABLE_ARGUMENT);
+ EXPECT_EQ(Inference::NULLABLE, infer());
+ add(Evidence::NONNULL_ARGUMENT);
+ EXPECT_EQ(Inference::NULLABLE, infer());
+ add(Evidence::UNKNOWN_ARGUMENT);
+ EXPECT_EQ(Inference::NULLABLE, infer());
+ add(Evidence::UNCHECKED_DEREFERENCE);
+ EXPECT_EQ(Inference::NONNULL, infer()); // TODO: expect conflict
+}
+
+TEST_F(InferTest, OnlyNonnullArgumentsPassed) {
+ add(Evidence::NONNULL_ARGUMENT);
+ EXPECT_EQ(Inference::NONNULL, infer());
+}
+
+TEST_F(InferTest, NonnullAndUnknownArgumentsPassed) {
+ add(Evidence::NONNULL_ARGUMENT);
+ add(Evidence::UNKNOWN_ARGUMENT);
+ EXPECT_EQ(Inference::UNKNOWN, infer());
+}
+
} // namespace
} // namespace clang::tidy::nullability