authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-03-18 11:16:25-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-03-18 11:16:25-04:00
logb1537b525fa0cd8d51ff89519254db0f066fc04b
tree7947d3da28ca685619fc46248634003b4331cb3f
parent013ada1b59e50bbbab19acab0a79dae72133999a
parent11a4ce42c16c17422cd272f154c9c33231bcc61a
signaturelock-open Commit is signed but in an unrecognized format.

Merge branch 'LemonBoy-fix-4749'

Closes #4750 Closes #4749

5 files changed, 70 insertions(+), 27 deletions(-)

lib/std/zig/parser_test.zig+2
...@@ -1509,6 +1509,8 @@ test "zig fmt: error set declaration" {...@@ -1509,6 +1509,8 @@ test "zig fmt: error set declaration" {
1509 \\const Error = error{OutOfMemory};1509 \\const Error = error{OutOfMemory};
1510 \\const Error = error{};1510 \\const Error = error{};
1511 \\1511 \\
1512 \\const Error = error{ OutOfMemory, OutOfTime };
1513 \\
1512 );1514 );
1513}1515}
15141516
lib/std/zig/render.zig+41-17
...@@ -1268,25 +1268,51 @@ fn renderExpression(...@@ -1268,25 +1268,51 @@ fn renderExpression(
1268 }1268 }
12691269
1270 try renderToken(tree, stream, err_set_decl.error_token, indent, start_col, Space.None); // error1270 try renderToken(tree, stream, err_set_decl.error_token, indent, start_col, Space.None); // error
1271 try renderToken(tree, stream, lbrace, indent, start_col, Space.Newline); // {
1272 const new_indent = indent + indent_delta;
12731271
1274 var it = err_set_decl.decls.iterator(0);1272 const src_has_trailing_comma = blk: {
1275 while (it.next()) |node| {1273 const maybe_comma = tree.prevToken(err_set_decl.rbrace_token);
1276 try stream.writeByteNTimes(' ', new_indent);1274 break :blk tree.tokens.at(maybe_comma).id == .Comma;
1275 };
12771276
1278 if (it.peek()) |next_node| {1277 if (src_has_trailing_comma) {
1279 try renderExpression(allocator, stream, tree, new_indent, start_col, node.*, Space.None);1278 try renderToken(tree, stream, lbrace, indent, start_col, Space.Newline); // {
1280 try renderToken(tree, stream, tree.nextToken(node.*.lastToken()), new_indent, start_col, Space.Newline); // ,1279 const new_indent = indent + indent_delta;
12811280
1282 try renderExtraNewline(tree, stream, start_col, next_node.*);1281 var it = err_set_decl.decls.iterator(0);
1283 } else {1282 while (it.next()) |node| {
1284 try renderExpression(allocator, stream, tree, new_indent, start_col, node.*, Space.Comma);1283 try stream.writeByteNTimes(' ', new_indent);
1284
1285 if (it.peek()) |next_node| {
1286 try renderExpression(allocator, stream, tree, new_indent, start_col, node.*, Space.None);
1287 try renderToken(tree, stream, tree.nextToken(node.*.lastToken()), new_indent, start_col, Space.Newline); // ,
1288
1289 try renderExtraNewline(tree, stream, start_col, next_node.*);
1290 } else {
1291 try renderExpression(allocator, stream, tree, new_indent, start_col, node.*, Space.Comma);
1292 }
1285 }1293 }
1286 }
12871294
1288 try stream.writeByteNTimes(' ', indent);1295 try stream.writeByteNTimes(' ', indent);
1289 return renderToken(tree, stream, err_set_decl.rbrace_token, indent, start_col, space); // }1296 return renderToken(tree, stream, err_set_decl.rbrace_token, indent, start_col, space); // }
1297 } else {
1298 try renderToken(tree, stream, lbrace, indent, start_col, Space.Space); // {
1299
1300 var it = err_set_decl.decls.iterator(0);
1301 while (it.next()) |node| {
1302 if (it.peek()) |next_node| {
1303 try renderExpression(allocator, stream, tree, indent, start_col, node.*, Space.None);
1304
1305 const comma_token = tree.nextToken(node.*.lastToken());
1306 assert(tree.tokens.at(comma_token).id == .Comma);
1307 try renderToken(tree, stream, comma_token, indent, start_col, Space.Space); // ,
1308 try renderExtraNewline(tree, stream, start_col, next_node.*);
1309 } else {
1310 try renderExpression(allocator, stream, tree, indent, start_col, node.*, Space.Space);
1311 }
1312 }
1313
1314 return renderToken(tree, stream, err_set_decl.rbrace_token, indent, start_col, space); // }
1315 }
1290 },1316 },
12911317
1292 .ErrorTag => {1318 .ErrorTag => {
...@@ -1589,8 +1615,7 @@ fn renderExpression(...@@ -1589,8 +1615,7 @@ fn renderExpression(
1589 }1615 }
1590 } else {1616 } else {
1591 var it = switch_case.items.iterator(0);1617 var it = switch_case.items.iterator(0);
1592 while (true) {1618 while (it.next()) |node| {
1593 const node = it.next().?;
1594 if (it.peek()) |next_node| {1619 if (it.peek()) |next_node| {
1595 try renderExpression(allocator, stream, tree, indent, start_col, node.*, Space.None);1620 try renderExpression(allocator, stream, tree, indent, start_col, node.*, Space.None);
15961621
...@@ -1601,7 +1626,6 @@ fn renderExpression(...@@ -1601,7 +1626,6 @@ fn renderExpression(
1601 } else {1626 } else {
1602 try renderExpression(allocator, stream, tree, indent, start_col, node.*, Space.Comma);1627 try renderExpression(allocator, stream, tree, indent, start_col, node.*, Space.Comma);
1603 try stream.writeByteNTimes(' ', indent);1628 try stream.writeByteNTimes(' ', indent);
1604 break;
1605 }1629 }
1606 }1630 }
1607 }1631 }
src/analyze.cpp+4-9
...@@ -803,13 +803,7 @@ ZigType *get_array_type(CodeGen *g, ZigType *child_type, uint64_t array_size, Zi...@@ -803,13 +803,7 @@ ZigType *get_array_type(CodeGen *g, ZigType *child_type, uint64_t array_size, Zi
803 }803 }
804 buf_appendf(&entry->name, "]%s", buf_ptr(&child_type->name));804 buf_appendf(&entry->name, "]%s", buf_ptr(&child_type->name));
805805
806 size_t full_array_size;806 size_t full_array_size = array_size + ((sentinel != nullptr) ? 1 : 0);
807 if (array_size == 0) {
808 full_array_size = 0;
809 } else {
810 full_array_size = array_size + ((sentinel != nullptr) ? 1 : 0);
811 }
812
813 entry->size_in_bits = child_type->size_in_bits * full_array_size;807 entry->size_in_bits = child_type->size_in_bits * full_array_size;
814 entry->abi_align = child_type->abi_align;808 entry->abi_align = child_type->abi_align;
815 entry->abi_size = child_type->abi_size * full_array_size;809 entry->abi_size = child_type->abi_size * full_array_size;
...@@ -1197,7 +1191,8 @@ Error type_val_resolve_zero_bits(CodeGen *g, ZigValue *type_val, ZigType *parent...@@ -1197,7 +1191,8 @@ Error type_val_resolve_zero_bits(CodeGen *g, ZigValue *type_val, ZigType *parent
1197 LazyValueArrayType *lazy_array_type =1191 LazyValueArrayType *lazy_array_type =
1198 reinterpret_cast<LazyValueArrayType *>(type_val->data.x_lazy);1192 reinterpret_cast<LazyValueArrayType *>(type_val->data.x_lazy);
11991193
1200 if (lazy_array_type->length < 1) {1194 // The sentinel counts as an extra element
1195 if (lazy_array_type->length == 0 && lazy_array_type->sentinel == nullptr) {
1201 *is_zero_bits = true;1196 *is_zero_bits = true;
1202 return ErrorNone;1197 return ErrorNone;
1203 }1198 }
...@@ -1452,7 +1447,7 @@ static OnePossibleValue type_val_resolve_has_one_possible_value(CodeGen *g, ZigV...@@ -1452,7 +1447,7 @@ static OnePossibleValue type_val_resolve_has_one_possible_value(CodeGen *g, ZigV
1452 case LazyValueIdArrayType: {1447 case LazyValueIdArrayType: {
1453 LazyValueArrayType *lazy_array_type =1448 LazyValueArrayType *lazy_array_type =
1454 reinterpret_cast<LazyValueArrayType *>(type_val->data.x_lazy);1449 reinterpret_cast<LazyValueArrayType *>(type_val->data.x_lazy);
1455 if (lazy_array_type->length < 1)1450 if (lazy_array_type->length == 0)
1456 return OnePossibleValueYes;1451 return OnePossibleValueYes;
1457 return type_val_resolve_has_one_possible_value(g, lazy_array_type->elem_type->value);1452 return type_val_resolve_has_one_possible_value(g, lazy_array_type->elem_type->value);
1458 }1453 }
src/codegen.cpp+3-1
...@@ -3584,7 +3584,9 @@ static bool value_is_all_undef(CodeGen *g, ZigValue *const_val) {...@@ -3584,7 +3584,9 @@ static bool value_is_all_undef(CodeGen *g, ZigValue *const_val) {
3584 }3584 }
3585 return true;3585 return true;
3586 } else if (const_val->type->id == ZigTypeIdArray) {3586 } else if (const_val->type->id == ZigTypeIdArray) {
3587 return value_is_all_undef_array(g, const_val, const_val->type->data.array.len);3587 const size_t full_len = const_val->type->data.array.len +
3588 (const_val->type->data.array.sentinel != nullptr);
3589 return value_is_all_undef_array(g, const_val, full_len);
3588 } else if (const_val->type->id == ZigTypeIdVector) {3590 } else if (const_val->type->id == ZigTypeIdVector) {
3589 return value_is_all_undef_array(g, const_val, const_val->type->data.vector.len);3591 return value_is_all_undef_array(g, const_val, const_val->type->data.vector.len);
3590 } else {3592 } else {
test/stage1/behavior/array.zig+20
...@@ -376,3 +376,23 @@ test "type deduction for array subscript expression" {...@@ -376,3 +376,23 @@ test "type deduction for array subscript expression" {
376 S.doTheTest();376 S.doTheTest();
377 comptime S.doTheTest();377 comptime S.doTheTest();
378}378}
379
380test "sentinel element count towards the ABI size calculation" {
381 const S = struct {
382 fn doTheTest() void {
383 const T = packed struct {
384 fill_pre: u8 = 0x55,
385 data: [0:0]u8 = undefined,
386 fill_post: u8 = 0xAA,
387 };
388 var x = T{};
389 var as_slice = mem.asBytes(&x);
390 expectEqual(@as(usize, 3), as_slice.len);
391 expectEqual(@as(u8, 0x55), as_slice[0]);
392 expectEqual(@as(u8, 0xAA), as_slice[2]);
393 }
394 };
395
396 S.doTheTest();
397 comptime S.doTheTest();
398}