Bug 1296814 - Report errors for bad increment/decrement operands using explicitly-specified offsets. r=anba
authorJeff Walden <jwalden@mit.edu>
Mon, 14 Nov 2016 14:59:26 -0800
changeset 323512 cf2c8cac755b120d95ba8d06749d9451596a3a73
parent 323511 38a15e0978e0e54fe1255eb62350e9f89d5ac25f
child 323513 96186bf75ec2d6f2a83c0c663ea03a683cec5ea1
push id30978
push usercbook@mozilla.com
push dateMon, 21 Nov 2016 14:44:46 +0000
treeherdermozilla-central@0534254e9a40 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersanba
bugs1296814
milestone53.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1296814 - Report errors for bad increment/decrement operands using explicitly-specified offsets. r=anba
js/src/frontend/Parser.cpp
js/src/frontend/Parser.h
--- a/js/src/frontend/Parser.cpp
+++ b/js/src/frontend/Parser.cpp
@@ -7776,41 +7776,38 @@ Parser<ParseHandler>::isValidSimpleAssig
             return true;
     }
 
     return false;
 }
 
 template <typename ParseHandler>
 bool
-Parser<ParseHandler>::checkAndMarkAsIncOperand(Node target)
-{
-    if (handler.isNameAnyParentheses(target)) {
-        if (const char* chars = handler.nameIsArgumentsEvalAnyParentheses(target, context)) {
-            if (!reportWithNode(ParseStrictError, pc->sc()->strict(), target,
-                                JSMSG_BAD_STRICT_ASSIGN, chars))
-            {
+Parser<ParseHandler>::checkIncDecOperand(Node operand, uint32_t operandOffset)
+{
+    if (handler.isNameAnyParentheses(operand)) {
+        if (const char* chars = handler.nameIsArgumentsEvalAnyParentheses(operand, context)) {
+            if (!strictModeErrorAt(operandOffset, JSMSG_BAD_STRICT_ASSIGN, chars))
                 return false;
-            }
-        }
-    } else if (handler.isPropertyAccess(target)) {
+        }
+    } else if (handler.isPropertyAccess(operand)) {
         // Permitted: no additional testing/fixup needed.
-    } else if (handler.isFunctionCall(target)) {
+    } else if (handler.isFunctionCall(operand)) {
         // Assignment to function calls is forbidden in ES6.  We're still
         // somewhat concerned about sites using this in dead code, so forbid it
         // only in strict mode code (or if the werror option has been set), and
         // otherwise warn.
-        if (!reportWithNode(ParseStrictError, pc->sc()->strict(), target, JSMSG_BAD_INCOP_OPERAND))
+        if (!strictModeErrorAt(operandOffset, JSMSG_BAD_INCOP_OPERAND))
             return false;
     } else {
-        reportWithNode(ParseError, pc->sc()->strict(), target, JSMSG_BAD_INCOP_OPERAND);
+        errorAt(operandOffset, JSMSG_BAD_INCOP_OPERAND);
         return false;
     }
 
-    MOZ_ASSERT(isValidSimpleAssignmentTarget(target, PermitAssignmentToFunctionCalls),
+    MOZ_ASSERT(isValidSimpleAssignmentTarget(operand, PermitAssignmentToFunctionCalls),
                "inconsistent increment/decrement operand validation");
     return true;
 }
 
 template <typename ParseHandler>
 typename ParseHandler::Node
 Parser<ParseHandler>::unaryOpExpr(YieldHandling yieldHandling, ParseNodeKind kind, JSOp op,
                                   uint32_t begin)
@@ -7865,24 +7862,24 @@ Parser<ParseHandler>::unaryExpr(YieldHan
       }
 
       case TOK_INC:
       case TOK_DEC:
       {
         TokenKind tt2;
         if (!tokenStream.getToken(&tt2, TokenStream::Operand))
             return null();
-        Node pn2 = memberExpr(yieldHandling, TripledotProhibited, tt2);
-        if (!pn2)
-            return null();
-        if (!checkAndMarkAsIncOperand(pn2))
-            return null();
+
+        uint32_t operandOffset = pos().begin;
+        Node operand = memberExpr(yieldHandling, TripledotProhibited, tt2);
+        if (!operand || !checkIncDecOperand(operand, operandOffset))
+            return null();
+
         return handler.newUpdate((tt == TOK_INC) ? PNK_PREINCREMENT : PNK_PREDECREMENT,
-                                 begin,
-                                 pn2);
+                                 begin, operand);
       }
 
       case TOK_DELETE: {
         uint32_t exprOffset;
         if (!tokenStream.peekOffset(&exprOffset, TokenStream::Operand))
             return null();
 
         Node expr = unaryExpr(yieldHandling, TripledotProhibited);
@@ -7919,33 +7916,33 @@ Parser<ParseHandler>::unaryExpr(YieldHan
             pc->lastAwaitOffset = begin;
             return newAwaitExpression(begin, kid);
         }
         error(JSMSG_LINE_BREAK_AFTER_AWAIT);
         return null();
       }
 
       default: {
-        Node pn = memberExpr(yieldHandling, tripledotHandling, tt, /* allowCallSyntax = */ true,
-                             possibleError, invoked);
-        if (!pn)
+        Node expr = memberExpr(yieldHandling, tripledotHandling, tt, /* allowCallSyntax = */ true,
+                               possibleError, invoked);
+        if (!expr)
             return null();
 
         /* Don't look across a newline boundary for a postfix incop. */
         if (!tokenStream.peekTokenSameLine(&tt))
             return null();
-        if (tt == TOK_INC || tt == TOK_DEC) {
-            tokenStream.consumeKnownToken(tt);
-            if (!checkAndMarkAsIncOperand(pn))
-                return null();
-            return handler.newUpdate((tt == TOK_INC) ? PNK_POSTINCREMENT : PNK_POSTDECREMENT,
-                                     begin,
-                                     pn);
-        }
-        return pn;
+
+        if (tt != TOK_INC && tt != TOK_DEC)
+            return expr;
+
+        tokenStream.consumeKnownToken(tt);
+        if (!checkIncDecOperand(expr, begin))
+            return null();
+        return handler.newUpdate((tt == TOK_INC) ? PNK_POSTINCREMENT : PNK_POSTDECREMENT,
+                                 begin, expr);
       }
     }
 }
 
 
 /*** Comprehensions *******************************************************************************
  *
  * We currently support two flavors of comprehensions, all deprecated:
--- a/js/src/frontend/Parser.h
+++ b/js/src/frontend/Parser.h
@@ -1359,17 +1359,17 @@ class Parser final : private JS::AutoGCR
         PermitAssignmentToFunctionCalls,
         ForbidAssignmentToFunctionCalls
     };
 
     bool isValidSimpleAssignmentTarget(Node node,
                                        FunctionCallBehavior behavior = ForbidAssignmentToFunctionCalls);
 
   private:
-    bool checkAndMarkAsIncOperand(Node kid);
+    bool checkIncDecOperand(Node operand, uint32_t operandOffset);
     bool checkStrictAssignment(Node lhs);
     bool checkStrictBinding(PropertyName* name, TokenPos pos);
 
     bool hasValidSimpleStrictParameterNames();
 
     bool isValidStrictBinding(PropertyName* name);
 
     void reportRedeclaration(HandlePropertyName name, DeclarationKind kind, TokenPos pos);