]> granicus.if.org Git - php/commitdiff
Print more precise warning for unresolved constants
authorNikita Popov <nikita.ppv@gmail.com>
Thu, 21 Feb 2019 09:35:59 +0000 (10:35 +0100)
committerNikita Popov <nikita.ppv@gmail.com>
Thu, 21 Feb 2019 09:35:59 +0000 (10:35 +0100)
ext/opcache/ZendAccelerator.c
ext/opcache/tests/preload_004.phpt
ext/opcache/tests/preload_009.phpt

index ff76eb9a63a71a6c2840f26cded8b28a7e25e15e..5c05afc92890e3e36327b0a2830cbc4ac8153e1f 100644 (file)
@@ -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 {
index eed73785f8c70d60bd9b32ee00892baea52a2dea..690d7f84fe0ed647c95c8a745501030da103e68d 100644 (file)
@@ -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)
index 563e0100a71806b83e5b62435ee6bb2e00277745..21c476623152e00098a3f356c9954ead3e3dc573 100644 (file)
@@ -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)