Skip to content

Commit f857648

Browse files
committed
Improve unlinked class diagnostics during preloading
1 parent d6d9024 commit f857648

File tree

3 files changed

+65
-5
lines changed

3 files changed

+65
-5
lines changed

ext/opcache/ZendAccelerator.c

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3350,6 +3350,63 @@ static void get_unresolved_initializer(zend_class_entry *ce, const char **kind,
33503350
} ZEND_HASH_FOREACH_END();
33513351
}
33523352

3353+
static zend_bool preload_all_types_known(zend_class_entry *ce);
3354+
static void get_unlinked_dependency(zend_class_entry *ce, const char **kind, const char **name) {
3355+
zend_class_entry *p;
3356+
*kind = "Unknown reason";
3357+
*name = "";
3358+
3359+
if (ce->parent_name) {
3360+
zend_string *key = zend_string_tolower(ce->parent_name);
3361+
p = zend_hash_find_ptr(EG(class_table), key);
3362+
zend_string_release(key);
3363+
if (!p) {
3364+
*kind = "Unknown parent ";
3365+
*name = ZSTR_VAL(ce->parent_name);
3366+
return;
3367+
}
3368+
if (!(p->ce_flags & ZEND_ACC_CONSTANTS_UPDATED)) {
3369+
*kind = "Parent with unresolved initializers ";
3370+
*name = ZSTR_VAL(ce->parent_name);
3371+
return;
3372+
}
3373+
if (!(p->ce_flags & ZEND_ACC_PROPERTY_TYPES_RESOLVED)) {
3374+
*kind = "Parent with unresolved property types ";
3375+
*name = ZSTR_VAL(ce->parent_name);
3376+
return;
3377+
}
3378+
}
3379+
3380+
if (ce->num_interfaces) {
3381+
uint32_t i;
3382+
for (i = 0; i < ce->num_interfaces; i++) {
3383+
p = zend_hash_find_ptr(EG(class_table), ce->interface_names[i].lc_name);
3384+
if (!p) {
3385+
*kind = "Unknown interface ";
3386+
*name = ZSTR_VAL(ce->interface_names[i].name);
3387+
return;
3388+
}
3389+
}
3390+
}
3391+
3392+
if (ce->num_traits) {
3393+
uint32_t i;
3394+
for (i = 0; i < ce->num_traits; i++) {
3395+
p = zend_hash_find_ptr(EG(class_table), ce->trait_names[i].lc_name);
3396+
if (!p) {
3397+
*kind = "Unknown trait ";
3398+
*name = ZSTR_VAL(ce->trait_names[i].name);
3399+
return;
3400+
}
3401+
}
3402+
}
3403+
3404+
if (!preload_all_types_known(ce)) {
3405+
*kind = "Unknown type dependencies";
3406+
return;
3407+
}
3408+
}
3409+
33533410
static zend_bool preload_try_resolve_constants(zend_class_entry *ce)
33543411
{
33553412
zend_bool ok, changed;
@@ -3650,9 +3707,12 @@ static void preload_link(void)
36503707
E_WARNING, ZSTR_VAL(ce->info.user.filename), ce->info.user.line_start,
36513708
"Can't preload already declared class %s", ZSTR_VAL(ce->name));
36523709
} else {
3710+
const char *kind, *name;
3711+
get_unlinked_dependency(ce, &kind, &name);
36533712
zend_error_at(
36543713
E_WARNING, ZSTR_VAL(ce->info.user.filename), ce->info.user.line_start,
3655-
"Can't preload unlinked class %s", ZSTR_VAL(ce->name));
3714+
"Can't preload unlinked class %s: %s%s",
3715+
ZSTR_VAL(ce->name), kind, name);
36563716
}
36573717
zend_string_release(key);
36583718
} else if (!(ce->ce_flags & ZEND_ACC_CONSTANTS_UPDATED)) {

ext/opcache/tests/bug78014.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ $c = new C;
1616
var_dump($c->foo());
1717
?>
1818
--EXPECTF--
19-
Warning: Can't preload unlinked class C in %s on line %d
19+
Warning: Can't preload unlinked class C: Parent with unresolved initializers B in %s on line %d
2020

2121
Warning: Can't preload class B with unresolved initializer for constant X in %s on line %d
2222

ext/opcache/tests/preload_011.phpt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,9 @@ $g = new G;
2222
?>
2323
===DONE===
2424
--EXPECTF--
25-
Warning: Can't preload unlinked class H in %s on line %d
25+
Warning: Can't preload unlinked class H: Unknown type dependencies in %s on line %d
2626

27-
Warning: Can't preload unlinked class B in %s on line %d
27+
Warning: Can't preload unlinked class B: Unknown type dependencies in %s on line %d
2828

29-
Warning: Can't preload unlinked class A in %s on line %d
29+
Warning: Can't preload unlinked class A: Unknown type dependencies in %s on line %d
3030
===DONE===

0 commit comments

Comments
 (0)