diff options
| author | kristopher tate <kris.tate+github@gmail.com> | 2018-12-20 22:47:44 +0900 |
|---|---|---|
| committer | kristopher tate <kris.tate+github@gmail.com> | 2018-12-20 22:53:54 +0900 |
| commit | 39567e8b50e9026288bb1323d84f481740bd0de7 (patch) | |
| tree | 212cab92b7aa7d0b586dc8363a7a3547b0f05d70 /src/analyze.cpp | |
| parent | 8768816d69ddf3253d2598923643f390cc18082c (diff) | |
| download | zig-39567e8b50e9026288bb1323d84f481740bd0de7.tar.gz zig-39567e8b50e9026288bb1323d84f481740bd0de7.zip | |
src/analyze.cpp: support alignOf(struct T) aligned member inside struct T;
ref: ziglang/zig#1832
Diffstat (limited to 'src/analyze.cpp')
| -rw-r--r-- | src/analyze.cpp | 25 |
1 files changed, 21 insertions, 4 deletions
diff --git a/src/analyze.cpp b/src/analyze.cpp index 46686ce772..e209822132 100644 --- a/src/analyze.cpp +++ b/src/analyze.cpp @@ -2686,13 +2686,22 @@ static Error resolve_struct_alignment(CodeGen *g, ZigType *struct_type) { } size_t field_count = struct_type->data.structure.src_field_count; + bool self_resolving = false; for (size_t i = 0; i < field_count; i += 1) { TypeStructField *field = &struct_type->data.structure.fields[i]; - // If this assertion trips, look up the call stack. Probably something is - // calling type_resolve with ResolveStatusAlignmentKnown when it should only - // be resolving ResolveStatusZeroBitsKnown - assert(field->type_entry != nullptr); + // If we have no type_entry for the field, assume that we are in the + // midst of resolving this struct. We further assume that since the + // resolved alignment of the other fields of this struct is ultimately + // equal to the resolved alignment of this struct, we can safely ignore. + // + // If this struct is used down-stream in aligning a sub-struct, ignoring + // this struct in the context of a sub struct has the same effect since + // the other fields will be calculated and bubble-up. + if (nullptr == field->type_entry) { + self_resolving = true; + continue; + } if (type_is_invalid(field->type_entry)) { struct_type->data.structure.resolve_status = ResolveStatusInvalid; @@ -2723,6 +2732,14 @@ static Error resolve_struct_alignment(CodeGen *g, ZigType *struct_type) { return ErrorSemanticAnalyzeFail; } + if ( self_resolving + && field_count > 0 + ) { + // If we get here it's due to self-referencing this struct before it has been fully resolved. + // In this case, set alignment to target pointer default. + struct_type->data.structure.abi_alignment = LLVMABIAlignmentOfType(g->target_data_ref, + LLVMPointerType(LLVMInt8Type(), 0)); + } struct_type->data.structure.resolve_status = ResolveStatusAlignmentKnown; return ErrorNone; } |
