]> granicus.if.org Git - php/commitdiff
Merge branch 'PHP-5.4' into PHP-5.5
authorArd Biesheuvel <ard.biesheuvel@linaro.org>
Wed, 11 Dec 2013 07:50:53 +0000 (08:50 +0100)
committerArd Biesheuvel <ard.biesheuvel@linaro.org>
Wed, 11 Dec 2013 07:50:53 +0000 (08:50 +0100)
1  2 
Zend/zend_operators.h

index 6e52de0698427ec2ea770b3619a4334132be8b97,815ef273406465986f02b710df267aa7f5fa0bc6..815cf582b6a11b2660b4388d246763a44388b6dd
@@@ -632,18 -588,19 +632,22 @@@ static zend_always_inline int fast_add_
                        "fstpl  (%0)\n"
                        "1:"
                        : 
 -                      : "r"(result),
 -                        "r"(op1),
 -                        "r"(op2)
 -                      : "rax");
 +                      : "r"(&result->value),
 +                        "r"(&op1->value),
 +                        "r"(&op2->value),
 +                        "n"(IS_LONG),
 +                        "n"(IS_DOUBLE),
 +                        "n"(ZVAL_OFFSETOF_TYPE)
 +                      : "rax","cc");
  #else
-                       Z_LVAL_P(result) = Z_LVAL_P(op1) + Z_LVAL_P(op2);
+                       /*
+                        * 'result' may alias with op1 or op2, so we need to
+                        * ensure that 'result' is not updated until after we
+                        * have read the values of op1 and op2.
+                        */
  
                        if (UNEXPECTED((Z_LVAL_P(op1) & LONG_SIGN_MASK) == (Z_LVAL_P(op2) & LONG_SIGN_MASK)
-                               && (Z_LVAL_P(op1) & LONG_SIGN_MASK) != (Z_LVAL_P(result) & LONG_SIGN_MASK))) {
+                               && (Z_LVAL_P(op1) & LONG_SIGN_MASK) != ((Z_LVAL_P(op1) + Z_LVAL_P(op2)) & LONG_SIGN_MASK))) {
                                Z_DVAL_P(result) = (double) Z_LVAL_P(op1) + (double) Z_LVAL_P(op2);
                                Z_TYPE_P(result) = IS_DOUBLE;
                        } else {