From: Nikita Popov Date: Tue, 21 Jul 2020 08:42:02 +0000 (+0200) Subject: Stricter verification of func info against arg info X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=3a9036ac54c016a39a101057f29da30cc0c4c475;p=php Stricter verification of func info against arg info Make sure they're actually the same up to cases where func info allows more accurate expressions. There are some awkward edge cases around true/false/null limitations in union types. --- diff --git a/ext/opcache/Optimizer/zend_func_info.c b/ext/opcache/Optimizer/zend_func_info.c index 135ff65f5d..b8c62f5420 100644 --- a/ext/opcache/Optimizer/zend_func_info.c +++ b/ext/opcache/Optimizer/zend_func_info.c @@ -932,12 +932,23 @@ uint32_t zend_get_func_info( } #if ZEND_DEBUG - /* Check whether the func_info information is a subset of the information we can compute - * from the specified return type. */ if (internal_ret) { + /* Check whether the func_info information is a subset of the information we can + * compute from the specified return type, otherwise it contains redundant types. */ if (internal_ret & ~ret) { fprintf(stderr, "Inaccurate func info for %s()\n", ZSTR_VAL(lcname)); } + /* If the return type is not mixed, check that the types match exactly if we exclude + * RC and array information. */ + uint32_t ret_any = ret & MAY_BE_ANY, internal_ret_any = internal_ret & MAY_BE_ANY; + if (ret_any != MAY_BE_ANY) { + uint32_t diff = internal_ret_any ^ ret_any; + /* Func info may contain "true" types as well as isolated "null" and "false". */ + if (diff && !(diff == MAY_BE_FALSE && (ret & MAY_BE_FALSE)) + && (internal_ret_any & ~(MAY_BE_NULL|MAY_BE_FALSE))) { + fprintf(stderr, "Incorrect func info for %s()\n", ZSTR_VAL(lcname)); + } + } return internal_ret; } #endif