Skip to content

Commit d534496

Browse files
committed
Elide UB
1 parent fac58cd commit d534496

File tree

3 files changed

+40
-4
lines changed

3 files changed

+40
-4
lines changed

ext/standard/array.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1249,7 +1249,7 @@ PHP_FUNCTION(min)
12491249
min_lval = Z_LVAL(args[i]);
12501250
min = &args[i];
12511251
}
1252-
} else if (Z_TYPE(args[i]) == IS_DOUBLE && ((zend_long)(double) min_lval == min_lval)) {
1252+
} else if (Z_TYPE(args[i]) == IS_DOUBLE && (zend_dval_to_lval((double) min_lval) == min_lval)) {
12531253
min_dval = (double) min_lval;
12541254
goto double_compare;
12551255
} else {
@@ -1268,7 +1268,7 @@ PHP_FUNCTION(min)
12681268
min_dval = Z_DVAL(args[i]);
12691269
min = &args[i];
12701270
}
1271-
} else if (Z_TYPE(args[i]) == IS_LONG && ((zend_long)(double) Z_LVAL(args[i]) == Z_LVAL(args[i]))) {
1271+
} else if (Z_TYPE(args[i]) == IS_LONG && (zend_dval_to_lval((double) Z_LVAL(args[i])) == Z_LVAL(args[i]))) {
12721272
if (min_dval > (double)Z_LVAL(args[i])) {
12731273
min_dval = (double)Z_LVAL(args[i]);
12741274
min = &args[i];
@@ -1336,7 +1336,7 @@ PHP_FUNCTION(max)
13361336
max_lval = Z_LVAL(args[i]);
13371337
max = &args[i];
13381338
}
1339-
} else if (Z_TYPE(args[i]) == IS_DOUBLE && ((zend_long)(double) max_lval == max_lval)) {
1339+
} else if (Z_TYPE(args[i]) == IS_DOUBLE && (zend_dval_to_lval((double) max_lval) == max_lval)) {
13401340
max_dval = (double) max_lval;
13411341
goto double_compare;
13421342
} else {
@@ -1355,7 +1355,7 @@ PHP_FUNCTION(max)
13551355
max_dval = Z_DVAL(args[i]);
13561356
max = &args[i];
13571357
}
1358-
} else if (Z_TYPE(args[i]) == IS_LONG && ((zend_long)(double) Z_LVAL(args[i]) == Z_LVAL(args[i]))) {
1358+
} else if (Z_TYPE(args[i]) == IS_LONG && (zend_dval_to_lval((double) Z_LVAL(args[i])) == Z_LVAL(args[i]))) {
13591359
if (max_dval < (double)Z_LVAL(args[i])) {
13601360
max_dval = (double)Z_LVAL(args[i]);
13611361
max = &args[i];

ext/standard/tests/array/max_int_float_optimisation.phpt

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,13 @@ echo "Check that int not representable as float works:\n";
3131
var_dump(max(
3232
PHP_INT_MIN+1, PHP_INT_MIN, PHP_INT_MIN*2)
3333
);
34+
var_dump(max(
35+
PHP_INT_MAX-1, PHP_INT_MAX, PHP_INT_MAX*2)
36+
);
37+
// Has INF
38+
var_dump(max(
39+
PHP_INT_MAX-1, PHP_INT_MAX, PHP_INT_MAX**20)
40+
);
3441

3542
echo "Start as float optimisation:\n";
3643
var_dump(max(
@@ -58,6 +65,13 @@ echo "Check that int not representable as float works:\n";
5865
var_dump(max(
5966
PHP_INT_MIN*2, PHP_INT_MIN, PHP_INT_MIN+1)
6067
);
68+
var_dump(max(
69+
PHP_INT_MAX*2, PHP_INT_MAX, PHP_INT_MAX-1)
70+
);
71+
// Has INF
72+
var_dump(max(
73+
PHP_INT_MAX**20, PHP_INT_MAX, PHP_INT_MAX-1)
74+
);
6175

6276
?>
6377
--EXPECT--
@@ -71,6 +85,8 @@ int(10)
7185
string(2) "15"
7286
Check that int not representable as float works:
7387
int(-9223372036854775807)
88+
float(1.8446744073709552E+19)
89+
float(INF)
7490
Start as float optimisation:
7591
float(10.5)
7692
float(10.5)
@@ -81,3 +97,5 @@ float(10.5)
8197
string(4) "15.5"
8298
Check that int not representable as float works:
8399
int(-9223372036854775807)
100+
float(1.8446744073709552E+19)
101+
float(INF)

ext/standard/tests/array/min_int_float_optimisation.phpt

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,13 @@ echo "Check that int not representable as float works:\n";
3131
var_dump(min(
3232
PHP_INT_MAX-1, PHP_INT_MAX, PHP_INT_MAX*2)
3333
);
34+
var_dump(min(
35+
PHP_INT_MIN+1, PHP_INT_MIN, PHP_INT_MIN*2)
36+
);
37+
// Has INF
38+
var_dump(min(
39+
PHP_INT_MAX-1, PHP_INT_MAX, PHP_INT_MAX**20)
40+
);
3441

3542
echo "Start as float optimisation:\n";
3643
var_dump(min(
@@ -58,6 +65,13 @@ echo "Check that int not representable as float works:\n";
5865
var_dump(min(
5966
PHP_INT_MAX*2, PHP_INT_MAX, PHP_INT_MAX-1)
6067
);
68+
var_dump(min(
69+
PHP_INT_MIN*2, PHP_INT_MIN, PHP_INT_MIN+1)
70+
);
71+
// Has INF
72+
var_dump(min(
73+
PHP_INT_MAX**20, PHP_INT_MAX, PHP_INT_MAX-1)
74+
);
6175

6276
?>
6377
--EXPECT--
@@ -71,6 +85,8 @@ int(2)
7185
string(1) "1"
7286
Check that int not representable as float works:
7387
int(9223372036854775806)
88+
float(-1.8446744073709552E+19)
89+
int(9223372036854775806)
7490
Start as float optimisation:
7591
float(2.5)
7692
float(2.5)
@@ -81,3 +97,5 @@ float(2.5)
8197
string(3) "1.5"
8298
Check that int not representable as float works:
8399
int(9223372036854775806)
100+
float(-1.8446744073709552E+19)
101+
int(9223372036854775806)

0 commit comments

Comments
 (0)