aboutsummaryrefslogtreecommitdiff
path: root/src/analyze.cpp
diff options
context:
space:
mode:
authorAndrew Kelley <superjoe30@gmail.com>2018-02-15 12:14:20 -0500
committerAndrew Kelley <superjoe30@gmail.com>2018-02-15 12:14:20 -0500
commitcc26148ba776f713bb81b5ac06fc646eb323e6dc (patch)
treebc044a383521ce427fd7f8072c2989d6b0e32555 /src/analyze.cpp
parent1c1c0691cc4d47a39f382aec29654ae94cdf524c (diff)
downloadzig-cc26148ba776f713bb81b5ac06fc646eb323e6dc.tar.gz
zig-cc26148ba776f713bb81b5ac06fc646eb323e6dc.zip
fix compiler crash when struct contains...
ptr to another struct which contains original struct
Diffstat (limited to 'src/analyze.cpp')
-rw-r--r--src/analyze.cpp19
1 files changed, 12 insertions, 7 deletions
diff --git a/src/analyze.cpp b/src/analyze.cpp
index bf7b6e363f..c16a5d462a 100644
--- a/src/analyze.cpp
+++ b/src/analyze.cpp
@@ -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");
+ }
}
}