Commit 84930fec27

LemonBoy <thatlemon@gmail.com>
2020-01-13 21:45:16
Validate switch range endpoints
1 parent b9f37ff
Changed files (2)
src/ir.cpp
@@ -26394,6 +26394,7 @@ static IrInstruction *ir_analyze_instruction_check_switch_prongs(IrAnalyze *ira,
             if (type_is_invalid(end_value->value->type))
                 return ira->codegen->invalid_instruction;
 
+            assert(start_value->value->type->id == ZigTypeIdEnum);
             BigInt start_index;
             bigint_init_bigint(&start_index, &start_value->value->data.x_enum_tag);
 
@@ -26401,6 +26402,11 @@ static IrInstruction *ir_analyze_instruction_check_switch_prongs(IrAnalyze *ira,
             BigInt end_index;
             bigint_init_bigint(&end_index, &end_value->value->data.x_enum_tag);
 
+            if (bigint_cmp(&start_index, &end_index) == CmpGT) {
+                ir_add_error(ira, start_value,
+                    buf_sprintf("range start value is greater than the end value"));
+            }
+
             BigInt field_index;
             bigint_init_bigint(&field_index, &start_index);
             for (;;) {
@@ -26530,6 +26536,12 @@ static IrInstruction *ir_analyze_instruction_check_switch_prongs(IrAnalyze *ira,
 
             assert(start_val->type->id == ZigTypeIdInt || start_val->type->id == ZigTypeIdComptimeInt);
             assert(end_val->type->id == ZigTypeIdInt || end_val->type->id == ZigTypeIdComptimeInt);
+
+            if (bigint_cmp(&start_val->data.x_bigint, &end_val->data.x_bigint) == CmpGT) {
+                ir_add_error(ira, start_value,
+                    buf_sprintf("range start value is greater than the end value"));
+            }
+
             AstNode *prev_node = rangeset_add_range(&rs, &start_val->data.x_bigint, &end_val->data.x_bigint,
                     start_value->source_node);
             if (prev_node != nullptr) {
test/compile_errors.zig
@@ -2,6 +2,20 @@ const tests = @import("tests.zig");
 const builtin = @import("builtin");
 
 pub fn addCases(cases: *tests.CompileErrorContext) void {
+    cases.addTest("switch ranges endpoints are validated",
+        \\pub export fn entry() void {
+        \\    var x: i32 = 0;
+        \\    switch (x) {
+        \\        6...1 => {},
+        \\        -1...-5 => {},
+        \\        else => unreachable,
+        \\    }
+        \\}
+    , &[_][]const u8{
+        "tmp.zig:4:9: error: range start value is greater than the end value",
+        "tmp.zig:5:9: error: range start value is greater than the end value",
+    });
+
     cases.addTest("errors in for loop bodies are propagated",
         \\pub export fn entry() void {
         \\    var arr: [100]u8 = undefined;