mirror of
https://github.com/ziglang/zig.git
synced 2024-11-15 16:45:27 +00:00
fix compiler crash when struct contains...
ptr to another struct which contains original struct
This commit is contained in:
parent
1c1c0691cc
commit
cc26148ba7
@ -2278,17 +2278,16 @@ static void resolve_struct_zero_bits(CodeGen *g, TypeTableEntry *struct_type) {
|
||||
return;
|
||||
|
||||
if (struct_type->data.structure.zero_bits_loop_flag) {
|
||||
// If we get here it's due to recursion. From this we conclude that the struct is
|
||||
// not zero bits, and if abi_alignment == 0 we further conclude that the first field
|
||||
// is a pointer to this very struct, or a function pointer with parameters that
|
||||
// reference such a type.
|
||||
// If we get here it's due to recursion. This is a design flaw in the compiler,
|
||||
// we should be able to still figure out alignment, but here we give up and say that
|
||||
// the alignment is pointer width, then assert that the first field is within that
|
||||
// alignment
|
||||
struct_type->data.structure.zero_bits_known = true;
|
||||
if (struct_type->data.structure.abi_alignment == 0) {
|
||||
if (struct_type->data.structure.layout == ContainerLayoutPacked) {
|
||||
struct_type->data.structure.abi_alignment = 1;
|
||||
} else {
|
||||
struct_type->data.structure.abi_alignment = LLVMABIAlignmentOfType(g->target_data_ref,
|
||||
LLVMPointerType(LLVMInt8Type(), 0));
|
||||
struct_type->data.structure.abi_alignment = LLVMABIAlignmentOfType(g->target_data_ref, LLVMPointerType(LLVMInt8Type(), 0));
|
||||
}
|
||||
}
|
||||
return;
|
||||
@ -2352,11 +2351,17 @@ static void resolve_struct_zero_bits(CodeGen *g, TypeTableEntry *struct_type) {
|
||||
if (gen_field_index == 0) {
|
||||
if (struct_type->data.structure.layout == ContainerLayoutPacked) {
|
||||
struct_type->data.structure.abi_alignment = 1;
|
||||
} else {
|
||||
} else if (struct_type->data.structure.abi_alignment == 0) {
|
||||
// Alignment of structs is the alignment of the first field, for now.
|
||||
// TODO change this when we re-order struct fields (issue #168)
|
||||
struct_type->data.structure.abi_alignment = get_abi_alignment(g, field_type);
|
||||
assert(struct_type->data.structure.abi_alignment != 0);
|
||||
} else {
|
||||
// due to a design flaw in the compiler we assumed that alignment was
|
||||
// pointer width, so we assert that this wasn't violated.
|
||||
if (get_abi_alignment(g, field_type) > struct_type->data.structure.abi_alignment) {
|
||||
zig_panic("compiler design flaw: incorrect alignment assumption");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -35,6 +35,7 @@ comptime {
|
||||
_ = @import("cases/slice.zig");
|
||||
_ = @import("cases/struct.zig");
|
||||
_ = @import("cases/struct_contains_slice_of_itself.zig");
|
||||
_ = @import("cases/struct_contains_null_ptr_itself.zig");
|
||||
_ = @import("cases/switch.zig");
|
||||
_ = @import("cases/switch_prong_err_enum.zig");
|
||||
_ = @import("cases/switch_prong_implicit_cast.zig");
|
||||
|
22
test/cases/struct_contains_null_ptr_itself.zig
Normal file
22
test/cases/struct_contains_null_ptr_itself.zig
Normal file
@ -0,0 +1,22 @@
|
||||
const std = @import("std");
|
||||
const assert = std.debug.assert;
|
||||
|
||||
test "struct contains null pointer which contains original struct" {
|
||||
var x: ?&NodeLineComment = null;
|
||||
assert(x == null);
|
||||
}
|
||||
|
||||
pub const Node = struct {
|
||||
id: Id,
|
||||
comment: ?&NodeLineComment,
|
||||
|
||||
pub const Id = enum {
|
||||
Root,
|
||||
LineComment,
|
||||
};
|
||||
};
|
||||
|
||||
pub const NodeLineComment = struct {
|
||||
base: Node,
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user