@@ -1612,6 +1612,27 @@ uint32_t zend_get_class_fetch_type(zend_string *name) /* {{{ */
1612
1612
}
1613
1613
/* }}} */
1614
1614
1615
+ static uint32_t zend_get_class_fetch_type_ast (zend_ast * name_ast ) /* {{{ */
1616
+ {
1617
+ /* Fully qualified names are always default refs */
1618
+ if (name_ast -> attr == ZEND_NAME_FQ ) {
1619
+ return ZEND_FETCH_CLASS_DEFAULT ;
1620
+ }
1621
+
1622
+ return zend_get_class_fetch_type (zend_ast_get_str (name_ast ));
1623
+ }
1624
+ /* }}} */
1625
+
1626
+ void zend_ensure_valid_class_fetch_type (uint32_t fetch_type ) /* {{{ */
1627
+ {
1628
+ if (fetch_type != ZEND_FETCH_CLASS_DEFAULT && !CG (active_class_entry )) {
1629
+ zend_error_noreturn (E_COMPILE_ERROR , "Cannot use \"%s\" when no class scope is active" ,
1630
+ fetch_type == ZEND_FETCH_CLASS_SELF ? "self" :
1631
+ fetch_type == ZEND_FETCH_CLASS_PARENT ? "parent" : "static" );
1632
+ }
1633
+ }
1634
+ /* }}} */
1635
+
1615
1636
ZEND_API zend_string * zend_get_compiled_variable_name (const zend_op_array * op_array , uint32_t var ) /* {{{ */
1616
1637
{
1617
1638
return op_array -> vars [EX_VAR_TO_NUM (var )];
@@ -2018,19 +2039,11 @@ static inline zend_bool zend_can_write_to_variable(zend_ast *ast) /* {{{ */
2018
2039
2019
2040
static inline zend_bool zend_is_const_default_class_ref (zend_ast * name_ast ) /* {{{ */
2020
2041
{
2021
- zend_string * name ;
2022
-
2023
2042
if (name_ast -> kind != ZEND_AST_ZVAL ) {
2024
2043
return 0 ;
2025
2044
}
2026
2045
2027
- /* Fully qualified names are always default refs */
2028
- if (!name_ast -> attr ) {
2029
- return 1 ;
2030
- }
2031
-
2032
- name = zend_ast_get_str (name_ast );
2033
- return ZEND_FETCH_CLASS_DEFAULT == zend_get_class_fetch_type (name );
2046
+ return ZEND_FETCH_CLASS_DEFAULT == zend_get_class_fetch_type_ast (name_ast );
2034
2047
}
2035
2048
/* }}} */
2036
2049
@@ -2077,6 +2090,8 @@ static zend_op *zend_compile_class_ref(znode *result, zend_ast *name_ast, int th
2077
2090
opline -> op2_type = IS_CONST ;
2078
2091
opline -> op2 .constant = zend_add_class_name_literal (CG (active_op_array ),
2079
2092
zend_resolve_class_name (name , type ));
2093
+ } else {
2094
+ zend_ensure_valid_class_fetch_type (fetch_type );
2080
2095
}
2081
2096
2082
2097
zend_string_release (name );
@@ -4147,7 +4162,7 @@ ZEND_API void zend_set_function_arg_flags(zend_function *func) /* {{{ */
4147
4162
}
4148
4163
/* }}} */
4149
4164
4150
- void zend_compile_params (zend_ast * ast , zend_ast * return_type_ast , zend_bool is_method ) /* {{{ */
4165
+ void zend_compile_params (zend_ast * ast , zend_ast * return_type_ast ) /* {{{ */
4151
4166
{
4152
4167
zend_ast_list * list = zend_ast_get_list (ast );
4153
4168
uint32_t i ;
@@ -4173,15 +4188,13 @@ void zend_compile_params(zend_ast *ast, zend_ast *return_type_ast, zend_bool is_
4173
4188
if (type != 0 ) {
4174
4189
arg_infos -> type_hint = type ;
4175
4190
} else {
4176
- if (zend_is_const_default_class_ref (return_type_ast )) {
4191
+ uint32_t fetch_type = zend_get_class_fetch_type_ast (return_type_ast );
4192
+ if (fetch_type == ZEND_FETCH_CLASS_DEFAULT ) {
4177
4193
class_name = zend_resolve_class_name_ast (return_type_ast );
4178
4194
zend_assert_valid_class_name (class_name );
4179
4195
} else {
4196
+ zend_ensure_valid_class_fetch_type (fetch_type );
4180
4197
zend_string_addref (class_name );
4181
- if (!is_method ) {
4182
- zend_error_noreturn (E_COMPILE_ERROR , "Cannot declare a return type of %s outside of a class scope" , class_name -> val );
4183
- return ;
4184
- }
4185
4198
}
4186
4199
4187
4200
arg_infos -> type_hint = IS_OBJECT ;
@@ -4302,10 +4315,12 @@ void zend_compile_params(zend_ast *ast, zend_ast *return_type_ast, zend_bool is_
4302
4315
if (type != 0 ) {
4303
4316
arg_info -> type_hint = type ;
4304
4317
} else {
4305
- if (zend_is_const_default_class_ref (type_ast )) {
4318
+ uint32_t fetch_type = zend_get_class_fetch_type_ast (type_ast );
4319
+ if (fetch_type == ZEND_FETCH_CLASS_DEFAULT ) {
4306
4320
class_name = zend_resolve_class_name_ast (type_ast );
4307
4321
zend_assert_valid_class_name (class_name );
4308
4322
} else {
4323
+ zend_ensure_valid_class_fetch_type (fetch_type );
4309
4324
zend_string_addref (class_name );
4310
4325
}
4311
4326
@@ -4626,7 +4641,7 @@ void zend_compile_func_decl(znode *result, zend_ast *ast) /* {{{ */
4626
4641
zend_stack_push (& CG (loop_var_stack ), (void * ) & dummy_var );
4627
4642
}
4628
4643
4629
- zend_compile_params (params_ast , return_type_ast , is_method );
4644
+ zend_compile_params (params_ast , return_type_ast );
4630
4645
if (uses_ast ) {
4631
4646
zend_compile_closure_uses (uses_ast );
4632
4647
}
@@ -6329,13 +6344,10 @@ void zend_compile_resolve_class_name(znode *result, zend_ast *ast) /* {{{ */
6329
6344
{
6330
6345
zend_ast * name_ast = ast -> child [0 ];
6331
6346
uint32_t fetch_type = zend_get_class_fetch_type (zend_ast_get_str (name_ast ));
6347
+ zend_ensure_valid_class_fetch_type (fetch_type );
6332
6348
6333
6349
switch (fetch_type ) {
6334
6350
case ZEND_FETCH_CLASS_SELF :
6335
- if (!CG (active_class_entry )) {
6336
- zend_error_noreturn (E_COMPILE_ERROR ,
6337
- "Cannot access self::class when no class scope is active" );
6338
- }
6339
6351
if (CG (active_class_entry )-> ce_flags & ZEND_ACC_TRAIT ) {
6340
6352
zval class_str_zv ;
6341
6353
zend_ast * class_str_ast , * class_const_ast ;
@@ -6354,11 +6366,7 @@ void zend_compile_resolve_class_name(znode *result, zend_ast *ast) /* {{{ */
6354
6366
break ;
6355
6367
case ZEND_FETCH_CLASS_STATIC :
6356
6368
case ZEND_FETCH_CLASS_PARENT :
6357
- if (!CG (active_class_entry )) {
6358
- zend_error_noreturn (E_COMPILE_ERROR ,
6359
- "Cannot access %s::class when no class scope is active" ,
6360
- fetch_type == ZEND_FETCH_CLASS_STATIC ? "static" : "parent" );
6361
- } else {
6369
+ {
6362
6370
zval class_str_zv ;
6363
6371
zend_ast * class_str_ast , * class_const_ast ;
6364
6372
@@ -6611,15 +6619,12 @@ void zend_compile_const_expr_resolve_class_name(zend_ast **ast_ptr) /* {{{ */
6611
6619
{
6612
6620
zend_ast * ast = * ast_ptr ;
6613
6621
zend_ast * name_ast = ast -> child [0 ];
6614
- uint32_t fetch_type = zend_get_class_fetch_type (zend_ast_get_str (name_ast ));
6615
6622
zval result ;
6623
+ uint32_t fetch_type = zend_get_class_fetch_type (zend_ast_get_str (name_ast ));
6624
+ zend_ensure_valid_class_fetch_type (fetch_type );
6616
6625
6617
6626
switch (fetch_type ) {
6618
6627
case ZEND_FETCH_CLASS_SELF :
6619
- if (!CG (active_class_entry )) {
6620
- zend_error_noreturn (E_COMPILE_ERROR ,
6621
- "Cannot access self::class when no class scope is active" );
6622
- }
6623
6628
ZVAL_STR_COPY (& result , CG (active_class_entry )-> name );
6624
6629
break ;
6625
6630
case ZEND_FETCH_CLASS_STATIC :
0 commit comments