Fix AstExpressionVisitor to correctly handle switch + for.
authorbradnelson <bradnelson@google.com>
Tue, 25 Aug 2015 16:07:13 +0000 (09:07 -0700)
committerCommit bot <commit-bot@chromium.org>
Tue, 25 Aug 2015 16:07:26 +0000 (16:07 +0000)
These were missed by the previous tests,
uncovered in another context.

BUG= https://code.google.com/p/v8/issues/detail?id=4203
TEST=test-ast-expression-visitor
R=rossberg@chromium.org,titzer@chromium.org
LOG=N

Review URL: https://codereview.chromium.org/1316633002

Cr-Commit-Position: refs/heads/master@{#30360}

src/ast-expression-visitor.cc
test/cctest/test-ast-expression-visitor.cc

index 08f2950..aa37f26 100644 (file)
@@ -111,8 +111,10 @@ void AstExpressionVisitor::VisitSwitchStatement(SwitchStatement* stmt) {
 
   for (int i = 0; i < clauses->length(); ++i) {
     CaseClause* clause = clauses->at(i);
-    Expression* label = clause->label();
-    RECURSE(Visit(label));
+    if (!clause->is_default()) {
+      Expression* label = clause->label();
+      RECURSE(Visit(label));
+    }
     ZoneList<Statement*>* stmts = clause->statements();
     RECURSE(VisitStatements(stmts));
   }
@@ -137,9 +139,15 @@ void AstExpressionVisitor::VisitWhileStatement(WhileStatement* stmt) {
 
 
 void AstExpressionVisitor::VisitForStatement(ForStatement* stmt) {
-  RECURSE(Visit(stmt->init()));
-  RECURSE(Visit(stmt->cond()));
-  RECURSE(Visit(stmt->next()));
+  if (stmt->init() != NULL) {
+    RECURSE(Visit(stmt->init()));
+  }
+  if (stmt->cond() != NULL) {
+    RECURSE(Visit(stmt->cond()));
+  }
+  if (stmt->next() != NULL) {
+    RECURSE(Visit(stmt->next()));
+  }
   RECURSE(Visit(stmt->body()));
 }
 
index f270963..bee0a73 100644 (file)
@@ -256,3 +256,44 @@ TEST(VisitExpressions) {
   }
   CHECK_TYPES_END
 }
+
+
+TEST(VisitEmptyForStatment) {
+  v8::V8::Initialize();
+  HandleAndZoneScope handles;
+  ZoneVector<ExpressionTypeEntry> types(handles.main_zone());
+  // Check that traversing an empty for statement works.
+  const char test_function[] =
+      "function foo() {\n"
+      "  for (;;) {}\n"
+      "}\n";
+  CollectTypes(&handles, test_function, &types);
+  CHECK_TYPES_BEGIN {
+    CHECK_EXPR(FunctionLiteral, DEFAULT_TYPE) {}
+  }
+  CHECK_TYPES_END
+}
+
+
+TEST(VisitSwitchStatment) {
+  v8::V8::Initialize();
+  HandleAndZoneScope handles;
+  ZoneVector<ExpressionTypeEntry> types(handles.main_zone());
+  // Check that traversing a switch with a default works.
+  const char test_function[] =
+      "function foo() {\n"
+      "  switch (0) { case 1: break; default: break; }\n"
+      "}\n";
+  CollectTypes(&handles, test_function, &types);
+  CHECK_TYPES_BEGIN {
+    CHECK_EXPR(FunctionLiteral, DEFAULT_TYPE) {
+      CHECK_EXPR(Assignment, DEFAULT_TYPE) {
+        CHECK_VAR(.switch_tag, DEFAULT_TYPE);
+        CHECK_EXPR(Literal, DEFAULT_TYPE);
+      }
+      CHECK_VAR(.switch_tag, DEFAULT_TYPE);
+      CHECK_EXPR(Literal, DEFAULT_TYPE);
+    }
+  }
+  CHECK_TYPES_END
+}