authorgravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2020-01-02 23:56:14+01:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-01-03 17:41:55-05:00
logb91eaba38c6661b5eb3558b0c0b88a22a50d2a57
treeda720b471378adace5db8901323b1fac55bb831c
parent3f19bc5d01ffd669dae09c0696613cc8f9656e34

Correct evaluation of optional type alignment

The lazy logic was too oversimplified and produced a different result than the one computed later causing all kinds of problems. Closes #4013

4 files changed, 20 insertions(+), 10 deletions(-)

src/analyze.cpp+9-7
......@@ -1331,7 +1331,7 @@ start_over:
13311331 zig_unreachable();
13321332}
13331333
1334Error type_val_resolve_abi_align(CodeGen *g, ZigValue *type_val, uint32_t *abi_align) {
1334Error type_val_resolve_abi_align(CodeGen *g, AstNode *source_node, ZigValue *type_val, uint32_t *abi_align) {
13351335 Error err;
13361336 if (type_val->special != ConstValSpecialLazy) {
13371337 assert(type_val->special == ConstValSpecialStatic);
......@@ -1356,19 +1356,21 @@ Error type_val_resolve_abi_align(CodeGen *g, ZigValue *type_val, uint32_t *abi_a
13561356 *abi_align = g->builtin_types.entry_usize->abi_align;
13571357 return ErrorNone;
13581358 case LazyValueIdOptType: {
1359 LazyValueOptType *lazy_opt_type = reinterpret_cast<LazyValueOptType *>(type_val->data.x_lazy);
1360 return type_val_resolve_abi_align(g, lazy_opt_type->payload_type->value, abi_align);
1359 if ((err = ir_resolve_lazy(g, nullptr, type_val)))
1360 return err;
1361
1362 return type_val_resolve_abi_align(g, source_node, type_val, abi_align);
13611363 }
13621364 case LazyValueIdArrayType: {
13631365 LazyValueArrayType *lazy_array_type =
13641366 reinterpret_cast<LazyValueArrayType *>(type_val->data.x_lazy);
1365 return type_val_resolve_abi_align(g, lazy_array_type->elem_type->value, abi_align);
1367 return type_val_resolve_abi_align(g, source_node, lazy_array_type->elem_type->value, abi_align);
13661368 }
13671369 case LazyValueIdErrUnionType: {
13681370 LazyValueErrUnionType *lazy_err_union_type =
13691371 reinterpret_cast<LazyValueErrUnionType *>(type_val->data.x_lazy);
13701372 uint32_t payload_abi_align;
1371 if ((err = type_val_resolve_abi_align(g, lazy_err_union_type->payload_type->value,
1373 if ((err = type_val_resolve_abi_align(g, source_node, lazy_err_union_type->payload_type->value,
13721374 &payload_abi_align)))
13731375 {
13741376 return err;
......@@ -2335,7 +2337,7 @@ static Error resolve_union_alignment(CodeGen *g, ZigType *union_type) {
23352337 }
23362338 field->align = field->type_entry->abi_align;
23372339 } else {
2338 if ((err = type_val_resolve_abi_align(g, field->type_val, &field->align))) {
2340 if ((err = type_val_resolve_abi_align(g, field->decl_node, field->type_val, &field->align))) {
23392341 if (g->trace_err != nullptr) {
23402342 g->trace_err = add_error_note(g, g->trace_err, field->decl_node,
23412343 buf_create_from_str("while checking this field"));
......@@ -2912,7 +2914,7 @@ static Error resolve_struct_alignment(CodeGen *g, ZigType *struct_type) {
29122914 } else if (packed) {
29132915 field->align = 1;
29142916 } else {
2915 if ((err = type_val_resolve_abi_align(g, field->type_val, &field->align))) {
2917 if ((err = type_val_resolve_abi_align(g, field->decl_node, field->type_val, &field->align))) {
29162918 if (g->trace_err != nullptr) {
29172919 g->trace_err = add_error_note(g, g->trace_err, field->decl_node,
29182920 buf_create_from_str("while checking this field"));
src/analyze.hpp+1-1
......@@ -260,7 +260,7 @@ ZigValue *analyze_const_value(CodeGen *g, Scope *scope, AstNode *node, ZigType *
260260void resolve_llvm_types_fn(CodeGen *g, ZigFn *fn);
261261bool fn_is_async(ZigFn *fn);
262262
263Error type_val_resolve_abi_align(CodeGen *g, ZigValue *type_val, uint32_t *abi_align);
263Error type_val_resolve_abi_align(CodeGen *g, AstNode *source_node, ZigValue *type_val, uint32_t *abi_align);
264264Error type_val_resolve_abi_size(CodeGen *g, AstNode *source_node, ZigValue *type_val,
265265 size_t *abi_size, size_t *size_in_bits);
266266Error type_val_resolve_zero_bits(CodeGen *g, ZigValue *type_val, ZigType *parent_type,
src/ir.cpp+2-2
......@@ -29200,8 +29200,8 @@ static Error ir_resolve_lazy_raw(AstNode *source_node, ZigValue *val) {
2920029200 }
2920129201
2920229202 uint32_t align_in_bytes;
29203 if ((err = type_val_resolve_abi_align(ira->codegen, lazy_align_of->target_type->value,
29204 &align_in_bytes)))
29203 if ((err = type_val_resolve_abi_align(ira->codegen, source_node,
29204 lazy_align_of->target_type->value, &align_in_bytes)))
2920529205 {
2920629206 return err;
2920729207 }
test/stage1/behavior/optional.zig+8
......@@ -145,3 +145,11 @@ test "coerce an anon struct literal to optional struct" {
145145 S.doTheTest();
146146 comptime S.doTheTest();
147147}
148
149test "optional with void type" {
150 const Foo = struct {
151 x: ?void,
152 };
153 var x = Foo{ .x = null };
154 expect(x.x == null);
155}