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
46824682 bit_offset_end = bigint_as_unsigned(node->data.addr_of_expr.bit_offset_end);
46834683 }
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
46854691 return ir_build_ptr_type_of(irb, scope, node, child_type, is_const, is_volatile,
46864692 align_value, bit_offset_start, bit_offset_end);
46874693}
......@@ -11060,6 +11066,10 @@ static TypeTableEntry *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field
1106011066 if (field) {
1106111067 bool is_packed = (bare_type->data.structure.layout == ContainerLayoutPacked);
1106211068 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);
1106311073 if (instr_is_comptime(container_ptr)) {
1106411074 ConstExprValue *ptr_val = ir_resolve_const(ira, container_ptr, UndefBad);
1106511075 if (!ptr_val)
......@@ -11069,7 +11079,9 @@ static TypeTableEntry *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field
1106911079 ConstExprValue *struct_val = const_ptr_pointee(ira->codegen, ptr_val);
1107011080 ConstExprValue *field_val = &struct_val->data.x_struct.fields[field->src_index];
1107111081 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);
1107311085 ConstExprValue *const_val = ir_build_const_from(ira, &field_ptr_instruction->base);
1107411086 const_val->data.x_ptr.special = ConstPtrSpecialBaseStruct;
1107511087 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
1107811090 return ptr_type;
1107911091 }
1108011092 }
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);
1108511093 ir_build_struct_field_ptr_from(&ira->new_irb, &field_ptr_instruction->base, container_ptr, field);
1108611094 return get_pointer_to_type_extra(ira->codegen, field->type_entry, is_const, is_volatile,
1108711095 align_bytes,
......@@ -14841,7 +14849,7 @@ static TypeTableEntry *ir_analyze_instruction_ptr_type_of(IrAnalyze *ira, IrInst
1484114849 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base);
1484214850 out_val->data.x_type = get_pointer_to_type_extra(ira->codegen, child_type,
1484314851 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
1484614854 return ira->codegen->builtin_types.entry_type;
1484714855}
test/behavior.zig+1
......@@ -1,4 +1,5 @@
11comptime {
2 _ = @import("cases/align.zig");
23 _ = @import("cases/alignof.zig");
34 _ = @import("cases/array.zig");
45 _ = @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}