From b9ddea42f2dec0f63b2091be35932c87ac430667 Mon Sep 17 00:00:00 2001 From: Bellangelo Date: Thu, 21 Nov 2024 00:58:57 +0200 Subject: [PATCH 1/4] Throw warning when yielding without a value in reference generator function --- ...ut_value_in_reference_generator_function.phpt | 16 ++++++++++++++++ Zend/zend_vm_def.h | 4 ++++ 2 files changed, 20 insertions(+) create mode 100644 Zend/tests/generators/errors/yield_without_value_in_reference_generator_function.phpt diff --git a/Zend/tests/generators/errors/yield_without_value_in_reference_generator_function.phpt b/Zend/tests/generators/errors/yield_without_value_in_reference_generator_function.phpt new file mode 100644 index 0000000000000..dd77edcca1fa6 --- /dev/null +++ b/Zend/tests/generators/errors/yield_without_value_in_reference_generator_function.phpt @@ -0,0 +1,16 @@ +--TEST-- +Yield without value in reference generator function should create notice +--FILE-- + +--EXPECTF-- +Notice: Only variable references should be yielded by reference in %s on line %d +Notice: Only variable references should be yielded by reference in %s on line %d diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index bcb9be8dab489..b21ff9c9d2a88 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -8051,6 +8051,10 @@ ZEND_VM_HANDLER(160, ZEND_YIELD, CONST|TMP|VAR|CV|UNUSED, CONST|TMPVAR|CV|UNUSED } } } else { + if (UNEXPECTED(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)) { + zend_error(E_NOTICE, "Only variable references should be yielded by reference"); + } + /* If no value was specified yield null */ ZVAL_NULL(&generator->value); } From 9877ea21f2115ab1f0d1f03f2e3e3220e95659b4 Mon Sep 17 00:00:00 2001 From: Bellangelo Date: Thu, 21 Nov 2024 02:17:43 +0200 Subject: [PATCH 2/4] Update existing tests --- Zend/tests/generators/return_from_by_ref_generator.phpt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Zend/tests/generators/return_from_by_ref_generator.phpt b/Zend/tests/generators/return_from_by_ref_generator.phpt index 32bebfbbde963..db43a7008fea3 100644 --- a/Zend/tests/generators/return_from_by_ref_generator.phpt +++ b/Zend/tests/generators/return_from_by_ref_generator.phpt @@ -16,5 +16,6 @@ function gen2() { gen2()->next(); ?> ---EXPECT-- +--EXPECTF-- +Notice: Only variable references should be yielded by reference in %s on line %d int(42) From e0057e5562e1a692f151262900451cd6e1e4df94 Mon Sep 17 00:00:00 2001 From: Bellangelo Date: Thu, 21 Nov 2024 02:18:32 +0200 Subject: [PATCH 3/4] Generate zend_vm --- Zend/zend_vm_execute.h | 80 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 049d0f2126bc2..457e125d5a0f4 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -7334,6 +7334,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_CONST_HANDLER } } } else { + if (UNEXPECTED(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)) { + zend_error(E_NOTICE, "Only variable references should be yielded by reference"); + } + /* If no value was specified yield null */ ZVAL_NULL(&generator->value); } @@ -9433,6 +9437,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_TMPVAR_HANDLE } } } else { + if (UNEXPECTED(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)) { + zend_error(E_NOTICE, "Only variable references should be yielded by reference"); + } + /* If no value was specified yield null */ ZVAL_NULL(&generator->value); } @@ -10308,6 +10316,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_UNUSED_HANDLE } } } else { + if (UNEXPECTED(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)) { + zend_error(E_NOTICE, "Only variable references should be yielded by reference"); + } + /* If no value was specified yield null */ ZVAL_NULL(&generator->value); } @@ -11819,6 +11831,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_CV_HANDLER(ZE } } } else { + if (UNEXPECTED(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)) { + zend_error(E_NOTICE, "Only variable references should be yielded by reference"); + } + /* If no value was specified yield null */ ZVAL_NULL(&generator->value); } @@ -19607,6 +19623,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_CONST_HANDLER(Z } } } else { + if (UNEXPECTED(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)) { + zend_error(E_NOTICE, "Only variable references should be yielded by reference"); + } + /* If no value was specified yield null */ ZVAL_NULL(&generator->value); } @@ -20010,6 +20030,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_TMPVAR_HANDLER( } } } else { + if (UNEXPECTED(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)) { + zend_error(E_NOTICE, "Only variable references should be yielded by reference"); + } + /* If no value was specified yield null */ ZVAL_NULL(&generator->value); } @@ -20470,6 +20494,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_UNUSED_HANDLER( } } } else { + if (UNEXPECTED(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)) { + zend_error(E_NOTICE, "Only variable references should be yielded by reference"); + } + /* If no value was specified yield null */ ZVAL_NULL(&generator->value); } @@ -20869,6 +20897,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_CV_HANDLER(ZEND } } } else { + if (UNEXPECTED(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)) { + zend_error(E_NOTICE, "Only variable references should be yielded by reference"); + } + /* If no value was specified yield null */ ZVAL_NULL(&generator->value); } @@ -24737,6 +24769,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_CONST_HANDLER(Z } } } else { + if (UNEXPECTED(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)) { + zend_error(E_NOTICE, "Only variable references should be yielded by reference"); + } + /* If no value was specified yield null */ ZVAL_NULL(&generator->value); } @@ -26956,6 +26992,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_TMPVAR_HANDLER( } } } else { + if (UNEXPECTED(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)) { + zend_error(E_NOTICE, "Only variable references should be yielded by reference"); + } + /* If no value was specified yield null */ ZVAL_NULL(&generator->value); } @@ -28802,6 +28842,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_UNUSED_HANDLER( } } } else { + if (UNEXPECTED(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)) { + zend_error(E_NOTICE, "Only variable references should be yielded by reference"); + } + /* If no value was specified yield null */ ZVAL_NULL(&generator->value); } @@ -31138,6 +31182,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_CV_HANDLER(ZEND } } } else { + if (UNEXPECTED(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)) { + zend_error(E_NOTICE, "Only variable references should be yielded by reference"); + } + /* If no value was specified yield null */ ZVAL_NULL(&generator->value); } @@ -33234,6 +33282,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_CONST_HANDLE } } } else { + if (UNEXPECTED(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)) { + zend_error(E_NOTICE, "Only variable references should be yielded by reference"); + } + /* If no value was specified yield null */ ZVAL_NULL(&generator->value); } @@ -34982,6 +35034,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_TMPVAR_HANDL } } } else { + if (UNEXPECTED(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)) { + zend_error(E_NOTICE, "Only variable references should be yielded by reference"); + } + /* If no value was specified yield null */ ZVAL_NULL(&generator->value); } @@ -35516,6 +35572,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_UNUSED_HANDL } } } else { + if (UNEXPECTED(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)) { + zend_error(E_NOTICE, "Only variable references should be yielded by reference"); + } + /* If no value was specified yield null */ ZVAL_NULL(&generator->value); } @@ -37425,6 +37485,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_CV_HANDLER(Z } } } else { + if (UNEXPECTED(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)) { + zend_error(E_NOTICE, "Only variable references should be yielded by reference"); + } + /* If no value was specified yield null */ ZVAL_NULL(&generator->value); } @@ -42593,6 +42657,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CV_CONST_HANDLER(ZE } } } else { + if (UNEXPECTED(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)) { + zend_error(E_NOTICE, "Only variable references should be yielded by reference"); + } + /* If no value was specified yield null */ ZVAL_NULL(&generator->value); } @@ -46064,6 +46132,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CV_TMPVAR_HANDLER(Z } } } else { + if (UNEXPECTED(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)) { + zend_error(E_NOTICE, "Only variable references should be yielded by reference"); + } + /* If no value was specified yield null */ ZVAL_NULL(&generator->value); } @@ -47809,6 +47881,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CV_UNUSED_HANDLER(Z } } } else { + if (UNEXPECTED(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)) { + zend_error(E_NOTICE, "Only variable references should be yielded by reference"); + } + /* If no value was specified yield null */ ZVAL_NULL(&generator->value); } @@ -51359,6 +51435,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CV_CV_HANDLER(ZEND_ } } } else { + if (UNEXPECTED(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)) { + zend_error(E_NOTICE, "Only variable references should be yielded by reference"); + } + /* If no value was specified yield null */ ZVAL_NULL(&generator->value); } From 288b17130167076cf6a8d856f68189c81c5ce183 Mon Sep 17 00:00:00 2001 From: Bellangelo Date: Thu, 21 Nov 2024 02:19:32 +0200 Subject: [PATCH 4/4] Add empty line --- .../yield_without_value_in_reference_generator_function.phpt | 1 + 1 file changed, 1 insertion(+) diff --git a/Zend/tests/generators/errors/yield_without_value_in_reference_generator_function.phpt b/Zend/tests/generators/errors/yield_without_value_in_reference_generator_function.phpt index dd77edcca1fa6..650fb0705ec3f 100644 --- a/Zend/tests/generators/errors/yield_without_value_in_reference_generator_function.phpt +++ b/Zend/tests/generators/errors/yield_without_value_in_reference_generator_function.phpt @@ -13,4 +13,5 @@ foreach (y() as &$y); ?> --EXPECTF-- Notice: Only variable references should be yielded by reference in %s on line %d + Notice: Only variable references should be yielded by reference in %s on line %d