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:...@@ -1331,7 +1331,7 @@ start_over:
1331 zig_unreachable();1331 zig_unreachable();
1332}1332}
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) {
1335 Error err;1335 Error err;
1336 if (type_val->special != ConstValSpecialLazy) {1336 if (type_val->special != ConstValSpecialLazy) {
1337 assert(type_val->special == ConstValSpecialStatic);1337 assert(type_val->special == ConstValSpecialStatic);
...@@ -1356,19 +1356,21 @@ Error type_val_resolve_abi_align(CodeGen *g, ZigValue *type_val, uint32_t *abi_a...@@ -1356,19 +1356,21 @@ Error type_val_resolve_abi_align(CodeGen *g, ZigValue *type_val, uint32_t *abi_a
1356 *abi_align = g->builtin_types.entry_usize->abi_align;1356 *abi_align = g->builtin_types.entry_usize->abi_align;
1357 return ErrorNone;1357 return ErrorNone;
1358 case LazyValueIdOptType: {1358 case LazyValueIdOptType: {
1359 LazyValueOptType *lazy_opt_type = reinterpret_cast<LazyValueOptType *>(type_val->data.x_lazy);1359 if ((err = ir_resolve_lazy(g, nullptr, type_val)))
1360 return type_val_resolve_abi_align(g, lazy_opt_type->payload_type->value, abi_align);1360 return err;
1361
1362 return type_val_resolve_abi_align(g, source_node, type_val, abi_align);
1361 }1363 }
1362 case LazyValueIdArrayType: {1364 case LazyValueIdArrayType: {
1363 LazyValueArrayType *lazy_array_type =1365 LazyValueArrayType *lazy_array_type =
1364 reinterpret_cast<LazyValueArrayType *>(type_val->data.x_lazy);1366 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);
1366 }1368 }
1367 case LazyValueIdErrUnionType: {1369 case LazyValueIdErrUnionType: {
1368 LazyValueErrUnionType *lazy_err_union_type =1370 LazyValueErrUnionType *lazy_err_union_type =
1369 reinterpret_cast<LazyValueErrUnionType *>(type_val->data.x_lazy);1371 reinterpret_cast<LazyValueErrUnionType *>(type_val->data.x_lazy);
1370 uint32_t payload_abi_align;1372 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,
1372 &payload_abi_align)))1374 &payload_abi_align)))
1373 {1375 {
1374 return err;1376 return err;
...@@ -2335,7 +2337,7 @@ static Error resolve_union_alignment(CodeGen *g, ZigType *union_type) {...@@ -2335,7 +2337,7 @@ static Error resolve_union_alignment(CodeGen *g, ZigType *union_type) {
2335 }2337 }
2336 field->align = field->type_entry->abi_align;2338 field->align = field->type_entry->abi_align;
2337 } else {2339 } 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))) {
2339 if (g->trace_err != nullptr) {2341 if (g->trace_err != nullptr) {
2340 g->trace_err = add_error_note(g, g->trace_err, field->decl_node,2342 g->trace_err = add_error_note(g, g->trace_err, field->decl_node,
2341 buf_create_from_str("while checking this field"));2343 buf_create_from_str("while checking this field"));
...@@ -2912,7 +2914,7 @@ static Error resolve_struct_alignment(CodeGen *g, ZigType *struct_type) {...@@ -2912,7 +2914,7 @@ static Error resolve_struct_alignment(CodeGen *g, ZigType *struct_type) {
2912 } else if (packed) {2914 } else if (packed) {
2913 field->align = 1;2915 field->align = 1;
2914 } else {2916 } 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))) {
2916 if (g->trace_err != nullptr) {2918 if (g->trace_err != nullptr) {
2917 g->trace_err = add_error_note(g, g->trace_err, field->decl_node,2919 g->trace_err = add_error_note(g, g->trace_err, field->decl_node,
2918 buf_create_from_str("while checking this field"));2920 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 *...@@ -260,7 +260,7 @@ ZigValue *analyze_const_value(CodeGen *g, Scope *scope, AstNode *node, ZigType *
260void resolve_llvm_types_fn(CodeGen *g, ZigFn *fn);260void resolve_llvm_types_fn(CodeGen *g, ZigFn *fn);
261bool fn_is_async(ZigFn *fn);261bool 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);
264Error type_val_resolve_abi_size(CodeGen *g, AstNode *source_node, ZigValue *type_val,264Error type_val_resolve_abi_size(CodeGen *g, AstNode *source_node, ZigValue *type_val,
265 size_t *abi_size, size_t *size_in_bits);265 size_t *abi_size, size_t *size_in_bits);
266Error type_val_resolve_zero_bits(CodeGen *g, ZigValue *type_val, ZigType *parent_type,266Error 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) {...@@ -29200,8 +29200,8 @@ static Error ir_resolve_lazy_raw(AstNode *source_node, ZigValue *val) {
29200 }29200 }
2920129201
29202 uint32_t align_in_bytes;29202 uint32_t align_in_bytes;
29203 if ((err = type_val_resolve_abi_align(ira->codegen, lazy_align_of->target_type->value,29203 if ((err = type_val_resolve_abi_align(ira->codegen, source_node,
29204 &align_in_bytes)))29204 lazy_align_of->target_type->value, &align_in_bytes)))
29205 {29205 {
29206 return err;29206 return err;
29207 }29207 }
test/stage1/behavior/optional.zig+8
...@@ -145,3 +145,11 @@ test "coerce an anon struct literal to optional struct" {...@@ -145,3 +145,11 @@ test "coerce an anon struct literal to optional struct" {
145 S.doTheTest();145 S.doTheTest();
146 comptime S.doTheTest();146 comptime S.doTheTest();
147}147}
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}