@@ -1268,15 +1268,16 @@ static void zend_traits_init_trait_structures(zend_class_entry *ce) /* {{{ */
1268
1268
j = 0 ;
1269
1269
while (cur_precedence -> exclude_from_classes [j ].class_name ) {
1270
1270
zend_string * class_name = cur_precedence -> exclude_from_classes [j ].class_name ;
1271
+ zend_class_entry * trait ;
1271
1272
1272
- if (!(cur_precedence -> exclude_from_classes [ j ]. ce = zend_fetch_class (class_name , ZEND_FETCH_CLASS_TRAIT |ZEND_FETCH_CLASS_NO_AUTOLOAD ))) {
1273
+ if (!(trait = zend_fetch_class (class_name , ZEND_FETCH_CLASS_TRAIT |ZEND_FETCH_CLASS_NO_AUTOLOAD ))) {
1273
1274
zend_error_noreturn (E_COMPILE_ERROR , "Could not find trait %s" , class_name -> val );
1274
1275
}
1275
- zend_check_trait_usage (ce , cur_precedence -> exclude_from_classes [ j ]. ce );
1276
+ zend_check_trait_usage (ce , trait );
1276
1277
1277
1278
/* make sure that the trait method is not from a class mentioned in
1278
1279
exclude_from_classes, for consistency */
1279
- if (cur_precedence -> trait_method -> ce == cur_precedence -> exclude_from_classes [ j ]. ce ) {
1280
+ if (cur_precedence -> trait_method -> ce == trait ) {
1280
1281
zend_error_noreturn (E_COMPILE_ERROR ,
1281
1282
"Inconsistent insteadof definition. "
1282
1283
"The method %s is to be used from %s, but %s is also on the exclude list" ,
@@ -1285,6 +1286,7 @@ static void zend_traits_init_trait_structures(zend_class_entry *ce) /* {{{ */
1285
1286
cur_precedence -> trait_method -> ce -> name -> val );
1286
1287
}
1287
1288
1289
+ cur_precedence -> exclude_from_classes [j ].ce = trait ;
1288
1290
zend_string_release (class_name );
1289
1291
j ++ ;
1290
1292
}
@@ -1358,18 +1360,22 @@ static void zend_do_traits_method_binding(zend_class_entry *ce) /* {{{ */
1358
1360
for (i = 0 ; i < ce -> num_traits ; i ++ ) {
1359
1361
if (ce -> trait_precedences ) {
1360
1362
HashTable exclude_table ;
1363
+ zend_trait_precedence * * precedences ;
1361
1364
1362
1365
/* TODO: revisit this start size, may be its not optimal */
1363
1366
zend_hash_init_ex (& exclude_table , 8 , NULL , NULL , 0 , 0 );
1364
1367
1365
- zend_traits_compile_exclude_table (& exclude_table , ce -> trait_precedences , ce -> traits [i ]);
1368
+ precedences = ce -> trait_precedences ;
1369
+ ce -> trait_precedences = NULL ;
1370
+ zend_traits_compile_exclude_table (& exclude_table , precedences , ce -> traits [i ]);
1366
1371
1367
1372
/* copies functions, applies defined aliasing, and excludes unused trait methods */
1368
1373
ZEND_HASH_FOREACH_STR_KEY_PTR (& ce -> traits [i ]-> function_table , key , fn ) {
1369
1374
zend_traits_copy_functions (key , fn , ce , & overriden , & exclude_table );
1370
1375
} ZEND_HASH_FOREACH_END ();
1371
1376
1372
1377
zend_hash_destroy (& exclude_table );
1378
+ ce -> trait_precedences = precedences ;
1373
1379
} else {
1374
1380
ZEND_HASH_FOREACH_STR_KEY_PTR (& ce -> traits [i ]-> function_table , key , fn ) {
1375
1381
zend_traits_copy_functions (key , fn , ce , & overriden , NULL );
@@ -1381,6 +1387,17 @@ static void zend_do_traits_method_binding(zend_class_entry *ce) /* {{{ */
1381
1387
zend_fixup_trait_method (fn , ce );
1382
1388
} ZEND_HASH_FOREACH_END ();
1383
1389
1390
+ if (ce -> trait_precedences ) {
1391
+ i = 0 ;
1392
+ while (ce -> trait_precedences [i ]) {
1393
+ if (ce -> trait_precedences [i ]-> exclude_from_classes ) {
1394
+ efree (ce -> trait_precedences [i ]-> exclude_from_classes );
1395
+ ce -> trait_precedences [i ]-> exclude_from_classes = NULL ;
1396
+ }
1397
+ i ++ ;
1398
+ }
1399
+ }
1400
+
1384
1401
if (overriden ) {
1385
1402
zend_hash_destroy (overriden );
1386
1403
FREE_HASHTABLE (overriden );
0 commit comments