Skip to content

Commit 897bdb4

Browse files
pmmaganikic
authored andcommitted
Fix #74922 - Try to resolve constants when importing trait properties
1 parent b27a6b1 commit 897bdb4

File tree

7 files changed

+99
-8
lines changed

7 files changed

+99
-8
lines changed

NEWS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ PHP NEWS
1414
(andrewnester)
1515
. Fixed bug #69954 (broken links and unused config items in distributed ini
1616
files). (petk)
17+
. Fixed bug #74922 (Composed class has fatal error with duplicate, equal const
18+
properties). (pmmaga)
1719

1820
- BCMath:
1921
. Fixed bug #66364 (BCMath bcmul ignores scale parameter). (cmb)

Zend/tests/traits/bug74922.phpt

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
--TEST--
2+
Bug #74922 (Composed class has fatal error with duplicate, equal const properties)
3+
--FILE--
4+
<?php
5+
6+
const VALUE = true;
7+
8+
trait Foo {public $var = VALUE;}
9+
trait Bar {public $var = VALUE;}
10+
class Baz {use Foo, Bar;}
11+
12+
echo "DONE";
13+
14+
?>
15+
--EXPECT--
16+
DONE

Zend/tests/traits/bug74922a.phpt

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
--TEST--
2+
Bug #74922 (Composed class has fatal error with duplicate, equal const properties)
3+
--FILE--
4+
<?php
5+
6+
const VALUE = true;
7+
8+
trait Foo {public $var = VALUE;}
9+
trait Bar {public $var = true;}
10+
class Baz {use Foo, Bar;}
11+
12+
echo "DONE";
13+
14+
?>
15+
--EXPECT--
16+
DONE

Zend/tests/traits/bug74922b.inc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?php
2+
3+
namespace Bug74922;
4+
5+
const FOO = 'foo';
6+
7+
trait T1 {
8+
public $var = FOO;
9+
}

Zend/tests/traits/bug74922b.phpt

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
--TEST--
2+
Bug #74922 (Composed class has fatal error with duplicate, equal const properties)
3+
--FILE--
4+
<?php
5+
6+
require('bug74922b.inc');
7+
8+
trait T2 {public $var = Bug74922\FOO;}
9+
class Baz {use Bug74922\T1, T2;}
10+
11+
echo "DONE";
12+
13+
?>
14+
--EXPECT--
15+
DONE

Zend/tests/traits/bug74922c.phpt

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
--TEST--
2+
Bug #74922 (Composed class has fatal error with duplicate, equal const properties)
3+
--FILE--
4+
<?php
5+
6+
trait T {
7+
public $x = self::X;
8+
}
9+
trait T2 {
10+
public $x = self::X;
11+
}
12+
class C {
13+
use T, T2;
14+
const X = 42;
15+
}
16+
var_dump((new C)->x);
17+
18+
?>
19+
--EXPECT--
20+
int(42)

Zend/zend_inheritance.c

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1584,19 +1584,32 @@ static void zend_do_traits_property_binding(zend_class_entry *ce) /* {{{ */
15841584
zend_hash_del(&ce->properties_info, prop_name);
15851585
flags |= ZEND_ACC_CHANGED;
15861586
} else {
1587+
not_compatible = 1;
1588+
15871589
if ((coliding_prop->flags & (ZEND_ACC_PPP_MASK | ZEND_ACC_STATIC))
15881590
== (flags & (ZEND_ACC_PPP_MASK | ZEND_ACC_STATIC))) {
1589-
/* flags are identical, now the value needs to be checked */
1591+
/* the flags are identical, thus, the properties may be compatible */
1592+
zval op1, op2;
1593+
15901594
if (flags & ZEND_ACC_STATIC) {
1591-
not_compatible = fast_is_not_identical_function(&ce->default_static_members_table[coliding_prop->offset],
1592-
&ce->traits[i]->default_static_members_table[property_info->offset]);
1595+
ZVAL_COPY_OR_DUP(&op1, &ce->default_static_members_table[coliding_prop->offset]);
1596+
ZVAL_COPY_OR_DUP(&op2, &ce->traits[i]->default_static_members_table[property_info->offset]);
15931597
} else {
1594-
not_compatible = fast_is_not_identical_function(&ce->default_properties_table[OBJ_PROP_TO_NUM(coliding_prop->offset)],
1595-
&ce->traits[i]->default_properties_table[OBJ_PROP_TO_NUM(property_info->offset)]);
1598+
ZVAL_COPY_OR_DUP(&op1, &ce->default_properties_table[OBJ_PROP_TO_NUM(coliding_prop->offset)]);
1599+
ZVAL_COPY_OR_DUP(&op2, &ce->traits[i]->default_properties_table[OBJ_PROP_TO_NUM(property_info->offset)]);
15961600
}
1597-
} else {
1598-
/* the flags are not identical, thus, we assume properties are not compatible */
1599-
not_compatible = 1;
1601+
1602+
/* if any of the values is a constant, we try to resolve it */
1603+
if (UNEXPECTED(Z_TYPE(op1) == IS_CONSTANT_AST)) {
1604+
zval_update_constant_ex(&op1, ce);
1605+
}
1606+
if (UNEXPECTED(Z_TYPE(op2) == IS_CONSTANT_AST)) {
1607+
zval_update_constant_ex(&op2, ce);
1608+
}
1609+
1610+
not_compatible = fast_is_not_identical_function(&op1, &op2);
1611+
zval_ptr_dtor_nogc(&op1);
1612+
zval_ptr_dtor_nogc(&op2);
16001613
}
16011614

16021615
if (not_compatible) {

0 commit comments

Comments
 (0)