fix bitfield pointer syntax

See #37
This commit is contained in:
Andrew Kelley 2017-08-29 08:35:51 -04:00
parent c5c9d98065
commit 1116d82197
3 changed files with 55 additions and 6 deletions

View File

@ -4682,6 +4682,12 @@ static IrInstruction *ir_gen_address_of(IrBuilder *irb, Scope *scope, AstNode *n
bit_offset_end = bigint_as_unsigned(node->data.addr_of_expr.bit_offset_end);
}
if ((bit_offset_start != 0 || bit_offset_end != 0) && bit_offset_start >= bit_offset_end) {
exec_add_error_node(irb->codegen, irb->exec, node,
buf_sprintf("bit offset start must be less than bit offset end"));
return irb->codegen->invalid_instruction;
}
return ir_build_ptr_type_of(irb, scope, node, child_type, is_const, is_volatile,
align_value, bit_offset_start, bit_offset_end);
}
@ -11060,6 +11066,10 @@ static TypeTableEntry *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field
if (field) {
bool is_packed = (bare_type->data.structure.layout == ContainerLayoutPacked);
uint32_t align_bytes = is_packed ? 1 : get_abi_alignment(ira->codegen, field->type_entry);
size_t ptr_bit_offset = container_ptr->value.type->data.pointer.bit_offset;
size_t ptr_unaligned_bit_count = container_ptr->value.type->data.pointer.unaligned_bit_count;
size_t unaligned_bit_count_for_result_type = (ptr_unaligned_bit_count == 0) ?
field->unaligned_bit_count : type_size_bits(ira->codegen, field->type_entry);
if (instr_is_comptime(container_ptr)) {
ConstExprValue *ptr_val = ir_resolve_const(ira, container_ptr, UndefBad);
if (!ptr_val)
@ -11069,7 +11079,9 @@ static TypeTableEntry *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field
ConstExprValue *struct_val = const_ptr_pointee(ira->codegen, ptr_val);
ConstExprValue *field_val = &struct_val->data.x_struct.fields[field->src_index];
TypeTableEntry *ptr_type = get_pointer_to_type_extra(ira->codegen, field_val->type,
is_const, is_volatile, align_bytes, 0, 0);
is_const, is_volatile, align_bytes,
(uint32_t)(ptr_bit_offset + field->packed_bits_offset),
(uint32_t)unaligned_bit_count_for_result_type);
ConstExprValue *const_val = ir_build_const_from(ira, &field_ptr_instruction->base);
const_val->data.x_ptr.special = ConstPtrSpecialBaseStruct;
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
return ptr_type;
}
}
size_t ptr_bit_offset = container_ptr->value.type->data.pointer.bit_offset;
size_t ptr_unaligned_bit_count = container_ptr->value.type->data.pointer.unaligned_bit_count;
size_t unaligned_bit_count_for_result_type = (ptr_unaligned_bit_count == 0) ?
field->unaligned_bit_count : type_size_bits(ira->codegen, field->type_entry);
ir_build_struct_field_ptr_from(&ira->new_irb, &field_ptr_instruction->base, container_ptr, field);
return get_pointer_to_type_extra(ira->codegen, field->type_entry, is_const, is_volatile,
align_bytes,
@ -14841,7 +14849,7 @@ static TypeTableEntry *ir_analyze_instruction_ptr_type_of(IrAnalyze *ira, IrInst
ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base);
out_val->data.x_type = get_pointer_to_type_extra(ira->codegen, child_type,
instruction->is_const, instruction->is_volatile, align_bytes,
instruction->bit_offset_start, instruction->bit_offset_end);
instruction->bit_offset_start, instruction->bit_offset_end - instruction->bit_offset_start);
return ira->codegen->builtin_types.entry_type;
}

View File

@ -1,4 +1,5 @@
comptime {
_ = @import("cases/align.zig");
_ = @import("cases/alignof.zig");
_ = @import("cases/array.zig");
_ = @import("cases/asm.zig");

40
test/cases/align.zig Normal file
View File

@ -0,0 +1,40 @@
const assert = @import("std").debug.assert;
var foo: u8 align 4 = 100;
test "global variable alignment" {
assert(@typeOf(&foo) == &align 4 u8);
const slice = (&foo)[0..1];
assert(@typeOf(slice) == []align 4 u8);
}
fn derp() align (@sizeOf(usize) * 2) -> i32 { 1234 }
test "function alignment" {
assert(derp() == 1234);
}
var baz: packed struct {
a: u32,
b: u32,
} = undefined;
test "packed struct alignment" {
assert(@typeOf(&baz.b) == &align 1 u32);
}
const blah: packed struct {
a: u3,
b: u3,
c: u2,
} = undefined;
test "bit field alignment" {
assert(@typeOf(&blah.b) == &align 1:3:6 const u3);
}
test "default alignment allows unspecified in type syntax" {
assert(&u32 == &align @alignOf(u32) u32);
}