Collect evidence for function parameters from observed call sites.

Records Nonnull, Nullable, and Unknown arguments for use in flexible heuristics.

PiperOrigin-RevId: 549105355
Change-Id: Iea59d3ff84987446357d84cdba11df6d6ba8478f
diff --git a/nullability/pointer_nullability.cc b/nullability/pointer_nullability.cc
index bff42e2..084c25c 100644
--- a/nullability/pointer_nullability.cc
+++ b/nullability/pointer_nullability.cc
@@ -5,6 +5,7 @@
 #include "nullability/pointer_nullability.h"
 
 #include "clang/Analysis/FlowSensitive/DataflowEnvironment.h"
+#include "clang/Analysis/FlowSensitive/Formula.h"
 #include "clang/Analysis/FlowSensitive/Value.h"
 #include "clang/Basic/Specifiers.h"
 #include "llvm/ADT/StringRef.h"
@@ -75,21 +76,27 @@
   initPointerBoolProperty(PointerVal, kNull, NullConstraint, Env);
 }
 
-bool isNullable(const PointerValue &PointerVal, const Environment &Env) {
+bool isNullable(const PointerValue &PointerVal, const Environment &Env,
+                const dataflow::Formula *AdditionalConstraints) {
   auto &A = Env.getDataflowAnalysisContext().arena();
   auto [FromNullable, Null] = getPointerNullState(PointerVal);
-  auto &ForseeablyNull = A.makeAnd(FromNullable.formula(), Null.formula());
-  return !Env.flowConditionImplies(A.makeNot(ForseeablyNull));
+  auto *ForseeablyNull = &A.makeAnd(FromNullable.formula(), Null.formula());
+  if (AdditionalConstraints)
+    ForseeablyNull = &A.makeAnd(*AdditionalConstraints, *ForseeablyNull);
+  return !Env.flowConditionImplies(A.makeNot(*ForseeablyNull));
 }
 
 NullabilityKind getNullability(const dataflow::PointerValue &PointerVal,
-                               const dataflow::Environment &Env) {
+                               const dataflow::Environment &Env,
+                               const dataflow::Formula *AdditionalConstraints) {
   auto &A = Env.getDataflowAnalysisContext().arena();
-  auto [FromNullable, Null] = getPointerNullState(PointerVal);
-  if (Env.flowConditionImplies(A.makeNot(Null.formula())))
+  auto *Null = &getPointerNullState(PointerVal).second.formula();
+  if (AdditionalConstraints) Null = &A.makeAnd(*AdditionalConstraints, *Null);
+  if (Env.flowConditionImplies(A.makeNot(*Null)))
     return NullabilityKind::NonNull;
-  return isNullable(PointerVal, Env) ? NullabilityKind::Nullable
-                                     : NullabilityKind::Unspecified;
+  return isNullable(PointerVal, Env, AdditionalConstraints)
+             ? NullabilityKind::Nullable
+             : NullabilityKind::Unspecified;
 }
 
 }  // namespace clang::tidy::nullability