Skip to content

Commit 3b23694

Browse files
committed
Deprecate unparenthesized concatenation and addition/subtraction
Implementing RFC https://wiki.php.net/rfc/concatenation_precedence
1 parent d9fbbbc commit 3b23694

File tree

5 files changed

+14
-2
lines changed

5 files changed

+14
-2
lines changed

Zend/zend_ast.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1682,6 +1682,7 @@ static ZEND_COLD void zend_ast_export_ex(smart_str *str, zend_ast *ast, int prio
16821682
case ZEND_MOD: BINARY_OP(" % ", 210, 210, 211);
16831683
case ZEND_SL: BINARY_OP(" << ", 190, 190, 191);
16841684
case ZEND_SR: BINARY_OP(" >> ", 190, 190, 191);
1685+
case ZEND_PARENTHESIZED_CONCAT: /* fallthrough */
16851686
case ZEND_CONCAT: BINARY_OP(" . ", 200, 200, 201);
16861687
case ZEND_BW_OR: BINARY_OP(" | ", 140, 140, 141);
16871688
case ZEND_BW_AND: BINARY_OP(" & ", 160, 160, 161);

Zend/zend_compile.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6966,6 +6966,16 @@ void zend_compile_binary_op(znode *result, zend_ast *ast) /* {{{ */
69666966
zend_ast *right_ast = ast->child[1];
69676967
uint32_t opcode = ast->attr;
69686968

6969+
if ((opcode == ZEND_ADD || opcode == ZEND_SUB) && left_ast->kind == ZEND_AST_BINARY_OP && left_ast->attr == ZEND_CONCAT) {
6970+
zend_error(E_DEPRECATED, "The behavior of unparenthesized expressions containing both '.' and '+'/'-' will change in PHP 8: '+'/'-' will take a higher precedence");
6971+
}
6972+
if ((opcode == ZEND_SL || opcode == ZEND_SR) && ((left_ast->kind == ZEND_AST_BINARY_OP && left_ast->attr == ZEND_CONCAT) || (right_ast->kind == ZEND_AST_BINARY_OP && right_ast->attr == ZEND_CONCAT))) {
6973+
zend_error(E_DEPRECATED, "The behavior of unparenthesized expressions containing both '.' and '>>'/'<<' will change in PHP 8: '<<'/'>>' will take a higher precedence");
6974+
}
6975+
if (opcode == ZEND_PARENTHESIZED_CONCAT) {
6976+
opcode = ZEND_CONCAT;
6977+
}
6978+
69696979
znode left_node, right_node;
69706980
zend_compile_expr(&left_node, left_ast);
69716981
zend_compile_expr(&right_node, right_ast);

Zend/zend_compile.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1003,11 +1003,11 @@ static zend_always_inline int zend_check_arg_send_type(const zend_function *zf,
10031003
#define ZEND_SYMBOL_CONST (1<<2)
10041004

10051005
/* Pseudo-opcodes that are used only temporarily during compilation */
1006+
#define ZEND_PARENTHESIZED_CONCAT 252 /* removed with PHP 8 */
10061007
#define ZEND_GOTO 253
10071008
#define ZEND_BRK 254
10081009
#define ZEND_CONT 255
10091010

1010-
10111011
END_EXTERN_C()
10121012

10131013
#define ZEND_CLONE_FUNC_NAME "__clone"

Zend/zend_language_parser.y

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -957,7 +957,7 @@ expr:
957957
{ $$ = zend_ast_create_binary_op(ZEND_SPACESHIP, $1, $3); }
958958
| expr T_INSTANCEOF class_name_reference
959959
{ $$ = zend_ast_create(ZEND_AST_INSTANCEOF, $1, $3); }
960-
| '(' expr ')' { $$ = $2; }
960+
| '(' expr ')' { $$ = $2; if ($$->kind == ZEND_AST_BINARY_OP && $$->attr == ZEND_CONCAT) $$->attr = ZEND_PARENTHESIZED_CONCAT; }
961961
| new_expr { $$ = $1; }
962962
| expr '?' expr ':' expr
963963
{ $$ = zend_ast_create(ZEND_AST_CONDITIONAL, $1, $3, $5); }

Zend/zend_opcode.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1041,6 +1041,7 @@ ZEND_API binary_op_type get_binary_op(int opcode)
10411041
case ZEND_SR:
10421042
case ZEND_ASSIGN_SR:
10431043
return (binary_op_type) shift_right_function;
1044+
case ZEND_PARENTHESIZED_CONCAT:
10441045
case ZEND_FAST_CONCAT:
10451046
case ZEND_CONCAT:
10461047
case ZEND_ASSIGN_CONCAT:

0 commit comments

Comments
 (0)