mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-04 14:48:47 +00:00
Fix bit_field comparison against nil #414
This commit is contained in:
@@ -281,6 +281,40 @@ memory_compare :: proc "contextless" (a, b: rawptr, n: int) -> int #no_bounds_ch
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
memory_compare_zero :: proc "contextless" (a: rawptr, n: int) -> int #no_bounds_check {
|
||||||
|
x := uintptr(a);
|
||||||
|
n := uintptr(n);
|
||||||
|
|
||||||
|
SU :: size_of(uintptr);
|
||||||
|
fast := uintptr(n/SU + 1);
|
||||||
|
offset := (fast-1)*SU;
|
||||||
|
curr_block := uintptr(0);
|
||||||
|
if n < SU {
|
||||||
|
fast = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for /**/; curr_block < fast; curr_block += 1 {
|
||||||
|
va := (^uintptr)(x + curr_block * size_of(uintptr))^;
|
||||||
|
if va ~ 0 != 0 {
|
||||||
|
for pos := curr_block*SU; pos < n; pos += 1 {
|
||||||
|
a := (^byte)(x+pos)^;
|
||||||
|
if a ~ 0 != 0 {
|
||||||
|
return int(a) < 0 ? -1 : +1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for /**/; offset < n; offset += 1 {
|
||||||
|
a := (^byte)(x+offset)^;
|
||||||
|
if a ~ 0 != 0 {
|
||||||
|
return int(a) < 0 ? -1 : +1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
string_eq :: proc "contextless" (a, b: string) -> bool {
|
string_eq :: proc "contextless" (a, b: string) -> bool {
|
||||||
switch {
|
switch {
|
||||||
case len(a) != len(b): return false;
|
case len(a) != len(b): return false;
|
||||||
|
|||||||
@@ -1615,6 +1615,7 @@ void generate_minimum_dependency_set(Checker *c, Entity *start) {
|
|||||||
str_lit("udivti3"),
|
str_lit("udivti3"),
|
||||||
|
|
||||||
str_lit("memory_compare"),
|
str_lit("memory_compare"),
|
||||||
|
str_lit("memory_compare_zero"),
|
||||||
};
|
};
|
||||||
for (isize i = 0; i < gb_count_of(required_runtime_entities); i++) {
|
for (isize i = 0; i < gb_count_of(required_runtime_entities); i++) {
|
||||||
add_dependency_to_set(c, scope_lookup(c->info.runtime_package->scope, required_runtime_entities[i]));
|
add_dependency_to_set(c, scope_lookup(c->info.runtime_package->scope, required_runtime_entities[i]));
|
||||||
|
|||||||
@@ -4017,6 +4017,15 @@ irValue *ir_emit_comp_against_nil(irProcedure *proc, TokenKind op_kind, irValue
|
|||||||
} else if (is_type_typeid(t)) {
|
} else if (is_type_typeid(t)) {
|
||||||
irValue *invalid_typeid = ir_value_constant(t_typeid, exact_value_i64(0));
|
irValue *invalid_typeid = ir_value_constant(t_typeid, exact_value_i64(0));
|
||||||
return ir_emit_comp(proc, op_kind, x, invalid_typeid);
|
return ir_emit_comp(proc, op_kind, x, invalid_typeid);
|
||||||
|
} else if (is_type_bit_field(t)) {
|
||||||
|
auto args = array_make<irValue *>(heap_allocator(), 2);
|
||||||
|
irValue *lhs = ir_address_from_load_or_generate_local(proc, x);
|
||||||
|
args[0] = ir_emit_conv(proc, lhs, t_rawptr);
|
||||||
|
args[1] = ir_const_int(type_size_of(t));
|
||||||
|
irValue *val = ir_emit_runtime_call(proc, "memory_compare_zero", args);
|
||||||
|
irValue *res = ir_emit_comp(proc, op_kind, val, v_zero);
|
||||||
|
return ir_emit_conv(proc, res, t_bool);
|
||||||
|
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user