[nullability] Fix assertion failure when calling free overloaded operator.

PiperOrigin-RevId: 526848860
diff --git a/nullability_verification/pointer_nullability_diagnosis.cc b/nullability_verification/pointer_nullability_diagnosis.cc
index f9f392c..c3064e4 100644
--- a/nullability_verification/pointer_nullability_diagnosis.cc
+++ b/nullability_verification/pointer_nullability_diagnosis.cc
@@ -195,9 +195,11 @@
 
   auto ParamTypes = CalleeFPT->getParamTypes();
   ArrayRef<const Expr*> Args(CE->getArgs(), CE->getNumArgs());
-  if (isa<CXXOperatorCallExpr>(CE)) {
-    // The first argument of an operator call expression is the operand which
-    // does not appear in the list of parameter types.
+  // The first argument of an member operator call expression is the implicit
+  // object argument, which does not appear in the list of parameter types.
+  // Note that operator calls always have a direct callee.
+  if (isa<CXXOperatorCallExpr>(CE) &&
+      isa<CXXMethodDecl>(CE->getDirectCallee())) {
     Args = Args.drop_front();
   }
   if (CalleeFPT->isVariadic()) {
diff --git a/nullability_verification/test/function_calls.cc b/nullability_verification/test/function_calls.cc
index 26b295c..77533ac 100644
--- a/nullability_verification/test/function_calls.cc
+++ b/nullability_verification/test/function_calls.cc
@@ -365,6 +365,19 @@
   )cc"));
 }
 
+TEST(PointerNullabilityTest, CallFreeOperator) {
+  // No nullability involved. This is just a regression test to make sure we can
+  // process a call to a free overloaded operator.
+  EXPECT_TRUE(checkDiagnostics(R"cc(
+    struct A {};
+    A operator+(A, A);
+    void target() {
+      A a;
+      a = a + a;
+    }
+  )cc"));
+}
+
 }  // namespace
 }  // namespace nullability
 }  // namespace tidy