Skip to content

Commit 371d36a

Browse files
committed
partial revert of an improvement this branch made
because it uncovered a result location bug, and I need to get this branch merged before going into a result location rabbit hole. also fix the result type of slicing when the indexes are runtime known and the result should be sentinel terminated.
1 parent 73db5c4 commit 371d36a

File tree

3 files changed

+79
-51
lines changed

3 files changed

+79
-51
lines changed

src/ir.cpp

Lines changed: 66 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -12693,34 +12693,50 @@ static IrInstGen *ir_resolve_ptr_of_array_to_slice(IrAnalyze *ira, IrInst* sourc
1269312693
assert(array_ptr->value->type->data.pointer.child_type->id == ZigTypeIdArray);
1269412694

1269512695
ZigType *array_type = array_ptr->value->type->data.pointer.child_type;
12696-
const size_t array_len = array_type->data.array.len;
12696+
size_t array_len = array_type->data.array.len;
1269712697

1269812698
// A zero-sized array can be casted regardless of the destination alignment, or
1269912699
// whether the pointer is undefined, and the result is always comptime known.
12700-
if (array_len == 0) {
12701-
ZigValue *undef_array = ira->codegen->pass1_arena->create<ZigValue>();
12702-
undef_array->special = ConstValSpecialUndef;
12703-
undef_array->type = array_type;
12704-
12705-
IrInstGen *result = ir_const(ira, source_instr, wanted_type);
12706-
init_const_slice(ira->codegen, result->value, undef_array, 0, 0, false);
12707-
result->value->data.x_struct.fields[slice_ptr_index]->data.x_ptr.mut = ConstPtrMutComptimeConst;
12708-
result->value->type = wanted_type;
12709-
return result;
12710-
}
12700+
// TODO However, this is exposing a result location bug that I failed to solve on the first try.
12701+
// If you want to try to fix the bug, uncomment this block and get the tests passing.
12702+
//if (array_len == 0 && array_type->data.array.sentinel == nullptr) {
12703+
// ZigValue *undef_array = ira->codegen->pass1_arena->create<ZigValue>();
12704+
// undef_array->special = ConstValSpecialUndef;
12705+
// undef_array->type = array_type;
12706+
12707+
// IrInstGen *result = ir_const(ira, source_instr, wanted_type);
12708+
// init_const_slice(ira->codegen, result->value, undef_array, 0, 0, false);
12709+
// result->value->data.x_struct.fields[slice_ptr_index]->data.x_ptr.mut = ConstPtrMutComptimeConst;
12710+
// result->value->type = wanted_type;
12711+
// return result;
12712+
//}
1271112713

1271212714
if ((err = type_resolve(ira->codegen, array_ptr->value->type, ResolveStatusAlignmentKnown))) {
1271312715
return ira->codegen->invalid_inst_gen;
1271412716
}
1271512717

12716-
wanted_type = adjust_slice_align(ira->codegen, wanted_type,
12717-
get_ptr_align(ira->codegen, array_ptr->value->type));
12718+
if (array_len != 0) {
12719+
wanted_type = adjust_slice_align(ira->codegen, wanted_type,
12720+
get_ptr_align(ira->codegen, array_ptr->value->type));
12721+
}
1271812722

1271912723
if (instr_is_comptime(array_ptr)) {
12720-
ZigValue *array_ptr_val = ir_resolve_const(ira, array_ptr, UndefBad);
12724+
UndefAllowed undef_allowed = (array_len == 0) ? UndefOk : UndefBad;
12725+
ZigValue *array_ptr_val = ir_resolve_const(ira, array_ptr, undef_allowed);
1272112726
if (array_ptr_val == nullptr)
1272212727
return ira->codegen->invalid_inst_gen;
1272312728
ir_assert(is_slice(wanted_type), source_instr);
12729+
if (array_ptr_val->special == ConstValSpecialUndef) {
12730+
ZigValue *undef_array = ira->codegen->pass1_arena->create<ZigValue>();
12731+
undef_array->special = ConstValSpecialUndef;
12732+
undef_array->type = array_type;
12733+
12734+
IrInstGen *result = ir_const(ira, source_instr, wanted_type);
12735+
init_const_slice(ira->codegen, result->value, undef_array, 0, 0, false);
12736+
result->value->data.x_struct.fields[slice_ptr_index]->data.x_ptr.mut = ConstPtrMutComptimeConst;
12737+
result->value->type = wanted_type;
12738+
return result;
12739+
}
1272412740
bool wanted_const = wanted_type->data.structure.fields[slice_ptr_index]->type_entry->data.pointer.is_const;
1272512741
// Optimization to avoid creating unnecessary ZigValue in const_ptr_pointee
1272612742
if (array_ptr_val->data.x_ptr.special == ConstPtrSpecialSubArray) {
@@ -26319,18 +26335,13 @@ static IrInstGen *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstSrcSlice *i
2631926335
// then the pointer-to-array would be casted to a slice anyway. So, we preserve the laziness of these
2632026336
// values by making the return type a slice.
2632126337
ZigType *res_loc_type = get_result_loc_type(ira, instruction->result_loc);
26322-
26323-
if ((res_loc_type == nullptr || !is_slice(res_loc_type)) &&
26324-
value_is_comptime(casted_start->value) &&
26338+
bool result_loc_is_slice = (res_loc_type != nullptr && is_slice(res_loc_type));
26339+
bool end_is_known = !result_loc_is_slice &&
2632526340
((end != nullptr && value_is_comptime(end->value)) ||
26326-
(end == nullptr && child_array_type->id == ZigTypeIdArray)))
26327-
{
26328-
ZigValue *start_val = ir_resolve_const(ira, casted_start, UndefBad);
26329-
if (!start_val)
26330-
return ira->codegen->invalid_inst_gen;
26331-
26332-
uint64_t start_scalar = bigint_as_u64(&start_val->data.x_bigint);
26341+
(end == nullptr && child_array_type->id == ZigTypeIdArray));
2633326342

26343+
ZigValue *array_sentinel = sentinel_val;
26344+
if (end_is_known) {
2633426345
uint64_t end_scalar;
2633526346
if (end != nullptr) {
2633626347
ZigValue *end_val = ir_resolve_const(ira, end, UndefBad);
@@ -26340,36 +26351,46 @@ static IrInstGen *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstSrcSlice *i
2634026351
} else {
2634126352
end_scalar = child_array_type->data.array.len;
2634226353
}
26343-
ZigValue *array_sentinel = (child_array_type->id == ZigTypeIdArray &&
26344-
end_scalar == child_array_type->data.array.len)
26345-
? child_array_type->data.array.sentinel : nullptr;
26354+
array_sentinel = (child_array_type->id == ZigTypeIdArray && end_scalar == child_array_type->data.array.len)
26355+
? child_array_type->data.array.sentinel : sentinel_val;
2634626356

26347-
if (start_scalar > end_scalar) {
26348-
ir_add_error(ira, &instruction->base.base, buf_sprintf("out of bounds slice"));
26349-
return ira->codegen->invalid_inst_gen;
26350-
}
26357+
if (value_is_comptime(casted_start->value)) {
26358+
ZigValue *start_val = ir_resolve_const(ira, casted_start, UndefBad);
26359+
if (!start_val)
26360+
return ira->codegen->invalid_inst_gen;
2635126361

26352-
uint32_t base_ptr_align = non_sentinel_slice_ptr_type->data.pointer.explicit_alignment;
26353-
uint32_t ptr_byte_alignment = 0;
26354-
if (end_scalar > start_scalar) {
26355-
if ((err = compute_elem_align(ira, elem_type, base_ptr_align, start_scalar, &ptr_byte_alignment)))
26362+
uint64_t start_scalar = bigint_as_u64(&start_val->data.x_bigint);
26363+
26364+
if (start_scalar > end_scalar) {
26365+
ir_add_error(ira, &instruction->base.base, buf_sprintf("out of bounds slice"));
2635626366
return ira->codegen->invalid_inst_gen;
26357-
}
26367+
}
26368+
26369+
uint32_t base_ptr_align = non_sentinel_slice_ptr_type->data.pointer.explicit_alignment;
26370+
uint32_t ptr_byte_alignment = 0;
26371+
if (end_scalar > start_scalar) {
26372+
if ((err = compute_elem_align(ira, elem_type, base_ptr_align, start_scalar, &ptr_byte_alignment)))
26373+
return ira->codegen->invalid_inst_gen;
26374+
}
2635826375

26359-
ZigType *return_array_type = get_array_type(ira->codegen, elem_type, end_scalar - start_scalar,
26360-
array_sentinel);
26361-
return_type = get_pointer_to_type_extra(ira->codegen, return_array_type,
26362-
non_sentinel_slice_ptr_type->data.pointer.is_const,
26363-
non_sentinel_slice_ptr_type->data.pointer.is_volatile,
26364-
PtrLenSingle, ptr_byte_alignment, 0, 0, false);
26365-
} else if (sentinel_val != nullptr) {
26376+
ZigType *return_array_type = get_array_type(ira->codegen, elem_type, end_scalar - start_scalar,
26377+
array_sentinel);
26378+
return_type = get_pointer_to_type_extra(ira->codegen, return_array_type,
26379+
non_sentinel_slice_ptr_type->data.pointer.is_const,
26380+
non_sentinel_slice_ptr_type->data.pointer.is_volatile,
26381+
PtrLenSingle, ptr_byte_alignment, 0, 0, false);
26382+
goto done_with_return_type;
26383+
}
26384+
}
26385+
if (array_sentinel != nullptr) {
2636626386
// TODO deal with non-abi-alignment here
26367-
ZigType *slice_ptr_type = adjust_ptr_sentinel(ira->codegen, non_sentinel_slice_ptr_type, sentinel_val);
26387+
ZigType *slice_ptr_type = adjust_ptr_sentinel(ira->codegen, non_sentinel_slice_ptr_type, array_sentinel);
2636826388
return_type = get_slice_type(ira->codegen, slice_ptr_type);
2636926389
} else {
2637026390
// TODO deal with non-abi-alignment here
2637126391
return_type = get_slice_type(ira->codegen, non_sentinel_slice_ptr_type);
2637226392
}
26393+
done_with_return_type:
2637326394

2637426395
if (instr_is_comptime(ptr_ptr) &&
2637526396
value_is_comptime(casted_start->value) &&

test/stage1/behavior/align.zig

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,17 @@ const builtin = @import("builtin");
55
var foo: u8 align(4) = 100;
66

77
test "global variable alignment" {
8-
expect(@TypeOf(&foo).alignment == 4);
9-
expect(@TypeOf(&foo) == *align(4) u8);
10-
const slice = @as(*[1]u8, &foo)[0..];
11-
expect(@TypeOf(slice) == []align(4) u8);
8+
comptime expect(@TypeOf(&foo).alignment == 4);
9+
comptime expect(@TypeOf(&foo) == *align(4) u8);
10+
{
11+
const slice = @as(*[1]u8, &foo)[0..];
12+
comptime expect(@TypeOf(slice) == *align(4) [1]u8);
13+
}
14+
{
15+
var runtime_zero: usize = 0;
16+
const slice = @as(*[1]u8, &foo)[runtime_zero..];
17+
comptime expect(@TypeOf(slice) == []align(4) u8);
18+
}
1219
}
1320

1421
fn derp() align(@sizeOf(usize) * 2) i32 {

test/stage1/behavior/misc.zig

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -572,9 +572,9 @@ test "slice string literal has correct type" {
572572
expect(@TypeOf(array[0..]) == *const [4]i32);
573573
}
574574
var runtime_zero: usize = 0;
575-
expect(@TypeOf("aoeu"[runtime_zero..]) == [:0]const u8);
575+
comptime expect(@TypeOf("aoeu"[runtime_zero..]) == [:0]const u8);
576576
const array = [_]i32{ 1, 2, 3, 4 };
577-
expect(@TypeOf(array[runtime_zero..]) == []const u8);
577+
comptime expect(@TypeOf(array[runtime_zero..]) == []const i32);
578578
}
579579

580580
test "pointer child field" {

0 commit comments

Comments
 (0)