mirror of
https://github.com/php/php-src.git
synced 2025-08-16 05:58:45 +02:00
Merge branch 'PHP-8.0' into PHP-8.1
* PHP-8.0: Remove range inference for booleans.
This commit is contained in:
commit
cfcee97ad6
3 changed files with 28 additions and 163 deletions
|
@ -1041,8 +1041,6 @@ static int zend_inference_calc_range(const zend_op_array *op_array, zend_ssa *ss
|
||||||
|
|
||||||
ZEND_API int zend_inference_propagate_range(const zend_op_array *op_array, zend_ssa *ssa, zend_op *opline, zend_ssa_op* ssa_op, int var, zend_ssa_range *tmp)
|
ZEND_API int zend_inference_propagate_range(const zend_op_array *op_array, zend_ssa *ssa, zend_op *opline, zend_ssa_op* ssa_op, int var, zend_ssa_range *tmp)
|
||||||
{
|
{
|
||||||
zend_long op1_min, op2_min, op1_max, op2_max;
|
|
||||||
|
|
||||||
tmp->underflow = 0;
|
tmp->underflow = 0;
|
||||||
tmp->overflow = 0;
|
tmp->overflow = 0;
|
||||||
switch (opline->opcode) {
|
switch (opline->opcode) {
|
||||||
|
@ -1070,8 +1068,8 @@ ZEND_API int zend_inference_propagate_range(const zend_op_array *op_array, zend_
|
||||||
tmp->min = ZEND_LONG_MIN;
|
tmp->min = ZEND_LONG_MIN;
|
||||||
tmp->max = ZEND_LONG_MAX;
|
tmp->max = ZEND_LONG_MAX;
|
||||||
} else {
|
} else {
|
||||||
op1_min = OP1_MIN_RANGE();
|
zend_long op1_min = OP1_MIN_RANGE();
|
||||||
op1_max = OP1_MAX_RANGE();
|
zend_long op1_max = OP1_MAX_RANGE();
|
||||||
tmp->min = ~op1_max;
|
tmp->min = ~op1_max;
|
||||||
tmp->max = ~op1_min;
|
tmp->max = ~op1_min;
|
||||||
}
|
}
|
||||||
|
@ -1104,144 +1102,6 @@ ZEND_API int zend_inference_propagate_range(const zend_op_array *op_array, zend_
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ZEND_BOOL:
|
|
||||||
case ZEND_JMPZ_EX:
|
|
||||||
case ZEND_JMPNZ_EX:
|
|
||||||
if (ssa_op->result_def == var) {
|
|
||||||
if (OP1_HAS_RANGE()) {
|
|
||||||
op1_min = OP1_MIN_RANGE();
|
|
||||||
op1_max = OP1_MAX_RANGE();
|
|
||||||
tmp->min = (op1_min > 0 || op1_max < 0);
|
|
||||||
tmp->max = (op1_min != 0 || op1_max != 0);
|
|
||||||
return 1;
|
|
||||||
} else {
|
|
||||||
tmp->min = 0;
|
|
||||||
tmp->max = 1;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case ZEND_BOOL_NOT:
|
|
||||||
if (ssa_op->result_def == var) {
|
|
||||||
if (OP1_HAS_RANGE()) {
|
|
||||||
op1_min = OP1_MIN_RANGE();
|
|
||||||
op1_max = OP1_MAX_RANGE();
|
|
||||||
tmp->min = (op1_min == 0 && op1_max == 0);
|
|
||||||
tmp->max = (op1_min <= 0 && op1_max >= 0);
|
|
||||||
return 1;
|
|
||||||
} else {
|
|
||||||
tmp->min = 0;
|
|
||||||
tmp->max = 1;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case ZEND_BOOL_XOR:
|
|
||||||
if (ssa_op->result_def == var) {
|
|
||||||
if (OP1_HAS_RANGE() && OP2_HAS_RANGE()) {
|
|
||||||
op1_min = OP1_MIN_RANGE();
|
|
||||||
op2_min = OP2_MIN_RANGE();
|
|
||||||
op1_max = OP1_MAX_RANGE();
|
|
||||||
op2_max = OP2_MAX_RANGE();
|
|
||||||
op1_min = (op1_min > 0 || op1_max < 0);
|
|
||||||
op1_max = (op1_min != 0 || op1_max != 0);
|
|
||||||
op2_min = (op2_min > 0 || op2_max < 0);
|
|
||||||
op2_max = (op2_min != 0 || op2_max != 0);
|
|
||||||
tmp->min = 0;
|
|
||||||
tmp->max = 1;
|
|
||||||
if (op1_min == op1_max && op2_min == op2_max) {
|
|
||||||
if (op1_min == op2_min) {
|
|
||||||
tmp->max = 0;
|
|
||||||
} else {
|
|
||||||
tmp->min = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
} else {
|
|
||||||
tmp->min = 0;
|
|
||||||
tmp->max = 1;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case ZEND_IS_IDENTICAL:
|
|
||||||
case ZEND_IS_EQUAL:
|
|
||||||
if (ssa_op->result_def == var) {
|
|
||||||
if (OP1_HAS_RANGE() && OP2_HAS_RANGE()) {
|
|
||||||
op1_min = OP1_MIN_RANGE();
|
|
||||||
op2_min = OP2_MIN_RANGE();
|
|
||||||
op1_max = OP1_MAX_RANGE();
|
|
||||||
op2_max = OP2_MAX_RANGE();
|
|
||||||
|
|
||||||
tmp->min = (op1_min == op1_max &&
|
|
||||||
op2_min == op2_max &&
|
|
||||||
op1_min == op2_max);
|
|
||||||
tmp->max = (op1_min <= op2_max && op1_max >= op2_min);
|
|
||||||
return 1;
|
|
||||||
} else {
|
|
||||||
tmp->min = 0;
|
|
||||||
tmp->max = 1;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case ZEND_IS_NOT_IDENTICAL:
|
|
||||||
case ZEND_IS_NOT_EQUAL:
|
|
||||||
if (ssa_op->result_def == var) {
|
|
||||||
if (OP1_HAS_RANGE() && OP2_HAS_RANGE()) {
|
|
||||||
op1_min = OP1_MIN_RANGE();
|
|
||||||
op2_min = OP2_MIN_RANGE();
|
|
||||||
op1_max = OP1_MAX_RANGE();
|
|
||||||
op2_max = OP2_MAX_RANGE();
|
|
||||||
|
|
||||||
tmp->min = (op1_min > op2_max || op1_max < op2_min);
|
|
||||||
tmp->max = (op1_min != op1_max ||
|
|
||||||
op2_min != op2_max ||
|
|
||||||
op1_min != op2_max);
|
|
||||||
return 1;
|
|
||||||
} else {
|
|
||||||
tmp->min = 0;
|
|
||||||
tmp->max = 1;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case ZEND_IS_SMALLER:
|
|
||||||
if (ssa_op->result_def == var) {
|
|
||||||
if (OP1_HAS_RANGE() && OP2_HAS_RANGE()) {
|
|
||||||
op1_min = OP1_MIN_RANGE();
|
|
||||||
op2_min = OP2_MIN_RANGE();
|
|
||||||
op1_max = OP1_MAX_RANGE();
|
|
||||||
op2_max = OP2_MAX_RANGE();
|
|
||||||
|
|
||||||
tmp->min = op1_max < op2_min;
|
|
||||||
tmp->max = op1_min < op2_max;
|
|
||||||
return 1;
|
|
||||||
} else {
|
|
||||||
tmp->min = 0;
|
|
||||||
tmp->max = 1;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case ZEND_IS_SMALLER_OR_EQUAL:
|
|
||||||
if (ssa_op->result_def == var) {
|
|
||||||
if (OP1_HAS_RANGE() && OP2_HAS_RANGE()) {
|
|
||||||
op1_min = OP1_MIN_RANGE();
|
|
||||||
op2_min = OP2_MIN_RANGE();
|
|
||||||
op1_max = OP1_MAX_RANGE();
|
|
||||||
op2_max = OP2_MAX_RANGE();
|
|
||||||
|
|
||||||
tmp->min = op1_max <= op2_min;
|
|
||||||
tmp->max = op1_min <= op2_max;
|
|
||||||
return 1;
|
|
||||||
} else {
|
|
||||||
tmp->min = 0;
|
|
||||||
tmp->max = 1;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case ZEND_QM_ASSIGN:
|
case ZEND_QM_ASSIGN:
|
||||||
case ZEND_JMP_SET:
|
case ZEND_JMP_SET:
|
||||||
case ZEND_COALESCE:
|
case ZEND_COALESCE:
|
||||||
|
@ -1267,13 +1127,6 @@ ZEND_API int zend_inference_propagate_range(const zend_op_array *op_array, zend_
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ZEND_ASSERT_CHECK:
|
|
||||||
if (ssa_op->result_def == var) {
|
|
||||||
tmp->min = 0;
|
|
||||||
tmp->max = 1;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case ZEND_SEND_VAR:
|
case ZEND_SEND_VAR:
|
||||||
if (ssa_op->op1_def == var) {
|
if (ssa_op->op1_def == var) {
|
||||||
if (ssa_op->op1_def >= 0) {
|
if (ssa_op->op1_def >= 0) {
|
||||||
|
@ -1454,12 +1307,6 @@ ZEND_API int zend_inference_propagate_range(const zend_op_array *op_array, zend_
|
||||||
tmp->max = ZEND_LONG_MAX;
|
tmp->max = ZEND_LONG_MAX;
|
||||||
tmp->overflow = 0;
|
tmp->overflow = 0;
|
||||||
return 1;
|
return 1;
|
||||||
} else if (mask == MAY_BE_BOOL) {
|
|
||||||
tmp->underflow = 0;
|
|
||||||
tmp->min = 0;
|
|
||||||
tmp->max = 1;
|
|
||||||
tmp->overflow = 0;
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -334,10 +334,6 @@ static void place_essa_pis(
|
||||||
|
|
||||||
if (Z_TYPE_P(zv) == IS_LONG) {
|
if (Z_TYPE_P(zv) == IS_LONG) {
|
||||||
add_val2 = Z_LVAL_P(zv);
|
add_val2 = Z_LVAL_P(zv);
|
||||||
} else if (Z_TYPE_P(zv) == IS_FALSE) {
|
|
||||||
add_val2 = 0;
|
|
||||||
} else if (Z_TYPE_P(zv) == IS_TRUE) {
|
|
||||||
add_val2 = 1;
|
|
||||||
} else {
|
} else {
|
||||||
var1 = -1;
|
var1 = -1;
|
||||||
}
|
}
|
||||||
|
@ -355,10 +351,6 @@ static void place_essa_pis(
|
||||||
zval *zv = CRT_CONSTANT_EX(op_array, (opline-1), (opline-1)->op1);
|
zval *zv = CRT_CONSTANT_EX(op_array, (opline-1), (opline-1)->op1);
|
||||||
if (Z_TYPE_P(zv) == IS_LONG) {
|
if (Z_TYPE_P(zv) == IS_LONG) {
|
||||||
add_val1 = Z_LVAL_P(CRT_CONSTANT_EX(op_array, (opline-1), (opline-1)->op1));
|
add_val1 = Z_LVAL_P(CRT_CONSTANT_EX(op_array, (opline-1), (opline-1)->op1));
|
||||||
} else if (Z_TYPE_P(zv) == IS_FALSE) {
|
|
||||||
add_val1 = 0;
|
|
||||||
} else if (Z_TYPE_P(zv) == IS_TRUE) {
|
|
||||||
add_val1 = 1;
|
|
||||||
} else {
|
} else {
|
||||||
var2 = -1;
|
var2 = -1;
|
||||||
}
|
}
|
||||||
|
|
26
ext/opcache/tests/jit/cmp_008.phpt
Normal file
26
ext/opcache/tests/jit/cmp_008.phpt
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
--TEST--
|
||||||
|
JIT CMP: 008 Wrong range inference for comparison between IS_LONG and IS_FALSE/IS_TRUE
|
||||||
|
--INI--
|
||||||
|
opcache.enable=1
|
||||||
|
opcache.enable_cli=1
|
||||||
|
opcache.file_update_protection=0
|
||||||
|
opcache.jit_buffer_size=1M
|
||||||
|
opcache.protect_memory=1
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
function test() {
|
||||||
|
for ($i = 0; $i < 10; $i %= -4 != -4 < ($a = $a + $a)) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
test();
|
||||||
|
?>
|
||||||
|
--EXPECTF--
|
||||||
|
Warning: Undefined variable $a in %scmp_008.php on line 3
|
||||||
|
|
||||||
|
Warning: Undefined variable $a in %scmp_008.php on line 3
|
||||||
|
|
||||||
|
Fatal error: Uncaught DivisionByZeroError: Modulo by zero in %scmp_008.php:3
|
||||||
|
Stack trace:
|
||||||
|
#0 %scmp_008.php(6): test()
|
||||||
|
#1 {main}
|
||||||
|
thrown in %scmp_008.php on line 3
|
Loading…
Add table
Add a link
Reference in a new issue