Skip to content

Commit 6249b46

Browse files
committed
Merge branch 'PHP-8.6'
* PHP-8.6: Fix GH-24063: SCCP merges 0.0 and -0.0 into a single constant (#24064)
2 parents 1b2bde4 + 38b2036 commit 6249b46

2 files changed

Lines changed: 70 additions & 2 deletions

File tree

‎Zend/Optimizer/sccp.c‎

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1951,6 +1951,28 @@ static void sccp_mark_feasible_successors(
19511951
scdf_mark_edge_feasible(scdf, block_num, block->successors[s]);
19521952
}
19531953

1954+
/* Unlike zend_is_identical(), this does not treat 0.0 and -0.0 as the same value.
1955+
* Returns int to be usable as compare_func_t. */
1956+
static int sccp_values_differ(const void *p1, const void *p2)
1957+
{
1958+
const zval *a = p1;
1959+
const zval *b = p2;
1960+
1961+
if (Z_TYPE_P(a) != Z_TYPE_P(b)) {
1962+
return 1;
1963+
}
1964+
if (Z_TYPE_P(a) == IS_DOUBLE) {
1965+
return memcmp(&Z_DVAL_P(a), &Z_DVAL_P(b), sizeof(double)) != 0;
1966+
}
1967+
if (Z_TYPE_P(a) == IS_ARRAY) {
1968+
return Z_ARRVAL_P(a) != Z_ARRVAL_P(b)
1969+
&& zend_hash_compare(Z_ARRVAL_P(a), Z_ARRVAL_P(b), sccp_values_differ, 1) != 0;
1970+
}
1971+
ZEND_ASSERT(IS_PARTIAL_ARRAY(a) || IS_PARTIAL_OBJECT(a)
1972+
|| ((1 << Z_TYPE_P(a)) & (MAY_BE_UNDEF|MAY_BE_NULL|MAY_BE_BOOL|MAY_BE_LONG|MAY_BE_STRING)));
1973+
return !zend_is_identical(a, b);
1974+
}
1975+
19541976
static void join_hash_tables(HashTable *ret, const HashTable *ht1, const HashTable *ht2)
19551977
{
19561978
zend_ulong index;
@@ -1963,7 +1985,7 @@ static void join_hash_tables(HashTable *ret, const HashTable *ht1, const HashTab
19631985
} else {
19641986
val2 = zend_hash_index_find(ht2, index);
19651987
}
1966-
if (val2 && zend_is_identical(val1, val2)) {
1988+
if (val2 && !sccp_values_differ(val1, val2)) {
19671989
if (key) {
19681990
val1 = zend_hash_add_new(ret, key, val1);
19691991
} else {
@@ -2031,7 +2053,7 @@ static void join_phi_values(zval *a, const zval *b, bool escape) {
20312053
zval_ptr_dtor_nogc(a);
20322054
MAKE_BOT(a);
20332055
}
2034-
} else if (!zend_is_identical(a, b)) {
2056+
} else if (sccp_values_differ(a, b)) {
20352057
if (join_partial_arrays(a, b) == FAILURE) {
20362058
zval_ptr_dtor_nogc(a);
20372059
MAKE_BOT(a);

‎ext/opcache/tests/opt/gh24063.phpt‎

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
--TEST--
2+
GH-24063 (SCCP merges 0.0 and -0.0 into a single constant)
3+
--EXTENSIONS--
4+
opcache
5+
--INI--
6+
opcache.enable=1
7+
opcache.enable_cli=1
8+
opcache.optimization_level=-1
9+
--FILE--
10+
<?php
11+
12+
function scalar(float $n): float
13+
{
14+
$r = $n < 0 ? -0.0 : 0.0;
15+
return $r;
16+
}
17+
18+
function arr(float $n): array
19+
{
20+
$r = $n < 0 ? [-0.0] : [0.0];
21+
return $r;
22+
}
23+
24+
function partial(float $n, $x): float
25+
{
26+
$a = ['x' => $x];
27+
if ($n < 0) {
28+
$a['k'] = -0.0;
29+
} else {
30+
$a['k'] = 0.0;
31+
}
32+
return $a['k'];
33+
}
34+
35+
var_dump(scalar(1.0), scalar(-1.0));
36+
var_dump(arr(1.0)[0], arr(-1.0)[0]);
37+
var_dump(partial(1.0, 1), partial(-1.0, 1));
38+
39+
?>
40+
--EXPECT--
41+
float(0)
42+
float(-0)
43+
float(0)
44+
float(-0)
45+
float(0)
46+
float(-0)

0 commit comments

Comments
 (0)