Skip to content

Commit a2c41c0

Browse files
TysonAndredstogov
authored andcommitted
Fix $x = (bool)$x; for undefined with opcache
And `$x = !$x` Noticed while working on GH-4912 The included test would not emit undefined variable errors in php 8.0 with opcache enabled. The command used: ``` php -d zend_extension=opcache.so --no-php-ini -d error_reporting=E_ALL \ -d opcache.file_cache= -d opcache.enable_cli=1 test.php ```
1 parent 2c9926f commit a2c41c0

File tree

3 files changed

+58
-8
lines changed

3 files changed

+58
-8
lines changed

Zend/zend_vm_def.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -758,8 +758,10 @@ ZEND_VM_HANDLER(13, ZEND_BOOL_NOT, CONST|TMPVAR|CV, ANY)
758758
if (Z_TYPE_INFO_P(val) == IS_TRUE) {
759759
ZVAL_FALSE(EX_VAR(opline->result.var));
760760
} else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) {
761+
/* The result and op1 can be the same cv zval */
762+
const uint32_t orig_val_type = Z_TYPE_INFO_P(val);
761763
ZVAL_TRUE(EX_VAR(opline->result.var));
762-
if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) {
764+
if (OP1_TYPE == IS_CV && UNEXPECTED(orig_val_type == IS_UNDEF)) {
763765
SAVE_OPLINE();
764766
GET_OP1_UNDEF_CV(val, BP_VAR_R);
765767
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
@@ -4755,8 +4757,10 @@ ZEND_VM_HANDLER(52, ZEND_BOOL, CONST|TMPVAR|CV, ANY)
47554757
if (Z_TYPE_INFO_P(val) == IS_TRUE) {
47564758
ZVAL_TRUE(EX_VAR(opline->result.var));
47574759
} else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) {
4760+
/* The result and op1 can be the same cv zval */
4761+
const uint32_t orig_val_type = Z_TYPE_INFO_P(val);
47584762
ZVAL_FALSE(EX_VAR(opline->result.var));
4759-
if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) {
4763+
if (OP1_TYPE == IS_CV && UNEXPECTED(orig_val_type == IS_UNDEF)) {
47604764
SAVE_OPLINE();
47614765
GET_OP1_UNDEF_CV(val, BP_VAR_R);
47624766
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();

Zend/zend_vm_execute.h

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2653,8 +2653,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BOOL_NOT_SPEC_CONST_HANDLER(ZE
26532653
if (Z_TYPE_INFO_P(val) == IS_TRUE) {
26542654
ZVAL_FALSE(EX_VAR(opline->result.var));
26552655
} else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) {
2656+
/* The result and op1 can be the same cv zval */
2657+
const uint32_t orig_val_type = Z_TYPE_INFO_P(val);
26562658
ZVAL_TRUE(EX_VAR(opline->result.var));
2657-
if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) {
2659+
if (IS_CONST == IS_CV && UNEXPECTED(orig_val_type == IS_UNDEF)) {
26582660
SAVE_OPLINE();
26592661
GET_OP1_UNDEF_CV(val, BP_VAR_R);
26602662
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
@@ -3185,8 +3187,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BOOL_SPEC_CONST_HANDLER(ZEND_O
31853187
if (Z_TYPE_INFO_P(val) == IS_TRUE) {
31863188
ZVAL_TRUE(EX_VAR(opline->result.var));
31873189
} else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) {
3190+
/* The result and op1 can be the same cv zval */
3191+
const uint32_t orig_val_type = Z_TYPE_INFO_P(val);
31883192
ZVAL_FALSE(EX_VAR(opline->result.var));
3189-
if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) {
3193+
if (IS_CONST == IS_CV && UNEXPECTED(orig_val_type == IS_UNDEF)) {
31903194
SAVE_OPLINE();
31913195
GET_OP1_UNDEF_CV(val, BP_VAR_R);
31923196
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
@@ -32866,8 +32870,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BOOL_NOT_SPEC_CV_HANDLER(ZEND_
3286632870
if (Z_TYPE_INFO_P(val) == IS_TRUE) {
3286732871
ZVAL_FALSE(EX_VAR(opline->result.var));
3286832872
} else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) {
32873+
/* The result and op1 can be the same cv zval */
32874+
const uint32_t orig_val_type = Z_TYPE_INFO_P(val);
3286932875
ZVAL_TRUE(EX_VAR(opline->result.var));
32870-
if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) {
32876+
if (IS_CV == IS_CV && UNEXPECTED(orig_val_type == IS_UNDEF)) {
3287132877
SAVE_OPLINE();
3287232878
GET_OP1_UNDEF_CV(val, BP_VAR_R);
3287332879
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
@@ -33704,8 +33710,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BOOL_SPEC_CV_HANDLER(ZEND_OPCO
3370433710
if (Z_TYPE_INFO_P(val) == IS_TRUE) {
3370533711
ZVAL_TRUE(EX_VAR(opline->result.var));
3370633712
} else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) {
33713+
/* The result and op1 can be the same cv zval */
33714+
const uint32_t orig_val_type = Z_TYPE_INFO_P(val);
3370733715
ZVAL_FALSE(EX_VAR(opline->result.var));
33708-
if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) {
33716+
if (IS_CV == IS_CV && UNEXPECTED(orig_val_type == IS_UNDEF)) {
3370933717
SAVE_OPLINE();
3371033718
GET_OP1_UNDEF_CV(val, BP_VAR_R);
3371133719
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
@@ -48537,8 +48545,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BOOL_NOT_SPEC_TMPVAR_HANDLER(Z
4853748545
if (Z_TYPE_INFO_P(val) == IS_TRUE) {
4853848546
ZVAL_FALSE(EX_VAR(opline->result.var));
4853948547
} else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) {
48548+
/* The result and op1 can be the same cv zval */
48549+
const uint32_t orig_val_type = Z_TYPE_INFO_P(val);
4854048550
ZVAL_TRUE(EX_VAR(opline->result.var));
48541-
if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) {
48551+
if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(orig_val_type == IS_UNDEF)) {
4854248552
SAVE_OPLINE();
4854348553
GET_OP1_UNDEF_CV(val, BP_VAR_R);
4854448554
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
@@ -48801,8 +48811,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BOOL_SPEC_TMPVAR_HANDLER(ZEND_
4880148811
if (Z_TYPE_INFO_P(val) == IS_TRUE) {
4880248812
ZVAL_TRUE(EX_VAR(opline->result.var));
4880348813
} else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) {
48814+
/* The result and op1 can be the same cv zval */
48815+
const uint32_t orig_val_type = Z_TYPE_INFO_P(val);
4880448816
ZVAL_FALSE(EX_VAR(opline->result.var));
48805-
if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) {
48817+
if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(orig_val_type == IS_UNDEF)) {
4880648818
SAVE_OPLINE();
4880748819
GET_OP1_UNDEF_CV(val, BP_VAR_R);
4880848820
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();

ext/opcache/tests/bool_not_cv.phpt

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
--TEST--
2+
$v = !$v/(bool)$v checks for undefined variables
3+
--INI--
4+
opcache.enable=1
5+
opcache.enable_cli=1
6+
opcache.file_cache_only=0
7+
--SKIPIF--
8+
<?php require_once('skipif.inc'); ?>
9+
--FILE--
10+
<?php
11+
function undef_negation() {
12+
echo "In undef_negation\n";
13+
$v = !$v;
14+
var_export($v);
15+
echo "\n";
16+
}
17+
function undef_bool_cast() {
18+
echo "In undef_bool_cast\n";
19+
$v = (bool)$v;
20+
var_export($v);
21+
echo "\n";
22+
}
23+
undef_negation();
24+
undef_bool_cast();
25+
?>
26+
--EXPECTF--
27+
In undef_negation
28+
29+
Notice: Undefined variable: v in %s on line 4
30+
true
31+
In undef_bool_cast
32+
33+
Notice: Undefined variable: v in %s on line 10
34+
false

0 commit comments

Comments
 (0)