authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-08-31 16:30:46-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-08-31 16:30:46-04:00
log67b6dd28ec70937a29176719b56457ee17b1c136
treecf6e7e1585d8cb1b56ba77ec53562f7502c5e65d
parenteb0979189be33d6d957dad5104650cb5c532055b

allow array literals to have size and fix comptime bug


4 files changed, 36 insertions(+), 9 deletions(-)

src/all_types.hpp+1
...@@ -50,6 +50,7 @@ struct IrExecutable {...@@ -50,6 +50,7 @@ struct IrExecutable {
50 size_t next_debug_id;50 size_t next_debug_id;
51 size_t *backward_branch_count;51 size_t *backward_branch_count;
52 size_t backward_branch_quota;52 size_t backward_branch_quota;
53 bool reported_quota_exceeded;
53 bool invalid;54 bool invalid;
54 ZigList<LabelTableEntry *> all_labels;55 ZigList<LabelTableEntry *> all_labels;
55 ZigList<IrGotoItem> goto_list;56 ZigList<IrGotoItem> goto_list;
src/ir.cpp+22-9
...@@ -7604,12 +7604,13 @@ static bool ir_emit_backward_branch(IrAnalyze *ira, IrInstruction *source_instru...@@ -7604,12 +7604,13 @@ static bool ir_emit_backward_branch(IrAnalyze *ira, IrInstruction *source_instru
7604 size_t *bbc = ira->new_irb.exec->backward_branch_count;7604 size_t *bbc = ira->new_irb.exec->backward_branch_count;
7605 size_t quota = ira->new_irb.exec->backward_branch_quota;7605 size_t quota = ira->new_irb.exec->backward_branch_quota;
76067606
7607 // If we're already over quota, we've already given an error message for this.7607 if (ira->new_irb.exec->reported_quota_exceeded) {
7608 if (*bbc > quota)
7609 return false;7608 return false;
7609 }
76107610
7611 *bbc += 1;7611 *bbc += 1;
7612 if (*bbc > quota) {7612 if (*bbc > quota) {
7613 ira->new_irb.exec->reported_quota_exceeded = true;
7613 ir_add_error(ira, source_instruction, buf_sprintf("evaluation exceeded %" ZIG_PRI_usize " backwards branches", quota));7614 ir_add_error(ira, source_instruction, buf_sprintf("evaluation exceeded %" ZIG_PRI_usize " backwards branches", quota));
7614 return false;7615 return false;
7615 }7616 }
...@@ -12815,10 +12816,25 @@ static TypeTableEntry *ir_analyze_instruction_container_init_list(IrAnalyze *ira...@@ -12815,10 +12816,25 @@ static TypeTableEntry *ir_analyze_instruction_container_init_list(IrAnalyze *ira
12815 if (container_type->id == TypeTableEntryIdStruct && !is_slice(container_type) && elem_count == 0) {12816 if (container_type->id == TypeTableEntryIdStruct && !is_slice(container_type) && elem_count == 0) {
12816 return ir_analyze_container_init_fields(ira, &instruction->base, container_type,12817 return ir_analyze_container_init_fields(ira, &instruction->base, container_type,
12817 0, nullptr);12818 0, nullptr);
12818 } else if (is_slice(container_type)) {12819 } else if (is_slice(container_type) || container_type->id == TypeTableEntryIdArray) {
12819 TypeTableEntry *pointer_type = container_type->data.structure.fields[slice_ptr_index].type_entry;12820 // array is same as slice init but we make a compile error if the length is wrong
12820 assert(pointer_type->id == TypeTableEntryIdPointer);12821 TypeTableEntry *child_type;
12821 TypeTableEntry *child_type = pointer_type->data.pointer.child_type;12822 if (container_type->id == TypeTableEntryIdArray) {
12823 child_type = container_type->data.array.child_type;
12824 if (container_type->data.array.len != elem_count) {
12825 TypeTableEntry *literal_type = get_array_type(ira->codegen, child_type, elem_count);
12826
12827 ir_add_error(ira, &instruction->base,
12828 buf_sprintf("expected %s literal, found %s literal",
12829 buf_ptr(&container_type->name), buf_ptr(&literal_type->name)));
12830 return ira->codegen->builtin_types.entry_invalid;
12831 }
12832 } else {
12833 TypeTableEntry *pointer_type = container_type->data.structure.fields[slice_ptr_index].type_entry;
12834 assert(pointer_type->id == TypeTableEntryIdPointer);
12835 child_type = pointer_type->data.pointer.child_type;
12836 }
12837
12822 TypeTableEntry *fixed_size_array_type = get_array_type(ira->codegen, child_type, elem_count);12838 TypeTableEntry *fixed_size_array_type = get_array_type(ira->codegen, child_type, elem_count);
1282312839
12824 ConstExprValue const_val = {};12840 ConstExprValue const_val = {};
...@@ -12882,9 +12898,6 @@ static TypeTableEntry *ir_analyze_instruction_container_init_list(IrAnalyze *ira...@@ -12882,9 +12898,6 @@ static TypeTableEntry *ir_analyze_instruction_container_init_list(IrAnalyze *ira
12882 container_type_value, elem_count, new_items);12898 container_type_value, elem_count, new_items);
12883 ir_add_alloca(ira, new_instruction, fixed_size_array_type);12899 ir_add_alloca(ira, new_instruction, fixed_size_array_type);
12884 return fixed_size_array_type;12900 return fixed_size_array_type;
12885 } else if (container_type->id == TypeTableEntryIdArray) {
12886 // same as slice init but we make a compile error if the length is wrong
12887 zig_panic("TODO array container init");
12888 } else if (container_type->id == TypeTableEntryIdVoid) {12901 } else if (container_type->id == TypeTableEntryIdVoid) {
12889 if (elem_count != 0) {12902 if (elem_count != 0) {
12890 ir_add_error_node(ira, instruction->base.source_node,12903 ir_add_error_node(ira, instruction->base.source_node,
test/cases/array.zig+6
...@@ -80,3 +80,9 @@ test "set global var array via slice embedded in struct" {...@@ -80,3 +80,9 @@ test "set global var array via slice embedded in struct" {
80 assert(s_array[1].b == 2);80 assert(s_array[1].b == 2);
81 assert(s_array[2].b == 3);81 assert(s_array[2].b == 3);
82}82}
83
84test "array literal with specified size" {
85 var array = [2]u8{1, 2};
86 assert(array[0] == 1);
87 assert(array[1] == 2);
88}
test/compile_errors.zig+7
...@@ -2061,4 +2061,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -2061,4 +2061,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
2061 ,2061 ,
2062 ".tmp_source.zig:4:23: error: expected pointer alignment of at least 4, found 1");2062 ".tmp_source.zig:4:23: error: expected pointer alignment of at least 4, found 1");
20632063
2064 cases.add("wrong size to an array literal",
2065 \\comptime {
2066 \\ const array = [2]u8{1, 2, 3};
2067 \\}
2068 ,
2069 ".tmp_source.zig:2:24: error: expected [2]u8 literal, found [3]u8 literal");
2070
2064}2071}