diff --git a/Zend/tests/006.phpt b/Zend/tests/006.phpt index ee6b56704020d..54eb6fb5209b8 100644 --- a/Zend/tests/006.phpt +++ b/Zend/tests/006.phpt @@ -24,6 +24,6 @@ int(0) int(-3) int(0) int(0) -int(2) +int(1) int(0) int(0) diff --git a/Zend/zend_operators.c b/Zend/zend_operators.c index 8a0cc8131be44..a35edc01501c0 100644 --- a/Zend/zend_operators.c +++ b/Zend/zend_operators.c @@ -2956,7 +2956,7 @@ ZEND_API int ZEND_FASTCALL zend_binary_strcmp(const char *s1, size_t len1, const } retval = memcmp(s1, s2, MIN(len1, len2)); if (!retval) { - return (int)(len1 - len2); + return ZEND_THREEWAY_COMPARE(len1, len2); } else { return retval; } @@ -2972,7 +2972,7 @@ ZEND_API int ZEND_FASTCALL zend_binary_strncmp(const char *s1, size_t len1, cons } retval = memcmp(s1, s2, MIN(length, MIN(len1, len2))); if (!retval) { - return (int)(MIN(length, len1) - MIN(length, len2)); + return ZEND_THREEWAY_COMPARE(MIN(length, len1), MIN(length, len2)); } else { return retval; } @@ -2997,7 +2997,7 @@ ZEND_API int ZEND_FASTCALL zend_binary_strcasecmp(const char *s1, size_t len1, c } } - return (int)(len1 - len2); + return ZEND_THREEWAY_COMPARE(len1, len2); } /* }}} */ @@ -3018,7 +3018,7 @@ ZEND_API int ZEND_FASTCALL zend_binary_strncasecmp(const char *s1, size_t len1, } } - return (int)(MIN(length, len1) - MIN(length, len2)); + return ZEND_THREEWAY_COMPARE(MIN(length, len1), MIN(length, len2)); } /* }}} */ @@ -3040,7 +3040,7 @@ ZEND_API int ZEND_FASTCALL zend_binary_strcasecmp_l(const char *s1, size_t len1, } } - return (int)(len1 - len2); + return ZEND_THREEWAY_COMPARE(len1, len2); } /* }}} */ @@ -3061,7 +3061,7 @@ ZEND_API int ZEND_FASTCALL zend_binary_strncasecmp_l(const char *s1, size_t len1 } } - return (int)(MIN(length, len1) - MIN(length, len2)); + return ZEND_THREEWAY_COMPARE(MIN(length, len1), MIN(length, len2)); } /* }}} */ diff --git a/Zend/zend_portability.h b/Zend/zend_portability.h index 6ad9f1b1db2f9..9da2d28fe67db 100644 --- a/Zend/zend_portability.h +++ b/Zend/zend_portability.h @@ -457,6 +457,12 @@ extern "C++" { #define ZEND_TRUTH(x) ((x) ? 1 : 0) #define ZEND_LOG_XOR(a, b) (ZEND_TRUTH(a) ^ ZEND_TRUTH(b)) +/** + * Do a three-way comparison of two integers and returns -1, 0 or 1 + * depending on whether #a is smaller, equal or larger than #b. + */ +#define ZEND_THREEWAY_COMPARE(a, b) ((a) == (b) ? 0 : ((a < b) ? -1 : 1)) + #define ZEND_MAX_RESERVED_RESOURCES 6 /* excpt.h on Digital Unix 4.0 defines function_table */ diff --git a/ext/opcache/jit/zend_jit_helpers.c b/ext/opcache/jit/zend_jit_helpers.c index 897a98ac22d83..fd2ee551a0c59 100644 --- a/ext/opcache/jit/zend_jit_helpers.c +++ b/ext/opcache/jit/zend_jit_helpers.c @@ -922,6 +922,10 @@ static zval* ZEND_FASTCALL zend_jit_fetch_dim_w_helper(zend_array *ht, zval *dim ZVAL_NULL(EX_VAR(opline->result.var)); } } + if (opline->opcode == ZEND_ASSIGN_DIM + && ((opline+1)->op1_type & (IS_VAR | IS_TMP_VAR))) { + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); + } return NULL; } ZEND_FALLTHROUGH; diff --git a/ext/opcache/jit/zend_jit_trace.c b/ext/opcache/jit/zend_jit_trace.c index 7ebb0487033ff..20934a8928327 100644 --- a/ext/opcache/jit/zend_jit_trace.c +++ b/ext/opcache/jit/zend_jit_trace.c @@ -4993,9 +4993,16 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par res_use_info = zend_jit_trace_type_to_info( STACK_MEM_TYPE(stack, EX_VAR_TO_NUM(opline->result.var))) & (MAY_BE_UNDEF|MAY_BE_NULL|MAY_BE_FALSE|MAY_BE_TRUE|MAY_BE_LONG|MAY_BE_DOUBLE); + res_addr = RES_REG_ADDR(); + if (Z_MODE(res_addr) != IS_REG && + STACK_TYPE(stack, EX_VAR_TO_NUM(opline->result.var)) != + STACK_MEM_TYPE(stack, EX_VAR_TO_NUM(opline->result.var))) { + /* type may be not set */ + res_use_info |= MAY_BE_NULL; + } if (!zend_jit_qm_assign(&dasm_state, opline, op1_info, op1_addr, op1_def_addr, - res_use_info, res_info, RES_REG_ADDR())) { + res_use_info, res_info, res_addr)) { goto jit_failure; } if (opline->op1_type == IS_CV diff --git a/ext/opcache/tests/jit/assign_dim_014.phpt b/ext/opcache/tests/jit/assign_dim_014.phpt new file mode 100644 index 0000000000000..d5680a4b60764 --- /dev/null +++ b/ext/opcache/tests/jit/assign_dim_014.phpt @@ -0,0 +1,19 @@ +--TEST-- +JIT ASSIGN_DIM: 014 +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_update_protection=0 +opcache.jit_buffer_size=1M +--FILE-- + +DONE +--EXPECT-- +Error: Undefined variable $y +DONE diff --git a/ext/opcache/tests/jit/qm_assign_003.phpt b/ext/opcache/tests/jit/qm_assign_003.phpt new file mode 100644 index 0000000000000..1c57a9bea22b5 --- /dev/null +++ b/ext/opcache/tests/jit/qm_assign_003.phpt @@ -0,0 +1,26 @@ +--TEST-- +JIT QM_ASSIGN: 003 missing type store +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_update_protection=0 +opcache.jit_buffer_size=1M +--FILE-- + +DONE +--EXPECT-- +DONE \ No newline at end of file diff --git a/ext/standard/tests/strings/bug40754.phpt b/ext/standard/tests/strings/bug40754.phpt index c2a563a7fd97a..c5bdeec2d0c73 100644 --- a/ext/standard/tests/strings/bug40754.phpt +++ b/ext/standard/tests/strings/bug40754.phpt @@ -90,6 +90,6 @@ stripos(): Argument #3 ($offset) must be contained in argument #1 ($haystack) strrpos(): Argument #3 ($offset) must be contained in argument #1 ($haystack) strripos(): Argument #3 ($offset) must be contained in argument #1 ($haystack) strripos(): Argument #3 ($offset) must be contained in argument #1 ($haystack) -int(2) +int(1) string(8) "abcdeabc" string(0) "" diff --git a/ext/standard/tests/strings/bug54454.phpt b/ext/standard/tests/strings/bug54454.phpt index 88835c983bbee..783fe43c42fcd 100644 --- a/ext/standard/tests/strings/bug54454.phpt +++ b/ext/standard/tests/strings/bug54454.phpt @@ -5,4 +5,4 @@ Bug #54454 (substr_compare incorrectly reports equality in some cases) var_dump(substr_compare('/', '/asd', 0, 4)); ?> --EXPECT-- -int(-3) +int(-1) diff --git a/ext/standard/tests/strings/strncasecmp_variation7.phpt b/ext/standard/tests/strings/strncasecmp_variation7.phpt index ed9a89e25a360..bb6be7c2e2269 100644 --- a/ext/standard/tests/strings/strncasecmp_variation7.phpt +++ b/ext/standard/tests/strings/strncasecmp_variation7.phpt @@ -17,6 +17,6 @@ echo "*** Done ***\n"; ?> --EXPECT-- *** Test strncasecmp() function: with null terminated strings and binary inputs *** -int(5) +int(1) int(-119) *** Done *** diff --git a/ext/standard/tests/strings/strncasecmp_variation9.phpt b/ext/standard/tests/strings/strncasecmp_variation9.phpt index 72e8e1e443fdb..7b0c19d20bcc8 100644 --- a/ext/standard/tests/strings/strncasecmp_variation9.phpt +++ b/ext/standard/tests/strings/strncasecmp_variation9.phpt @@ -71,9 +71,9 @@ echo "*** Done ***\n"; --EXPECT-- *** Test strncasecmp() function: with here-doc strings *** int(0) -int(63) +int(1) int(0) -int(83) +int(1) int(0) int(-1) int(0) diff --git a/ext/standard/tests/strings/strncmp_variation7.phpt b/ext/standard/tests/strings/strncmp_variation7.phpt index 0bdc2c4a58b17..f7232613ab7da 100644 --- a/ext/standard/tests/strings/strncmp_variation7.phpt +++ b/ext/standard/tests/strings/strncmp_variation7.phpt @@ -15,5 +15,5 @@ echo "*** Done ***\n"; ?> --EXPECT-- *** Test strncmp() function: Checking with the null terminated strings *** -int(5) +int(1) *** Done ***