summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Zend/zend_ast.c1
-rw-r--r--Zend/zend_compile.c10
-rw-r--r--Zend/zend_compile.h2
-rw-r--r--Zend/zend_language_parser.y1
-rw-r--r--Zend/zend_opcode.c1
5 files changed, 14 insertions, 1 deletions
diff --git a/Zend/zend_ast.c b/Zend/zend_ast.c
index ea55f394c3..953f12b155 100644
--- a/Zend/zend_ast.c
+++ b/Zend/zend_ast.c
@@ -1733,6 +1733,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 155844e2e0..303aefcf9d 100644
--- a/Zend/zend_compile.c
+++ b/Zend/zend_compile.c
@@ -7069,6 +7069,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 a3a781046a..963314ced8 100644
--- a/Zend/zend_compile.h
+++ b/Zend/zend_compile.h
@@ -980,11 +980,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 22394868ba..b20c619f05 100644
--- a/Zend/zend_language_parser.y
+++ b/Zend/zend_language_parser.y
@@ -964,6 +964,7 @@ expr:
| '(' expr ')' {
$$ = $2;
if ($$->kind == ZEND_AST_CONDITIONAL) $$->attr = ZEND_PARENTHESIZED_CONDITIONAL;
+ if ($$->kind == ZEND_AST_BINARY_OP && $$->attr == ZEND_CONCAT) $$->attr = ZEND_PARENTHESIZED_CONCAT;
}
| new_expr { $$ = $1; }
| expr '?' expr ':' expr
diff --git a/Zend/zend_opcode.c b/Zend/zend_opcode.c
index 7d70d297d4..5ac5c8a859 100644
--- a/Zend/zend_opcode.c
+++ b/Zend/zend_opcode.c
@@ -1049,6 +1049,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: