]> granicus.if.org Git - php/commitdiff
Make class name references use the class_name production
authorNikita Popov <nikita.ppv@gmail.com>
Mon, 13 Jan 2020 10:34:04 +0000 (11:34 +0100)
committerNikita Popov <nikita.ppv@gmail.com>
Mon, 13 Jan 2020 10:51:09 +0000 (11:51 +0100)
Throw a compile error for "static" references instead, where it
isn't already the case.

Also extract the code that does that -- we have quite a few places
where we get a const class ref and require it to be default.

12 files changed:
Zend/tests/catch_static.phpt [new file with mode: 0644]
Zend/tests/class_uses_static.phpt [new file with mode: 0644]
Zend/tests/errmsg_030.phpt
Zend/tests/errmsg_031.phpt
Zend/tests/errmsg_035.phpt
Zend/tests/errmsg_036.phpt
Zend/tests/interface_extends_static.phpt [new file with mode: 0644]
Zend/tests/lsb_007.phpt
Zend/tests/static_in_trait_insteadof_list.phpt [new file with mode: 0644]
Zend/tests/static_in_trait_insteadof_reference.phpt [new file with mode: 0644]
Zend/zend_compile.c
Zend/zend_language_parser.y

diff --git a/Zend/tests/catch_static.phpt b/Zend/tests/catch_static.phpt
new file mode 100644 (file)
index 0000000..283aef9
--- /dev/null
@@ -0,0 +1,17 @@
+--TEST--
+Cannot catch "static"
+--FILE--
+<?php
+
+// This could in principle be supported, but isn't right now.
+class Test {
+    public function method() {
+        try {
+            foo();
+        } catch (static $e) {}
+    }
+}
+
+?>
+--EXPECTF--
+Fatal error: Bad class name in the catch statement in %s on line %d
diff --git a/Zend/tests/class_uses_static.phpt b/Zend/tests/class_uses_static.phpt
new file mode 100644 (file)
index 0000000..96a9132
--- /dev/null
@@ -0,0 +1,12 @@
+--TEST--
+Class cannot use static as a trait, as it is reserved
+--FILE--
+<?php
+
+class Test {
+    use static;
+}
+
+?>
+--EXPECTF--
+Fatal error: Cannot use 'static' as trait name as it is reserved in %s on line %d
index c0d42263c34e0c8e02873db911ef6dcef1a27e6d..589965cf08c03362755f234adac589f19b8b30fa 100644 (file)
@@ -9,4 +9,4 @@ class test extends self {
 echo "Done\n";
 ?>
 --EXPECTF--
-Fatal error: Cannot use 'self' as class name as it is reserved in %s on line %d
+Fatal error: Cannot use 'self' as class name, as it is reserved in %s on line %d
index c847a26e64257f7b9593e8a09a1f3301c4a1c64e..ed1d0bec2d763e1386882c11b47cf6c3cd56caf0 100644 (file)
@@ -9,4 +9,4 @@ class test extends parent {
 echo "Done\n";
 ?>
 --EXPECTF--
-Fatal error: Cannot use 'parent' as class name as it is reserved in %s on line %d
+Fatal error: Cannot use 'parent' as class name, as it is reserved in %s on line %d
index e8fa8da8e8a72db21baf1178dc9b182a5b059733..140e3e9cf47f9cfb75de09a335cd3a4775de1c4f 100644 (file)
@@ -9,4 +9,4 @@ class test implements self {
 echo "Done\n";
 ?>
 --EXPECTF--
-Fatal error: Cannot use 'self' as interface name as it is reserved in %s on line %d
+Fatal error: Cannot use 'self' as interface name, as it is reserved in %s on line %d
index 4f98f384d78582c9a4150dba772c311f04a03fef..33c6bca1d6a743fcf9a02d97d2ae3aa6e2c1c480 100644 (file)
@@ -9,4 +9,4 @@ class test implements parent {
 echo "Done\n";
 ?>
 --EXPECTF--
-Fatal error: Cannot use 'parent' as interface name as it is reserved in %s on line %d
+Fatal error: Cannot use 'parent' as interface name, as it is reserved in %s on line %d
diff --git a/Zend/tests/interface_extends_static.phpt b/Zend/tests/interface_extends_static.phpt
new file mode 100644 (file)
index 0000000..3d12070
--- /dev/null
@@ -0,0 +1,10 @@
+--TEST--
+Interface cannot extend static, as it is reserved
+--FILE--
+<?php
+
+interface Foo extends static {}
+
+?>
+--EXPECTF--
+Fatal error: Cannot use 'static' as interface name, as it is reserved in %s on line %d
index c28e815be03a019f5855143c736302f20ef5c5dd..970044eab29e941320a1821c1830a2d51ff8a247 100644 (file)
@@ -9,4 +9,4 @@ class Foo implements static {
 ?>
 ==DONE==
 --EXPECTF--
-Parse error: %s error,%sexpecting %s in %s on line %d
+Fatal error: Cannot use 'static' as interface name, as it is reserved in %s on line %d
diff --git a/Zend/tests/static_in_trait_insteadof_list.phpt b/Zend/tests/static_in_trait_insteadof_list.phpt
new file mode 100644 (file)
index 0000000..77ecf1e
--- /dev/null
@@ -0,0 +1,18 @@
+--TEST--
+Cannot use static in trait insteadof list
+--FILE--
+<?php
+
+trait SomeTrait {
+    public function foobar() {}
+}
+
+class Test {
+    use SomeTrait {
+        SomeTrait::foobar insteadof static;
+    }
+}
+
+?>
+--EXPECTF--
+Fatal error: Cannot use 'static' as trait name, as it is reserved in %s on line %d
diff --git a/Zend/tests/static_in_trait_insteadof_reference.phpt b/Zend/tests/static_in_trait_insteadof_reference.phpt
new file mode 100644 (file)
index 0000000..95a6b3c
--- /dev/null
@@ -0,0 +1,18 @@
+--TEST--
+Cannot use static in trait insteadof method reference
+--FILE--
+<?php
+
+trait SomeTrait {
+    public function foobar() {}
+}
+
+class Test {
+    use SomeTrait {
+        static::foobar insteadof SomeTrait;
+    }
+}
+
+?>
+--EXPECTF--
+Fatal error: Cannot use 'static' as trait name, as it is reserved in %s on line %d
index 7cd71426f5d8f2358ad5d3504666f6dc5a512b8f..6b26630869b3878c3d58c533d74b2884b557a5e9 100644 (file)
@@ -1498,6 +1498,17 @@ static uint32_t zend_get_class_fetch_type_ast(zend_ast *name_ast) /* {{{ */
 }
 /* }}} */
 
+static zend_string *zend_resolve_const_class_name_reference(zend_ast *ast, const char *type)
+{
+       zend_string *class_name = zend_ast_get_str(ast);
+       if (ZEND_FETCH_CLASS_DEFAULT != zend_get_class_fetch_type_ast(ast)) {
+               zend_error_noreturn(E_COMPILE_ERROR,
+                       "Cannot use '%s' as %s, as it is reserved",
+                       ZSTR_VAL(class_name), type);
+       }
+       return zend_resolve_class_name(class_name, ast->attr);
+}
+
 static void zend_ensure_valid_class_fetch_type(uint32_t fetch_type) /* {{{ */
 {
        if (fetch_type != ZEND_FETCH_CLASS_DEFAULT && zend_is_scope_known()) {
@@ -6399,7 +6410,7 @@ static void zend_compile_method_ref(zend_ast *ast, zend_trait_method_reference *
        method_ref->method_name = zend_string_copy(zend_ast_get_str(method_ast));
 
        if (class_ast) {
-               method_ref->class_name = zend_resolve_class_name_ast(class_ast);
+               method_ref->class_name = zend_resolve_const_class_name_reference(class_ast, "trait name");
        } else {
                method_ref->class_name = NULL;
        }
@@ -6419,7 +6430,8 @@ static void zend_compile_trait_precedence(zend_ast *ast) /* {{{ */
 
        for (i = 0; i < insteadof_list->children; ++i) {
                zend_ast *name_ast = insteadof_list->child[i];
-               precedence->exclude_class_names[i] = zend_resolve_class_name_ast(name_ast);
+               precedence->exclude_class_names[i] =
+                       zend_resolve_const_class_name_reference(name_ast, "trait name");
        }
 
        zend_add_to_list(&CG(active_class_entry)->trait_precedences, precedence);
@@ -6513,15 +6525,8 @@ void zend_compile_implements(zend_ast *ast) /* {{{ */
 
        for (i = 0; i < list->children; ++i) {
                zend_ast *class_ast = list->child[i];
-               zend_string *name = zend_ast_get_str(class_ast);
-
-               if (!zend_is_const_default_class_ref(class_ast)) {
-                       efree(interface_names);
-                       zend_error_noreturn(E_COMPILE_ERROR,
-                               "Cannot use '%s' as interface name as it is reserved", ZSTR_VAL(name));
-               }
-
-               interface_names[i].name = zend_resolve_class_name_ast(class_ast);
+               interface_names[i].name =
+                       zend_resolve_const_class_name_reference(class_ast, "interface name");
                interface_names[i].lc_name = zend_string_tolower(interface_names[i].name);
        }
 
@@ -6605,23 +6610,8 @@ zend_op *zend_compile_class_decl(zend_ast *ast, zend_bool toplevel) /* {{{ */
        }
 
        if (extends_ast) {
-               znode extends_node;
-               zend_string *extends_name;
-
-               if (!zend_is_const_default_class_ref(extends_ast)) {
-                       extends_name = zend_ast_get_str(extends_ast);
-                       zend_error_noreturn(E_COMPILE_ERROR,
-                               "Cannot use '%s' as class name as it is reserved", ZSTR_VAL(extends_name));
-               }
-
-               zend_compile_expr(&extends_node, extends_ast);
-               if (extends_node.op_type != IS_CONST || Z_TYPE(extends_node.u.constant) != IS_STRING) {
-                       zend_error_noreturn(E_COMPILE_ERROR, "Illegal class name");
-               }
-               extends_name = Z_STR(extends_node.u.constant);
-               ce->parent_name = zend_resolve_class_name(extends_name,
-                                       extends_ast->kind == ZEND_AST_ZVAL ? extends_ast->attr : ZEND_NAME_FQ);
-               zend_string_release_ex(extends_name, 0);
+               ce->parent_name =
+                       zend_resolve_const_class_name_reference(extends_ast, "class name");
                ce->ce_flags |= ZEND_ACC_INHERITED;
        }
 
index f501527740598444d192e67a14ff52fb53fa5cc6..3d31ce03fe26c59acab5e7950d8f6bb7e6ccfe00 100644 (file)
@@ -249,7 +249,7 @@ static YYSIZE_T zend_yytnamerr(char*, const char*);
 %type <ast> echo_expr_list unset_variables catch_name_list catch_list parameter_list class_statement_list
 %type <ast> implements_list case_list if_stmt_without_else
 %type <ast> non_empty_parameter_list argument_list non_empty_argument_list property_list
-%type <ast> class_const_list class_const_decl name_list trait_adaptations method_body non_empty_for_exprs
+%type <ast> class_const_list class_const_decl class_name_list trait_adaptations method_body non_empty_for_exprs
 %type <ast> ctor_arguments alt_if_stmt_without_else trait_adaptation_list lexical_vars
 %type <ast> lexical_var_list encaps_list
 %type <ast> array_pair non_empty_array_pair_list array_pair_list possible_array_pair
@@ -469,8 +469,8 @@ catch_list:
 ;
 
 catch_name_list:
-               name { $$ = zend_ast_create_list(1, ZEND_AST_NAME_LIST, $1); }
-       |       catch_name_list '|' name { $$ = zend_ast_list_add($1, $3); }
+               class_name { $$ = zend_ast_create_list(1, ZEND_AST_NAME_LIST, $1); }
+       |       catch_name_list '|' class_name { $$ = zend_ast_list_add($1, $3); }
 ;
 
 finally_statement:
@@ -542,13 +542,13 @@ extends_from:
 ;
 
 interface_extends_list:
-               /* empty */                     { $$ = NULL; }
-       |       T_EXTENDS name_list     { $$ = $2; }
+               /* empty */                             { $$ = NULL; }
+       |       T_EXTENDS class_name_list       { $$ = $2; }
 ;
 
 implements_list:
-               /* empty */                             { $$ = NULL; }
-       |       T_IMPLEMENTS name_list  { $$ = $2; }
+               /* empty */                                     { $$ = NULL; }
+       |       T_IMPLEMENTS class_name_list    { $$ = $2; }
 ;
 
 foreach_variable:
@@ -732,7 +732,7 @@ class_statement:
                          $$->attr = $1; }
        |       method_modifiers T_CONST class_const_list ';'
                        { $$ = $3; $$->attr = $1; }
-       |       T_USE name_list trait_adaptations
+       |       T_USE class_name_list trait_adaptations
                        { $$ = zend_ast_create(ZEND_AST_USE_TRAIT, $2, $3); }
        |       method_modifiers function returns_ref identifier backup_doc_comment '(' parameter_list ')'
                return_type backup_fn_flags method_body backup_fn_flags
@@ -740,9 +740,9 @@ class_statement:
                                  zend_ast_get_str($4), $7, NULL, $11, $9); CG(extra_fn_flags) = $10; }
 ;
 
-name_list:
-               name { $$ = zend_ast_create_list(1, ZEND_AST_NAME_LIST, $1); }
-       |       name_list ',' name { $$ = zend_ast_list_add($1, $3); }
+class_name_list:
+               class_name { $$ = zend_ast_create_list(1, ZEND_AST_NAME_LIST, $1); }
+       |       class_name_list ',' class_name { $$ = zend_ast_list_add($1, $3); }
 ;
 
 trait_adaptations:
@@ -764,7 +764,7 @@ trait_adaptation:
 ;
 
 trait_precedence:
-       absolute_trait_method_reference T_INSTEADOF name_list
+       absolute_trait_method_reference T_INSTEADOF class_name_list
                { $$ = zend_ast_create(ZEND_AST_TRAIT_PRECEDENCE, $1, $3); }
 ;
 
@@ -786,7 +786,7 @@ trait_method_reference:
 ;
 
 absolute_trait_method_reference:
-       name T_PAAMAYIM_NEKUDOTAYIM identifier
+       class_name T_PAAMAYIM_NEKUDOTAYIM identifier
                { $$ = zend_ast_create(ZEND_AST_METHOD_REFERENCE, $1, $3); }
 ;