Check that constructor initializers for pointer fields are null-safe.

Nullable values should not passed to fields marked nonnull.
For example:
```
int * _Nullable makeNullable();
struct Foo {
  int * _Nonnull ptr_nonnull;
  Foo(): ptr_nonnull(makeNullable); // unsafe
};
```

PiperOrigin-RevId: 475349613
diff --git a/nullability_verification/pointer_nullability_diagnosis.cc b/nullability_verification/pointer_nullability_diagnosis.cc
index 4fedd7a..d1aa1e0 100644
--- a/nullability_verification/pointer_nullability_diagnosis.cc
+++ b/nullability_verification/pointer_nullability_diagnosis.cc
@@ -7,6 +7,7 @@
 #include "nullability_verification/pointer_nullability.h"
 #include "nullability_verification/pointer_nullability_matchers.h"
 #include "clang/AST/ASTContext.h"
+#include "clang/AST/DeclCXX.h"
 #include "clang/AST/Expr.h"
 #include "clang/AST/ExprCXX.h"
 #include "clang/AST/Stmt.h"
@@ -127,6 +128,28 @@
              : llvm::None;
 }
 
+llvm::Optional<const Stmt*> diagnoseMemberInitializer(
+    const CXXCtorInitializer* CI, const MatchFinder::MatchResult& Result,
+    const Environment& Env) {
+  assert(CI->isAnyMemberInitializer());
+  auto MemberType = CI->getAnyMember()->getType();
+  if (!MemberType->isAnyPointerType()) {
+    return llvm::None;
+  }
+  auto MemberInitExpr = CI->getInit();
+  return isIncompatibleAssignment(MemberType, MemberInitExpr, Env,
+                                  *Result.Context)
+             // TODO(b/233582219): CtorInitializer is not compatible with the
+             // return type as it is not a Stmt. Therefore, we currently return
+             // the expression in the initializer. The return type should be
+             // modified to work over different AST nodes. For example,
+             // returning a SourceLocation or creating a Diagnostic base class
+             // that will contain more information about the violation and store
+             // the relevant AST nodes.
+             ? llvm::Optional<const Stmt*>(MemberInitExpr)
+             : llvm::None;
+}
+
 auto buildDiagnoser() {
   return CFGMatchSwitchBuilder<const Environment, llvm::Optional<const Stmt*>>()
       // (*)
@@ -137,6 +160,8 @@
       .CaseOfCFGStmt<CallExpr>(isCallExpr(), diagnoseCallExpr)
       .CaseOfCFGStmt<ReturnStmt>(isPointerReturn(), diagnoseReturn)
       .CaseOfCFGStmt<CXXConstructExpr>(isConstructExpr(), diagnoseConstructExpr)
+      .CaseOfCFGInit<CXXCtorInitializer>(isCtorMemberInitializer(),
+                                         diagnoseMemberInitializer)
       .Build();
 }