@@ -3350,6 +3350,63 @@ static void get_unresolved_initializer(zend_class_entry *ce, const char **kind,
3350
3350
} ZEND_HASH_FOREACH_END ();
3351
3351
}
3352
3352
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
+
3353
3410
static zend_bool preload_try_resolve_constants (zend_class_entry * ce )
3354
3411
{
3355
3412
zend_bool ok , changed ;
@@ -3650,9 +3707,12 @@ static void preload_link(void)
3650
3707
E_WARNING , ZSTR_VAL (ce -> info .user .filename ), ce -> info .user .line_start ,
3651
3708
"Can't preload already declared class %s" , ZSTR_VAL (ce -> name ));
3652
3709
} else {
3710
+ const char * kind , * name ;
3711
+ get_unlinked_dependency (ce , & kind , & name );
3653
3712
zend_error_at (
3654
3713
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 );
3656
3716
}
3657
3717
zend_string_release (key );
3658
3718
} else if (!(ce -> ce_flags & ZEND_ACC_CONSTANTS_UPDATED )) {
0 commit comments