diff --git a/UPGRADING.INTERNALS b/UPGRADING.INTERNALS index bce419d784e4..c54c5971e48f 100644 --- a/UPGRADING.INTERNALS +++ b/UPGRADING.INTERNALS @@ -21,6 +21,12 @@ PHP 8.7 INTERNALS UPGRADE NOTES - The sapi_force_http_10() function was removed. - The sapi_get_fd() function was removed. - The sapi_get_target_uid() and sapi_get_target_gid() functions were removed. +- Removed HAVE_NORETURN and HAVE_NORETURN_ALIAS. ZEND_NORETURN is guaranteed to + work. +- Redefined ZEND_NORETURN to make use of the [[noreturn]] attribute for C++ + and C23, which means that ZEND_NORETURN needs to come first in the modifier + list. Consider using noreturn (C11) / [[noreturn]] (C23) directly if + header interoperability is not required. ======================== 2. Build system changes diff --git a/Zend/zend.c b/Zend/zend.c index 3b16dc9c315b..22be95d59fb9 100644 --- a/Zend/zend.c +++ b/Zend/zend.c @@ -1264,7 +1264,7 @@ ZEND_COLD void zenderror(const char *error) /* {{{ */ } /* }}} */ -ZEND_API ZEND_COLD ZEND_NORETURN void _zend_bailout(const char *filename, uint32_t lineno) /* {{{ */ +ZEND_NORETURN ZEND_API ZEND_COLD void _zend_bailout(const char *filename, uint32_t lineno) /* {{{ */ { if (!EG(bailout)) { @@ -1715,7 +1715,7 @@ ZEND_API ZEND_COLD void zend_error_unchecked(int type, const char *format, ...) zend_error_impl(type, format); } -ZEND_API ZEND_COLD ZEND_NORETURN void zend_error_at_noreturn( +ZEND_NORETURN ZEND_API ZEND_COLD void zend_error_at_noreturn( int type, zend_string *filename, uint32_t lineno, const char *format, ...) { va_list args; @@ -1744,17 +1744,17 @@ ZEND_API ZEND_COLD ZEND_NORETURN void zend_error_at_noreturn( abort(); \ } while (0) -ZEND_API ZEND_COLD ZEND_NORETURN void zend_error_noreturn(int type, const char *format, ...) +ZEND_NORETURN ZEND_API ZEND_COLD void zend_error_noreturn(int type, const char *format, ...) { zend_error_noreturn_impl(type, format); } -ZEND_API ZEND_COLD ZEND_NORETURN void zend_error_noreturn_unchecked(int type, const char *format, ...) +ZEND_NORETURN ZEND_API ZEND_COLD void zend_error_noreturn_unchecked(int type, const char *format, ...) { zend_error_noreturn_impl(type, format); } -ZEND_API ZEND_COLD ZEND_NORETURN void zend_strerror_noreturn(int type, int errn, const char *message) +ZEND_NORETURN ZEND_API ZEND_COLD void zend_strerror_noreturn(int type, int errn, const char *message) { #ifdef HAVE_STRERROR_R char b[1024]; diff --git a/Zend/zend.h b/Zend/zend.h index 6faab6353920..f700c3bddcbb 100644 --- a/Zend/zend.h +++ b/Zend/zend.h @@ -298,7 +298,7 @@ zend_result zend_post_startup(void); void zend_set_utility_values(zend_utility_values *utility_values); void zend_unload_modules(void); -ZEND_API ZEND_COLD ZEND_NORETURN void _zend_bailout(const char *filename, uint32_t lineno); +ZEND_NORETURN ZEND_API ZEND_COLD void _zend_bailout(const char *filename, uint32_t lineno); ZEND_API size_t zend_get_page_size(void); ZEND_API size_t zend_vspprintf(char **pbuf, size_t max_len, const char *format, va_list ap); @@ -387,13 +387,13 @@ extern ZEND_API void (*zend_post_shutdown_cb)(void); extern ZEND_API void (*zend_accel_schedule_restart_hook)(int reason); ZEND_API ZEND_COLD void zend_error(int type, const char *format, ...) ZEND_ATTRIBUTE_FORMAT(printf, 2, 3); -ZEND_API ZEND_COLD ZEND_NORETURN void zend_error_noreturn(int type, const char *format, ...) ZEND_ATTRIBUTE_FORMAT(printf, 2, 3); -ZEND_API ZEND_COLD ZEND_NORETURN void zend_error_noreturn_unchecked(int type, const char *format, ...); +ZEND_NORETURN ZEND_API ZEND_COLD void zend_error_noreturn(int type, const char *format, ...) ZEND_ATTRIBUTE_FORMAT(printf, 2, 3); +ZEND_NORETURN ZEND_API ZEND_COLD void zend_error_noreturn_unchecked(int type, const char *format, ...); /* For custom format specifiers like H */ ZEND_API ZEND_COLD void zend_error_unchecked(int type, const char *format, ...); /* If filename is NULL the default filename is used. */ ZEND_API ZEND_COLD void zend_error_at(int type, zend_string *filename, uint32_t lineno, const char *format, ...) ZEND_ATTRIBUTE_FORMAT(printf, 4, 5); -ZEND_API ZEND_COLD ZEND_NORETURN void zend_error_at_noreturn(int type, zend_string *filename, uint32_t lineno, const char *format, ...) ZEND_ATTRIBUTE_FORMAT(printf, 4, 5); +ZEND_NORETURN ZEND_API ZEND_COLD void zend_error_at_noreturn(int type, zend_string *filename, uint32_t lineno, const char *format, ...) ZEND_ATTRIBUTE_FORMAT(printf, 4, 5); ZEND_API ZEND_COLD void zend_error_zstr(int type, zend_string *message); ZEND_API ZEND_COLD void zend_error_zstr_at(int type, zend_string *filename, uint32_t lineno, zend_string *message); @@ -407,7 +407,7 @@ ZEND_API ZEND_COLD void zend_illegal_container_offset(const zend_string *contain ZEND_COLD void zenderror(const char *error); /* For internal C errors */ -ZEND_API ZEND_COLD ZEND_NORETURN void zend_strerror_noreturn(int type, int errn, const char *message); +ZEND_NORETURN ZEND_API ZEND_COLD void zend_strerror_noreturn(int type, int errn, const char *message); /* The following #define is used for code duality in PHP for Engine 1 & 2 */ #define ZEND_STANDARD_CLASS_DEF_PTR zend_standard_class_def diff --git a/Zend/zend_alloc.c b/Zend/zend_alloc.c index c652cbd39ce7..7988ddf3f4a6 100644 --- a/Zend/zend_alloc.c +++ b/Zend/zend_alloc.c @@ -380,7 +380,7 @@ static const uint32_t bin_pages[] = { ZEND_MM_BINS_INFO(_BIN_DATA_PAGES, x, y) }; -static ZEND_COLD ZEND_NORETURN void zend_mm_panic(const char *message) +ZEND_NORETURN static ZEND_COLD void zend_mm_panic(const char *message) { fprintf(stderr, "%s\n", message); /* See http://support.microsoft.com/kb/190351 */ @@ -393,7 +393,7 @@ static ZEND_COLD ZEND_NORETURN void zend_mm_panic(const char *message) abort(); } -static ZEND_COLD ZEND_NORETURN void zend_mm_safe_error(zend_mm_heap *heap, +ZEND_NORETURN static ZEND_COLD void zend_mm_safe_error(zend_mm_heap *heap, const char *format, size_t limit, #if ZEND_DEBUG @@ -2995,7 +2995,7 @@ ZEND_API char* ZEND_FASTCALL _estrndup(const char *s, size_t length ZEND_FILE_LI return p; } -static ZEND_COLD ZEND_NORETURN void zend_out_of_memory(void); +ZEND_NORETURN static ZEND_COLD void zend_out_of_memory(void); ZEND_API char* ZEND_FASTCALL zend_strndup(const char *s, size_t length) { @@ -3091,7 +3091,7 @@ ZEND_API void refresh_memory_manager(void) zend_mm_refresh_key_child(AG(mm_heap)); } -static ZEND_COLD ZEND_NORETURN void zend_out_of_memory(void) +ZEND_NORETURN static ZEND_COLD void zend_out_of_memory(void) { fprintf(stderr, "Out of memory\n"); abort(); diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 8d65f1e91394..fa1ebe53afe5 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -1295,7 +1295,7 @@ ZEND_API void function_add_ref(zend_function *function) /* {{{ */ } /* }}} */ -static zend_never_inline ZEND_COLD ZEND_NORETURN void do_bind_function_error(const zend_string *lcname, const zend_op_array *op_array, bool compile_time) /* {{{ */ +ZEND_NORETURN static zend_never_inline ZEND_COLD void do_bind_function_error(const zend_string *lcname, const zend_op_array *op_array, bool compile_time) /* {{{ */ { const zval *zv = zend_hash_find_known_hash(compile_time ? CG(function_table) : EG(function_table), lcname); int error_level = compile_time ? E_COMPILE_ERROR : E_ERROR; diff --git a/Zend/zend_execute.h b/Zend/zend_execute.h index f7679d920d21..0869eec59a56 100644 --- a/Zend/zend_execute.h +++ b/Zend/zend_execute.h @@ -525,7 +525,7 @@ ZEND_API zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_cannot_pass_by_refe ZEND_API void zend_set_timeout(zend_long seconds, bool reset_signals); ZEND_API void zend_unset_timeout(void); -ZEND_API ZEND_NORETURN void ZEND_FASTCALL zend_timeout(void); +ZEND_NORETURN ZEND_API void ZEND_FASTCALL zend_timeout(void); ZEND_API zend_class_entry *zend_fetch_class(zend_string *class_name, uint32_t fetch_type); ZEND_API zend_class_entry *zend_fetch_class_with_scope(zend_string *class_name, uint32_t fetch_type, zend_class_entry *scope); ZEND_API zend_class_entry *zend_fetch_class_by_name(zend_string *class_name, zend_string *lcname, uint32_t fetch_type); diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 59fb717b5d28..900487cf3898 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -1467,7 +1467,7 @@ ZEND_API zend_result zend_eval_string_ex(const char *str, zval *retval_ptr, cons static void zend_set_timeout_ex(zend_long seconds, bool reset_signals); -ZEND_API ZEND_NORETURN void ZEND_FASTCALL zend_timeout(void) /* {{{ */ +ZEND_NORETURN ZEND_API void ZEND_FASTCALL zend_timeout(void) /* {{{ */ { #if defined(PHP_WIN32) # ifndef ZTS diff --git a/Zend/zend_fibers.c b/Zend/zend_fibers.c index c91436050856..6d392f3dcc3d 100644 --- a/Zend/zend_fibers.c +++ b/Zend/zend_fibers.c @@ -358,9 +358,9 @@ ZEND_API void* zend_fiber_stack_base(zend_fiber_stack *stack) #endif #ifdef ZEND_FIBER_UCONTEXT -static ZEND_NORETURN void zend_fiber_trampoline(void) +ZEND_NORETURN static void zend_fiber_trampoline(void) #else -static ZEND_NORETURN void zend_fiber_trampoline(boost_context_data data) +ZEND_NORETURN static void zend_fiber_trampoline(boost_context_data data) #endif { /* Initialize transfer struct with a copy of passed data. */ diff --git a/Zend/zend_gc.c b/Zend/zend_gc.c index 5de2b69bf568..6c7e2a728e93 100644 --- a/Zend/zend_gc.c +++ b/Zend/zend_gc.c @@ -1857,12 +1857,12 @@ static void zend_gc_remove_root_tmpvars(void); static zend_internal_function gc_destructor_fiber; -static ZEND_COLD ZEND_NORETURN void gc_create_destructor_fiber_error(void) +ZEND_NORETURN static ZEND_COLD void gc_create_destructor_fiber_error(void) { zend_error_noreturn(E_ERROR, "Unable to create destructor fiber"); } -static ZEND_COLD ZEND_NORETURN void gc_start_destructor_fiber_error(void) +ZEND_NORETURN static ZEND_COLD void gc_start_destructor_fiber_error(void) { zend_error_noreturn(E_ERROR, "Unable to start destructor fiber"); } diff --git a/Zend/zend_inheritance.c b/Zend/zend_inheritance.c index 4424c9a1a3ab..99b88c90f913 100644 --- a/Zend/zend_inheritance.c +++ b/Zend/zend_inheritance.c @@ -1779,13 +1779,13 @@ ZEND_API void zend_verify_hooked_property(const zend_class_entry *ce, zend_prope } } -ZEND_API ZEND_COLD ZEND_NORETURN void zend_hooked_property_variance_error_ex(zend_string *value_param_name, zend_string *class_name, zend_string *prop_name) +ZEND_NORETURN ZEND_API ZEND_COLD void zend_hooked_property_variance_error_ex(zend_string *value_param_name, zend_string *class_name, zend_string *prop_name) { zend_error_noreturn(E_COMPILE_ERROR, "Type of parameter $%s of hook %s::$%s::set must be compatible with property type", ZSTR_VAL(value_param_name), ZSTR_VAL(class_name), zend_get_unmangled_property_name(prop_name)); } -ZEND_API ZEND_COLD ZEND_NORETURN void zend_hooked_property_variance_error(const zend_property_info *prop_info) +ZEND_NORETURN ZEND_API ZEND_COLD void zend_hooked_property_variance_error(const zend_property_info *prop_info) { zend_string *value_param_name = prop_info->hooks[ZEND_PROPERTY_HOOK_SET]->op_array.arg_info[0].name; zend_hooked_property_variance_error_ex(value_param_name, prop_info->ce->name, prop_info->name); diff --git a/Zend/zend_inheritance.h b/Zend/zend_inheritance.h index fdcbd95764b3..49e022c4dfbe 100644 --- a/Zend/zend_inheritance.h +++ b/Zend/zend_inheritance.h @@ -50,8 +50,8 @@ typedef enum { } zend_inheritance_status; ZEND_API zend_inheritance_status zend_verify_property_hook_variance(const zend_property_info *prop_info, const zend_function *func); -ZEND_API ZEND_COLD ZEND_NORETURN void zend_hooked_property_variance_error(const zend_property_info *prop_info); -ZEND_API ZEND_COLD ZEND_NORETURN void zend_hooked_property_variance_error_ex(zend_string *value_param_name, zend_string *class_name, zend_string *prop_name); +ZEND_NORETURN ZEND_API ZEND_COLD void zend_hooked_property_variance_error(const zend_property_info *prop_info); +ZEND_NORETURN ZEND_API ZEND_COLD void zend_hooked_property_variance_error_ex(zend_string *value_param_name, zend_string *class_name, zend_string *prop_name); ZEND_API void zend_verify_hooked_property(const zend_class_entry *ce, zend_property_info *prop_info, zend_string *prop_name); END_EXTERN_C() diff --git a/Zend/zend_portability.h b/Zend/zend_portability.h index a4f72d76881c..0ffd8baa2cfa 100644 --- a/Zend/zend_portability.h +++ b/Zend/zend_portability.h @@ -357,14 +357,10 @@ char *alloca(); # endif #endif -#if (defined(__GNUC__) && __GNUC__ >= 3 && !defined(__INTEL_COMPILER) && !defined(__APPLE__) && !defined(__hpux) && !defined(_AIX) && !defined(__osf__)) || __has_attribute(noreturn) -# define HAVE_NORETURN -# define ZEND_NORETURN __attribute__((noreturn)) -#elif defined(ZEND_WIN32) -# define HAVE_NORETURN -# define ZEND_NORETURN __declspec(noreturn) +#if __STDC_VERSION__ >= 202311L || defined(__cplusplus) +# define ZEND_NORETURN [[noreturn]] #else -# define ZEND_NORETURN +# define ZEND_NORETURN _Noreturn #endif #if __has_attribute(force_align_arg_pointer) @@ -374,7 +370,6 @@ char *alloca(); #endif #if (defined(__GNUC__) && __GNUC__ >= 3 && !defined(__INTEL_COMPILER) && !defined(__APPLE__) && !defined(__hpux) && !defined(_AIX) && !defined(__osf__)) -# define HAVE_NORETURN_ALIAS # define HAVE_ATTRIBUTE_WEAK #endif diff --git a/Zend/zend_string.h b/Zend/zend_string.h index ad66fe168c8e..dfdf73a2e356 100644 --- a/Zend/zend_string.h +++ b/Zend/zend_string.h @@ -26,7 +26,7 @@ BEGIN_EXTERN_C() -ZEND_API ZEND_COLD ZEND_NORETURN void zend_error_noreturn(int type, const char *format, ...) ZEND_ATTRIBUTE_FORMAT(printf, 2, 3); +ZEND_NORETURN ZEND_API ZEND_COLD void zend_error_noreturn(int type, const char *format, ...) ZEND_ATTRIBUTE_FORMAT(printf, 2, 3); #include "zend_multiply.h" diff --git a/ext/ffi/php_ffi.h b/ext/ffi/php_ffi.h index 02fdb221c3df..d56dc5a5552f 100644 --- a/ext/ffi/php_ffi.h +++ b/ext/ffi/php_ffi.h @@ -209,7 +209,7 @@ zend_result zend_ffi_parse_type(const char *str, size_t len, zend_ffi_dcl *dcl); void zend_ffi_cleanup_dcl(zend_ffi_dcl *dcl); /* parser callbacks */ -void ZEND_NORETURN zend_ffi_parser_error(const char *msg, ...); +ZEND_NORETURN void zend_ffi_parser_error(const char *msg, ...); bool zend_ffi_is_typedef_name(const char *name, size_t name_len); void zend_ffi_resolve_typedef(const char *name, size_t name_len, zend_ffi_dcl *dcl); void zend_ffi_resolve_const(const char *name, size_t name_len, zend_ffi_val *val); diff --git a/ext/soap/soap.c b/ext/soap/soap.c index 97a653955825..a96a21162c20 100644 --- a/ext/soap/soap.c +++ b/ext/soap/soap.c @@ -51,9 +51,9 @@ static void set_soap_fault(zval *obj, const char *fault_code_ns, const char *fau static void add_soap_fault_en(zval *obj, const char *fault_code, const char *fault_string); static void add_soap_fault_ex(zval *fault, zval *obj, const char *fault_code, const char *fault_string, zend_string *fault_actor, zval *fault_detail, zend_string *lang); static void add_soap_fault_ex_en(zval *fault, zval *obj, const char *fault_code, const char *fault_string); -static ZEND_NORETURN void soap_server_fault(const char *code, const char *string, zend_string *actor, zval* details, zend_string *name, zend_string *lang); +ZEND_NORETURN static void soap_server_fault(const char *code, const char *string, zend_string *actor, zval* details, zend_string *name, zend_string *lang); static void soap_server_fault_ex(sdlFunctionPtr function, zval* fault, soapHeader* hdr); -static ZEND_NORETURN void soap_server_fault_en(const char *code, const char *string); +ZEND_NORETURN static void soap_server_fault_en(const char *code, const char *string); static sdlParamPtr get_param(sdlFunctionPtr function, const char *param_name, zend_ulong index, int); static sdlFunctionPtr get_function(sdlPtr sdl, const char *function_name, size_t function_name_length); @@ -1944,7 +1944,7 @@ static void soap_server_fault_ex(sdlFunctionPtr function, zval* fault, soapHeade } /* }}} */ -static ZEND_NORETURN void soap_server_fault(const char *code, const char *string, zend_string *actor, zval* details, zend_string* name, zend_string *lang) /* {{{ */ +ZEND_NORETURN static void soap_server_fault(const char *code, const char *string, zend_string *actor, zval* details, zend_string* name, zend_string *lang) /* {{{ */ { zval ret; @@ -1956,7 +1956,7 @@ static ZEND_NORETURN void soap_server_fault(const char *code, const char *string } /* }}} */ -static ZEND_NORETURN void soap_server_fault_en(const char *code, const char *string) +ZEND_NORETURN static void soap_server_fault_en(const char *code, const char *string) { soap_server_fault(code, string, NULL, NULL, NULL, soap_lang_en); } diff --git a/sapi/phpdbg/phpdbg.c b/sapi/phpdbg/phpdbg.c index 834948e6815c..eb003e8a2ead 100644 --- a/sapi/phpdbg/phpdbg.c +++ b/sapi/phpdbg/phpdbg.c @@ -1060,7 +1060,7 @@ static void phpdbg_signal_handler(int sig, siginfo_t *info, void *context) /* {{ } /* }}} */ -static ZEND_NORETURN void phpdbg_sighup_handler(int sig) /* {{{ */ +ZEND_NORETURN static void phpdbg_sighup_handler(int sig) /* {{{ */ { exit(0); } /* }}} */