-
Notifications
You must be signed in to change notification settings - Fork 7.9k
Warn when coercing NAN to other types #19573
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
d43ae9a
to
bfb238b
Compare
5cf5f9f
to
564b005
Compare
564b005
to
8da693f
Compare
8da693f
to
729488f
Compare
AWS x86_64 (c7i.24xl)
Laravel 12.2.0 demo app - 100 consecutive runs, 50 warmups, 100 requests (sec)
Symfony 2.7.0 demo app - 100 consecutive runs, 50 warmups, 100 requests (sec)
Wordpress 6.2 main page - 100 consecutive runs, 20 warmups, 20 requests (sec)
bench.php - 100 consecutive runs, 10 warmups, 2 requests (sec)
|
case ZEND_CAST: { | ||
uint32_t t1 = OP1_INFO(); | ||
/* Cast from NAN emits warning */ | ||
if (t1 & MAY_BE_DOUBLE) { | ||
return true; | ||
} | ||
if (t1 & MAY_BE_ARRAY) { | ||
/* Array cast to string emits warning */ | ||
return opline->extended_value == IS_STRING; | ||
} | ||
return false; | ||
} | ||
case ZEND_BOOL: | ||
case ZEND_BOOL_NOT: { | ||
uint32_t t1 = OP1_INFO(); | ||
/* Cast from NAN emits warning */ | ||
if (t1 & MAY_BE_DOUBLE) { | ||
return true; | ||
} | ||
return false; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Only zend_may_throw()
needs to be modified:
* * We separate intrinsic side-effects from potential side-effects in the form of notices thrown
* by the instruction (in case we want to make this configurable). See may_have_side_effects() and
* zend_may_throw().
|| opcode == ZEND_BOOL | ||
|| opcode == ZEND_BOOL_NOT | ||
) { | ||
/* BW_NOT on string does not convert the string into an integer. */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This comment should be updated :)
opcode == ZEND_IS_EQUAL | ||
|| opcode == ZEND_IS_NOT_EQUAL |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These are not unary
@@ -16,6 +16,7 @@ | |||
+----------------------------------------------------------------------+ | |||
*/ | |||
|
|||
#include "../../../Zend/zend_portability.h" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#include "../../../Zend/zend_portability.h" | |
#include "Zend/zend_portability.h" |
@@ -7728,7 +7728,14 @@ static int zend_jit_bool_jmpznz(zend_jit_ctx *jit, const zend_op *opline, uint32 | |||
if_double = ir_IF(ir_EQ(type, ir_CONST_U8(IS_DOUBLE))); | |||
ir_IF_TRUE(if_double); | |||
} | |||
ref = ir_NE(jit_Z_DVAL(jit, op1_addr), ir_CONST_DOUBLE(0.0)); | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Need to avoid calling zend_is_true()
during compilation above when the value is a const nan, otherwise we emit two warnings here: (during tracing, then while compiling the trace)
echo (bool)NAN;
@@ -7728,7 +7728,14 @@ static int zend_jit_bool_jmpznz(zend_jit_ctx *jit, const zend_op *opline, uint32 | |||
if_double = ir_IF(ir_EQ(type, ir_CONST_U8(IS_DOUBLE))); | |||
ir_IF_TRUE(if_double); | |||
} | |||
ref = ir_NE(jit_Z_DVAL(jit, op1_addr), ir_CONST_DOUBLE(0.0)); | |||
|
|||
ir_ref dval = jit_Z_DVAL(jit, op1_addr);ir_ref is_nan = ir_NE(dval, dval); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ir_ref dval = jit_Z_DVAL(jit, op1_addr);ir_ref is_nan = ir_NE(dval, dval); | |
ir_ref dval = jit_Z_DVAL(jit, op1_addr); | |
ir_ref is_nan = ir_NE(dval, dval); |
@@ -2566,6 +2567,11 @@ static void ZEND_FASTCALL zend_jit_invalid_array_access(zval *container) | |||
zend_error(E_WARNING, "Trying to access array offset on %s", zend_zval_value_name(container)); | |||
} | |||
|
|||
static void ZEND_FASTCALL zend_jit_check_nan_to_bool_coercion(void) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
static void ZEND_FASTCALL zend_jit_check_nan_to_bool_coercion(void) | |
static void ZEND_FASTCALL zend_jit_nan_coerced_to_type_warning(void) |
* Those optimizations are not safe if the other operand end up being NAN | ||
* as BOOL/BOOL_NOT will warn which IS_EQUAL/IS_NOT_EQUAL do not. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Triggered a benchmark to check the effect of this: valgrind shows no regression (changes are under 0.0x%).
RFC: https://wiki.php.net/rfc/warnings-php-8-5#coercing_nan_to_other_types