Skip to content

Commit cff8da5

Browse files
committed
zend_compile: Fix leak of unused result in array_map() optimization
1 parent 635b9d2 commit cff8da5

File tree

5 files changed

+67
-10
lines changed

5 files changed

+67
-10
lines changed

Zend/zend_compile.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5090,7 +5090,7 @@ static zend_result zend_compile_func_array_map(znode *result, zend_ast_list *arg
50905090
Z_EXTRA_P(CT_CONSTANT(opline->op1)) = fbc_bucket - CG(function_table)->arData;
50915091

50925092
/* Initialize the result array. */
5093-
zend_emit_op(result, ZEND_INIT_ARRAY, NULL, NULL);
5093+
zend_emit_op_tmp(result, ZEND_INIT_ARRAY, NULL, NULL);
50945094

50955095
/* foreach loop starts here. */
50965096
znode key;

ext/standard/tests/array/array_map_foreach_optimization_001.phpt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,16 +31,16 @@ $_main:
3131
0003 V2 = DO_ICALL
3232
0004 ASSIGN CV0($array) V2
3333
0005 TYPE_ASSERT 131079 string("array_map") CV0($array)
34-
0006 V2 = INIT_ARRAY 0 (packed) NEXT
34+
0006 T2 = INIT_ARRAY 0 (packed) NEXT
3535
0007 V3 = FE_RESET_R CV0($array) 0014
3636
0008 T5 = FE_FETCH_R V3 T4 0014
3737
0009 INIT_FCALL 1 %d string("plus1")
3838
0010 SEND_VAL T4 1
3939
0011 V4 = DO_UCALL
40-
0012 V2 = ADD_ARRAY_ELEMENT V4 T5
40+
0012 T2 = ADD_ARRAY_ELEMENT V4 T5
4141
0013 JMP 0008
4242
0014 FE_FREE V3
43-
0015 ASSIGN CV1($foo) V2
43+
0015 ASSIGN CV1($foo) T2
4444
0016 INIT_FCALL 1 %d string("var_dump")
4545
0017 SEND_VAR CV1($foo) 1
4646
0018 DO_ICALL

ext/standard/tests/array/array_map_foreach_optimization_002.phpt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,16 +37,16 @@ $_main:
3737
0006 SEND_VAR%S CV0($array) 1
3838
0007 DO_FCALL
3939
0008 TYPE_ASSERT 131079 string("array_map") V5
40-
0009 V2 = INIT_ARRAY 0 (packed) NEXT
40+
0009 T2 = INIT_ARRAY 0 (packed) NEXT
4141
0010 V3 = FE_RESET_R V5 0017
4242
0011 T5 = FE_FETCH_R V3 T4 0017
4343
0012 INIT_FCALL 1 %d string("plus1")
4444
0013 SEND_VAL T4 1
4545
0014 V4 = DO_UCALL
46-
0015 V2 = ADD_ARRAY_ELEMENT V4 T5
46+
0015 T2 = ADD_ARRAY_ELEMENT V4 T5
4747
0016 JMP 0011
4848
0017 FE_FREE V3
49-
0018 ASSIGN CV1($foo) V2
49+
0018 ASSIGN CV1($foo) T2
5050
0019 INIT_FCALL 1 %d string("var_dump")
5151
0020 SEND_VAR CV1($foo) 1
5252
0021 DO_ICALL

ext/standard/tests/array/array_map_foreach_optimization_003.phpt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,16 +24,16 @@ $_main:
2424
; (after optimizer)
2525
; %s
2626
0000 TYPE_ASSERT 131079 string("array_map") array(...)
27-
0001 V1 = INIT_ARRAY 0 (packed) NEXT
27+
0001 T1 = INIT_ARRAY 0 (packed) NEXT
2828
0002 V2 = FE_RESET_R array(...) 0009
2929
0003 T4 = FE_FETCH_R V2 T3 0009
3030
0004 INIT_FCALL 1 %d string("plus1")
3131
0005 SEND_VAL T3 1
3232
0006 V3 = DO_UCALL
33-
0007 V1 = ADD_ARRAY_ELEMENT V3 T4
33+
0007 T1 = ADD_ARRAY_ELEMENT V3 T4
3434
0008 JMP 0003
3535
0009 FE_FREE V2
36-
0010 ASSIGN CV0($foo) V1
36+
0010 ASSIGN CV0($foo) T1
3737
0011 INIT_FCALL 1 %d string("var_dump")
3838
0012 SEND_VAR CV0($foo) 1
3939
0013 DO_ICALL
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
--TEST--
2+
array_map(): foreach optimization - unused refcounted result
3+
--EXTENSIONS--
4+
opcache
5+
--INI--
6+
opcache.enable=1
7+
opcache.enable_cli=1
8+
opcache.opt_debug_level=0x20000
9+
--FILE--
10+
<?php
11+
12+
function stdClass() {
13+
return new stdClass();
14+
}
15+
16+
$array = range(1, 10);
17+
18+
array_map(stdClass(...), $array);
19+
20+
?>
21+
--EXPECTF--
22+
$_main:
23+
; (lines=%d, args=0, vars=%d, tmps=%d)
24+
; (after optimizer)
25+
; %s
26+
0000 INIT_FCALL 2 %d string("range")
27+
0001 SEND_VAL int(1) 1
28+
0002 SEND_VAL int(10) 2
29+
0003 V1 = DO_ICALL
30+
0004 ASSIGN CV0($array) V1
31+
0005 TYPE_ASSERT 131079 string("array_map") CV0($array)
32+
0006 T1 = INIT_ARRAY 0 (packed) NEXT
33+
0007 V2 = FE_RESET_R CV0($array) 0014
34+
0008 T4 = FE_FETCH_R V2 T3 0014
35+
0009 INIT_FCALL 1 %d string("stdclass")
36+
0010 SEND_VAL T3 1
37+
0011 V3 = DO_UCALL
38+
0012 T1 = ADD_ARRAY_ELEMENT V3 T4
39+
0013 JMP 0008
40+
0014 FE_FREE V2
41+
0015 FREE T1
42+
0016 RETURN int(1)
43+
LIVE RANGES:
44+
1: 0007 - 0015 (tmp/var)
45+
2: 0008 - 0014 (loop)
46+
3: 0009 - 0010 (tmp/var)
47+
4: 0009 - 0012 (tmp/var)
48+
49+
stdClass:
50+
; (lines=3, args=0, vars=0, tmps=1)
51+
; (after optimizer)
52+
; %s
53+
0000 V0 = NEW 0 string("stdClass")
54+
0001 DO_FCALL
55+
0002 RETURN V0
56+
LIVE RANGES:
57+
0: 0001 - 0002 (new)

0 commit comments

Comments
 (0)