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