Commit de6f052c367 for php
commit de6f052c367d51e5a02d400c7b68c82035804b9a
Author: Gina Peter Banyard <girgias@php.net>
Date: Thu Oct 15 23:06:22 2026 +0100
Zend: add zend_cannot_instantiate_class() (#24336)
diff --git a/Zend/zend_API.c b/Zend/zend_API.c
index c3a0b4cfbaf..de7c3bfc341 100644
--- a/Zend/zend_API.c
+++ b/Zend/zend_API.c
@@ -1873,16 +1873,7 @@ ZEND_API void object_properties_load(zend_object *object, const HashTable *prope
static zend_always_inline zend_result _object_and_properties_init(zval *arg, zend_class_entry *ce, HashTable *properties) /* {{{ */
{
if (UNEXPECTED(ce->ce_flags & ZEND_ACC_UNINSTANTIABLE)) {
- if (ce->ce_flags & ZEND_ACC_INTERFACE) {
- zend_throw_error(NULL, "Cannot instantiate interface %s", ZSTR_VAL(ce->name));
- } else if (ce->ce_flags & ZEND_ACC_TRAIT) {
- zend_throw_error(NULL, "Cannot instantiate trait %s", ZSTR_VAL(ce->name));
- } else if (ce->ce_flags & ZEND_ACC_ENUM) {
- zend_throw_error(NULL, "Cannot instantiate enum %s", ZSTR_VAL(ce->name));
- } else {
- ZEND_ASSERT(ce->ce_flags & (ZEND_ACC_IMPLICIT_ABSTRACT_CLASS|ZEND_ACC_EXPLICIT_ABSTRACT_CLASS));
- zend_throw_error(NULL, "Cannot instantiate abstract class %s", ZSTR_VAL(ce->name));
- }
+ zend_cannot_instantiate_class(ce);
ZVAL_NULL(arg);
Z_OBJ_P(arg) = NULL;
return FAILURE;
diff --git a/Zend/zend_lazy_objects.c b/Zend/zend_lazy_objects.c
index de9538bbb4c..17f2f3a344c 100644
--- a/Zend/zend_lazy_objects.c
+++ b/Zend/zend_lazy_objects.c
@@ -260,11 +260,7 @@ ZEND_API zend_object *zend_object_make_lazy(zend_object *obj,
if (!obj) {
if (UNEXPECTED(reflection_ce->ce_flags & ZEND_ACC_UNINSTANTIABLE)) {
- zval zobj;
- /* Call object_init_ex() for the generated exception */
- zend_result result = object_init_ex(&zobj, reflection_ce);
- ZEND_ASSERT(result == FAILURE && EG(exception));
- (void)result;
+ zend_cannot_instantiate_class(reflection_ce);
return NULL;
}
diff --git a/Zend/zend_objects_API.c b/Zend/zend_objects_API.c
index 537cad8a364..12362ab929b 100644
--- a/Zend/zend_objects_API.c
+++ b/Zend/zend_objects_API.c
@@ -211,3 +211,18 @@ ZEND_API ZEND_COLD zend_property_info *zend_get_property_info_for_slot_slow(zend
} ZEND_HASH_FOREACH_END();
return NULL;
}
+
+ZEND_API ZEND_COLD zend_never_inline void zend_cannot_instantiate_class(
+ const zend_class_entry *ce
+) {
+ ZEND_ASSERT(ce->ce_flags & ZEND_ACC_UNINSTANTIABLE);
+ if (ce->ce_flags & ZEND_ACC_INTERFACE) {
+ zend_throw_error(NULL, "Cannot instantiate interface %s", ZSTR_VAL(ce->name));
+ } else if (ce->ce_flags & ZEND_ACC_TRAIT) {
+ zend_throw_error(NULL, "Cannot instantiate trait %s", ZSTR_VAL(ce->name));
+ } else if (ce->ce_flags & ZEND_ACC_ENUM) {
+ zend_throw_error(NULL, "Cannot instantiate enum %s", ZSTR_VAL(ce->name));
+ } else if (ce->ce_flags & (ZEND_ACC_IMPLICIT_ABSTRACT_CLASS|ZEND_ACC_EXPLICIT_ABSTRACT_CLASS)) {
+ zend_throw_error(NULL, "Cannot instantiate abstract class %s", ZSTR_VAL(ce->name));
+ }
+}
diff --git a/Zend/zend_objects_API.h b/Zend/zend_objects_API.h
index b66a3d307e5..0c1acb90f59 100644
--- a/Zend/zend_objects_API.h
+++ b/Zend/zend_objects_API.h
@@ -160,4 +160,6 @@ static zend_always_inline bool zend_check_method_accessible(const zend_function
return true;
}
+ZEND_API ZEND_COLD zend_never_inline void zend_cannot_instantiate_class(const zend_class_entry *ce);
+
#endif /* ZEND_OBJECTS_H */