Skip to content

Commit f29972a

Browse files
committed
start keeping track of own nested classes
1 parent 64f1bb5 commit f29972a

File tree

7 files changed

+52
-1
lines changed

7 files changed

+52
-1
lines changed

Zend/zend.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,7 @@ struct _zend_class_entry {
210210
uint32_t num_traits;
211211
uint32_t num_hooked_props;
212212
uint32_t num_hooked_prop_variance_checks;
213+
uint32_t num_nested_classes;
213214

214215
/* class_entry or string(s) depending on ZEND_ACC_LINKED */
215216
union {
@@ -218,6 +219,7 @@ struct _zend_class_entry {
218219
};
219220

220221
zend_class_name *trait_names;
222+
zend_class_entry **nested_classes;
221223
zend_trait_alias **trait_aliases;
222224
zend_trait_precedence **trait_precedences;
223225
HashTable *attributes;

Zend/zend_compile.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2201,6 +2201,8 @@ ZEND_API void zend_initialize_class_data(zend_class_entry *ce, bool nullify_hand
22012201
ce->trait_names = NULL;
22022202
ce->trait_aliases = NULL;
22032203
ce->trait_precedences = NULL;
2204+
ce->num_nested_classes = 0;
2205+
ce->nested_classes = NULL;
22042206
ce->serialize = NULL;
22052207
ce->unserialize = NULL;
22062208
if (ce->type == ZEND_INTERNAL_CLASS) {
@@ -9220,6 +9222,9 @@ static void zend_compile_class_decl(znode *result, zend_ast *ast, bool toplevel)
92209222
ce->required_scope = propFlags & (ZEND_ACC_PRIVATE | ZEND_ACC_PROTECTED) ? CG(active_class_entry) : NULL;
92219223
ce->required_scope_absolute = propFlags & ZEND_ACC_PRIVATE ? true : false;
92229224
ce->lexical_scope = CG(active_class_entry);
9225+
ce->lexical_scope->nested_classes =
9226+
erealloc(ce->lexical_scope->nested_classes, sizeof(zend_class_entry *) * (ce->lexical_scope->num_nested_classes + 1));
9227+
ce->lexical_scope->nested_classes[ce->lexical_scope->num_nested_classes++] = ce;
92239228
} else {
92249229
name = zend_prefix_with_ns(unqualified_name);
92259230
ce->required_scope = NULL;

Zend/zend_opcode.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -366,6 +366,8 @@ ZEND_API void destroy_zend_class(zval *zv)
366366
}
367367
}
368368

369+
efree(ce->nested_classes);
370+
369371
if (ce->default_properties_table) {
370372
zval *p = ce->default_properties_table;
371373
zval *end = p + ce->default_properties_count;

tests/classes/inner_classes/inheritance.phpt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
--TEST--
22
circular inheritance
3+
--SKIPIF--
4+
<?php
5+
if (!extension_loaded('opcache')) {
6+
die('skip opcache required');
7+
}
8+
?>
39
--FILE--
410
<?php
511

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
--TEST--
2+
resolution of outer scopes
3+
--FILE--
4+
<?php
5+
6+
class Outside {}
7+
8+
class Outer {
9+
class Inner extends Outside {}
10+
}
11+
12+
echo (new Outer\Inner) instanceof Outside;
13+
?>
14+
--EXPECT--
15+
1
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
--TEST--
2+
shadowing
3+
--FILE--
4+
<?php
5+
6+
namespace Foo\Bar;
7+
8+
class Outside {}
9+
10+
class Outer {
11+
class Outside {}
12+
class Inner extends Outside {}
13+
class Middle extends \Foo\Bar\Outside {}
14+
}
15+
16+
echo Outer\Inner::class . ': ' . (new Outer\Inner()) instanceof Outer\Outside . "\n";
17+
echo Outer\Middle::class . ': ' . (new Outer\Middle()) instanceof Outside . "\n";
18+
?>
19+
--EXPECT--
20+
Foo\Bar\Outer\Inner: 1
21+
Foo\Bar\Outer\Middle: 1

tests/classes/inner_classes/simple_declaration_005.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,4 @@ var_dump(Outer2::testSelf());
3131

3232
?>
3333
--EXPECTF--
34-
Fatal error: Declaration of Outer2::testSelf(): Outer2\middle must be compatible with Outer::testSelf(): Outer\middle in %s on line %d
34+
Fatal error: Declaration of Outer2::testSelf(): Outer2\Middle must be compatible with Outer::testSelf(): Outer\Middle in %s on line %d

0 commit comments

Comments
 (0)