From 0989b7001597fe59e54109ce2839bbfa8d041f2d Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Thu, 21 Feb 2019 10:35:59 +0100 Subject: [PATCH] Print more precise warning for unresolved constants --- ext/opcache/ZendAccelerator.c | 32 +++++++++++++++++++++++++++++- ext/opcache/tests/preload_004.phpt | 2 +- ext/opcache/tests/preload_009.phpt | 2 +- 3 files changed, 33 insertions(+), 3 deletions(-) diff --git a/ext/opcache/ZendAccelerator.c b/ext/opcache/ZendAccelerator.c index ff76eb9a63..5c05afc928 100644 --- a/ext/opcache/ZendAccelerator.c +++ b/ext/opcache/ZendAccelerator.c @@ -3258,6 +3258,34 @@ try_again: } } +static void get_unresolved_initializer(zend_class_entry *ce, const char **kind, const char **name) { + zend_string *key; + zend_class_constant *c; + zend_property_info *prop; + + *kind = "unknown"; + *name = ""; + + ZEND_HASH_FOREACH_STR_KEY_PTR(&ce->constants_table, key, c) { + if (Z_TYPE(c->value) == IS_CONSTANT_AST) { + *kind = "constant "; + *name = ZSTR_VAL(key); + } + } ZEND_HASH_FOREACH_END(); + ZEND_HASH_FOREACH_STR_KEY_PTR(&ce->properties_info, key, prop) { + zval *val; + if (prop->flags & ZEND_ACC_STATIC) { + val = &ce->default_static_members_table[OBJ_PROP_TO_NUM(prop->offset)]; + } else { + val = &ce->default_properties_table[OBJ_PROP_TO_NUM(prop->offset)]; + } + if (Z_TYPE_P(val) == IS_CONSTANT_AST) { + *kind = (prop->flags & ZEND_ACC_STATIC) ? "static property $" : "property $"; + *name = ZSTR_VAL(key); + } + } ZEND_HASH_FOREACH_END(); +} + static void preload_link(void) { zval *zv; @@ -3479,7 +3507,9 @@ static void preload_link(void) } zend_string_release(key); } else if (!(ce->ce_flags & ZEND_ACC_CONSTANTS_UPDATED)) { - zend_error(E_WARNING, "Can't preload class %s with unresolved constants at %s:%d", ZSTR_VAL(ce->name), ZSTR_VAL(ce->info.user.filename), ce->info.user.line_start); + const char *kind, *name; + get_unresolved_initializer(ce, &kind, &name); + zend_error(E_WARNING, "Can't preload class %s with unresolved initializer for %s%s at %s:%d", ZSTR_VAL(ce->name), kind, name, ZSTR_VAL(ce->info.user.filename), ce->info.user.line_start); } else if (!(ce->ce_flags & ZEND_ACC_PROPERTY_TYPES_RESOLVED)) { zend_error(E_WARNING, "Can't preload class %s with unresolved property types at %s:%d", ZSTR_VAL(ce->name), ZSTR_VAL(ce->info.user.filename), ce->info.user.line_start); } else { diff --git a/ext/opcache/tests/preload_004.phpt b/ext/opcache/tests/preload_004.phpt index eed73785f8..690d7f84fe 100644 --- a/ext/opcache/tests/preload_004.phpt +++ b/ext/opcache/tests/preload_004.phpt @@ -12,5 +12,5 @@ opcache.preload={PWD}/preload_undef_const.inc var_dump(class_exists('Foo')); ?> --EXPECTF-- -Warning: Can't preload class Foo with unresolved constants at %s:%d in Unknown on line 0 +Warning: Can't preload class Foo with unresolved initializer for constant A at %s:%d in Unknown on line 0 bool(false) diff --git a/ext/opcache/tests/preload_009.phpt b/ext/opcache/tests/preload_009.phpt index 563e0100a7..21c4766231 100644 --- a/ext/opcache/tests/preload_009.phpt +++ b/ext/opcache/tests/preload_009.phpt @@ -13,6 +13,6 @@ var_dump(trait_exists('T')); var_dump(class_exists('Foo')); ?> --EXPECTF-- -Warning: Can't preload class Foo with unresolved constants at %s:%d in Unknown on line 0 +Warning: Can't preload class Foo with unresolved initializer for constant C at %s:%d in Unknown on line 0 bool(true) bool(false) -- 2.50.0