authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-08-29 08:35:51-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-08-29 08:35:51-04:00
log1116d82197b46010b80e0e4454abc8881a642947
tree7daeb5c5849ce25f20c4268c39274d0294e55bf4
parentc5c9d98065890eaeb9070cba20e5a1ed48b392af

fix bitfield pointer syntax

See #37

3 files changed, 55 insertions(+), 6 deletions(-)

src/ir.cpp+14-6
...@@ -4682,6 +4682,12 @@ static IrInstruction *ir_gen_address_of(IrBuilder *irb, Scope *scope, AstNode *n...@@ -4682,6 +4682,12 @@ static IrInstruction *ir_gen_address_of(IrBuilder *irb, Scope *scope, AstNode *n
4682 bit_offset_end = bigint_as_unsigned(node->data.addr_of_expr.bit_offset_end);4682 bit_offset_end = bigint_as_unsigned(node->data.addr_of_expr.bit_offset_end);
4683 }4683 }
46844684
4685 if ((bit_offset_start != 0 || bit_offset_end != 0) && bit_offset_start >= bit_offset_end) {
4686 exec_add_error_node(irb->codegen, irb->exec, node,
4687 buf_sprintf("bit offset start must be less than bit offset end"));
4688 return irb->codegen->invalid_instruction;
4689 }
4690
4685 return ir_build_ptr_type_of(irb, scope, node, child_type, is_const, is_volatile,4691 return ir_build_ptr_type_of(irb, scope, node, child_type, is_const, is_volatile,
4686 align_value, bit_offset_start, bit_offset_end);4692 align_value, bit_offset_start, bit_offset_end);
4687}4693}
...@@ -11060,6 +11066,10 @@ static TypeTableEntry *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field...@@ -11060,6 +11066,10 @@ static TypeTableEntry *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field
11060 if (field) {11066 if (field) {
11061 bool is_packed = (bare_type->data.structure.layout == ContainerLayoutPacked);11067 bool is_packed = (bare_type->data.structure.layout == ContainerLayoutPacked);
11062 uint32_t align_bytes = is_packed ? 1 : get_abi_alignment(ira->codegen, field->type_entry);11068 uint32_t align_bytes = is_packed ? 1 : get_abi_alignment(ira->codegen, field->type_entry);
11069 size_t ptr_bit_offset = container_ptr->value.type->data.pointer.bit_offset;
11070 size_t ptr_unaligned_bit_count = container_ptr->value.type->data.pointer.unaligned_bit_count;
11071 size_t unaligned_bit_count_for_result_type = (ptr_unaligned_bit_count == 0) ?
11072 field->unaligned_bit_count : type_size_bits(ira->codegen, field->type_entry);
11063 if (instr_is_comptime(container_ptr)) {11073 if (instr_is_comptime(container_ptr)) {
11064 ConstExprValue *ptr_val = ir_resolve_const(ira, container_ptr, UndefBad);11074 ConstExprValue *ptr_val = ir_resolve_const(ira, container_ptr, UndefBad);
11065 if (!ptr_val)11075 if (!ptr_val)
...@@ -11069,7 +11079,9 @@ static TypeTableEntry *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field...@@ -11069,7 +11079,9 @@ static TypeTableEntry *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field
11069 ConstExprValue *struct_val = const_ptr_pointee(ira->codegen, ptr_val);11079 ConstExprValue *struct_val = const_ptr_pointee(ira->codegen, ptr_val);
11070 ConstExprValue *field_val = &struct_val->data.x_struct.fields[field->src_index];11080 ConstExprValue *field_val = &struct_val->data.x_struct.fields[field->src_index];
11071 TypeTableEntry *ptr_type = get_pointer_to_type_extra(ira->codegen, field_val->type,11081 TypeTableEntry *ptr_type = get_pointer_to_type_extra(ira->codegen, field_val->type,
11072 is_const, is_volatile, align_bytes, 0, 0);11082 is_const, is_volatile, align_bytes,
11083 (uint32_t)(ptr_bit_offset + field->packed_bits_offset),
11084 (uint32_t)unaligned_bit_count_for_result_type);
11073 ConstExprValue *const_val = ir_build_const_from(ira, &field_ptr_instruction->base);11085 ConstExprValue *const_val = ir_build_const_from(ira, &field_ptr_instruction->base);
11074 const_val->data.x_ptr.special = ConstPtrSpecialBaseStruct;11086 const_val->data.x_ptr.special = ConstPtrSpecialBaseStruct;
11075 const_val->data.x_ptr.mut = container_ptr->value.data.x_ptr.mut;11087 const_val->data.x_ptr.mut = container_ptr->value.data.x_ptr.mut;
...@@ -11078,10 +11090,6 @@ static TypeTableEntry *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field...@@ -11078,10 +11090,6 @@ static TypeTableEntry *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field
11078 return ptr_type;11090 return ptr_type;
11079 }11091 }
11080 }11092 }
11081 size_t ptr_bit_offset = container_ptr->value.type->data.pointer.bit_offset;
11082 size_t ptr_unaligned_bit_count = container_ptr->value.type->data.pointer.unaligned_bit_count;
11083 size_t unaligned_bit_count_for_result_type = (ptr_unaligned_bit_count == 0) ?
11084 field->unaligned_bit_count : type_size_bits(ira->codegen, field->type_entry);
11085 ir_build_struct_field_ptr_from(&ira->new_irb, &field_ptr_instruction->base, container_ptr, field);11093 ir_build_struct_field_ptr_from(&ira->new_irb, &field_ptr_instruction->base, container_ptr, field);
11086 return get_pointer_to_type_extra(ira->codegen, field->type_entry, is_const, is_volatile,11094 return get_pointer_to_type_extra(ira->codegen, field->type_entry, is_const, is_volatile,
11087 align_bytes,11095 align_bytes,
...@@ -14841,7 +14849,7 @@ static TypeTableEntry *ir_analyze_instruction_ptr_type_of(IrAnalyze *ira, IrInst...@@ -14841,7 +14849,7 @@ static TypeTableEntry *ir_analyze_instruction_ptr_type_of(IrAnalyze *ira, IrInst
14841 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base);14849 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base);
14842 out_val->data.x_type = get_pointer_to_type_extra(ira->codegen, child_type,14850 out_val->data.x_type = get_pointer_to_type_extra(ira->codegen, child_type,
14843 instruction->is_const, instruction->is_volatile, align_bytes,14851 instruction->is_const, instruction->is_volatile, align_bytes,
14844 instruction->bit_offset_start, instruction->bit_offset_end);14852 instruction->bit_offset_start, instruction->bit_offset_end - instruction->bit_offset_start);
1484514853
14846 return ira->codegen->builtin_types.entry_type;14854 return ira->codegen->builtin_types.entry_type;
14847}14855}
test/behavior.zig+1
...@@ -1,4 +1,5 @@...@@ -1,4 +1,5 @@
1comptime {1comptime {
2 _ = @import("cases/align.zig");
2 _ = @import("cases/alignof.zig");3 _ = @import("cases/alignof.zig");
3 _ = @import("cases/array.zig");4 _ = @import("cases/array.zig");
4 _ = @import("cases/asm.zig");5 _ = @import("cases/asm.zig");
test/cases/align.zig created+40
...@@ -0,0 +1,40 @@
1const assert = @import("std").debug.assert;
2
3var foo: u8 align 4 = 100;
4
5test "global variable alignment" {
6 assert(@typeOf(&foo) == &align 4 u8);
7 const slice = (&foo)[0..1];
8 assert(@typeOf(slice) == []align 4 u8);
9}
10
11fn derp() align (@sizeOf(usize) * 2) -> i32 { 1234 }
12
13test "function alignment" {
14 assert(derp() == 1234);
15}
16
17
18var baz: packed struct {
19 a: u32,
20 b: u32,
21} = undefined;
22
23test "packed struct alignment" {
24 assert(@typeOf(&baz.b) == &align 1 u32);
25}
26
27
28const blah: packed struct {
29 a: u3,
30 b: u3,
31 c: u2,
32} = undefined;
33
34test "bit field alignment" {
35 assert(@typeOf(&blah.b) == &align 1:3:6 const u3);
36}
37
38test "default alignment allows unspecified in type syntax" {
39 assert(&u32 == &align @alignOf(u32) u32);
40}