authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-01-16 15:24:03-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-01-16 15:24:03-05:00
logfdbc2d8da1c707859af8f8bb42a27ae9d3a62159
tree1a1289cac097941e6bef0757a1c7e0fdf3c1668c
parent98faf4f74984db615ba62de285308dfc5092ec7c

implement error when assigning to field of const struct

closes #48

4 files changed, 17 insertions(+), 5 deletions(-)

src/ir.cpp+4-2
...@@ -8423,6 +8423,8 @@ static TypeTableEntry *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field...@@ -8423,6 +8423,8 @@ static TypeTableEntry *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field
8423 TypeTableEntry *bare_type = container_ref_type(container_type);8423 TypeTableEntry *bare_type = container_ref_type(container_type);
8424 ensure_complete_type(ira->codegen, bare_type);8424 ensure_complete_type(ira->codegen, bare_type);
84258425
8426 assert(container_ptr->value.type->id == TypeTableEntryIdPointer);
8427 bool is_const = container_ptr->value.type->data.pointer.is_const;
8426 if (bare_type->id == TypeTableEntryIdStruct) {8428 if (bare_type->id == TypeTableEntryIdStruct) {
8427 if (bare_type->data.structure.is_invalid)8429 if (bare_type->data.structure.is_invalid)
8428 return ira->codegen->builtin_types.entry_invalid;8430 return ira->codegen->builtin_types.entry_invalid;
...@@ -8430,7 +8432,7 @@ static TypeTableEntry *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field...@@ -8430,7 +8432,7 @@ static TypeTableEntry *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field
8430 TypeStructField *field = find_struct_type_field(bare_type, field_name);8432 TypeStructField *field = find_struct_type_field(bare_type, field_name);
8431 if (field) {8433 if (field) {
8432 ir_build_struct_field_ptr_from(&ira->new_irb, &field_ptr_instruction->base, container_ptr, field);8434 ir_build_struct_field_ptr_from(&ira->new_irb, &field_ptr_instruction->base, container_ptr, field);
8433 return get_pointer_to_type(ira->codegen, field->type_entry, false);8435 return get_pointer_to_type(ira->codegen, field->type_entry, is_const);
8434 } else {8436 } else {
8435 return ir_analyze_container_member_access_inner(ira, bare_type, field_name,8437 return ir_analyze_container_member_access_inner(ira, bare_type, field_name,
8436 field_ptr_instruction, container_ptr, container_type);8438 field_ptr_instruction, container_ptr, container_type);
...@@ -8442,7 +8444,7 @@ static TypeTableEntry *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field...@@ -8442,7 +8444,7 @@ static TypeTableEntry *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field
8442 TypeEnumField *field = find_enum_type_field(bare_type, field_name);8444 TypeEnumField *field = find_enum_type_field(bare_type, field_name);
8443 if (field) {8445 if (field) {
8444 ir_build_enum_field_ptr_from(&ira->new_irb, &field_ptr_instruction->base, container_ptr, field);8446 ir_build_enum_field_ptr_from(&ira->new_irb, &field_ptr_instruction->base, container_ptr, field);
8445 return get_pointer_to_type(ira->codegen, field->type_entry, false);8447 return get_pointer_to_type(ira->codegen, field->type_entry, is_const);
8446 } else {8448 } else {
8447 return ir_analyze_container_member_access_inner(ira, bare_type, field_name,8449 return ir_analyze_container_member_access_inner(ira, bare_type, field_name,
8448 field_ptr_instruction, container_ptr, container_type);8450 field_ptr_instruction, container_ptr, container_type);
std/debug.zig+2-2
...@@ -327,8 +327,8 @@ fn parseAbbrevTable(in_stream: &io.InStream) -> %AbbrevTable {...@@ -327,8 +327,8 @@ fn parseAbbrevTable(in_stream: &io.InStream) -> %AbbrevTable {
327327
328/// Gets an already existing AbbrevTable given the abbrev_offset, or if not found,328/// Gets an already existing AbbrevTable given the abbrev_offset, or if not found,
329/// seeks in the stream and parses it.329/// seeks in the stream and parses it.
330fn getAbbrevTable(st: &ElfStackTrace, abbrev_offset: u64) -> %&AbbrevTable {330fn getAbbrevTable(st: &ElfStackTrace, abbrev_offset: u64) -> %&const AbbrevTable {
331 for (st.abbrev_table_list.toSlice()) |header| {331 for (st.abbrev_table_list.toSlice()) |*header| {
332 if (header.offset == abbrev_offset) {332 if (header.offset == abbrev_offset) {
333 return &header.table;333 return &header.table;
334 }334 }
test/run_tests.cpp+10
...@@ -1595,6 +1595,16 @@ const zero: i32 = 0;...@@ -1595,6 +1595,16 @@ const zero: i32 = 0;
1595const a = zero{1};1595const a = zero{1};
1596 )SOURCE", 1, ".tmp_source.zig:3:11: error: expected type, found 'i32'");1596 )SOURCE", 1, ".tmp_source.zig:3:11: error: expected type, found 'i32'");
15971597
1598 add_compile_fail_case("assign to constant field", R"SOURCE(
1599const Foo = struct {
1600 field: i32,
1601};
1602fn derp() {
1603 const f = Foo {.field = 1234,};
1604 f.field = 0;
1605}
1606 )SOURCE", 1, ".tmp_source.zig:7:13: error: cannot assign to constant");
1607
1598}1608}
15991609
1600//////////////////////////////////////////////////////////////////////////////1610//////////////////////////////////////////////////////////////////////////////
test/self_hosted.zig+1-1
...@@ -2,7 +2,7 @@...@@ -2,7 +2,7 @@
2const test_array = @import("cases/array.zig");2const test_array = @import("cases/array.zig");
3const test_atomics = @import("cases/atomics.zig");3const test_atomics = @import("cases/atomics.zig");
4const test_bool = @import("cases/bool.zig");4const test_bool = @import("cases/bool.zig");
5const test_cast= @import("cases/cast.zig");5const test_cast = @import("cases/cast.zig");
6const test_const_slice_child = @import("cases/const_slice_child.zig");6const test_const_slice_child = @import("cases/const_slice_child.zig");
7const test_defer = @import("cases/defer.zig");7const test_defer = @import("cases/defer.zig");
8const test_enum = @import("cases/enum.zig");8const test_enum = @import("cases/enum.zig");