[php-src] master: zend_API: Add `_ex` variants of `zend_argument_error*` (#21829)

Arnaud Le Blanc via GitHub <[email protected]>
Newsgroups gmane.comp.php.cvs.general
Message-ID <[email protected]>
Author: Arnaud Le Blanc (arnaud-lb)
Committer: GitHub (web-flow)
Pusher: TimWolla
Date: 2026-07-16T18:43:40+02:00

Commit: https://github.com/php/php-src/commit/e60d756f2ccf5754b4acb656c39d35b74f423b8c
Raw diff: https://github.com/php/php-src/commit/e60d756f2ccf5754b4acb656c39d35b74f423b8c.diff

zend_API: Add `_ex` variants of `zend_argument_error*` (#21829)

These variants take the function as parameter instead of infering it from the
call stack. This is useful in ZEND_TYPE_ASSERT, and will be used in PFA impl.

Changed paths:
  M  UPGRADING.INTERNALS
  M  Zend/zend_API.c
  M  Zend/zend_API.h
  M  Zend/zend_vm_def.h
  M  Zend/zend_vm_execute.h
  M  ext/openssl/openssl.c


Diff:

diff --git a/UPGRADING.INTERNALS b/UPGRADING.INTERNALS
index 462e567f3f36..cca78d1d3b44 100644
--- a/UPGRADING.INTERNALS
+++ b/UPGRADING.INTERNALS
@@ -129,6 +129,9 @@ PHP 8.6 INTERNALS UPGRADE NOTES
     zend_reflection_property_set_raw_value() to expose the functionality of
     ReflectionProperty::setRawValueWithoutLazyInitialization() and
     ReflectionProperty::setRawValue() to C extensions.
+  . zend_argument_error_variadic() now takes a new 'function' parameters.
+  . Added zend_argument_error_ex(), zend_argument_type_error_ex(),
+    zend_argument_value_error_ex().
 
 ========================
 2. Build system changes
diff --git a/Zend/zend_API.c b/Zend/zend_API.c
index e334b18fe1a4..72f4727eeddf 100644
--- a/Zend/zend_API.c
+++ b/Zend/zend_API.c
@@ -374,7 +374,8 @@ ZEND_API ZEND_COLD void ZEND_FASTCALL zend_unexpected_extra_named_error(void)
 	);
 }
 
-ZEND_API ZEND_COLD void ZEND_FASTCALL zend_argument_error_variadic(zend_class_entry *error_ce, uint32_t arg_num, const char *format, va_list va) /* {{{ */
+ZEND_API ZEND_COLD void ZEND_FASTCALL zend_argument_error_variadic(
+	zend_class_entry *error_ce, const zend_function *function, uint32_t arg_num, const char *format, va_list va)
 {
 	zend_string *func_name;
 	const char *arg_name;
@@ -383,8 +384,8 @@ ZEND_API ZEND_COLD void ZEND_FASTCALL zend_argument_error_variadic(zend_class_en
 		return;
 	}
 
-	func_name = get_active_function_or_method_name();
-	arg_name = get_active_function_arg_name(arg_num);
+	func_name = get_function_or_method_name(function);
+	arg_name = get_function_arg_name(function, arg_num);
 
 	zend_vspprintf(&message, 0, format, va);
 	zend_throw_error(error_ce, "%s(): Argument #%d%s%s%s %s",
@@ -394,34 +395,65 @@ ZEND_API ZEND_COLD void ZEND_FASTCALL zend_argument_error_variadic(zend_class_en
 	efree(message);
 	zend_string_release(func_name);
 }
-/* }}} */
+
+ZEND_API ZEND_COLD void zend_argument_error_ex(zend_class_entry *error_ce, const zend_function *function, uint32_t arg_num, const char *format, ...)
+{
+	va_list va;
+
+	va_start(va, format);
+	zend_argument_error_variadic(error_ce, function, arg_num, format, va);
+	va_end(va);
+}
 
 ZEND_API ZEND_COLD void zend_argument_error(zend_class_entry *error_ce, uint32_t arg_num, const char *format, ...) /* {{{ */
 {
 	va_list va;
+	const zend_function *function = zend_active_function();
 
 	va_start(va, format);
-	zend_argument_error_variadic(error_ce, arg_num, format, va);
+	zend_argument_error_variadic(error_ce, function, arg_num, format, va);
 	va_end(va);
 }
 /* }}} */
 
+ZEND_API ZEND_COLD void zend_argument_type_error_ex(
+		const zend_function *function, uint32_t arg_num, const char *format, ...)
+{
+	va_list va;
+
+	va_start(va, format);
+	zend_argument_error_variadic(zend_ce_type_error, function, arg_num, format, va);
+	va_end(va);
+}
+
 ZEND_API ZEND_COLD void zend_argument_type_error(uint32_t arg_num, const char *format, ...) /* {{{ */
 {
 	va_list va;
+	const zend_function *function = zend_active_function();
 
 	va_start(va, format);
-	zend_argument_error_variadic(zend_ce_type_error, arg_num, format, va);
+	zend_argument_error_variadic(zend_ce_type_error, function, arg_num, format, va);
 	va_end(va);
 }
 /* }}} */
 
+ZEND_API ZEND_COLD void zend_argument_value_error_ex(
+	const zend_function *function, uint32_t arg_num, const char *format, ...)
+{
+	va_list va;
+
+	va_start(va, format);
+	zend_argument_error_variadic(zend_ce_value_error, function, arg_num, format, va);
+	va_end(va);
+}
+
 ZEND_API ZEND_COLD void zend_argument_value_error(uint32_t arg_num, const char *format, ...) /* {{{ */
 {
 	va_list va;
+	const zend_function *function = zend_active_function();
 
 	va_start(va, format);
-	zend_argument_error_variadic(zend_ce_value_error, arg_num, format, va);
+	zend_argument_error_variadic(zend_ce_value_error, function, arg_num, format, va);
 	va_end(va);
 }
 /* }}} */
diff --git a/Zend/zend_API.h b/Zend/zend_API.h
index 593be26788d7..bbfe64257744 100644
--- a/Zend/zend_API.h
+++ b/Zend/zend_API.h
@@ -1579,10 +1579,13 @@ ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_class_or_string_or_nu
 ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_callback_error(uint32_t num, char *error);
 ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_callback_or_null_error(uint32_t num, char *error);
 ZEND_API ZEND_COLD void ZEND_FASTCALL zend_unexpected_extra_named_error(void);
-ZEND_API ZEND_COLD void ZEND_FASTCALL zend_argument_error_variadic(zend_class_entry *error_ce, uint32_t arg_num, const char *format, va_list va);
+ZEND_API ZEND_COLD void ZEND_FASTCALL zend_argument_error_variadic(zend_class_entry *error_ce, const zend_function *function, uint32_t arg_num, const char *format, va_list va);
 ZEND_API ZEND_COLD void zend_argument_error(zend_class_entry *error_ce, uint32_t arg_num, const char *format, ...);
+ZEND_API ZEND_COLD void zend_argument_error_ex(zend_class_entry *error_ce, const zend_function *function, uint32_t arg_num, const char *format, ...);
 ZEND_API ZEND_COLD void zend_argument_type_error(uint32_t arg_num, const char *format, ...);
+ZEND_API ZEND_COLD void zend_argument_type_error_ex(const zend_function *function, uint32_t arg_num, const char *format, ...);
 ZEND_API ZEND_COLD void zend_argument_value_error(uint32_t arg_num, const char *format, ...);
+ZEND_API ZEND_COLD void zend_argument_value_error_ex(const zend_function *function, uint32_t arg_num, const char *format, ...);
 ZEND_API ZEND_COLD void zend_argument_must_not_be_empty_error(uint32_t arg_num);
 ZEND_API ZEND_COLD void zend_class_redeclaration_error(int type, const zend_class_entry *old_ce);
 ZEND_API ZEND_COLD void zend_class_redeclaration_error_ex(int type, zend_string *new_name, const zend_class_entry *old_ce);
diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h
index ec9a97eeb254..61f89435843e 100644
--- a/Zend/zend_vm_def.h
+++ b/Zend/zend_vm_def.h
@@ -8921,9 +8921,10 @@ ZEND_VM_HOT_HANDLER(211, ZEND_TYPE_ASSERT, CONST, ANY, NUM)
 		zend_arg_info *arginfo = &fbc->common.arg_info[argno - 1];
 
 		if (!zend_check_type(&arginfo->type, value, /* is_return_type */ false, /* is_internal */ true)) {
-			const char *param_name = get_function_arg_name(fbc, argno);
 			zend_string *expected = zend_type_to_string(arginfo->type);
-			zend_type_error("%s(): Argument #%d%s%s%s must be of type %s, %s given", ZSTR_VAL(fbc->common.function_name), argno, param_name ? " ($" : "", param_name ? param_name : "", param_name ? ")" : "", ZSTR_VAL(expected), zend_zval_value_name(value));
+			zend_argument_type_error_ex(fbc, argno,
+					"must be of type %s, %s given",
+					ZSTR_VAL(expected), zend_zval_value_name(value));
 			zend_string_release(expected);
 		}
 	}
diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h
index 34b2455ce439..bcf4df0c8e74 100644
--- a/Zend/zend_vm_execute.h
+++ b/Zend/zend_vm_execute.h
@@ -6170,9 +6170,10 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_T
 		zend_arg_info *arginfo = &fbc->common.arg_info[argno - 1];
 
 		if (!zend_check_type(&arginfo->type, value, /* is_return_type */ false, /* is_internal */ true)) {
-			const char *param_name = get_function_arg_name(fbc, argno);
 			zend_string *expected = zend_type_to_string(arginfo->type);
-			zend_type_error("%s(): Argument #%d%s%s%s must be of type %s, %s given", ZSTR_VAL(fbc->common.function_name), argno, param_name ? " ($" : "", param_name ? param_name : "", param_name ? ")" : "", ZSTR_VAL(expected), zend_zval_value_name(value));
+			zend_argument_type_error_ex(fbc, argno,
+					"must be of type %s, %s given",
+					ZSTR_VAL(expected), zend_zval_value_name(value));
 			zend_string_release(expected);
 		}
 	}
@@ -58859,9 +58860,10 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_TYPE_A
 		zend_arg_info *arginfo = &fbc->common.arg_info[argno - 1];
 
 		if (!zend_check_type(&arginfo->type, value, /* is_return_type */ false, /* is_internal */ true)) {
-			const char *param_name = get_function_arg_name(fbc, argno);
 			zend_string *expected = zend_type_to_string(arginfo->type);
-			zend_type_error("%s(): Argument #%d%s%s%s must be of type %s, %s given", ZSTR_VAL(fbc->common.function_name), argno, param_name ? " ($" : "", param_name ? param_name : "", param_name ? ")" : "", ZSTR_VAL(expected), zend_zval_value_name(value));
+			zend_argument_type_error_ex(fbc, argno,
+					"must be of type %s, %s given",
+					ZSTR_VAL(expected), zend_zval_value_name(value));
 			zend_string_release(expected);
 		}
 	}
diff --git a/ext/openssl/openssl.c b/ext/openssl/openssl.c
index e11ad5c3428c..fa91f232bcdf 100644
--- a/ext/openssl/openssl.c
+++ b/ext/openssl/openssl.c
@@ -640,7 +640,7 @@ static void php_openssl_check_path_error(uint32_t arg_num, int type, const char
 	va_start(va, format);
 
 	if (type == E_ERROR) {
-		zend_argument_error_variadic(zend_ce_value_error, arg_num, format, va);
+		zend_argument_error_variadic(zend_ce_value_error, zend_active_function(), arg_num, format, va);
 	} else {
 		arg_name = get_active_function_arg_name(arg_num);
 		php_verror(NULL, arg_name, type, format, va);
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.