From: Bob Weinand Date: Thu, 28 Mar 2019 11:56:53 +0000 (+0100) Subject: Deprecate unparenthesized concatenation and addition/subtraction X-Git-Tag: php-7.4.0alpha1~251^2 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=3b23694aac62ad9c2dfdb60cafb304f9fc0b7c04;p=php Deprecate unparenthesized concatenation and addition/subtraction Implementing RFC https://wiki.php.net/rfc/concatenation_precedence --- diff --git a/Zend/zend_ast.c b/Zend/zend_ast.c index 2cacd53287..79935cde90 100644 --- a/Zend/zend_ast.c +++ b/Zend/zend_ast.c @@ -1682,6 +1682,7 @@ simple_list: case ZEND_MOD: BINARY_OP(" % ", 210, 210, 211); case ZEND_SL: BINARY_OP(" << ", 190, 190, 191); case ZEND_SR: BINARY_OP(" >> ", 190, 190, 191); + case ZEND_PARENTHESIZED_CONCAT: /* fallthrough */ case ZEND_CONCAT: BINARY_OP(" . ", 200, 200, 201); case ZEND_BW_OR: BINARY_OP(" | ", 140, 140, 141); case ZEND_BW_AND: BINARY_OP(" & ", 160, 160, 161); diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 2fa847d180..2909d684e1 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -6966,6 +6966,16 @@ void zend_compile_binary_op(znode *result, zend_ast *ast) /* {{{ */ zend_ast *right_ast = ast->child[1]; uint32_t opcode = ast->attr; + if ((opcode == ZEND_ADD || opcode == ZEND_SUB) && left_ast->kind == ZEND_AST_BINARY_OP && left_ast->attr == ZEND_CONCAT) { + zend_error(E_DEPRECATED, "The behavior of unparenthesized expressions containing both '.' and '+'/'-' will change in PHP 8: '+'/'-' will take a higher precedence"); + } + 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))) { + zend_error(E_DEPRECATED, "The behavior of unparenthesized expressions containing both '.' and '>>'/'<<' will change in PHP 8: '<<'/'>>' will take a higher precedence"); + } + if (opcode == ZEND_PARENTHESIZED_CONCAT) { + opcode = ZEND_CONCAT; + } + znode left_node, right_node; zend_compile_expr(&left_node, left_ast); zend_compile_expr(&right_node, right_ast); diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h index 82d70fd4b0..9ea2b7999d 100644 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@ -1003,11 +1003,11 @@ static zend_always_inline int zend_check_arg_send_type(const zend_function *zf, #define ZEND_SYMBOL_CONST (1<<2) /* Pseudo-opcodes that are used only temporarily during compilation */ +#define ZEND_PARENTHESIZED_CONCAT 252 /* removed with PHP 8 */ #define ZEND_GOTO 253 #define ZEND_BRK 254 #define ZEND_CONT 255 - END_EXTERN_C() #define ZEND_CLONE_FUNC_NAME "__clone" diff --git a/Zend/zend_language_parser.y b/Zend/zend_language_parser.y index af5ce87fa2..4c2a7fdce7 100644 --- a/Zend/zend_language_parser.y +++ b/Zend/zend_language_parser.y @@ -957,7 +957,7 @@ 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_BINARY_OP && $$->attr == ZEND_CONCAT) $$->attr = ZEND_PARENTHESIZED_CONCAT; } | new_expr { $$ = $1; } | expr '?' expr ':' expr { $$ = zend_ast_create(ZEND_AST_CONDITIONAL, $1, $3, $5); } diff --git a/Zend/zend_opcode.c b/Zend/zend_opcode.c index 5b1914c99d..ef8ae4b386 100644 --- a/Zend/zend_opcode.c +++ b/Zend/zend_opcode.c @@ -1041,6 +1041,7 @@ ZEND_API binary_op_type get_binary_op(int opcode) case ZEND_SR: case ZEND_ASSIGN_SR: return (binary_op_type) shift_right_function; + case ZEND_PARENTHESIZED_CONCAT: case ZEND_FAST_CONCAT: case ZEND_CONCAT: case ZEND_ASSIGN_CONCAT: