From 86b93bc479477e6c0de6207bfe59c1e276dfdafb Mon Sep 17 00:00:00 2001
From: Dmitry Stogov <dmitry@zend.com>
Date: Wed, 5 Jun 2024 23:53:31 +0300
Subject: [PATCH] Fix GH-14480: Method visibility issue introduced in version
 8.3.8 (#14484)

---
 Zend/tests/gh14480.phpt | 60 +++++++++++++++++++++++++++++++++++++++++
 Zend/zend_inheritance.c |  8 +++---
 2 files changed, 65 insertions(+), 3 deletions(-)
 create mode 100644 Zend/tests/gh14480.phpt

diff --git a/Zend/tests/gh14480.phpt b/Zend/tests/gh14480.phpt
new file mode 100644
index 0000000000000..bab74785b6b23
--- /dev/null
+++ b/Zend/tests/gh14480.phpt
@@ -0,0 +1,60 @@
+--TEST--
+GH-14480: Method visibility issue
+--FILE--
+<?php
+trait PropertyHelperTrait
+{
+    protected function splitPropertyParts(): void
+    {
+	    echo "OK\n";
+    }
+}
+
+trait OrmPropertyHelperTrait
+{
+    abstract protected function splitPropertyParts(): void;
+    
+    protected function addJoinsForNestedProperty(): void
+    {
+        $this->splitPropertyParts();
+    }
+}
+
+trait SearchFilterTrait
+{
+    use PropertyHelperTrait;
+}
+
+abstract class AbstractFilter
+{
+    use OrmPropertyHelperTrait, PropertyHelperTrait;
+    
+    public function apply(): void
+    {
+        $this->filterProperty();
+    }
+    
+    abstract protected function filterProperty(): void;
+}
+
+class SearchFilter extends AbstractFilter
+{
+    use SearchFilterTrait;
+    protected function filterProperty(): void
+    {
+        $this->addJoinsForNestedProperty();
+    }
+}
+
+class FilterExtension
+{
+    public function applyToCollection(): void
+    {
+        (new SearchFilter())->apply();
+    }
+}
+
+(new FilterExtension)->applyToCollection();
+?>
+--EXPECT--
+OK
diff --git a/Zend/zend_inheritance.c b/Zend/zend_inheritance.c
index 402354baa8..228c5b6e54 100644
--- a/Zend/zend_inheritance.c
+++ b/Zend/zend_inheritance.c
@@ -2018,12 +2018,14 @@ static void zend_add_trait_method(zend_class_entry *ce, zend_string *name, zend_
 	if (check_inheritance) {
 		/* Inherited members are overridden by members inserted by traits.
 		 * Check whether the trait method fulfills the inheritance requirements. */
+		uint32_t flags = ZEND_INHERITANCE_CHECK_PROTO | ZEND_INHERITANCE_CHECK_VISIBILITY;
+		if (!(existing_fn->common.scope->ce_flags & ZEND_ACC_TRAIT)) {
+			flags |= ZEND_INHERITANCE_SET_CHILD_CHANGED |ZEND_INHERITANCE_SET_CHILD_PROTO |
+				ZEND_INHERITANCE_RESET_CHILD_OVERRIDE;
+		}
 		do_inheritance_check_on_method(
 			fn, fixup_trait_scope(fn, ce), existing_fn, fixup_trait_scope(existing_fn, ce),
-			ce, NULL,
-			ZEND_INHERITANCE_CHECK_PROTO | ZEND_INHERITANCE_CHECK_VISIBILITY |
-			ZEND_INHERITANCE_SET_CHILD_CHANGED| ZEND_INHERITANCE_SET_CHILD_PROTO |
-			ZEND_INHERITANCE_RESET_CHILD_OVERRIDE);
+			ce, NULL, flags);
 	}
 }
 /* }}} */
