Add transfer function for `MaterializeTemporaryExpr` in nullability verification

This allows us to handle expressions where `prvalue` temporaries are written to memory so they can be bound to references. For example, passing a member call to a function that takes a const reference argument.

PiperOrigin-RevId: 502610175
diff --git a/nullability_verification/pointer_nullability_analysis.cc b/nullability_verification/pointer_nullability_analysis.cc
index fd73e18..a750066 100644
--- a/nullability_verification/pointer_nullability_analysis.cc
+++ b/nullability_verification/pointer_nullability_analysis.cc
@@ -486,6 +486,26 @@
   });
 }
 
+void transferNonFlowSensitiveMaterializeTemporaryExpr(
+    const MaterializeTemporaryExpr* MTE, const MatchFinder::MatchResult& MR,
+    TransferState<PointerNullabilityLattice>& State) {
+  State.Lattice.insertExprNullabilityIfAbsent(MTE, [&]() {
+    auto BaseNullability = State.Lattice.getExprNullability(MTE->getSubExpr());
+    if (BaseNullability.has_value()) {
+      return BaseNullability->vec();
+    } else {
+      // Since we process child nodes before parents, we should already have
+      // computed the base (child) nullability. However, this is not true in all
+      // test cases. So, we return unspecified nullability annotations.
+      // TODO: Fix this issue, add a CHECK(BaseNullability.has_value()) and
+      // remove the else branch.
+      llvm::dbgs() << "Nullability of child node not found\n";
+      return std::vector<NullabilityKind>(countPointersInType(MTE->getType()),
+                                          NullabilityKind::Unspecified);
+    }
+  });
+}
+
 auto buildNonFlowSensitiveTransferer() {
   return CFGMatchSwitchBuilder<TransferState<PointerNullabilityLattice>>()
       .CaseOfCFGStmt<DeclRefExpr>(ast_matchers::declRefExpr(),
@@ -496,6 +516,9 @@
                                         transferNonFlowSensitiveMemberCallExpr)
       .CaseOfCFGStmt<CastExpr>(ast_matchers::castExpr(),
                                transferNonFlowSensitiveCastExpr)
+      .CaseOfCFGStmt<MaterializeTemporaryExpr>(
+          ast_matchers::materializeTemporaryExpr(),
+          transferNonFlowSensitiveMaterializeTemporaryExpr)
       .Build();
 }