Index: src/asmjs/asm-typer.cc |
diff --git a/src/asmjs/asm-typer.cc b/src/asmjs/asm-typer.cc |
index 165ef9e148faf65e0b4e29701d7ba9b5edf97d07..076cd4db9da0084a71087c564a1dab394aed04b3 100644 |
--- a/src/asmjs/asm-typer.cc |
+++ b/src/asmjs/asm-typer.cc |
@@ -1255,17 +1255,23 @@ AsmType* AsmTyper::ValidateSwitchStatement(SwitchStatement* stmt) { |
FAIL(stmt, "Switch tag must be signed."); |
} |
- bool has_default = false; |
- |
+ int default_pos = kNoSourcePosition; |
+ int last_case_pos = kNoSourcePosition; |
ZoneSet<int32_t> cases_seen(zone_); |
for (auto* a_case : *stmt->cases()) { |
if (a_case->is_default()) { |
- CHECK(!has_default); |
+ CHECK(default_pos == kNoSourcePosition); |
RECURSE(ValidateDefault(a_case)); |
- has_default = true; |
+ default_pos = a_case->position(); |
continue; |
} |
+ if (last_case_pos == kNoSourcePosition) { |
+ last_case_pos = a_case->position(); |
+ } else { |
+ last_case_pos = std::max(last_case_pos, a_case->position()); |
+ } |
+ |
int32_t case_lbl; |
RECURSE(ValidateCase(a_case, &case_lbl)); |
auto case_lbl_pos = cases_seen.find(case_lbl); |
@@ -1283,6 +1289,11 @@ AsmType* AsmTyper::ValidateSwitchStatement(SwitchStatement* stmt) { |
} |
} |
+ if (last_case_pos != kNoSourcePosition && default_pos != kNoSourcePosition && |
+ default_pos < last_case_pos) { |
+ FAIL(stmt, "Switch default must appear last."); |
+ } |
+ |
return AsmType::Void(); |
} |