mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
Exhaustive switch on enums. This addresses #838
This commit is contained in:
committed by
Christoffer Lerno
parent
8b605d9183
commit
9543fbbf1c
@@ -79,7 +79,6 @@ fn void*! arena_allocator_function(Allocator* data, usz size, usz alignment, usz
|
||||
arena.used = size;
|
||||
return null;
|
||||
}
|
||||
unreachable();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -237,5 +237,4 @@ fn void*! dynamic_arena_allocator_function(Allocator* data, usz size, usz alignm
|
||||
allocator.reset();
|
||||
return null;
|
||||
}
|
||||
unreachable();
|
||||
}
|
||||
|
||||
@@ -97,7 +97,6 @@ fn void*! on_stack_allocator_function(Allocator* data, usz size, usz alignment,
|
||||
case RESET:
|
||||
unreachable("Reset unsupported");
|
||||
}
|
||||
unreachable();
|
||||
}
|
||||
|
||||
fn bool allocation_in_stack_mem(OnStackAllocator* a, void* ptr) @local
|
||||
|
||||
@@ -83,7 +83,6 @@ fn void*! temp_allocator_function(Allocator* data, usz size, usz alignment, usz
|
||||
arena._reset(size)!;
|
||||
return null;
|
||||
}
|
||||
unreachable();
|
||||
}
|
||||
|
||||
fn void! TempAllocator._free(&self, void* old_pointer) @local
|
||||
|
||||
@@ -104,5 +104,4 @@ fn void*! tracking_allocator_fn(Allocator* data, usz size, usz alignment, usz of
|
||||
this.map.clear();
|
||||
return null;
|
||||
}
|
||||
unreachable();
|
||||
}
|
||||
|
||||
@@ -69,7 +69,6 @@ fn Object*! JsonParser.parse_from_token(&self, JsonTokenType token)
|
||||
case NULL: return object::new_null();
|
||||
case EOF: return JsonParsingError.EOF?;
|
||||
}
|
||||
unreachable();
|
||||
}
|
||||
fn Object*! JsonParser.parse_any(&self)
|
||||
{
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
## 0.5.0 Change List
|
||||
|
||||
### Changes / improvements
|
||||
- Exhaustive switches with enums has better analysis.
|
||||
- Globals may now be initialized with optional values.
|
||||
- New generic syntax.
|
||||
- Added `$embed` to embed binary data.
|
||||
|
||||
@@ -2110,8 +2110,10 @@ static bool sema_analyse_switch_body(SemaContext *context, Ast *statement, Sourc
|
||||
return false;
|
||||
}
|
||||
// We need an if-chain if this isn't an enum/integer type.
|
||||
TypeKind flat_switch_type_kind = type_flatten(switch_type)->type_kind;
|
||||
bool if_chain = flat_switch_type_kind != TYPE_ENUM && !type_kind_is_any_integer(flat_switch_type_kind);
|
||||
Type *flat = type_flatten(switch_type);
|
||||
TypeKind flat_switch_type_kind = flat->type_kind;
|
||||
bool is_enum_switch = flat_switch_type_kind == TYPE_ENUM;
|
||||
bool if_chain = !is_enum_switch && !type_kind_is_any_integer(flat_switch_type_kind);
|
||||
|
||||
Ast *default_case = NULL;
|
||||
assert(context->active_scope.defer_start == context->active_scope.defer_last);
|
||||
@@ -2163,6 +2165,7 @@ static bool sema_analyse_switch_body(SemaContext *context, Ast *statement, Sourc
|
||||
POP_NEXT();
|
||||
}
|
||||
|
||||
if (!exhaustive && is_enum_switch && case_count == vec_size(flat->decl->enums.values)) exhaustive = true;
|
||||
bool all_jump_end = exhaustive;
|
||||
for (unsigned i = 0; i < case_count; i++)
|
||||
{
|
||||
|
||||
39
test/test_suite/statements/exhaustive_switch.c3t
Normal file
39
test/test_suite/statements/exhaustive_switch.c3t
Normal file
@@ -0,0 +1,39 @@
|
||||
// #target: macos-x64
|
||||
module test;
|
||||
import std::io;
|
||||
|
||||
enum Foo
|
||||
{
|
||||
ABC,
|
||||
DEF
|
||||
}
|
||||
|
||||
fn int hello(Foo a)
|
||||
{
|
||||
switch (a)
|
||||
{
|
||||
case ABC: return 1;
|
||||
case DEF: return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* #expect: test.ll
|
||||
|
||||
define i32 @test.hello(i32 %0) #0 {
|
||||
entry:
|
||||
%switch = alloca i32, align 4
|
||||
store i32 %0, ptr %switch, align 4
|
||||
br label %switch.entry
|
||||
switch.entry: ; preds = %entry
|
||||
%1 = load i32, ptr %switch, align 4
|
||||
switch i32 %1, label %switch.exit [
|
||||
i32 0, label %switch.case
|
||||
i32 1, label %switch.case1
|
||||
]
|
||||
switch.case: ; preds = %switch.entry
|
||||
ret i32 1
|
||||
switch.case1: ; preds = %switch.entry
|
||||
ret i32 0
|
||||
switch.exit: ; preds = %switch.entry
|
||||
unreachable
|
||||
}
|
||||
Reference in New Issue
Block a user