Implement transfer function for checking that member accesses on pointers via the arrow (->) operator are null-safe.

We use a single matcher to handle both cases:\
Case 1: checking -> access on pointers\
Case 2: initialisation of null state for pointers which are members

We don't use distinct matchers as the `MatchSwitch` utility will only invoke one matcher case at a time, so the situation where both cases need to be invoked (see example below) will not be handled correctly.

```
struct Foo {
  Foo* MemberPtr;
};
Foo* BasePtr;
BasePtr->MemberPtr; // Matches case 1 and 2
```

PiperOrigin-RevId: 454133816
diff --git a/nullability_verification/pointer_nullability_matchers.cc b/nullability_verification/pointer_nullability_matchers.cc
index 4f277dc..c37ce4a 100644
--- a/nullability_verification/pointer_nullability_matchers.cc
+++ b/nullability_verification/pointer_nullability_matchers.cc
@@ -11,6 +11,7 @@
 namespace tidy {
 namespace nullability {
 
+using ast_matchers::anyOf;
 using ast_matchers::binaryOperator;
 using ast_matchers::declRefExpr;
 using ast_matchers::expr;
@@ -23,6 +24,7 @@
 using ast_matchers::ignoringImplicit;
 using ast_matchers::implicitCastExpr;
 using ast_matchers::isAnyPointer;
+using ast_matchers::isArrow;
 using ast_matchers::memberExpr;
 using ast_matchers::nullPointerConstant;
 using ast_matchers::unaryOperator;
@@ -46,8 +48,8 @@
 Matcher<Stmt> isImplicitCastPointerToBool() {
   return implicitCastExpr(hasCastKind(CK_PointerToBoolean));
 }
-Matcher<Stmt> isPointerMemberExpr() {
-  return memberExpr(hasType(isAnyPointer()));
+Matcher<Stmt> isMemberExprInvolvingPointers() {
+  return memberExpr(anyOf(isArrow(), hasType(isAnyPointer())));
 }
 }  // namespace nullability
 }  // namespace tidy