Skip to content

Commit d7dc774

Browse files
committed
Add (void) cast
1 parent de9cb02 commit d7dc774

12 files changed

+79
-14
lines changed

Zend/Optimizer/dce.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,6 @@ static inline bool may_have_side_effects(
107107
case ZEND_IS_SMALLER_OR_EQUAL:
108108
case ZEND_CASE:
109109
case ZEND_CASE_STRICT:
110-
case ZEND_CAST:
111110
case ZEND_ROPE_INIT:
112111
case ZEND_ROPE_ADD:
113112
case ZEND_INIT_ARRAY:
@@ -127,6 +126,8 @@ static inline bool may_have_side_effects(
127126
case ZEND_ARRAY_KEY_EXISTS:
128127
/* No side effects */
129128
return 0;
129+
case ZEND_CAST:
130+
return opline->extended_value == IS_UNDEF;
130131
case ZEND_ADD_ARRAY_ELEMENT:
131132
/* TODO: We can't free two vars. Keep instruction alive. <?php [0, "$a" => "$b"]; */
132133
if ((opline->op1_type & (IS_VAR|IS_TMP_VAR)) && (opline->op2_type & (IS_VAR|IS_TMP_VAR))) {

Zend/Optimizer/zend_inference.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5287,6 +5287,8 @@ ZEND_API bool zend_may_throw_ex(const zend_op *opline, const zend_ssa_op *ssa_op
52875287
return (t1 & MAY_BE_OBJECT);
52885288
case IS_OBJECT:
52895289
return 0;
5290+
case IS_UNDEF:
5291+
return 0;
52905292
EMPTY_SWITCH_DEFAULT_CASE()
52915293
}
52925294
/* GCC is getting confused here for the Wimplicit-fallthrough warning with

Zend/tests/attributes/nodiscard/suppress_cast.phpt

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
--TEST--
2-
#[\NoDiscard]: Casting to (bool) suppresses.
2+
#[\NoDiscard]: Casting to (void) suppresses.
33
--FILE--
44
<?php
55

@@ -43,22 +43,22 @@ $closure2 = #[\NoDiscard] function(): int {
4343
return 0;
4444
};
4545

46-
(bool)test();
47-
(bool)test2();
48-
(bool)test3(1, 2, named: 3);
49-
(bool)call_user_func("test");
46+
(void)test();
47+
(void)test2();
48+
(void)test3(1, 2, named: 3);
49+
(void)call_user_func("test");
5050
$fcc = test(...);
51-
(bool)$fcc();
51+
(void)$fcc();
5252

5353
$cls = new Clazz();
54-
(bool)$cls->test();
55-
(bool)$cls->test2();
56-
(bool)call_user_func([$cls, "test"]);
57-
(bool)Clazz::test3();
54+
(void)$cls->test();
55+
(void)$cls->test2();
56+
(void)call_user_func([$cls, "test"]);
57+
(void)Clazz::test3();
5858

59-
(bool)$closure();
59+
(void)$closure();
6060

61-
(bool)$closure2();
61+
(void)$closure2();
6262

6363
?>
6464
DONE
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
--TEST--
2+
#[\NoDiscard]: Casting to (void) destroys the value.
3+
--FILE--
4+
<?php
5+
6+
class WithDestructor {
7+
public function __destruct() {
8+
echo __METHOD__, PHP_EOL;
9+
}
10+
}
11+
12+
#[\NoDiscard]
13+
function test(): WithDestructor {
14+
return new WithDestructor();
15+
}
16+
17+
function do_it(): void {
18+
echo "Before", PHP_EOL;
19+
20+
(void)test();
21+
22+
echo "After", PHP_EOL;
23+
}
24+
25+
do_it();
26+
27+
?>
28+
--EXPECT--
29+
Before
30+
WithDestructor::__destruct
31+
After

Zend/zend_compile.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10247,6 +10247,9 @@ static void zend_compile_cast(znode *result, zend_ast *ast) /* {{{ */
1024710247
opline = zend_emit_op_tmp(result, ZEND_BOOL, &expr_node, NULL);
1024810248
} else if (ast->attr == IS_NULL) {
1024910249
zend_error(E_COMPILE_ERROR, "The (unset) cast is no longer supported");
10250+
} else if (ast->attr == IS_UNDEF) {
10251+
opline = zend_emit_op_tmp(NULL, ZEND_CAST, &expr_node, NULL);
10252+
opline->extended_value = IS_UNDEF;
1025010253
} else {
1025110254
opline = zend_emit_op_tmp(result, ZEND_CAST, &expr_node, NULL);
1025210255
opline->extended_value = ast->attr;

Zend/zend_language_parser.y

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,7 @@ static YYSIZE_T zend_yytnamerr(char*, const char*);
217217
%token T_OBJECT_CAST "'(object)'"
218218
%token T_BOOL_CAST "'(bool)'"
219219
%token T_UNSET_CAST "'(unset)'"
220+
%token T_VOID_CAST "'(void)'"
220221
%token T_OBJECT_OPERATOR "'->'"
221222
%token T_NULLSAFE_OBJECT_OPERATOR "'?->'"
222223
%token T_DOUBLE_ARROW "'=>'"
@@ -534,6 +535,7 @@ statement:
534535
{ $$ = zend_ast_create(ZEND_AST_TRY, $3, $5, $6); }
535536
| T_GOTO T_STRING ';' { $$ = zend_ast_create(ZEND_AST_GOTO, $2); }
536537
| T_STRING ':' { $$ = zend_ast_create(ZEND_AST_LABEL, $1); }
538+
| T_VOID_CAST expr ';' { $$ = zend_ast_create_cast(IS_UNDEF, $2); }
537539
;
538540

539541
catch_list:

Zend/zend_language_scanner.l

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1657,6 +1657,10 @@ OPTIONAL_WHITESPACE_OR_COMMENTS ({WHITESPACE}|{MULTI_LINE_COMMENT}|{SINGLE_LINE_
16571657
RETURN_TOKEN(T_UNSET_CAST);
16581658
}
16591659

1660+
<ST_IN_SCRIPTING>"("{TABS_AND_SPACES}("void"){TABS_AND_SPACES}")" {
1661+
RETURN_TOKEN(T_VOID_CAST);
1662+
}
1663+
16601664
<ST_IN_SCRIPTING>"eval" {
16611665
RETURN_TOKEN_WITH_IDENT(T_EVAL);
16621666
}

Zend/zend_vm_def.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6446,6 +6446,9 @@ ZEND_VM_COLD_CONST_HANDLER(51, ZEND_CAST, CONST|TMP|VAR|CV, ANY, TYPE)
64466446
case IS_STRING:
64476447
ZVAL_STR(result, zval_get_string(expr));
64486448
break;
6449+
case IS_UNDEF:
6450+
FREE_OP1();
6451+
ZEND_VM_NEXT_OPCODE();
64496452
default:
64506453
ZEND_ASSERT(opline->extended_value != _IS_BOOL && "Must use ZEND_BOOL instead");
64516454
if (OP1_TYPE & (IS_VAR|IS_CV)) {

Zend/zend_vm_execute.h

Lines changed: 12 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

ext/tokenizer/tokenizer_data.c

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

ext/tokenizer/tokenizer_data.stub.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -642,6 +642,11 @@
642642
* @cvalue T_UNSET_CAST
643643
*/
644644
const T_UNSET_CAST = UNKNOWN;
645+
/**
646+
* @var int
647+
* @cvalue T_VOID_CAST
648+
*/
649+
const T_VOID_CAST = UNKNOWN;
645650
/**
646651
* @var int
647652
* @cvalue T_OBJECT_OPERATOR

ext/tokenizer/tokenizer_data_arginfo.h

Lines changed: 2 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)