authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-03-16 21:41:46-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-03-19 09:53:54-04:00
log0707be8de88823ff943c3fbd7d0035f88d32dd87
tree97e21a5c78e3aa7272e929a3fb3621aeb67dcb3b
parent2182d28cb0917b8d869d13802a5955ee35b4537a
signaturelock-open Commit is signed but in an unrecognized format.

fixes in semantic analysis needed to support this feature


13 files changed, 172 insertions(+), 88 deletions(-)

lib/std/mem.zig+2-2
...@@ -560,7 +560,7 @@ pub fn span(ptr: var) Span(@TypeOf(ptr)) {...@@ -560,7 +560,7 @@ pub fn span(ptr: var) Span(@TypeOf(ptr)) {
560560
561test "span" {561test "span" {
562 var array: [5]u16 = [_]u16{ 1, 2, 3, 4, 5 };562 var array: [5]u16 = [_]u16{ 1, 2, 3, 4, 5 };
563 const ptr = array[0..2 :3].ptr;563 const ptr = @as([*:3]u16, array[0..2 :3]);
564 testing.expect(eql(u16, span(ptr), &[_]u16{ 1, 2 }));564 testing.expect(eql(u16, span(ptr), &[_]u16{ 1, 2 }));
565 testing.expect(eql(u16, span(&array), &[_]u16{ 1, 2, 3, 4, 5 }));565 testing.expect(eql(u16, span(&array), &[_]u16{ 1, 2, 3, 4, 5 }));
566}566}
...@@ -602,7 +602,7 @@ test "len" {...@@ -602,7 +602,7 @@ test "len" {
602 testing.expect(len(&array) == 5);602 testing.expect(len(&array) == 5);
603 testing.expect(len(array[0..3]) == 3);603 testing.expect(len(array[0..3]) == 3);
604 array[2] = 0;604 array[2] = 0;
605 const ptr = array[0..2 :0].ptr;605 const ptr = @as([*:0]u16, array[0..2 :0]);
606 testing.expect(len(ptr) == 2);606 testing.expect(len(ptr) == 2);
607 }607 }
608 {608 {
src-self-hosted/stage2.zig+1-1
...@@ -128,7 +128,7 @@ export fn stage2_translate_c(...@@ -128,7 +128,7 @@ export fn stage2_translate_c(
128 args_end: [*]?[*]const u8,128 args_end: [*]?[*]const u8,
129 resources_path: [*:0]const u8,129 resources_path: [*:0]const u8,
130) Error {130) Error {
131 var errors = @as([*]translate_c.ClangErrMsg, undefined)[0..0];131 var errors: []translate_c.ClangErrMsg = &[0]translate_c.ClangErrMsg{};
132 out_ast.* = translate_c.translate(std.heap.c_allocator, args_begin, args_end, &errors, resources_path) catch |err| switch (err) {132 out_ast.* = translate_c.translate(std.heap.c_allocator, args_begin, args_end, &errors, resources_path) catch |err| switch (err) {
133 error.SemanticAnalyzeFail => {133 error.SemanticAnalyzeFail => {
134 out_errors_ptr.* = errors.ptr;134 out_errors_ptr.* = errors.ptr;
src/all_types.hpp+5
...@@ -231,6 +231,7 @@ enum ConstPtrSpecial {...@@ -231,6 +231,7 @@ enum ConstPtrSpecial {
231 // The pointer is a reference to a single object.231 // The pointer is a reference to a single object.
232 ConstPtrSpecialRef,232 ConstPtrSpecialRef,
233 // The pointer points to an element in an underlying array.233 // The pointer points to an element in an underlying array.
234 // Not to be confused with ConstPtrSpecialSubArray.
234 ConstPtrSpecialBaseArray,235 ConstPtrSpecialBaseArray,
235 // The pointer points to a field in an underlying struct.236 // The pointer points to a field in an underlying struct.
236 ConstPtrSpecialBaseStruct,237 ConstPtrSpecialBaseStruct,
...@@ -257,6 +258,10 @@ enum ConstPtrSpecial {...@@ -257,6 +258,10 @@ enum ConstPtrSpecial {
257 // types to be the same, so all optionals of pointer types use x_ptr258 // types to be the same, so all optionals of pointer types use x_ptr
258 // instead of x_optional.259 // instead of x_optional.
259 ConstPtrSpecialNull,260 ConstPtrSpecialNull,
261 // The pointer points to a sub-array (not an individual element).
262 // Not to be confused with ConstPtrSpecialBaseArray. However, it uses the same
263 // union payload struct (base_array).
264 ConstPtrSpecialSubArray,
260};265};
261266
262enum ConstPtrMut {267enum ConstPtrMut {
src/analyze.cpp+7
...@@ -5280,6 +5280,11 @@ static uint32_t hash_const_val_ptr(ZigValue *const_val) {...@@ -5280,6 +5280,11 @@ static uint32_t hash_const_val_ptr(ZigValue *const_val) {
5280 hash_val += hash_ptr(const_val->data.x_ptr.data.base_array.array_val);5280 hash_val += hash_ptr(const_val->data.x_ptr.data.base_array.array_val);
5281 hash_val += hash_size(const_val->data.x_ptr.data.base_array.elem_index);5281 hash_val += hash_size(const_val->data.x_ptr.data.base_array.elem_index);
5282 return hash_val;5282 return hash_val;
5283 case ConstPtrSpecialSubArray:
5284 hash_val += (uint32_t)2643358777;
5285 hash_val += hash_ptr(const_val->data.x_ptr.data.base_array.array_val);
5286 hash_val += hash_size(const_val->data.x_ptr.data.base_array.elem_index);
5287 return hash_val;
5283 case ConstPtrSpecialBaseStruct:5288 case ConstPtrSpecialBaseStruct:
5284 hash_val += (uint32_t)3518317043;5289 hash_val += (uint32_t)3518317043;
5285 hash_val += hash_ptr(const_val->data.x_ptr.data.base_struct.struct_val);5290 hash_val += hash_ptr(const_val->data.x_ptr.data.base_struct.struct_val);
...@@ -6746,6 +6751,7 @@ bool const_values_equal_ptr(ZigValue *a, ZigValue *b) {...@@ -6746,6 +6751,7 @@ bool const_values_equal_ptr(ZigValue *a, ZigValue *b) {
6746 return false;6751 return false;
6747 return true;6752 return true;
6748 case ConstPtrSpecialBaseArray:6753 case ConstPtrSpecialBaseArray:
6754 case ConstPtrSpecialSubArray:
6749 if (a->data.x_ptr.data.base_array.array_val != b->data.x_ptr.data.base_array.array_val) {6755 if (a->data.x_ptr.data.base_array.array_val != b->data.x_ptr.data.base_array.array_val) {
6750 return false;6756 return false;
6751 }6757 }
...@@ -7003,6 +7009,7 @@ static void render_const_val_ptr(CodeGen *g, Buf *buf, ZigValue *const_val, ZigT...@@ -7003,6 +7009,7 @@ static void render_const_val_ptr(CodeGen *g, Buf *buf, ZigValue *const_val, ZigT
7003 render_const_value(g, buf, const_ptr_pointee(nullptr, g, const_val, nullptr));7009 render_const_value(g, buf, const_ptr_pointee(nullptr, g, const_val, nullptr));
7004 return;7010 return;
7005 case ConstPtrSpecialBaseArray:7011 case ConstPtrSpecialBaseArray:
7012 case ConstPtrSpecialSubArray:
7006 buf_appendf(buf, "*");7013 buf_appendf(buf, "*");
7007 // TODO we need a source node for const_ptr_pointee because it can generate compile errors7014 // TODO we need a source node for const_ptr_pointee because it can generate compile errors
7008 render_const_value(g, buf, const_ptr_pointee(nullptr, g, const_val, nullptr));7015 render_const_value(g, buf, const_ptr_pointee(nullptr, g, const_val, nullptr));
src/codegen.cpp+14-17
...@@ -5418,8 +5418,6 @@ static LLVMValueRef ir_render_slice(CodeGen *g, IrExecutableGen *executable, IrI...@@ -5418,8 +5418,6 @@ static LLVMValueRef ir_render_slice(CodeGen *g, IrExecutableGen *executable, IrI
5418 ZigType *array_type = array_ptr_type->data.pointer.child_type;5418 ZigType *array_type = array_ptr_type->data.pointer.child_type;
5419 LLVMValueRef array_ptr = get_handle_value(g, array_ptr_ptr, array_type, array_ptr_type);5419 LLVMValueRef array_ptr = get_handle_value(g, array_ptr_ptr, array_type, array_ptr_type);
54205420
5421 LLVMValueRef tmp_struct_ptr = ir_llvm_value(g, instruction->result_loc);
5422
5423 bool want_runtime_safety = instruction->safety_check_on && ir_want_runtime_safety(g, &instruction->base);5421 bool want_runtime_safety = instruction->safety_check_on && ir_want_runtime_safety(g, &instruction->base);
54245422
5425 ZigType *result_type = instruction->base.value->type;5423 ZigType *result_type = instruction->base.value->type;
...@@ -5472,6 +5470,8 @@ static LLVMValueRef ir_render_slice(CodeGen *g, IrExecutableGen *executable, IrI...@@ -5472,6 +5470,8 @@ static LLVMValueRef ir_render_slice(CodeGen *g, IrExecutableGen *executable, IrI
5472 }5470 }
5473 }5471 }
5474 if (!type_has_bits(g, array_type)) {5472 if (!type_has_bits(g, array_type)) {
5473 LLVMValueRef tmp_struct_ptr = ir_llvm_value(g, instruction->result_loc);
5474
5475 LLVMValueRef len_field_ptr = LLVMBuildStructGEP(g->builder, tmp_struct_ptr, slice_len_index, "");5475 LLVMValueRef len_field_ptr = LLVMBuildStructGEP(g->builder, tmp_struct_ptr, slice_len_index, "");
54765476
5477 // TODO if runtime safety is on, store 0xaaaaaaa in ptr field5477 // TODO if runtime safety is on, store 0xaaaaaaa in ptr field
...@@ -5486,20 +5486,20 @@ static LLVMValueRef ir_render_slice(CodeGen *g, IrExecutableGen *executable, IrI...@@ -5486,20 +5486,20 @@ static LLVMValueRef ir_render_slice(CodeGen *g, IrExecutableGen *executable, IrI
5486 };5486 };
5487 LLVMValueRef slice_start_ptr = LLVMBuildInBoundsGEP(g->builder, array_ptr, indices, 2, "");5487 LLVMValueRef slice_start_ptr = LLVMBuildInBoundsGEP(g->builder, array_ptr, indices, 2, "");
5488 if (result_type->id == ZigTypeIdPointer) {5488 if (result_type->id == ZigTypeIdPointer) {
5489 ir_assert(instruction->result_loc == nullptr, &instruction->base);
5489 LLVMTypeRef result_ptr_type = get_llvm_type(g, result_type);5490 LLVMTypeRef result_ptr_type = get_llvm_type(g, result_type);
5490 LLVMValueRef bitcasted = LLVMBuildBitCast(g->builder, slice_start_ptr, result_ptr_type, "");5491 return LLVMBuildBitCast(g->builder, slice_start_ptr, result_ptr_type, "");
5491 gen_store_untyped(g, bitcasted, tmp_struct_ptr, 0, false);
5492 return slice_start_ptr;
5493 } else {5492 } else {
5493 LLVMValueRef tmp_struct_ptr = ir_llvm_value(g, instruction->result_loc);
5494 LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP(g->builder, tmp_struct_ptr, slice_ptr_index, "");5494 LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP(g->builder, tmp_struct_ptr, slice_ptr_index, "");
5495 gen_store_untyped(g, slice_start_ptr, ptr_field_ptr, 0, false);5495 gen_store_untyped(g, slice_start_ptr, ptr_field_ptr, 0, false);
54965496
5497 LLVMValueRef len_field_ptr = LLVMBuildStructGEP(g->builder, tmp_struct_ptr, slice_len_index, "");5497 LLVMValueRef len_field_ptr = LLVMBuildStructGEP(g->builder, tmp_struct_ptr, slice_len_index, "");
5498 LLVMValueRef len_value = LLVMBuildNSWSub(g->builder, end_val, start_val, "");5498 LLVMValueRef len_value = LLVMBuildNSWSub(g->builder, end_val, start_val, "");
5499 gen_store_untyped(g, len_value, len_field_ptr, 0, false);5499 gen_store_untyped(g, len_value, len_field_ptr, 0, false);
5500 }
55015500
5502 return tmp_struct_ptr;5501 return tmp_struct_ptr;
5502 }
5503 } else if (array_type->id == ZigTypeIdPointer) {5503 } else if (array_type->id == ZigTypeIdPointer) {
5504 assert(array_type->data.pointer.ptr_len != PtrLenSingle);5504 assert(array_type->data.pointer.ptr_len != PtrLenSingle);
5505 LLVMValueRef start_val = ir_llvm_value(g, instruction->start);5505 LLVMValueRef start_val = ir_llvm_value(g, instruction->start);
...@@ -5515,12 +5515,12 @@ static LLVMValueRef ir_render_slice(CodeGen *g, IrExecutableGen *executable, IrI...@@ -5515,12 +5515,12 @@ static LLVMValueRef ir_render_slice(CodeGen *g, IrExecutableGen *executable, IrI
55155515
5516 LLVMValueRef slice_start_ptr = LLVMBuildInBoundsGEP(g->builder, array_ptr, &start_val, 1, "");5516 LLVMValueRef slice_start_ptr = LLVMBuildInBoundsGEP(g->builder, array_ptr, &start_val, 1, "");
5517 if (result_type->id == ZigTypeIdPointer) {5517 if (result_type->id == ZigTypeIdPointer) {
5518 ir_assert(instruction->result_loc == nullptr, &instruction->base);
5518 LLVMTypeRef result_ptr_type = get_llvm_type(g, result_type);5519 LLVMTypeRef result_ptr_type = get_llvm_type(g, result_type);
5519 LLVMValueRef bitcasted = LLVMBuildBitCast(g->builder, slice_start_ptr, result_ptr_type, "");5520 return LLVMBuildBitCast(g->builder, slice_start_ptr, result_ptr_type, "");
5520 gen_store_untyped(g, bitcasted, tmp_struct_ptr, 0, false);
5521 return bitcasted;
5522 }5521 }
55235522
5523 LLVMValueRef tmp_struct_ptr = ir_llvm_value(g, instruction->result_loc);
5524 if (type_has_bits(g, array_type)) {5524 if (type_has_bits(g, array_type)) {
5525 size_t gen_ptr_index = result_type->data.structure.fields[slice_ptr_index]->gen_index;5525 size_t gen_ptr_index = result_type->data.structure.fields[slice_ptr_index]->gen_index;
5526 LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP(g->builder, tmp_struct_ptr, gen_ptr_index, "");5526 LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP(g->builder, tmp_struct_ptr, gen_ptr_index, "");
...@@ -5537,9 +5537,6 @@ static LLVMValueRef ir_render_slice(CodeGen *g, IrExecutableGen *executable, IrI...@@ -5537,9 +5537,6 @@ static LLVMValueRef ir_render_slice(CodeGen *g, IrExecutableGen *executable, IrI
5537 assert(array_type->data.structure.special == StructSpecialSlice);5537 assert(array_type->data.structure.special == StructSpecialSlice);
5538 assert(LLVMGetTypeKind(LLVMTypeOf(array_ptr)) == LLVMPointerTypeKind);5538 assert(LLVMGetTypeKind(LLVMTypeOf(array_ptr)) == LLVMPointerTypeKind);
5539 assert(LLVMGetTypeKind(LLVMGetElementType(LLVMTypeOf(array_ptr))) == LLVMStructTypeKind);5539 assert(LLVMGetTypeKind(LLVMGetElementType(LLVMTypeOf(array_ptr))) == LLVMStructTypeKind);
5540 if (result_type->id != ZigTypeIdPointer) {
5541 assert(LLVMGetTypeKind(LLVMGetElementType(LLVMTypeOf(tmp_struct_ptr))) == LLVMStructTypeKind);
5542 }
55435540
5544 size_t ptr_index = array_type->data.structure.fields[slice_ptr_index]->gen_index;5541 size_t ptr_index = array_type->data.structure.fields[slice_ptr_index]->gen_index;
5545 assert(ptr_index != SIZE_MAX);5542 assert(ptr_index != SIZE_MAX);
...@@ -5578,11 +5575,11 @@ static LLVMValueRef ir_render_slice(CodeGen *g, IrExecutableGen *executable, IrI...@@ -5578,11 +5575,11 @@ static LLVMValueRef ir_render_slice(CodeGen *g, IrExecutableGen *executable, IrI
55785575
5579 LLVMValueRef slice_start_ptr = LLVMBuildInBoundsGEP(g->builder, src_ptr, &start_val, 1, "");5576 LLVMValueRef slice_start_ptr = LLVMBuildInBoundsGEP(g->builder, src_ptr, &start_val, 1, "");
5580 if (result_type->id == ZigTypeIdPointer) {5577 if (result_type->id == ZigTypeIdPointer) {
5578 ir_assert(instruction->result_loc == nullptr, &instruction->base);
5581 LLVMTypeRef result_ptr_type = get_llvm_type(g, result_type);5579 LLVMTypeRef result_ptr_type = get_llvm_type(g, result_type);
5582 LLVMValueRef bitcasted = LLVMBuildBitCast(g->builder, slice_start_ptr, result_ptr_type, "");5580 return LLVMBuildBitCast(g->builder, slice_start_ptr, result_ptr_type, "");
5583 gen_store_untyped(g, bitcasted, tmp_struct_ptr, 0, false);
5584 return bitcasted;
5585 } else {5581 } else {
5582 LLVMValueRef tmp_struct_ptr = ir_llvm_value(g, instruction->result_loc);
5586 LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP(g->builder, tmp_struct_ptr, (unsigned)ptr_index, "");5583 LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP(g->builder, tmp_struct_ptr, (unsigned)ptr_index, "");
5587 gen_store_untyped(g, slice_start_ptr, ptr_field_ptr, 0, false);5584 gen_store_untyped(g, slice_start_ptr, ptr_field_ptr, 0, false);
55885585
...@@ -6676,7 +6673,6 @@ static LLVMValueRef gen_const_ptr_array_recursive(CodeGen *g, ZigValue *array_co...@@ -6676,7 +6673,6 @@ static LLVMValueRef gen_const_ptr_array_recursive(CodeGen *g, ZigValue *array_co
6676 };6673 };
6677 return LLVMConstInBoundsGEP(base_ptr, indices, 2);6674 return LLVMConstInBoundsGEP(base_ptr, indices, 2);
6678 } else {6675 } else {
6679 assert(parent->id == ConstParentIdScalar);
6680 return base_ptr;6676 return base_ptr;
6681 }6677 }
6682}6678}
...@@ -6904,6 +6900,7 @@ static LLVMValueRef gen_const_val_ptr(CodeGen *g, ZigValue *const_val, const cha...@@ -6904,6 +6900,7 @@ static LLVMValueRef gen_const_val_ptr(CodeGen *g, ZigValue *const_val, const cha
6904 return const_val->llvm_value;6900 return const_val->llvm_value;
6905 }6901 }
6906 case ConstPtrSpecialBaseArray:6902 case ConstPtrSpecialBaseArray:
6903 case ConstPtrSpecialSubArray:
6907 {6904 {
6908 ZigValue *array_const_val = const_val->data.x_ptr.data.base_array.array_val;6905 ZigValue *array_const_val = const_val->data.x_ptr.data.base_array.array_val;
6909 assert(array_const_val->type->id == ZigTypeIdArray);6906 assert(array_const_val->type->id == ZigTypeIdArray);
src/ir.cpp+110-45
...@@ -784,14 +784,32 @@ static ZigValue *const_ptr_pointee_unchecked_no_isf(CodeGen *g, ZigValue *const_...@@ -784,14 +784,32 @@ static ZigValue *const_ptr_pointee_unchecked_no_isf(CodeGen *g, ZigValue *const_
784 break;784 break;
785 case ConstPtrSpecialBaseArray: {785 case ConstPtrSpecialBaseArray: {
786 ZigValue *array_val = const_val->data.x_ptr.data.base_array.array_val;786 ZigValue *array_val = const_val->data.x_ptr.data.base_array.array_val;
787 if (const_val->data.x_ptr.data.base_array.elem_index == array_val->type->data.array.len) {787 size_t elem_index = const_val->data.x_ptr.data.base_array.elem_index;
788 if (elem_index == array_val->type->data.array.len) {
788 result = array_val->type->data.array.sentinel;789 result = array_val->type->data.array.sentinel;
789 } else {790 } else {
790 expand_undef_array(g, array_val);791 expand_undef_array(g, array_val);
791 result = &array_val->data.x_array.data.s_none.elements[const_val->data.x_ptr.data.base_array.elem_index];792 result = &array_val->data.x_array.data.s_none.elements[elem_index];
792 }793 }
793 break;794 break;
794 }795 }
796 case ConstPtrSpecialSubArray: {
797 ZigValue *array_val = const_val->data.x_ptr.data.base_array.array_val;
798 size_t elem_index = const_val->data.x_ptr.data.base_array.elem_index;
799
800 // TODO handle sentinel terminated arrays
801 expand_undef_array(g, array_val);
802 result = g->pass1_arena->create<ZigValue>();
803 result->special = array_val->special;
804 result->type = get_array_type(g, array_val->type->data.array.child_type,
805 array_val->type->data.array.len - elem_index, nullptr);
806 result->data.x_array.special = ConstArraySpecialNone;
807 result->data.x_array.data.s_none.elements = &array_val->data.x_array.data.s_none.elements[elem_index];
808 result->parent.id = ConstParentIdArray;
809 result->parent.data.p_array.array_val = array_val;
810 result->parent.data.p_array.elem_index = elem_index;
811 break;
812 }
795 case ConstPtrSpecialBaseStruct: {813 case ConstPtrSpecialBaseStruct: {
796 ZigValue *struct_val = const_val->data.x_ptr.data.base_struct.struct_val;814 ZigValue *struct_val = const_val->data.x_ptr.data.base_struct.struct_val;
797 expand_undef_struct(g, struct_val);815 expand_undef_struct(g, struct_val);
...@@ -3727,8 +3745,8 @@ static IrInstGen *ir_build_slice_gen(IrAnalyze *ira, IrInst *source_instruction,...@@ -3727,8 +3745,8 @@ static IrInstGen *ir_build_slice_gen(IrAnalyze *ira, IrInst *source_instruction,
37273745
3728 ir_ref_inst_gen(ptr, ira->new_irb.current_basic_block);3746 ir_ref_inst_gen(ptr, ira->new_irb.current_basic_block);
3729 ir_ref_inst_gen(start, ira->new_irb.current_basic_block);3747 ir_ref_inst_gen(start, ira->new_irb.current_basic_block);
3730 if (end) ir_ref_inst_gen(end, ira->new_irb.current_basic_block);3748 if (end != nullptr) ir_ref_inst_gen(end, ira->new_irb.current_basic_block);
3731 ir_ref_inst_gen(result_loc, ira->new_irb.current_basic_block);3749 if (result_loc != nullptr) ir_ref_inst_gen(result_loc, ira->new_irb.current_basic_block);
37323750
3733 return &instruction->base;3751 return &instruction->base;
3734}3752}
...@@ -12672,40 +12690,63 @@ static IrInstGen *ir_resolve_ptr_of_array_to_slice(IrAnalyze *ira, IrInst* sourc...@@ -12672,40 +12690,63 @@ static IrInstGen *ir_resolve_ptr_of_array_to_slice(IrAnalyze *ira, IrInst* sourc
12672 Error err;12690 Error err;
1267312691
12674 assert(array_ptr->value->type->id == ZigTypeIdPointer);12692 assert(array_ptr->value->type->id == ZigTypeIdPointer);
12693 assert(array_ptr->value->type->data.pointer.child_type->id == ZigTypeIdArray);
1267512694
12676 if ((err = type_resolve(ira->codegen, array_ptr->value->type, ResolveStatusAlignmentKnown))) {12695 ZigType *array_type = array_ptr->value->type->data.pointer.child_type;
12677 return ira->codegen->invalid_inst_gen;12696 const size_t array_len = array_type->data.array.len;
12678 }
1267912697
12680 assert(array_ptr->value->type->data.pointer.child_type->id == ZigTypeIdArray);12698 // A zero-sized array can be casted regardless of the destination alignment, or
12699 // 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;
1268112704
12682 const size_t array_len = array_ptr->value->type->data.pointer.child_type->data.array.len;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 }
1268312711
12684 // A zero-sized array can always be casted irregardless of the destination12712 if ((err = type_resolve(ira->codegen, array_ptr->value->type, ResolveStatusAlignmentKnown))) {
12685 // alignment12713 return ira->codegen->invalid_inst_gen;
12686 if (array_len != 0) {
12687 wanted_type = adjust_slice_align(ira->codegen, wanted_type,
12688 get_ptr_align(ira->codegen, array_ptr->value->type));
12689 }12714 }
1269012715
12716 wanted_type = adjust_slice_align(ira->codegen, wanted_type,
12717 get_ptr_align(ira->codegen, array_ptr->value->type));
12718
12691 if (instr_is_comptime(array_ptr)) {12719 if (instr_is_comptime(array_ptr)) {
12692 ZigValue *array_ptr_val = ir_resolve_const(ira, array_ptr, UndefBad);12720 ZigValue *array_ptr_val = ir_resolve_const(ira, array_ptr, UndefBad);
12693 if (array_ptr_val == nullptr)12721 if (array_ptr_val == nullptr)
12694 return ira->codegen->invalid_inst_gen;12722 return ira->codegen->invalid_inst_gen;
12695 ZigValue *pointee = const_ptr_pointee(ira, ira->codegen, array_ptr_val, source_instr->source_node);12723 ir_assert(is_slice(wanted_type), source_instr);
12696 if (pointee == nullptr)12724 bool wanted_const = wanted_type->data.structure.fields[slice_ptr_index]->type_entry->data.pointer.is_const;
12697 return ira->codegen->invalid_inst_gen;12725 // Optimization to avoid creating unnecessary ZigValue in const_ptr_pointee
12698 if (pointee->special != ConstValSpecialRuntime) {12726 if (array_ptr_val->data.x_ptr.special == ConstPtrSpecialSubArray) {
12699 assert(array_ptr_val->type->id == ZigTypeIdPointer);12727 ZigValue *array_val = array_ptr_val->data.x_ptr.data.base_array.array_val;
12700 ZigType *array_type = array_ptr_val->type->data.pointer.child_type;12728 if (array_val->special != ConstValSpecialRuntime) {
12701 assert(is_slice(wanted_type));12729 IrInstGen *result = ir_const(ira, source_instr, wanted_type);
12702 bool is_const = wanted_type->data.structure.fields[slice_ptr_index]->type_entry->data.pointer.is_const;12730 init_const_slice(ira->codegen, result->value, array_val,
12731 array_ptr_val->data.x_ptr.data.base_array.elem_index,
12732 array_type->data.array.len, wanted_const);
12733 result->value->data.x_struct.fields[slice_ptr_index]->data.x_ptr.mut = array_ptr_val->data.x_ptr.mut;
12734 result->value->type = wanted_type;
12735 return result;
12736 }
12737 } else {
12738 ZigValue *pointee = const_ptr_pointee(ira, ira->codegen, array_ptr_val, source_instr->source_node);
12739 if (pointee == nullptr)
12740 return ira->codegen->invalid_inst_gen;
12741 if (pointee->special != ConstValSpecialRuntime) {
12742 assert(array_ptr_val->type->id == ZigTypeIdPointer);
1270312743
12704 IrInstGen *result = ir_const(ira, source_instr, wanted_type);12744 IrInstGen *result = ir_const(ira, source_instr, wanted_type);
12705 init_const_slice(ira->codegen, result->value, pointee, 0, array_type->data.array.len, is_const);12745 init_const_slice(ira->codegen, result->value, pointee, 0, array_type->data.array.len, wanted_const);
12706 result->value->data.x_struct.fields[slice_ptr_index]->data.x_ptr.mut = array_ptr_val->data.x_ptr.mut;12746 result->value->data.x_struct.fields[slice_ptr_index]->data.x_ptr.mut = array_ptr_val->data.x_ptr.mut;
12707 result->value->type = wanted_type;12747 result->value->type = wanted_type;
12708 return result;12748 return result;
12749 }
12709 }12750 }
12710 }12751 }
1271112752
...@@ -19931,6 +19972,7 @@ static Error ir_read_const_ptr(IrAnalyze *ira, CodeGen *codegen, AstNode *source...@@ -19931,6 +19972,7 @@ static Error ir_read_const_ptr(IrAnalyze *ira, CodeGen *codegen, AstNode *source
19931 dst_size, buf_ptr(&pointee->type->name), src_size));19972 dst_size, buf_ptr(&pointee->type->name), src_size));
19932 return ErrorSemanticAnalyzeFail;19973 return ErrorSemanticAnalyzeFail;
19933 }19974 }
19975 case ConstPtrSpecialSubArray:
19934 case ConstPtrSpecialBaseArray: {19976 case ConstPtrSpecialBaseArray: {
19935 ZigValue *array_val = ptr_val->data.x_ptr.data.base_array.array_val;19977 ZigValue *array_val = ptr_val->data.x_ptr.data.base_array.array_val;
19936 assert(array_val->type->id == ZigTypeIdArray);19978 assert(array_val->type->id == ZigTypeIdArray);
...@@ -20814,6 +20856,7 @@ static IrInstGen *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstSrcElemP...@@ -20814,6 +20856,7 @@ static IrInstGen *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstSrcElemP
20814 }20856 }
20815 break;20857 break;
20816 case ConstPtrSpecialBaseArray:20858 case ConstPtrSpecialBaseArray:
20859 case ConstPtrSpecialSubArray:
20817 {20860 {
20818 size_t offset = array_ptr_val->data.x_ptr.data.base_array.elem_index;20861 size_t offset = array_ptr_val->data.x_ptr.data.base_array.elem_index;
20819 new_index = offset + index;20862 new_index = offset + index;
...@@ -20884,6 +20927,7 @@ static IrInstGen *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstSrcElemP...@@ -20884,6 +20927,7 @@ static IrInstGen *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstSrcElemP
20884 out_val->data.x_ptr.special = ConstPtrSpecialRef;20927 out_val->data.x_ptr.special = ConstPtrSpecialRef;
20885 out_val->data.x_ptr.data.ref.pointee = ptr_field->data.x_ptr.data.ref.pointee;20928 out_val->data.x_ptr.data.ref.pointee = ptr_field->data.x_ptr.data.ref.pointee;
20886 break;20929 break;
20930 case ConstPtrSpecialSubArray:
20887 case ConstPtrSpecialBaseArray:20931 case ConstPtrSpecialBaseArray:
20888 {20932 {
20889 size_t offset = ptr_field->data.x_ptr.data.base_array.elem_index;20933 size_t offset = ptr_field->data.x_ptr.data.base_array.elem_index;
...@@ -25894,6 +25938,7 @@ static IrInstGen *ir_analyze_instruction_memset(IrAnalyze *ira, IrInstSrcMemset...@@ -25894,6 +25938,7 @@ static IrInstGen *ir_analyze_instruction_memset(IrAnalyze *ira, IrInstSrcMemset
25894 start = 0;25938 start = 0;
25895 bound_end = 1;25939 bound_end = 1;
25896 break;25940 break;
25941 case ConstPtrSpecialSubArray:
25897 case ConstPtrSpecialBaseArray:25942 case ConstPtrSpecialBaseArray:
25898 {25943 {
25899 ZigValue *array_val = dest_ptr_val->data.x_ptr.data.base_array.array_val;25944 ZigValue *array_val = dest_ptr_val->data.x_ptr.data.base_array.array_val;
...@@ -26027,6 +26072,7 @@ static IrInstGen *ir_analyze_instruction_memcpy(IrAnalyze *ira, IrInstSrcMemcpy...@@ -26027,6 +26072,7 @@ static IrInstGen *ir_analyze_instruction_memcpy(IrAnalyze *ira, IrInstSrcMemcpy
26027 dest_start = 0;26072 dest_start = 0;
26028 dest_end = 1;26073 dest_end = 1;
26029 break;26074 break;
26075 case ConstPtrSpecialSubArray:
26030 case ConstPtrSpecialBaseArray:26076 case ConstPtrSpecialBaseArray:
26031 {26077 {
26032 ZigValue *array_val = dest_ptr_val->data.x_ptr.data.base_array.array_val;26078 ZigValue *array_val = dest_ptr_val->data.x_ptr.data.base_array.array_val;
...@@ -26070,6 +26116,7 @@ static IrInstGen *ir_analyze_instruction_memcpy(IrAnalyze *ira, IrInstSrcMemcpy...@@ -26070,6 +26116,7 @@ static IrInstGen *ir_analyze_instruction_memcpy(IrAnalyze *ira, IrInstSrcMemcpy
26070 src_start = 0;26116 src_start = 0;
26071 src_end = 1;26117 src_end = 1;
26072 break;26118 break;
26119 case ConstPtrSpecialSubArray:
26073 case ConstPtrSpecialBaseArray:26120 case ConstPtrSpecialBaseArray:
26074 {26121 {
26075 ZigValue *array_val = src_ptr_val->data.x_ptr.data.base_array.array_val;26122 ZigValue *array_val = src_ptr_val->data.x_ptr.data.base_array.array_val;
...@@ -26219,7 +26266,8 @@ static IrInstGen *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstSrcSlice *i...@@ -26219,7 +26266,8 @@ static IrInstGen *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstSrcSlice *i
26219 ZigType *return_type;26266 ZigType *return_type;
2622026267
26221 if (value_is_comptime(casted_start->value) &&26268 if (value_is_comptime(casted_start->value) &&
26222 ((end != nullptr && value_is_comptime(end->value)) || array_type->id == ZigTypeIdArray ))26269 ((end != nullptr && value_is_comptime(end->value)) ||
26270 (end == nullptr && array_type->id == ZigTypeIdArray)))
26223 {26271 {
26224 ZigValue *start_val = ir_resolve_const(ira, casted_start, UndefBad);26272 ZigValue *start_val = ir_resolve_const(ira, casted_start, UndefBad);
26225 if (!start_val)26273 if (!start_val)
...@@ -26244,13 +26292,16 @@ static IrInstGen *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstSrcSlice *i...@@ -26244,13 +26292,16 @@ static IrInstGen *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstSrcSlice *i
26244 return ira->codegen->invalid_inst_gen;26292 return ira->codegen->invalid_inst_gen;
26245 }26293 }
2624626294
26295 // TODO in the case of non-zero start index, the byte alignment should be smarter here.
26296 // we should be able to use the same logic as indexing.
26297 uint32_t ptr_byte_alignment = ((end_scalar - start_scalar != 0) && start_scalar == 0) ?
26298 non_sentinel_slice_ptr_type->data.pointer.explicit_alignment : 0;
26247 ZigType *return_array_type = get_array_type(ira->codegen, elem_type, end_scalar - start_scalar,26299 ZigType *return_array_type = get_array_type(ira->codegen, elem_type, end_scalar - start_scalar,
26248 array_sentinel);26300 array_sentinel);
26249 return_type = get_pointer_to_type_extra(ira->codegen, return_array_type,26301 return_type = get_pointer_to_type_extra(ira->codegen, return_array_type,
26250 non_sentinel_slice_ptr_type->data.pointer.is_const,26302 non_sentinel_slice_ptr_type->data.pointer.is_const,
26251 non_sentinel_slice_ptr_type->data.pointer.is_volatile,26303 non_sentinel_slice_ptr_type->data.pointer.is_volatile,
26252 PtrLenSingle,26304 PtrLenSingle, ptr_byte_alignment, 0, 0, false);
26253 0, 0, 0, false);
26254 } else if (sentinel_val != nullptr) {26305 } else if (sentinel_val != nullptr) {
26255 ZigType *slice_ptr_type = adjust_ptr_sentinel(ira->codegen, non_sentinel_slice_ptr_type, sentinel_val);26306 ZigType *slice_ptr_type = adjust_ptr_sentinel(ira->codegen, non_sentinel_slice_ptr_type, sentinel_val);
26256 return_type = get_slice_type(ira->codegen, slice_ptr_type);26307 return_type = get_slice_type(ira->codegen, slice_ptr_type);
...@@ -26283,6 +26334,10 @@ static IrInstGen *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstSrcSlice *i...@@ -26283,6 +26334,10 @@ static IrInstGen *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstSrcSlice *i
26283 abs_offset = 0;26334 abs_offset = 0;
26284 rel_end = SIZE_MAX;26335 rel_end = SIZE_MAX;
26285 ptr_is_undef = true;26336 ptr_is_undef = true;
26337 } else if (parent_ptr->data.x_ptr.special == ConstPtrSpecialHardCodedAddr) {
26338 array_val = nullptr;
26339 abs_offset = 0;
26340 rel_end = SIZE_MAX;
26286 } else {26341 } else {
26287 array_val = const_ptr_pointee(ira, ira->codegen, parent_ptr, instruction->base.base.source_node);26342 array_val = const_ptr_pointee(ira, ira->codegen, parent_ptr, instruction->base.base.source_node);
26288 if (array_val == nullptr)26343 if (array_val == nullptr)
...@@ -26325,6 +26380,7 @@ static IrInstGen *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstSrcSlice *i...@@ -26325,6 +26380,7 @@ static IrInstGen *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstSrcSlice *i
26325 rel_end = 1;26380 rel_end = 1;
26326 }26381 }
26327 break;26382 break;
26383 case ConstPtrSpecialSubArray:
26328 case ConstPtrSpecialBaseArray:26384 case ConstPtrSpecialBaseArray:
26329 array_val = parent_ptr->data.x_ptr.data.base_array.array_val;26385 array_val = parent_ptr->data.x_ptr.data.base_array.array_val;
26330 abs_offset = parent_ptr->data.x_ptr.data.base_array.elem_index;26386 abs_offset = parent_ptr->data.x_ptr.data.base_array.elem_index;
...@@ -26375,6 +26431,7 @@ static IrInstGen *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstSrcSlice *i...@@ -26375,6 +26431,7 @@ static IrInstGen *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstSrcSlice *i
26375 abs_offset = SIZE_MAX;26431 abs_offset = SIZE_MAX;
26376 rel_end = 1;26432 rel_end = 1;
26377 break;26433 break;
26434 case ConstPtrSpecialSubArray:
26378 case ConstPtrSpecialBaseArray:26435 case ConstPtrSpecialBaseArray:
26379 array_val = parent_ptr->data.x_ptr.data.base_array.array_val;26436 array_val = parent_ptr->data.x_ptr.data.base_array.array_val;
26380 abs_offset = parent_ptr->data.x_ptr.data.base_array.elem_index;26437 abs_offset = parent_ptr->data.x_ptr.data.base_array.elem_index;
...@@ -26454,6 +26511,9 @@ static IrInstGen *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstSrcSlice *i...@@ -26454,6 +26511,9 @@ static IrInstGen *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstSrcSlice *i
26454 if (array_val) {26511 if (array_val) {
26455 size_t index = abs_offset + start_scalar;26512 size_t index = abs_offset + start_scalar;
26456 init_const_ptr_array(ira->codegen, ptr_val, array_val, index, return_type_is_const, PtrLenUnknown);26513 init_const_ptr_array(ira->codegen, ptr_val, array_val, index, return_type_is_const, PtrLenUnknown);
26514 if (return_type->id == ZigTypeIdPointer) {
26515 ptr_val->data.x_ptr.special = ConstPtrSpecialSubArray;
26516 }
26457 if (array_type->id == ZigTypeIdArray) {26517 if (array_type->id == ZigTypeIdArray) {
26458 ptr_val->data.x_ptr.mut = ptr_ptr->value->data.x_ptr.mut;26518 ptr_val->data.x_ptr.mut = ptr_ptr->value->data.x_ptr.mut;
26459 } else if (is_slice(array_type)) {26519 } else if (is_slice(array_type)) {
...@@ -26463,7 +26523,7 @@ static IrInstGen *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstSrcSlice *i...@@ -26463,7 +26523,7 @@ static IrInstGen *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstSrcSlice *i
26463 }26523 }
26464 } else if (ptr_is_undef) {26524 } else if (ptr_is_undef) {
26465 ptr_val->type = get_pointer_to_type(ira->codegen, parent_ptr->type->data.pointer.child_type,26525 ptr_val->type = get_pointer_to_type(ira->codegen, parent_ptr->type->data.pointer.child_type,
26466 return_type_is_const);26526 return_type_is_const);
26467 ptr_val->special = ConstValSpecialUndef;26527 ptr_val->special = ConstValSpecialUndef;
26468 } else switch (parent_ptr->data.x_ptr.special) {26528 } else switch (parent_ptr->data.x_ptr.special) {
26469 case ConstPtrSpecialInvalid:26529 case ConstPtrSpecialInvalid:
...@@ -26473,6 +26533,7 @@ static IrInstGen *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstSrcSlice *i...@@ -26473,6 +26533,7 @@ static IrInstGen *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstSrcSlice *i
26473 init_const_ptr_ref(ira->codegen, ptr_val, parent_ptr->data.x_ptr.data.ref.pointee,26533 init_const_ptr_ref(ira->codegen, ptr_val, parent_ptr->data.x_ptr.data.ref.pointee,
26474 return_type_is_const);26534 return_type_is_const);
26475 break;26535 break;
26536 case ConstPtrSpecialSubArray:
26476 case ConstPtrSpecialBaseArray:26537 case ConstPtrSpecialBaseArray:
26477 zig_unreachable();26538 zig_unreachable();
26478 case ConstPtrSpecialBaseStruct:26539 case ConstPtrSpecialBaseStruct:
...@@ -26500,20 +26561,6 @@ static IrInstGen *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstSrcSlice *i...@@ -26500,20 +26561,6 @@ static IrInstGen *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstSrcSlice *i
26500 return result;26561 return result;
26501 }26562 }
2650226563
26503 IrInstGen *result_loc = ir_resolve_result(ira, &instruction->base.base, instruction->result_loc,
26504 return_type, nullptr, true, true);
26505 if (result_loc != nullptr) {
26506 if (type_is_invalid(result_loc->value->type) || result_loc->value->type->id == ZigTypeIdUnreachable) {
26507 return result_loc;
26508 }
26509 IrInstGen *dummy_value = ir_const(ira, &instruction->base.base, return_type);
26510 dummy_value->value->special = ConstValSpecialRuntime;
26511 IrInstGen *dummy_result = ir_implicit_cast2(ira, &instruction->base.base,
26512 dummy_value, result_loc->value->type->data.pointer.child_type);
26513 if (type_is_invalid(dummy_result->value->type))
26514 return ira->codegen->invalid_inst_gen;
26515 }
26516
26517 if (generate_non_null_assert) {26564 if (generate_non_null_assert) {
26518 IrInstGen *ptr_val = ir_get_deref(ira, &instruction->base.base, ptr_ptr, nullptr);26565 IrInstGen *ptr_val = ir_get_deref(ira, &instruction->base.base, ptr_ptr, nullptr);
2651926566
...@@ -26523,6 +26570,24 @@ static IrInstGen *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstSrcSlice *i...@@ -26523,6 +26570,24 @@ static IrInstGen *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstSrcSlice *i
26523 ir_build_assert_non_null(ira, &instruction->base.base, ptr_val);26570 ir_build_assert_non_null(ira, &instruction->base.base, ptr_val);
26524 }26571 }
2652526572
26573 IrInstGen *result_loc = nullptr;
26574
26575 if (return_type->id != ZigTypeIdPointer) {
26576 result_loc = ir_resolve_result(ira, &instruction->base.base, instruction->result_loc,
26577 return_type, nullptr, true, true);
26578 if (result_loc != nullptr) {
26579 if (type_is_invalid(result_loc->value->type) || result_loc->value->type->id == ZigTypeIdUnreachable) {
26580 return result_loc;
26581 }
26582 IrInstGen *dummy_value = ir_const(ira, &instruction->base.base, return_type);
26583 dummy_value->value->special = ConstValSpecialRuntime;
26584 IrInstGen *dummy_result = ir_implicit_cast2(ira, &instruction->base.base,
26585 dummy_value, result_loc->value->type->data.pointer.child_type);
26586 if (type_is_invalid(dummy_result->value->type))
26587 return ira->codegen->invalid_inst_gen;
26588 }
26589 }
26590
26526 return ir_build_slice_gen(ira, &instruction->base.base, return_type, ptr_ptr,26591 return ir_build_slice_gen(ira, &instruction->base.base, return_type, ptr_ptr,
26527 casted_start, end, instruction->safety_check_on, result_loc);26592 casted_start, end, instruction->safety_check_on, result_loc);
26528}26593}
test/stage1/behavior/align.zig+11-10
...@@ -171,18 +171,19 @@ test "runtime known array index has best alignment possible" {...@@ -171,18 +171,19 @@ test "runtime known array index has best alignment possible" {
171171
172 // because pointer is align 2 and u32 align % 2 == 0 we can assume align 2172 // because pointer is align 2 and u32 align % 2 == 0 we can assume align 2
173 var smaller align(2) = [_]u32{ 1, 2, 3, 4 };173 var smaller align(2) = [_]u32{ 1, 2, 3, 4 };
174 comptime expect(@TypeOf(smaller[0..]) == []align(2) u32);174 var runtime_zero: usize = 0;
175 comptime expect(@TypeOf(smaller[0..].ptr) == [*]align(2) u32);175 comptime expect(@TypeOf(smaller[runtime_zero..]) == []align(2) u32);
176 testIndex(smaller[0..].ptr, 0, *align(2) u32);176 comptime expect(@TypeOf(smaller[runtime_zero..].ptr) == [*]align(2) u32);
177 testIndex(smaller[0..].ptr, 1, *align(2) u32);177 testIndex(smaller[runtime_zero..].ptr, 0, *align(2) u32);
178 testIndex(smaller[0..].ptr, 2, *align(2) u32);178 testIndex(smaller[runtime_zero..].ptr, 1, *align(2) u32);
179 testIndex(smaller[0..].ptr, 3, *align(2) u32);179 testIndex(smaller[runtime_zero..].ptr, 2, *align(2) u32);
180 testIndex(smaller[runtime_zero..].ptr, 3, *align(2) u32);
180181
181 // has to use ABI alignment because index known at runtime only182 // has to use ABI alignment because index known at runtime only
182 testIndex2(array[0..].ptr, 0, *u8);183 testIndex2(array[runtime_zero..].ptr, 0, *u8);
183 testIndex2(array[0..].ptr, 1, *u8);184 testIndex2(array[runtime_zero..].ptr, 1, *u8);
184 testIndex2(array[0..].ptr, 2, *u8);185 testIndex2(array[runtime_zero..].ptr, 2, *u8);
185 testIndex2(array[0..].ptr, 3, *u8);186 testIndex2(array[runtime_zero..].ptr, 3, *u8);
186}187}
187fn testIndex(smaller: [*]align(2) u32, index: usize, comptime T: type) void {188fn testIndex(smaller: [*]align(2) u32, index: usize, comptime T: type) void {
188 comptime expect(@TypeOf(&smaller[index]) == T);189 comptime expect(@TypeOf(&smaller[index]) == T);
test/stage1/behavior/cast.zig+2-1
...@@ -435,7 +435,8 @@ fn incrementVoidPtrValue(value: ?*c_void) void {...@@ -435,7 +435,8 @@ fn incrementVoidPtrValue(value: ?*c_void) void {
435435
436test "implicit cast from [*]T to ?*c_void" {436test "implicit cast from [*]T to ?*c_void" {
437 var a = [_]u8{ 3, 2, 1 };437 var a = [_]u8{ 3, 2, 1 };
438 incrementVoidPtrArray(a[0..].ptr, 3);438 var runtime_zero: usize = 0;
439 incrementVoidPtrArray(a[runtime_zero..].ptr, 3);
439 expect(std.mem.eql(u8, &a, &[_]u8{ 4, 3, 2 }));440 expect(std.mem.eql(u8, &a, &[_]u8{ 4, 3, 2 }));
440}441}
441442
test/stage1/behavior/eval.zig+1-1
...@@ -524,7 +524,7 @@ test "comptime slice of slice preserves comptime var" {...@@ -524,7 +524,7 @@ test "comptime slice of slice preserves comptime var" {
524test "comptime slice of pointer preserves comptime var" {524test "comptime slice of pointer preserves comptime var" {
525 comptime {525 comptime {
526 var buff: [10]u8 = undefined;526 var buff: [10]u8 = undefined;
527 var a = buff[0..].ptr;527 var a = @ptrCast([*]u8, &buff);
528 a[0..1][0] = 1;528 a[0..1][0] = 1;
529 expect(buff[0..][0..][0] == 1);529 expect(buff[0..][0..][0] == 1);
530 }530 }
test/stage1/behavior/misc.zig+9-5
...@@ -102,8 +102,8 @@ test "memcpy and memset intrinsics" {...@@ -102,8 +102,8 @@ test "memcpy and memset intrinsics" {
102 var foo: [20]u8 = undefined;102 var foo: [20]u8 = undefined;
103 var bar: [20]u8 = undefined;103 var bar: [20]u8 = undefined;
104104
105 @memset(foo[0..].ptr, 'A', foo.len);105 @memset(&foo, 'A', foo.len);
106 @memcpy(bar[0..].ptr, foo[0..].ptr, bar.len);106 @memcpy(&bar, &foo, bar.len);
107107
108 if (bar[11] != 'A') unreachable;108 if (bar[11] != 'A') unreachable;
109}109}
...@@ -565,12 +565,16 @@ test "volatile load and store" {...@@ -565,12 +565,16 @@ test "volatile load and store" {
565 expect(ptr.* == 1235);565 expect(ptr.* == 1235);
566}566}
567567
568test "slice string literal has type []const u8" {568test "slice string literal has correct type" {
569 comptime {569 comptime {
570 expect(@TypeOf("aoeu"[0..]) == []const u8);570 expect(@TypeOf("aoeu"[0..]) == *const [4:0]u8);
571 const array = [_]i32{ 1, 2, 3, 4 };571 const array = [_]i32{ 1, 2, 3, 4 };
572 expect(@TypeOf(array[0..]) == []const i32);572 expect(@TypeOf(array[0..]) == *const [4]i32);
573 }573 }
574 var runtime_zero: usize = 0;
575 expect(@TypeOf("aoeu"[runtime_zero..]) == [:0]const u8);
576 const array = [_]i32{ 1, 2, 3, 4 };
577 expect(@TypeOf(array[runtime_zero..]) == []const u8);
574}578}
575579
576test "pointer child field" {580test "pointer child field" {
test/stage1/behavior/ptrcast.zig+1-1
...@@ -13,7 +13,7 @@ fn testReinterpretBytesAsInteger() void {...@@ -13,7 +13,7 @@ fn testReinterpretBytesAsInteger() void {
13 builtin.Endian.Little => 0xab785634,13 builtin.Endian.Little => 0xab785634,
14 builtin.Endian.Big => 0x345678ab,14 builtin.Endian.Big => 0x345678ab,
15 };15 };
16 expect(@ptrCast(*align(1) const u32, bytes[1..5].ptr).* == expected);16 expect(@ptrCast(*align(1) const u32, bytes[1..5]).* == expected);
17}17}
1818
19test "reinterpret bytes of an array into an extern struct" {19test "reinterpret bytes of an array into an extern struct" {
test/stage1/behavior/slice.zig+7-3
...@@ -7,7 +7,7 @@ const mem = std.mem;...@@ -7,7 +7,7 @@ const mem = std.mem;
7const x = @intToPtr([*]i32, 0x1000)[0..0x500];7const x = @intToPtr([*]i32, 0x1000)[0..0x500];
8const y = x[0x100..];8const y = x[0x100..];
9test "compile time slice of pointer to hard coded address" {9test "compile time slice of pointer to hard coded address" {
10 expect(@ptrToInt(x.ptr) == 0x1000);10 expect(@ptrToInt(x) == 0x1000);
11 expect(x.len == 0x500);11 expect(x.len == 0x500);
1212
13 expect(@ptrToInt(y.ptr) == 0x1100);13 expect(@ptrToInt(y.ptr) == 0x1100);
...@@ -47,7 +47,9 @@ test "C pointer slice access" {...@@ -47,7 +47,9 @@ test "C pointer slice access" {
47 var buf: [10]u32 = [1]u32{42} ** 10;47 var buf: [10]u32 = [1]u32{42} ** 10;
48 const c_ptr = @ptrCast([*c]const u32, &buf);48 const c_ptr = @ptrCast([*c]const u32, &buf);
4949
50 comptime expectEqual([]const u32, @TypeOf(c_ptr[0..1]));50 var runtime_zero: usize = 0;
51 comptime expectEqual([]const u32, @TypeOf(c_ptr[runtime_zero..1]));
52 comptime expectEqual(*const [1]u32, @TypeOf(c_ptr[0..1]));
5153
52 for (c_ptr[0..5]) |*cl| {54 for (c_ptr[0..5]) |*cl| {
53 expectEqual(@as(u32, 42), cl.*);55 expectEqual(@as(u32, 42), cl.*);
...@@ -107,7 +109,9 @@ test "obtaining a null terminated slice" {...@@ -107,7 +109,9 @@ test "obtaining a null terminated slice" {
107 const ptr2 = buf[0..runtime_len :0];109 const ptr2 = buf[0..runtime_len :0];
108 // ptr2 is a null-terminated slice110 // ptr2 is a null-terminated slice
109 comptime expect(@TypeOf(ptr2) == [:0]u8);111 comptime expect(@TypeOf(ptr2) == [:0]u8);
110 comptime expect(@TypeOf(ptr2[0..2]) == []u8);112 comptime expect(@TypeOf(ptr2[0..2]) == *[2]u8);
113 var runtime_zero: usize = 0;
114 comptime expect(@TypeOf(ptr2[runtime_zero..2]) == []u8);
111}115}
112116
113test "empty array to slice" {117test "empty array to slice" {
test/stage1/behavior/struct.zig+2-2
...@@ -409,8 +409,8 @@ const Bitfields = packed struct {...@@ -409,8 +409,8 @@ const Bitfields = packed struct {
409test "native bit field understands endianness" {409test "native bit field understands endianness" {
410 var all: u64 = 0x7765443322221111;410 var all: u64 = 0x7765443322221111;
411 var bytes: [8]u8 = undefined;411 var bytes: [8]u8 = undefined;
412 @memcpy(bytes[0..].ptr, @ptrCast([*]u8, &all), 8);412 @memcpy(&bytes, @ptrCast([*]u8, &all), 8);
413 var bitfields = @ptrCast(*Bitfields, bytes[0..].ptr).*;413 var bitfields = @ptrCast(*Bitfields, &bytes).*;
414414
415 expect(bitfields.f1 == 0x1111);415 expect(bitfields.f1 == 0x1111);
416 expect(bitfields.f2 == 0x2222);416 expect(bitfields.f2 == 0x2222);