diff --git a/src/typing-asm.cc b/src/typing-asm.cc index 7074169355..a062b733c8 100644 --- a/src/typing-asm.cc +++ b/src/typing-asm.cc @@ -388,14 +388,15 @@ void AsmTyper::VisitSwitchStatement(SwitchStatement* stmt) { ZoneList* clauses = stmt->cases(); for (int i = 0; i < clauses->length(); ++i) { CaseClause* clause = clauses->at(i); - if (clause->is_default()) continue; - Expression* label = clause->label(); - RECURSE(VisitWithExpectation(label, cache_.kAsmSigned, - "case label non-integer")); - if (!label->IsLiteral()) FAIL(label, "non-literal case label"); - Handle value = label->AsLiteral()->value(); - int32_t value32; - if (!value->ToInt32(&value32)) FAIL(label, "illegal case label value"); + if (!clause->is_default()) { + Expression* label = clause->label(); + RECURSE(VisitWithExpectation(label, cache_.kAsmSigned, + "case label non-integer")); + if (!label->IsLiteral()) FAIL(label, "non-literal case label"); + Handle value = label->AsLiteral()->value(); + int32_t value32; + if (!value->ToInt32(&value32)) FAIL(label, "illegal case label value"); + } // TODO(bradnelson): Detect duplicates. ZoneList* stmts = clause->statements(); RECURSE(VisitStatements(stmts)); @@ -538,7 +539,12 @@ void AsmTyper::VisitVariableProxy(VariableProxy* expr) { Variable* var = expr->var(); VariableInfo* info = GetVariableInfo(var, false); if (info == NULL || info->type == NULL) { - FAIL(expr, "unbound variable"); + if (var->mode() == TEMPORARY) { + SetType(var, Type::Any(zone())); + info = GetVariableInfo(var, false); + } else { + FAIL(expr, "unbound variable"); + } } if (property_info_ != NULL) { SetVariableInfo(var, property_info_); diff --git a/test/cctest/test-asm-validator.cc b/test/cctest/test-asm-validator.cc index 7f3b1194ff..1149d19f24 100644 --- a/test/cctest/test-asm-validator.cc +++ b/test/cctest/test-asm-validator.cc @@ -1978,3 +1978,49 @@ TEST(TypeConsistency) { CHECK(!cache.kAsmDouble->Is(cache.kAsmFixnum)); CHECK(!cache.kAsmDouble->Is(cache.kAsmFloat)); } + + +TEST(SwitchTest) { + CHECK_FUNC_TYPES_BEGIN( + "function switcher(x) {\n" + " x = x|0;\n" + " switch (x|0) {\n" + " case 1: return 23;\n" + " case 2: return 43;\n" + " default: return 66;\n" + " }\n" + " return 0;\n" + "}\n" + "function foo() { switcher(1); }") { + CHECK_EXPR(FunctionLiteral, FUNC_I2I_TYPE) { + CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) { + CHECK_VAR(x, Bounds(cache.kAsmInt)); + CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) { + CHECK_VAR(x, Bounds(cache.kAsmInt)); + CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); + } + } + CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) { + CHECK_VAR(.switch_tag, Bounds(cache.kAsmInt)); + CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) { + CHECK_VAR(x, Bounds(cache.kAsmInt)); + CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); + } + } + CHECK_EXPR(Literal, Bounds(Type::Undefined(zone))); + CHECK_VAR(.switch_tag, Bounds(cache.kAsmSigned)); + // case 1: return 23; + CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); + CHECK_EXPR(Literal, Bounds(cache.kAsmSigned)); + // case 2: return 43; + CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); + CHECK_EXPR(Literal, Bounds(cache.kAsmSigned)); + // default: return 66; + CHECK_EXPR(Literal, Bounds(cache.kAsmSigned)); + // return 0; + CHECK_EXPR(Literal, Bounds(cache.kAsmSigned)); + } + CHECK_SKIP(); + } + CHECK_FUNC_TYPES_END +}