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)) {
560560
561561test "span" {
562562 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]);
564564 testing.expect(eql(u16, span(ptr), &[_]u16{ 1, 2 }));
565565 testing.expect(eql(u16, span(&array), &[_]u16{ 1, 2, 3, 4, 5 }));
566566}
......@@ -602,7 +602,7 @@ test "len" {
602602 testing.expect(len(&array) == 5);
603603 testing.expect(len(array[0..3]) == 3);
604604 array[2] = 0;
605 const ptr = array[0..2 :0].ptr;
605 const ptr = @as([*:0]u16, array[0..2 :0]);
606606 testing.expect(len(ptr) == 2);
607607 }
608608 {
src-self-hosted/stage2.zig+1-1
......@@ -128,7 +128,7 @@ export fn stage2_translate_c(
128128 args_end: [*]?[*]const u8,
129129 resources_path: [*:0]const u8,
130130) Error {
131 var errors = @as([*]translate_c.ClangErrMsg, undefined)[0..0];
131 var errors: []translate_c.ClangErrMsg = &[0]translate_c.ClangErrMsg{};
132132 out_ast.* = translate_c.translate(std.heap.c_allocator, args_begin, args_end, &errors, resources_path) catch |err| switch (err) {
133133 error.SemanticAnalyzeFail => {
134134 out_errors_ptr.* = errors.ptr;
src/all_types.hpp+5
......@@ -231,6 +231,7 @@ enum ConstPtrSpecial {
231231 // The pointer is a reference to a single object.
232232 ConstPtrSpecialRef,
233233 // The pointer points to an element in an underlying array.
234 // Not to be confused with ConstPtrSpecialSubArray.
234235 ConstPtrSpecialBaseArray,
235236 // The pointer points to a field in an underlying struct.
236237 ConstPtrSpecialBaseStruct,
......@@ -257,6 +258,10 @@ enum ConstPtrSpecial {
257258 // types to be the same, so all optionals of pointer types use x_ptr
258259 // instead of x_optional.
259260 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,
260265};
261266
262267enum ConstPtrMut {
src/analyze.cpp+7
......@@ -5280,6 +5280,11 @@ static uint32_t hash_const_val_ptr(ZigValue *const_val) {
52805280 hash_val += hash_ptr(const_val->data.x_ptr.data.base_array.array_val);
52815281 hash_val += hash_size(const_val->data.x_ptr.data.base_array.elem_index);
52825282 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;
52835288 case ConstPtrSpecialBaseStruct:
52845289 hash_val += (uint32_t)3518317043;
52855290 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) {
67466751 return false;
67476752 return true;
67486753 case ConstPtrSpecialBaseArray:
6754 case ConstPtrSpecialSubArray:
67496755 if (a->data.x_ptr.data.base_array.array_val != b->data.x_ptr.data.base_array.array_val) {
67506756 return false;
67516757 }
......@@ -7003,6 +7009,7 @@ static void render_const_val_ptr(CodeGen *g, Buf *buf, ZigValue *const_val, ZigT
70037009 render_const_value(g, buf, const_ptr_pointee(nullptr, g, const_val, nullptr));
70047010 return;
70057011 case ConstPtrSpecialBaseArray:
7012 case ConstPtrSpecialSubArray:
70067013 buf_appendf(buf, "*");
70077014 // TODO we need a source node for const_ptr_pointee because it can generate compile errors
70087015 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
54185418 ZigType *array_type = array_ptr_type->data.pointer.child_type;
54195419 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
54235421 bool want_runtime_safety = instruction->safety_check_on && ir_want_runtime_safety(g, &instruction->base);
54245422
54255423 ZigType *result_type = instruction->base.value->type;
......@@ -5472,6 +5470,8 @@ static LLVMValueRef ir_render_slice(CodeGen *g, IrExecutableGen *executable, IrI
54725470 }
54735471 }
54745472 if (!type_has_bits(g, array_type)) {
5473 LLVMValueRef tmp_struct_ptr = ir_llvm_value(g, instruction->result_loc);
5474
54755475 LLVMValueRef len_field_ptr = LLVMBuildStructGEP(g->builder, tmp_struct_ptr, slice_len_index, "");
54765476
54775477 // 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
54865486 };
54875487 LLVMValueRef slice_start_ptr = LLVMBuildInBoundsGEP(g->builder, array_ptr, indices, 2, "");
54885488 if (result_type->id == ZigTypeIdPointer) {
5489 ir_assert(instruction->result_loc == nullptr, &instruction->base);
54895490 LLVMTypeRef result_ptr_type = get_llvm_type(g, result_type);
5490 LLVMValueRef bitcasted = 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;
5491 return LLVMBuildBitCast(g->builder, slice_start_ptr, result_ptr_type, "");
54935492 } else {
5493 LLVMValueRef tmp_struct_ptr = ir_llvm_value(g, instruction->result_loc);
54945494 LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP(g->builder, tmp_struct_ptr, slice_ptr_index, "");
54955495 gen_store_untyped(g, slice_start_ptr, ptr_field_ptr, 0, false);
54965496
54975497 LLVMValueRef len_field_ptr = LLVMBuildStructGEP(g->builder, tmp_struct_ptr, slice_len_index, "");
54985498 LLVMValueRef len_value = LLVMBuildNSWSub(g->builder, end_val, start_val, "");
54995499 gen_store_untyped(g, len_value, len_field_ptr, 0, false);
5500 }
55015500
5502 return tmp_struct_ptr;
5501 return tmp_struct_ptr;
5502 }
55035503 } else if (array_type->id == ZigTypeIdPointer) {
55045504 assert(array_type->data.pointer.ptr_len != PtrLenSingle);
55055505 LLVMValueRef start_val = ir_llvm_value(g, instruction->start);
......@@ -5515,12 +5515,12 @@ static LLVMValueRef ir_render_slice(CodeGen *g, IrExecutableGen *executable, IrI
55155515
55165516 LLVMValueRef slice_start_ptr = LLVMBuildInBoundsGEP(g->builder, array_ptr, &start_val, 1, "");
55175517 if (result_type->id == ZigTypeIdPointer) {
5518 ir_assert(instruction->result_loc == nullptr, &instruction->base);
55185519 LLVMTypeRef result_ptr_type = get_llvm_type(g, result_type);
5519 LLVMValueRef bitcasted = LLVMBuildBitCast(g->builder, slice_start_ptr, result_ptr_type, "");
5520 gen_store_untyped(g, bitcasted, tmp_struct_ptr, 0, false);
5521 return bitcasted;
5520 return LLVMBuildBitCast(g->builder, slice_start_ptr, result_ptr_type, "");
55225521 }
55235522
5523 LLVMValueRef tmp_struct_ptr = ir_llvm_value(g, instruction->result_loc);
55245524 if (type_has_bits(g, array_type)) {
55255525 size_t gen_ptr_index = result_type->data.structure.fields[slice_ptr_index]->gen_index;
55265526 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
55375537 assert(array_type->data.structure.special == StructSpecialSlice);
55385538 assert(LLVMGetTypeKind(LLVMTypeOf(array_ptr)) == LLVMPointerTypeKind);
55395539 assert(LLVMGetTypeKind(LLVMGetElementType(LLVMTypeOf(array_ptr))) == LLVMStructTypeKind);
5540 if (result_type->id != ZigTypeIdPointer) {
5541 assert(LLVMGetTypeKind(LLVMGetElementType(LLVMTypeOf(tmp_struct_ptr))) == LLVMStructTypeKind);
5542 }
55435540
55445541 size_t ptr_index = array_type->data.structure.fields[slice_ptr_index]->gen_index;
55455542 assert(ptr_index != SIZE_MAX);
......@@ -5578,11 +5575,11 @@ static LLVMValueRef ir_render_slice(CodeGen *g, IrExecutableGen *executable, IrI
55785575
55795576 LLVMValueRef slice_start_ptr = LLVMBuildInBoundsGEP(g->builder, src_ptr, &start_val, 1, "");
55805577 if (result_type->id == ZigTypeIdPointer) {
5578 ir_assert(instruction->result_loc == nullptr, &instruction->base);
55815579 LLVMTypeRef result_ptr_type = get_llvm_type(g, result_type);
5582 LLVMValueRef bitcasted = LLVMBuildBitCast(g->builder, slice_start_ptr, result_ptr_type, "");
5583 gen_store_untyped(g, bitcasted, tmp_struct_ptr, 0, false);
5584 return bitcasted;
5580 return LLVMBuildBitCast(g->builder, slice_start_ptr, result_ptr_type, "");
55855581 } else {
5582 LLVMValueRef tmp_struct_ptr = ir_llvm_value(g, instruction->result_loc);
55865583 LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP(g->builder, tmp_struct_ptr, (unsigned)ptr_index, "");
55875584 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
66766673 };
66776674 return LLVMConstInBoundsGEP(base_ptr, indices, 2);
66786675 } else {
6679 assert(parent->id == ConstParentIdScalar);
66806676 return base_ptr;
66816677 }
66826678}
......@@ -6904,6 +6900,7 @@ static LLVMValueRef gen_const_val_ptr(CodeGen *g, ZigValue *const_val, const cha
69046900 return const_val->llvm_value;
69056901 }
69066902 case ConstPtrSpecialBaseArray:
6903 case ConstPtrSpecialSubArray:
69076904 {
69086905 ZigValue *array_const_val = const_val->data.x_ptr.data.base_array.array_val;
69096906 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_
784784 break;
785785 case ConstPtrSpecialBaseArray: {
786786 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) {
788789 result = array_val->type->data.array.sentinel;
789790 } else {
790791 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];
792793 }
793794 break;
794795 }
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 }
795813 case ConstPtrSpecialBaseStruct: {
796814 ZigValue *struct_val = const_val->data.x_ptr.data.base_struct.struct_val;
797815 expand_undef_struct(g, struct_val);
......@@ -3727,8 +3745,8 @@ static IrInstGen *ir_build_slice_gen(IrAnalyze *ira, IrInst *source_instruction,
37273745
37283746 ir_ref_inst_gen(ptr, ira->new_irb.current_basic_block);
37293747 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);
3731 ir_ref_inst_gen(result_loc, ira->new_irb.current_basic_block);
3748 if (end != nullptr) ir_ref_inst_gen(end, ira->new_irb.current_basic_block);
3749 if (result_loc != nullptr) ir_ref_inst_gen(result_loc, ira->new_irb.current_basic_block);
37323750
37333751 return &instruction->base;
37343752}
......@@ -12672,40 +12690,63 @@ static IrInstGen *ir_resolve_ptr_of_array_to_slice(IrAnalyze *ira, IrInst* sourc
1267212690 Error err;
1267312691
1267412692 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))) {
12677 return ira->codegen->invalid_inst_gen;
12678 }
12695 ZigType *array_type = array_ptr->value->type->data.pointer.child_type;
12696 const size_t array_len = array_type->data.array.len;
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 destination
12685 // alignment
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));
12712 if ((err = type_resolve(ira->codegen, array_ptr->value->type, ResolveStatusAlignmentKnown))) {
12713 return ira->codegen->invalid_inst_gen;
1268912714 }
1269012715
12716 wanted_type = adjust_slice_align(ira->codegen, wanted_type,
12717 get_ptr_align(ira->codegen, array_ptr->value->type));
12718
1269112719 if (instr_is_comptime(array_ptr)) {
1269212720 ZigValue *array_ptr_val = ir_resolve_const(ira, array_ptr, UndefBad);
1269312721 if (array_ptr_val == nullptr)
1269412722 return ira->codegen->invalid_inst_gen;
12695 ZigValue *pointee = const_ptr_pointee(ira, ira->codegen, array_ptr_val, source_instr->source_node);
12696 if (pointee == nullptr)
12697 return ira->codegen->invalid_inst_gen;
12698 if (pointee->special != ConstValSpecialRuntime) {
12699 assert(array_ptr_val->type->id == ZigTypeIdPointer);
12700 ZigType *array_type = array_ptr_val->type->data.pointer.child_type;
12701 assert(is_slice(wanted_type));
12702 bool is_const = wanted_type->data.structure.fields[slice_ptr_index]->type_entry->data.pointer.is_const;
12723 ir_assert(is_slice(wanted_type), source_instr);
12724 bool wanted_const = wanted_type->data.structure.fields[slice_ptr_index]->type_entry->data.pointer.is_const;
12725 // Optimization to avoid creating unnecessary ZigValue in const_ptr_pointee
12726 if (array_ptr_val->data.x_ptr.special == ConstPtrSpecialSubArray) {
12727 ZigValue *array_val = array_ptr_val->data.x_ptr.data.base_array.array_val;
12728 if (array_val->special != ConstValSpecialRuntime) {
12729 IrInstGen *result = ir_const(ira, source_instr, wanted_type);
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);
12705 init_const_slice(ira->codegen, result->value, pointee, 0, array_type->data.array.len, is_const);
12706 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;
12708 return result;
12744 IrInstGen *result = ir_const(ira, source_instr, wanted_type);
12745 init_const_slice(ira->codegen, result->value, pointee, 0, array_type->data.array.len, wanted_const);
12746 result->value->data.x_struct.fields[slice_ptr_index]->data.x_ptr.mut = array_ptr_val->data.x_ptr.mut;
12747 result->value->type = wanted_type;
12748 return result;
12749 }
1270912750 }
1271012751 }
1271112752
......@@ -19931,6 +19972,7 @@ static Error ir_read_const_ptr(IrAnalyze *ira, CodeGen *codegen, AstNode *source
1993119972 dst_size, buf_ptr(&pointee->type->name), src_size));
1993219973 return ErrorSemanticAnalyzeFail;
1993319974 }
19975 case ConstPtrSpecialSubArray:
1993419976 case ConstPtrSpecialBaseArray: {
1993519977 ZigValue *array_val = ptr_val->data.x_ptr.data.base_array.array_val;
1993619978 assert(array_val->type->id == ZigTypeIdArray);
......@@ -20814,6 +20856,7 @@ static IrInstGen *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstSrcElemP
2081420856 }
2081520857 break;
2081620858 case ConstPtrSpecialBaseArray:
20859 case ConstPtrSpecialSubArray:
2081720860 {
2081820861 size_t offset = array_ptr_val->data.x_ptr.data.base_array.elem_index;
2081920862 new_index = offset + index;
......@@ -20884,6 +20927,7 @@ static IrInstGen *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstSrcElemP
2088420927 out_val->data.x_ptr.special = ConstPtrSpecialRef;
2088520928 out_val->data.x_ptr.data.ref.pointee = ptr_field->data.x_ptr.data.ref.pointee;
2088620929 break;
20930 case ConstPtrSpecialSubArray:
2088720931 case ConstPtrSpecialBaseArray:
2088820932 {
2088920933 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
2589425938 start = 0;
2589525939 bound_end = 1;
2589625940 break;
25941 case ConstPtrSpecialSubArray:
2589725942 case ConstPtrSpecialBaseArray:
2589825943 {
2589925944 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
2602726072 dest_start = 0;
2602826073 dest_end = 1;
2602926074 break;
26075 case ConstPtrSpecialSubArray:
2603026076 case ConstPtrSpecialBaseArray:
2603126077 {
2603226078 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
2607026116 src_start = 0;
2607126117 src_end = 1;
2607226118 break;
26119 case ConstPtrSpecialSubArray:
2607326120 case ConstPtrSpecialBaseArray:
2607426121 {
2607526122 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
2621926266 ZigType *return_type;
2622026267
2622126268 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)))
2622326271 {
2622426272 ZigValue *start_val = ir_resolve_const(ira, casted_start, UndefBad);
2622526273 if (!start_val)
......@@ -26244,13 +26292,16 @@ static IrInstGen *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstSrcSlice *i
2624426292 return ira->codegen->invalid_inst_gen;
2624526293 }
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;
2624726299 ZigType *return_array_type = get_array_type(ira->codegen, elem_type, end_scalar - start_scalar,
2624826300 array_sentinel);
2624926301 return_type = get_pointer_to_type_extra(ira->codegen, return_array_type,
2625026302 non_sentinel_slice_ptr_type->data.pointer.is_const,
2625126303 non_sentinel_slice_ptr_type->data.pointer.is_volatile,
26252 PtrLenSingle,
26253 0, 0, 0, false);
26304 PtrLenSingle, ptr_byte_alignment, 0, 0, false);
2625426305 } else if (sentinel_val != nullptr) {
2625526306 ZigType *slice_ptr_type = adjust_ptr_sentinel(ira->codegen, non_sentinel_slice_ptr_type, sentinel_val);
2625626307 return_type = get_slice_type(ira->codegen, slice_ptr_type);
......@@ -26283,6 +26334,10 @@ static IrInstGen *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstSrcSlice *i
2628326334 abs_offset = 0;
2628426335 rel_end = SIZE_MAX;
2628526336 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;
2628626341 } else {
2628726342 array_val = const_ptr_pointee(ira, ira->codegen, parent_ptr, instruction->base.base.source_node);
2628826343 if (array_val == nullptr)
......@@ -26325,6 +26380,7 @@ static IrInstGen *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstSrcSlice *i
2632526380 rel_end = 1;
2632626381 }
2632726382 break;
26383 case ConstPtrSpecialSubArray:
2632826384 case ConstPtrSpecialBaseArray:
2632926385 array_val = parent_ptr->data.x_ptr.data.base_array.array_val;
2633026386 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
2637526431 abs_offset = SIZE_MAX;
2637626432 rel_end = 1;
2637726433 break;
26434 case ConstPtrSpecialSubArray:
2637826435 case ConstPtrSpecialBaseArray:
2637926436 array_val = parent_ptr->data.x_ptr.data.base_array.array_val;
2638026437 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
2645426511 if (array_val) {
2645526512 size_t index = abs_offset + start_scalar;
2645626513 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 }
2645726517 if (array_type->id == ZigTypeIdArray) {
2645826518 ptr_val->data.x_ptr.mut = ptr_ptr->value->data.x_ptr.mut;
2645926519 } else if (is_slice(array_type)) {
......@@ -26463,7 +26523,7 @@ static IrInstGen *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstSrcSlice *i
2646326523 }
2646426524 } else if (ptr_is_undef) {
2646526525 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);
2646726527 ptr_val->special = ConstValSpecialUndef;
2646826528 } else switch (parent_ptr->data.x_ptr.special) {
2646926529 case ConstPtrSpecialInvalid:
......@@ -26473,6 +26533,7 @@ static IrInstGen *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstSrcSlice *i
2647326533 init_const_ptr_ref(ira->codegen, ptr_val, parent_ptr->data.x_ptr.data.ref.pointee,
2647426534 return_type_is_const);
2647526535 break;
26536 case ConstPtrSpecialSubArray:
2647626537 case ConstPtrSpecialBaseArray:
2647726538 zig_unreachable();
2647826539 case ConstPtrSpecialBaseStruct:
......@@ -26500,20 +26561,6 @@ static IrInstGen *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstSrcSlice *i
2650026561 return result;
2650126562 }
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
2651726564 if (generate_non_null_assert) {
2651826565 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
2652326570 ir_build_assert_non_null(ira, &instruction->base.base, ptr_val);
2652426571 }
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
2652626591 return ir_build_slice_gen(ira, &instruction->base.base, return_type, ptr_ptr,
2652726592 casted_start, end, instruction->safety_check_on, result_loc);
2652826593}
test/stage1/behavior/align.zig+11-10
......@@ -171,18 +171,19 @@ test "runtime known array index has best alignment possible" {
171171
172172 // because pointer is align 2 and u32 align % 2 == 0 we can assume align 2
173173 var smaller align(2) = [_]u32{ 1, 2, 3, 4 };
174 comptime expect(@TypeOf(smaller[0..]) == []align(2) u32);
175 comptime expect(@TypeOf(smaller[0..].ptr) == [*]align(2) u32);
176 testIndex(smaller[0..].ptr, 0, *align(2) u32);
177 testIndex(smaller[0..].ptr, 1, *align(2) u32);
178 testIndex(smaller[0..].ptr, 2, *align(2) u32);
179 testIndex(smaller[0..].ptr, 3, *align(2) u32);
174 var runtime_zero: usize = 0;
175 comptime expect(@TypeOf(smaller[runtime_zero..]) == []align(2) u32);
176 comptime expect(@TypeOf(smaller[runtime_zero..].ptr) == [*]align(2) u32);
177 testIndex(smaller[runtime_zero..].ptr, 0, *align(2) u32);
178 testIndex(smaller[runtime_zero..].ptr, 1, *align(2) u32);
179 testIndex(smaller[runtime_zero..].ptr, 2, *align(2) u32);
180 testIndex(smaller[runtime_zero..].ptr, 3, *align(2) u32);
180181
181182 // has to use ABI alignment because index known at runtime only
182 testIndex2(array[0..].ptr, 0, *u8);
183 testIndex2(array[0..].ptr, 1, *u8);
184 testIndex2(array[0..].ptr, 2, *u8);
185 testIndex2(array[0..].ptr, 3, *u8);
183 testIndex2(array[runtime_zero..].ptr, 0, *u8);
184 testIndex2(array[runtime_zero..].ptr, 1, *u8);
185 testIndex2(array[runtime_zero..].ptr, 2, *u8);
186 testIndex2(array[runtime_zero..].ptr, 3, *u8);
186187}
187188fn testIndex(smaller: [*]align(2) u32, index: usize, comptime T: type) void {
188189 comptime expect(@TypeOf(&smaller[index]) == T);
test/stage1/behavior/cast.zig+2-1
......@@ -435,7 +435,8 @@ fn incrementVoidPtrValue(value: ?*c_void) void {
435435
436436test "implicit cast from [*]T to ?*c_void" {
437437 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);
439440 expect(std.mem.eql(u8, &a, &[_]u8{ 4, 3, 2 }));
440441}
441442
test/stage1/behavior/eval.zig+1-1
......@@ -524,7 +524,7 @@ test "comptime slice of slice preserves comptime var" {
524524test "comptime slice of pointer preserves comptime var" {
525525 comptime {
526526 var buff: [10]u8 = undefined;
527 var a = buff[0..].ptr;
527 var a = @ptrCast([*]u8, &buff);
528528 a[0..1][0] = 1;
529529 expect(buff[0..][0..][0] == 1);
530530 }
test/stage1/behavior/misc.zig+9-5
......@@ -102,8 +102,8 @@ test "memcpy and memset intrinsics" {
102102 var foo: [20]u8 = undefined;
103103 var bar: [20]u8 = undefined;
104104
105 @memset(foo[0..].ptr, 'A', foo.len);
106 @memcpy(bar[0..].ptr, foo[0..].ptr, bar.len);
105 @memset(&foo, 'A', foo.len);
106 @memcpy(&bar, &foo, bar.len);
107107
108108 if (bar[11] != 'A') unreachable;
109109}
......@@ -565,12 +565,16 @@ test "volatile load and store" {
565565 expect(ptr.* == 1235);
566566}
567567
568test "slice string literal has type []const u8" {
568test "slice string literal has correct type" {
569569 comptime {
570 expect(@TypeOf("aoeu"[0..]) == []const u8);
570 expect(@TypeOf("aoeu"[0..]) == *const [4:0]u8);
571571 const array = [_]i32{ 1, 2, 3, 4 };
572 expect(@TypeOf(array[0..]) == []const i32);
572 expect(@TypeOf(array[0..]) == *const [4]i32);
573573 }
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);
574578}
575579
576580test "pointer child field" {
test/stage1/behavior/ptrcast.zig+1-1
......@@ -13,7 +13,7 @@ fn testReinterpretBytesAsInteger() void {
1313 builtin.Endian.Little => 0xab785634,
1414 builtin.Endian.Big => 0x345678ab,
1515 };
16 expect(@ptrCast(*align(1) const u32, bytes[1..5].ptr).* == expected);
16 expect(@ptrCast(*align(1) const u32, bytes[1..5]).* == expected);
1717}
1818
1919test "reinterpret bytes of an array into an extern struct" {
test/stage1/behavior/slice.zig+7-3
......@@ -7,7 +7,7 @@ const mem = std.mem;
77const x = @intToPtr([*]i32, 0x1000)[0..0x500];
88const y = x[0x100..];
99test "compile time slice of pointer to hard coded address" {
10 expect(@ptrToInt(x.ptr) == 0x1000);
10 expect(@ptrToInt(x) == 0x1000);
1111 expect(x.len == 0x500);
1212
1313 expect(@ptrToInt(y.ptr) == 0x1100);
......@@ -47,7 +47,9 @@ test "C pointer slice access" {
4747 var buf: [10]u32 = [1]u32{42} ** 10;
4848 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
5254 for (c_ptr[0..5]) |*cl| {
5355 expectEqual(@as(u32, 42), cl.*);
......@@ -107,7 +109,9 @@ test "obtaining a null terminated slice" {
107109 const ptr2 = buf[0..runtime_len :0];
108110 // ptr2 is a null-terminated slice
109111 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);
111115}
112116
113117test "empty array to slice" {
test/stage1/behavior/struct.zig+2-2
......@@ -409,8 +409,8 @@ const Bitfields = packed struct {
409409test "native bit field understands endianness" {
410410 var all: u64 = 0x7765443322221111;
411411 var bytes: [8]u8 = undefined;
412 @memcpy(bytes[0..].ptr, @ptrCast([*]u8, &all), 8);
413 var bitfields = @ptrCast(*Bitfields, bytes[0..].ptr).*;
412 @memcpy(&bytes, @ptrCast([*]u8, &all), 8);
413 var bitfields = @ptrCast(*Bitfields, &bytes).*;
414414
415415 expect(bitfields.f1 == 0x1111);
416416 expect(bitfields.f2 == 0x2222);