@@ -1366,21 +1366,12 @@ static void zend_ensure_valid_class_fetch_type(uint32_t fetch_type) /* {{{ */
1366
1366
}
1367
1367
/* }}} */
1368
1368
1369
- static zend_bool zend_try_compile_const_expr_resolve_class_name (zval * zv , zend_ast * class_ast , zend_ast * name_ast , zend_bool constant ) /* {{{ */
1369
+ static zend_bool zend_try_compile_const_expr_resolve_class_name (zval * zv , zend_ast * class_ast , zend_bool constant ) /* {{{ */
1370
1370
{
1371
1371
uint32_t fetch_type ;
1372
1372
1373
- if (name_ast -> kind != ZEND_AST_ZVAL ) {
1374
- return 0 ;
1375
- }
1376
-
1377
- if (!zend_string_equals_literal_ci (zend_ast_get_str (name_ast ), "class" )) {
1378
- return 0 ;
1379
- }
1380
-
1381
1373
if (class_ast -> kind != ZEND_AST_ZVAL ) {
1382
- zend_error_noreturn (E_COMPILE_ERROR ,
1383
- "Dynamic class names are not allowed in compile-time ::class fetch" );
1374
+ zend_error_noreturn (E_COMPILE_ERROR , "Cannot use ::class with dynamic class name" );
1384
1375
}
1385
1376
1386
1377
fetch_type = zend_get_class_fetch_type (zend_ast_get_str (class_ast ));
@@ -1390,21 +1381,18 @@ static zend_bool zend_try_compile_const_expr_resolve_class_name(zval *zv, zend_a
1390
1381
case ZEND_FETCH_CLASS_SELF :
1391
1382
if (CG (active_class_entry ) && zend_is_scope_known ()) {
1392
1383
ZVAL_STR_COPY (zv , CG (active_class_entry )-> name );
1393
- } else {
1394
- ZVAL_NULL (zv );
1384
+ return 1 ;
1395
1385
}
1396
- return 1 ;
1386
+ return 0 ;
1397
1387
case ZEND_FETCH_CLASS_STATIC :
1398
1388
case ZEND_FETCH_CLASS_PARENT :
1399
1389
if (constant ) {
1400
1390
zend_error_noreturn (E_COMPILE_ERROR ,
1401
1391
"%s::class cannot be used for compile-time class name resolution" ,
1402
1392
fetch_type == ZEND_FETCH_CLASS_STATIC ? "static" : "parent"
1403
1393
);
1404
- } else {
1405
- ZVAL_NULL (zv );
1406
1394
}
1407
- return 1 ;
1395
+ return 0 ;
1408
1396
case ZEND_FETCH_CLASS_DEFAULT :
1409
1397
ZVAL_STR (zv , zend_resolve_class_name_ast (class_ast ));
1410
1398
return 1 ;
@@ -7689,16 +7677,6 @@ void zend_compile_class_const(znode *result, zend_ast *ast) /* {{{ */
7689
7677
znode class_node , const_node ;
7690
7678
zend_op * opline ;
7691
7679
7692
- if (zend_try_compile_const_expr_resolve_class_name (& result -> u .constant , class_ast , const_ast , 0 )) {
7693
- if (Z_TYPE (result -> u .constant ) == IS_NULL ) {
7694
- zend_op * opline = zend_emit_op_tmp (result , ZEND_FETCH_CLASS_NAME , NULL , NULL );
7695
- opline -> op1 .num = zend_get_class_fetch_type (zend_ast_get_str (class_ast ));
7696
- } else {
7697
- result -> op_type = IS_CONST ;
7698
- }
7699
- return ;
7700
- }
7701
-
7702
7680
zend_eval_const_expr (& ast -> child [0 ]);
7703
7681
zend_eval_const_expr (& ast -> child [1 ]);
7704
7682
@@ -7716,10 +7694,6 @@ void zend_compile_class_const(znode *result, zend_ast *ast) /* {{{ */
7716
7694
}
7717
7695
zend_string_release_ex (resolved_name , 0 );
7718
7696
}
7719
- if (const_ast -> kind == ZEND_AST_ZVAL && zend_string_equals_literal_ci (zend_ast_get_str (const_ast ), "class" )) {
7720
- zend_error_noreturn (E_COMPILE_ERROR ,
7721
- "Dynamic class names are not allowed in compile-time ::class fetch" );
7722
- }
7723
7697
7724
7698
zend_compile_class_ref (& class_node , class_ast , ZEND_FETCH_CLASS_EXCEPTION );
7725
7699
@@ -7733,6 +7707,21 @@ void zend_compile_class_const(znode *result, zend_ast *ast) /* {{{ */
7733
7707
}
7734
7708
/* }}} */
7735
7709
7710
+ void zend_compile_class_name (znode * result , zend_ast * ast ) /* {{{ */
7711
+ {
7712
+ zend_ast * class_ast = ast -> child [0 ];
7713
+ zend_op * opline ;
7714
+
7715
+ if (zend_try_compile_const_expr_resolve_class_name (& result -> u .constant , class_ast , 0 )) {
7716
+ result -> op_type = IS_CONST ;
7717
+ return ;
7718
+ }
7719
+
7720
+ opline = zend_emit_op_tmp (result , ZEND_FETCH_CLASS_NAME , NULL , NULL );
7721
+ opline -> op1 .num = zend_get_class_fetch_type (zend_ast_get_str (class_ast ));
7722
+ }
7723
+ /* }}} */
7724
+
7736
7725
void zend_compile_resolve_class_name (znode * result , zend_ast * ast ) /* {{{ */
7737
7726
{
7738
7727
zend_ast * name_ast = ast -> child [0 ];
@@ -7924,6 +7913,7 @@ zend_bool zend_is_allowed_in_const_expr(zend_ast_kind kind) /* {{{ */
7924
7913
|| kind == ZEND_AST_CONDITIONAL || kind == ZEND_AST_DIM
7925
7914
|| kind == ZEND_AST_ARRAY || kind == ZEND_AST_ARRAY_ELEM
7926
7915
|| kind == ZEND_AST_CONST || kind == ZEND_AST_CLASS_CONST
7916
+ || kind == ZEND_AST_CLASS_NAME
7927
7917
|| kind == ZEND_AST_MAGIC_CONST || kind == ZEND_AST_COALESCE ;
7928
7918
}
7929
7919
/* }}} */
@@ -7936,19 +7926,13 @@ void zend_compile_const_expr_class_const(zend_ast **ast_ptr) /* {{{ */
7936
7926
zend_string * class_name ;
7937
7927
zend_string * const_name = zend_ast_get_str (const_ast );
7938
7928
zend_string * name ;
7939
- zval result ;
7940
7929
int fetch_type ;
7941
7930
7942
7931
if (class_ast -> kind != ZEND_AST_ZVAL ) {
7943
7932
zend_error_noreturn (E_COMPILE_ERROR ,
7944
7933
"Dynamic class names are not allowed in compile-time class constant references" );
7945
7934
}
7946
7935
7947
- if (zend_try_compile_const_expr_resolve_class_name (& result , class_ast , const_ast , 1 )) {
7948
- * ast_ptr = zend_ast_create_zval (& result );
7949
- return ;
7950
- }
7951
-
7952
7936
class_name = zend_ast_get_str (class_ast );
7953
7937
fetch_type = zend_get_class_fetch_type (class_name );
7954
7938
@@ -7973,6 +7957,19 @@ void zend_compile_const_expr_class_const(zend_ast **ast_ptr) /* {{{ */
7973
7957
}
7974
7958
/* }}} */
7975
7959
7960
+ void zend_compile_const_expr_class_name (zend_ast * * ast_ptr ) /* {{{ */
7961
+ {
7962
+ zend_ast * class_ast = (* ast_ptr )-> child [0 ];
7963
+ uint32_t fetch_type = zend_get_class_fetch_type (zend_ast_get_str (class_ast ));
7964
+
7965
+ /* If we reach here, ::class should have either been constant evaluated or replaced
7966
+ * by a AST_MAGIC_CONST, so only the error case is left here. */
7967
+ zend_error_noreturn (E_COMPILE_ERROR ,
7968
+ "%s::class cannot be used for compile-time class name resolution" ,
7969
+ fetch_type == ZEND_FETCH_CLASS_STATIC ? "static" : "parent"
7970
+ );
7971
+ }
7972
+
7976
7973
void zend_compile_const_expr_const (zend_ast * * ast_ptr ) /* {{{ */
7977
7974
{
7978
7975
zend_ast * ast = * ast_ptr ;
@@ -8024,6 +8021,9 @@ void zend_compile_const_expr(zend_ast **ast_ptr) /* {{{ */
8024
8021
case ZEND_AST_CLASS_CONST :
8025
8022
zend_compile_const_expr_class_const (ast_ptr );
8026
8023
break ;
8024
+ case ZEND_AST_CLASS_NAME :
8025
+ zend_compile_const_expr_class_name (ast_ptr );
8026
+ break ;
8027
8027
case ZEND_AST_CONST :
8028
8028
zend_compile_const_expr_const (ast_ptr );
8029
8029
break ;
@@ -8312,6 +8312,9 @@ void zend_compile_expr(znode *result, zend_ast *ast) /* {{{ */
8312
8312
case ZEND_AST_CLASS_CONST :
8313
8313
zend_compile_class_const (result , ast );
8314
8314
return ;
8315
+ case ZEND_AST_CLASS_NAME :
8316
+ zend_compile_class_name (result , ast );
8317
+ return ;
8315
8318
case ZEND_AST_ENCAPS_LIST :
8316
8319
zend_compile_encaps_list (result , ast );
8317
8320
return ;
@@ -8605,32 +8608,16 @@ void zend_eval_const_expr(zend_ast **ast_ptr) /* {{{ */
8605
8608
}
8606
8609
case ZEND_AST_CLASS_CONST :
8607
8610
{
8608
- zend_ast * class_ast = ast -> child [ 0 ] ;
8609
- zend_ast * name_ast = ast -> child [ 1 ] ;
8611
+ zend_ast * class_ast ;
8612
+ zend_ast * name_ast ;
8610
8613
zend_string * resolved_name ;
8611
8614
8612
- if (zend_try_compile_const_expr_resolve_class_name (& result , class_ast , name_ast , 0 )) {
8613
- if (Z_TYPE (result ) == IS_NULL ) {
8614
- if (zend_get_class_fetch_type (zend_ast_get_str (class_ast )) == ZEND_FETCH_CLASS_SELF ) {
8615
- zend_ast_destroy (ast );
8616
- * ast_ptr = zend_ast_create_ex (ZEND_AST_MAGIC_CONST , T_CLASS_C );
8617
- }
8618
- return ;
8619
- }
8620
- break ;
8621
- }
8622
-
8623
8615
zend_eval_const_expr (& ast -> child [0 ]);
8624
8616
zend_eval_const_expr (& ast -> child [1 ]);
8625
8617
8626
8618
class_ast = ast -> child [0 ];
8627
8619
name_ast = ast -> child [1 ];
8628
8620
8629
- if (name_ast -> kind == ZEND_AST_ZVAL && zend_string_equals_literal_ci (zend_ast_get_str (name_ast ), "class" )) {
8630
- zend_error_noreturn (E_COMPILE_ERROR ,
8631
- "Dynamic class names are not allowed in compile-time ::class fetch" );
8632
- }
8633
-
8634
8621
if (class_ast -> kind != ZEND_AST_ZVAL || name_ast -> kind != ZEND_AST_ZVAL ) {
8635
8622
return ;
8636
8623
}
@@ -8645,7 +8632,20 @@ void zend_eval_const_expr(zend_ast **ast_ptr) /* {{{ */
8645
8632
zend_string_release_ex (resolved_name , 0 );
8646
8633
break ;
8647
8634
}
8648
-
8635
+ case ZEND_AST_CLASS_NAME :
8636
+ {
8637
+ zend_ast * class_ast = ast -> child [0 ];
8638
+ if (zend_try_compile_const_expr_resolve_class_name (& result , class_ast , 0 )) {
8639
+ break ;
8640
+ }
8641
+ /* TODO We should not use AST_MAGIC_CONST for this, because the semantics are slightly
8642
+ * different. */
8643
+ if (zend_get_class_fetch_type (zend_ast_get_str (class_ast )) == ZEND_FETCH_CLASS_SELF ) {
8644
+ zend_ast_destroy (ast );
8645
+ * ast_ptr = zend_ast_create_ex (ZEND_AST_MAGIC_CONST , T_CLASS_C );
8646
+ }
8647
+ return ;
8648
+ }
8649
8649
default :
8650
8650
return ;
8651
8651
}
0 commit comments