Don't pass `nullptr` arena to constructors in `CreateArenaCompatible` when constructing types that use arena offsets.

Note that we can't do this for all arena-constructible types, since user-defined types can be constructed on arenas.

PiperOrigin-RevId: 812352250
diff --git a/src/google/protobuf/arena.h b/src/google/protobuf/arena.h
index 623d076..2246117 100644
--- a/src/google/protobuf/arena.h
+++ b/src/google/protobuf/arena.h
@@ -115,6 +115,15 @@
   }
 };
 
+// Returns true if `T` uses arena offsets instead of holding a copy of the arena
+// pointer. This can be deduced if the field's arena representation is not the
+// same as the field itself.
+template <typename T>
+constexpr bool FieldHasArenaOffset() {
+  using ArenaRepT = typename FieldArenaRep<T>::Type;
+  return !std::is_same_v<T, ArenaRepT>;
+}
+
 template <typename T>
 void arena_delete_object(void* PROTOBUF_NONNULL object) {
   delete reinterpret_cast<T*>(object);
@@ -498,9 +507,10 @@
     }
 
     static PROTOBUF_ALWAYS_INLINE T* PROTOBUF_NONNULL New() {
-      // Repeated pointer fields no longer have an arena constructor, so
-      // specialize calling their default constructor.
-      if constexpr (std::is_base_of_v<internal::RepeatedPtrFieldBase, T>) {
+      // Fields which use arena offsets don't have constructors that take an
+      // arena pointer. Since the arena is nullptr, it is safe to default
+      // construct the object.
+      if constexpr (internal::FieldHasArenaOffset<T>()) {
         return new T();
       } else {
         return new T(nullptr);
@@ -580,7 +590,11 @@
     static_assert(is_arena_constructable<T>::value,
                   "Can only construct types that are ArenaConstructable");
     if (ABSL_PREDICT_FALSE(arena == nullptr)) {
-      return new T(nullptr, static_cast<Args&&>(args)...);
+      if constexpr (internal::FieldHasArenaOffset<T>()) {
+        return new T(static_cast<Args&&>(args)...);
+      } else {
+        return new T(nullptr, static_cast<Args&&>(args)...);
+      }
     } else {
       using ArenaRepT = typename internal::FieldArenaRep<T>::Type;
       auto* arena_repr =