mirror of
https://github.com/php/php-src.git
synced 2026-04-28 10:43:30 +02:00
Deprecate left-associative ternary
Deprecate nesting ternary operators without explicit parentheses. RFC: https://wiki.php.net/rfc/ternary_associativity
This commit is contained in:
@@ -27,6 +27,16 @@ PHP 7.4 UPGRADE NOTES
|
||||
. "fn" is now a reserved keyword. In particular it can no longer be used as a
|
||||
function or class name. It can still be used as a method or class constant
|
||||
name.
|
||||
. Nesting ternary operators without explicit parentheses is deprecated:
|
||||
|
||||
// Code like
|
||||
$a ? $b : $c ? $d : $e
|
||||
// should be replaced by (current interpretation)
|
||||
($a ? $b : $c) ? $d : $e
|
||||
// or (likely intended interpretation)
|
||||
$a ? $b : ($c ? $d : $e)
|
||||
|
||||
RFC: https://wiki.php.net/rfc/ternary_associativity
|
||||
|
||||
- Curl:
|
||||
. Attempting to serialize a CURLFile class will now generate an exception.
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
Bug #72944 (Null pointer deref in zval_delref_p).
|
||||
--FILE--
|
||||
<?php
|
||||
"a"== e & $A = $A? 0 : 0 ?:0;
|
||||
("a"== e & $A = $A? 0 : 0) ?:0;
|
||||
echo "OK\n";
|
||||
?>
|
||||
--EXPECTF--
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
--TEST--
|
||||
Using ternary associativity is deprecated
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
1 ? 2 : 3 ? 4 : 5; // deprecated
|
||||
(1 ? 2 : 3) ? 4 : 5; // ok
|
||||
1 ? 2 : (3 ? 4 : 5); // ok
|
||||
|
||||
// While the associativity of ?: is also incorrect, it will not cause a
|
||||
// functional difference, only some unnecessary checks.
|
||||
1 ?: 2 ?: 3; // ok
|
||||
(1 ?: 2) ?: 3; // ok
|
||||
1 ?: (2 ?: 3); // ok
|
||||
|
||||
1 ?: 2 ? 3 : 4; // deprecated
|
||||
(1 ?: 2) ? 3 : 4; // ok
|
||||
1 ?: (2 ? 3 : 4); // ok
|
||||
|
||||
1 ? 2 : 3 ?: 4; // deprecated
|
||||
(1 ? 2 : 3) ?: 4; // ok
|
||||
1 ? 2 : (3 ?: 4); // ok
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Deprecated: Unparenthesized `a ? b : c ? d : e` is deprecated. Use either `(a ? b : c) ? d : e` or `a ? b : (c ? d : e)` in %s on line 3
|
||||
|
||||
Deprecated: Unparenthesized `a ?: b ? c : d` is deprecated. Use either `(a ?: b) ? c : d` or `a ?: (b ? c : d)` in %s on line 13
|
||||
|
||||
Deprecated: Unparenthesized `a ? b : c ?: d` is deprecated. Use either `(a ? b : c) ?: d` or `a ? b : (c ?: d)` in %s on line 17
|
||||
@@ -7373,6 +7373,30 @@ void zend_compile_conditional(znode *result, zend_ast *ast) /* {{{ */
|
||||
zend_op *opline_qm_assign2;
|
||||
uint32_t opnum_jmpz, opnum_jmp;
|
||||
|
||||
if (cond_ast->kind == ZEND_AST_CONDITIONAL
|
||||
&& cond_ast->attr != ZEND_PARENTHESIZED_CONDITIONAL) {
|
||||
if (cond_ast->child[1]) {
|
||||
if (true_ast) {
|
||||
zend_error(E_DEPRECATED,
|
||||
"Unparenthesized `a ? b : c ? d : e` is deprecated. "
|
||||
"Use either `(a ? b : c) ? d : e` or `a ? b : (c ? d : e)`");
|
||||
} else {
|
||||
zend_error(E_DEPRECATED,
|
||||
"Unparenthesized `a ? b : c ?: d` is deprecated. "
|
||||
"Use either `(a ? b : c) ?: d` or `a ? b : (c ?: d)`");
|
||||
}
|
||||
} else {
|
||||
if (true_ast) {
|
||||
zend_error(E_DEPRECATED,
|
||||
"Unparenthesized `a ?: b ? c : d` is deprecated. "
|
||||
"Use either `(a ?: b) ? c : d` or `a ?: (b ? c : d)`");
|
||||
} else {
|
||||
/* This case is harmless: (a ?: b) ?: c always produces the same result
|
||||
* as a ?: (b ?: c). */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!true_ast) {
|
||||
zend_compile_shorthand_conditional(result, ast);
|
||||
return;
|
||||
|
||||
@@ -994,6 +994,9 @@ static zend_always_inline int zend_check_arg_send_type(const zend_function *zf,
|
||||
#define ZEND_ARRAY_NOT_PACKED (1<<1)
|
||||
#define ZEND_ARRAY_SIZE_SHIFT 2
|
||||
|
||||
/* Attribute for ternary inside parentheses */
|
||||
#define ZEND_PARENTHESIZED_CONDITIONAL 1
|
||||
|
||||
/* For "use" AST nodes and the seen symbol table */
|
||||
#define ZEND_SYMBOL_CLASS (1<<0)
|
||||
#define ZEND_SYMBOL_FUNCTION (1<<1)
|
||||
|
||||
@@ -961,7 +961,10 @@ expr:
|
||||
{ $$ = zend_ast_create_binary_op(ZEND_SPACESHIP, $1, $3); }
|
||||
| expr T_INSTANCEOF class_name_reference
|
||||
{ $$ = zend_ast_create(ZEND_AST_INSTANCEOF, $1, $3); }
|
||||
| '(' expr ')' { $$ = $2; }
|
||||
| '(' expr ')' {
|
||||
$$ = $2;
|
||||
if ($$->kind == ZEND_AST_CONDITIONAL) $$->attr = ZEND_PARENTHESIZED_CONDITIONAL;
|
||||
}
|
||||
| new_expr { $$ = $1; }
|
||||
| expr '?' expr ':' expr
|
||||
{ $$ = zend_ast_create(ZEND_AST_CONDITIONAL, $1, $3, $5); }
|
||||
|
||||
Reference in New Issue
Block a user