Skip to content

Commit 78760f1

Browse files
Implemented FR #6768 (list() construct reference assignment)
1 parent e68c1ef commit 78760f1

4 files changed

Lines changed: 43 additions & 8 deletions

File tree

‎Zend/tests/list_008.phpt‎

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
--TEST--
2+
Request #6768 (list() construct reference assignment)
3+
--FILE--
4+
<?php
5+
6+
$arr = [1, 2, [3, 4]];
7+
8+
list(&$a, $b, list(&$c, $d)) = $arr;
9+
10+
list($a, $b, $c, $d) = [4, 3, 2, 1];
11+
12+
var_dump($arr);
13+
--EXPECT--
14+
array(3) {
15+
[0]=>
16+
&int(4)
17+
[1]=>
18+
int(2)
19+
[2]=>
20+
array(2) {
21+
[0]=>
22+
&int(2)
23+
[1]=>
24+
int(4)
25+
}
26+
}
27+

‎Zend/zend_compile.c‎

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5806,14 +5806,15 @@ void zend_do_add_static_array_element(znode *result, znode *offset, const znode
58065806
}
58075807
/* }}} */
58085808

5809-
void zend_do_add_list_element(const znode *element TSRMLS_DC) /* {{{ */
5809+
void zend_do_add_list_element(const znode *element, zend_bool by_ref TSRMLS_DC) /* {{{ */
58105810
{
58115811
list_llist_element lle;
58125812

58135813
if (element) {
58145814
zend_check_writable_variable(element);
58155815

58165816
lle.var = *element;
5817+
lle.by_ref = by_ref;
58175818
zend_llist_copy(&lle.dimensions, &CG(dimension_llist));
58185819
zend_llist_prepend_element(&CG(list_llist), &lle);
58195820
}
@@ -5854,7 +5855,8 @@ void zend_do_list_end(znode *result, znode *expr TSRMLS_DC) /* {{{ */
58545855

58555856
le = CG(list_llist).head;
58565857
while (le) {
5857-
zend_llist *tmp_dimension_llist = &((list_llist_element *)le->data)->dimensions;
5858+
list_llist_element *ld = (list_llist_element *) le->data;
5859+
zend_llist *tmp_dimension_llist = &ld->dimensions;
58585860
dimension = tmp_dimension_llist->head;
58595861
while (dimension) {
58605862
opline = get_next_op(CG(active_op_array) TSRMLS_CC);
@@ -5885,9 +5887,13 @@ void zend_do_list_end(znode *result, znode *expr TSRMLS_DC) /* {{{ */
58855887
GET_NODE(&last_container, opline->result);
58865888
dimension = dimension->next;
58875889
}
5888-
((list_llist_element *) le->data)->value = last_container;
5889-
zend_llist_destroy(&((list_llist_element *) le->data)->dimensions);
5890-
zend_do_assign(result, &((list_llist_element *) le->data)->var, &((list_llist_element *) le->data)->value TSRMLS_CC);
5890+
ld->value = last_container;
5891+
zend_llist_destroy(&ld->dimensions);
5892+
if (ld->by_ref) {
5893+
zend_do_assign_ref(result, &ld->var, &ld->value TSRMLS_CC);
5894+
} else {
5895+
zend_do_assign(result, &ld->var, &ld->value TSRMLS_CC);
5896+
}
58915897
zend_do_free(result TSRMLS_CC);
58925898
le = le->next;
58935899
}

‎Zend/zend_compile.h‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,7 @@ typedef struct _list_llist_element {
370370
znode var;
371371
zend_llist dimensions;
372372
znode value;
373+
zend_bool by_ref;
373374
} list_llist_element;
374375

375376
union _temp_variable;
@@ -586,7 +587,7 @@ void zend_do_add_array_element(znode *result, const znode *expr, const znode *of
586587
void zend_do_add_static_array_element(znode *result, znode *offset, const znode *expr);
587588
void zend_do_list_init(TSRMLS_D);
588589
void zend_do_list_end(znode *result, znode *expr TSRMLS_DC);
589-
void zend_do_add_list_element(const znode *element TSRMLS_DC);
590+
void zend_do_add_list_element(const znode *element, zend_bool by_ref TSRMLS_DC);
590591
void zend_do_new_list_begin(TSRMLS_D);
591592
void zend_do_new_list_end(TSRMLS_D);
592593

‎Zend/zend_language_parser.y‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1136,9 +1136,10 @@ assignment_list:
11361136

11371137

11381138
assignment_list_element:
1139-
variable { zend_do_add_list_element(&$1 TSRMLS_CC); }
1139+
variable { zend_do_add_list_element(&$1, 0 TSRMLS_CC); }
1140+
| '&' variable { zend_do_add_list_element(&$2, 1 TSRMLS_CC); }
11401141
| T_LIST '(' { zend_do_new_list_begin(TSRMLS_C); } assignment_list ')' { zend_do_new_list_end(TSRMLS_C); }
1141-
| /* empty */ { zend_do_add_list_element(NULL TSRMLS_CC); }
1142+
| /* empty */ { zend_do_add_list_element(NULL, 0 TSRMLS_CC); }
11421143
;
11431144

11441145

0 commit comments

Comments
 (0)