authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2020-08-12 23:35:11+03:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2020-08-13 01:13:17+03:00
log373488157751dbaa22415ce842c4f5616fc845ff
treefaa6c045484c41b141ed7dce97c6f4a0346a01e8
parent67d684d89aeb0bb3cfa86c57e8d77359d45743fa
signature Commit is signed but in an unrecognized format.

add error for unused/duplicate block labels


7 files changed, 97 insertions(+), 11 deletions(-)

lib/std/dwarf.zig+1-1
...@@ -322,7 +322,7 @@ fn parseFormValue(allocator: *mem.Allocator, in_stream: anytype, form_id: u64, e...@@ -322,7 +322,7 @@ fn parseFormValue(allocator: *mem.Allocator, in_stream: anytype, form_id: u64, e
322 FORM_block1 => parseFormValueBlock(allocator, in_stream, endian, 1),322 FORM_block1 => parseFormValueBlock(allocator, in_stream, endian, 1),
323 FORM_block2 => parseFormValueBlock(allocator, in_stream, endian, 2),323 FORM_block2 => parseFormValueBlock(allocator, in_stream, endian, 2),
324 FORM_block4 => parseFormValueBlock(allocator, in_stream, endian, 4),324 FORM_block4 => parseFormValueBlock(allocator, in_stream, endian, 4),
325 FORM_block => x: {325 FORM_block => {
326 const block_len = try nosuspend leb.readULEB128(usize, in_stream);326 const block_len = try nosuspend leb.readULEB128(usize, in_stream);
327 return parseFormValueBlockLen(allocator, in_stream, block_len);327 return parseFormValueBlockLen(allocator, in_stream, block_len);
328 },328 },
lib/std/special/c.zig+3-3
...@@ -536,7 +536,7 @@ fn generic_fmod(comptime T: type, x: T, y: T) T {...@@ -536,7 +536,7 @@ fn generic_fmod(comptime T: type, x: T, y: T) T {
536 // normalize x and y536 // normalize x and y
537 if (ex == 0) {537 if (ex == 0) {
538 i = ux << exp_bits;538 i = ux << exp_bits;
539 while (i >> bits_minus_1 == 0) : (b: {539 while (i >> bits_minus_1 == 0) : ({
540 ex -= 1;540 ex -= 1;
541 i <<= 1;541 i <<= 1;
542 }) {}542 }) {}
...@@ -547,7 +547,7 @@ fn generic_fmod(comptime T: type, x: T, y: T) T {...@@ -547,7 +547,7 @@ fn generic_fmod(comptime T: type, x: T, y: T) T {
547 }547 }
548 if (ey == 0) {548 if (ey == 0) {
549 i = uy << exp_bits;549 i = uy << exp_bits;
550 while (i >> bits_minus_1 == 0) : (b: {550 while (i >> bits_minus_1 == 0) : ({
551 ey -= 1;551 ey -= 1;
552 i <<= 1;552 i <<= 1;
553 }) {}553 }) {}
...@@ -573,7 +573,7 @@ fn generic_fmod(comptime T: type, x: T, y: T) T {...@@ -573,7 +573,7 @@ fn generic_fmod(comptime T: type, x: T, y: T) T {
573 return 0 * x;573 return 0 * x;
574 ux = i;574 ux = i;
575 }575 }
576 while (ux >> digits == 0) : (b: {576 while (ux >> digits == 0) : ({
577 ux <<= 1;577 ux <<= 1;
578 ex -= 1;578 ex -= 1;
579 }) {}579 }) {}
lib/std/zig/render.zig+1-1
...@@ -2385,7 +2385,7 @@ fn renderTokenOffset(...@@ -2385,7 +2385,7 @@ fn renderTokenOffset(
2385 }2385 }
2386 }2386 }
23872387
2388 if (next_token_id != .LineComment) blk: {2388 if (next_token_id != .LineComment) {
2389 switch (space) {2389 switch (space) {
2390 Space.None, Space.NoNewline => return,2390 Space.None, Space.NoNewline => return,
2391 Space.Newline => {2391 Space.Newline => {
src-self-hosted/translate_c.zig+6-6
...@@ -931,7 +931,7 @@ fn transRecordDecl(c: *Context, record_decl: *const ZigClangRecordDecl) Error!?*...@@ -931,7 +931,7 @@ fn transRecordDecl(c: *Context, record_decl: *const ZigClangRecordDecl) Error!?*
931 else => |e| return e,931 else => |e| return e,
932 };932 };
933933
934 const align_expr = blk: {934 const align_expr = blk_2: {
935 const alignment = ZigClangFieldDecl_getAlignedAttribute(field_decl, rp.c.clang_context);935 const alignment = ZigClangFieldDecl_getAlignedAttribute(field_decl, rp.c.clang_context);
936 if (alignment != 0) {936 if (alignment != 0) {
937 _ = try appendToken(rp.c, .Keyword_align, "align");937 _ = try appendToken(rp.c, .Keyword_align, "align");
...@@ -940,9 +940,9 @@ fn transRecordDecl(c: *Context, record_decl: *const ZigClangRecordDecl) Error!?*...@@ -940,9 +940,9 @@ fn transRecordDecl(c: *Context, record_decl: *const ZigClangRecordDecl) Error!?*
940 const expr = try transCreateNodeInt(rp.c, alignment / 8);940 const expr = try transCreateNodeInt(rp.c, alignment / 8);
941 _ = try appendToken(rp.c, .RParen, ")");941 _ = try appendToken(rp.c, .RParen, ")");
942942
943 break :blk expr;943 break :blk_2 expr;
944 }944 }
945 break :blk null;945 break :blk_2 null;
946 };946 };
947947
948 const field_node = try c.arena.create(ast.Node.ContainerField);948 const field_node = try c.arena.create(ast.Node.ContainerField);
...@@ -1073,9 +1073,9 @@ fn transEnumDecl(c: *Context, enum_decl: *const ZigClangEnumDecl) Error!?*ast.No...@@ -1073,9 +1073,9 @@ fn transEnumDecl(c: *Context, enum_decl: *const ZigClangEnumDecl) Error!?*ast.No
10731073
1074 const field_name_tok = try appendIdentifier(c, field_name);1074 const field_name_tok = try appendIdentifier(c, field_name);
10751075
1076 const int_node = if (!pure_enum) blk: {1076 const int_node = if (!pure_enum) blk_2: {
1077 _ = try appendToken(c, .Colon, "=");1077 _ = try appendToken(c, .Colon, "=");
1078 break :blk try transCreateNodeAPInt(c, ZigClangEnumConstantDecl_getInitVal(enum_const));1078 break :blk_2 try transCreateNodeAPInt(c, ZigClangEnumConstantDecl_getInitVal(enum_const));
1079 } else1079 } else
1080 null;1080 null;
10811081
...@@ -2388,7 +2388,7 @@ fn transZeroInitExpr(...@@ -2388,7 +2388,7 @@ fn transZeroInitExpr(
2388 ty: *const ZigClangType,2388 ty: *const ZigClangType,
2389) TransError!*ast.Node {2389) TransError!*ast.Node {
2390 switch (ZigClangType_getTypeClass(ty)) {2390 switch (ZigClangType_getTypeClass(ty)) {
2391 .Builtin => blk: {2391 .Builtin => {
2392 const builtin_ty = @ptrCast(*const ZigClangBuiltinType, ty);2392 const builtin_ty = @ptrCast(*const ZigClangBuiltinType, ty);
2393 switch (ZigClangBuiltinType_getKind(builtin_ty)) {2393 switch (ZigClangBuiltinType_getKind(builtin_ty)) {
2394 .Bool => return try transCreateNodeBoolLiteral(rp.c, false),2394 .Bool => return try transCreateNodeBoolLiteral(rp.c, false),
src/all_types.hpp+3
...@@ -2438,6 +2438,7 @@ struct ScopeBlock {...@@ -2438,6 +2438,7 @@ struct ScopeBlock {
2438 LVal lval;2438 LVal lval;
2439 bool safety_off;2439 bool safety_off;
2440 bool fast_math_on;2440 bool fast_math_on;
2441 bool name_used;
2441};2442};
24422443
2443// This scope is created from every defer expression.2444// This scope is created from every defer expression.
...@@ -2488,6 +2489,8 @@ struct ScopeLoop {...@@ -2488,6 +2489,8 @@ struct ScopeLoop {
2488 ZigList<IrBasicBlockSrc *> *incoming_blocks;2489 ZigList<IrBasicBlockSrc *> *incoming_blocks;
2489 ResultLocPeerParent *peer_parent;2490 ResultLocPeerParent *peer_parent;
2490 ScopeExpr *spill_scope;2491 ScopeExpr *spill_scope;
2492
2493 bool name_used;
2491};2494};
24922495
2493// This scope blocks certain things from working such as comptime continue2496// This scope blocks certain things from working such as comptime continue
src/ir.cpp+60
...@@ -5476,6 +5476,25 @@ static ResultLocPeer *create_peer_result(ResultLocPeerParent *peer_parent) {...@@ -5476,6 +5476,25 @@ static ResultLocPeer *create_peer_result(ResultLocPeerParent *peer_parent) {
5476 return result;5476 return result;
5477}5477}
54785478
5479static bool is_duplicate_label(CodeGen *g, Scope *scope, AstNode *node, Buf *name) {
5480 if (name == nullptr) return false;
5481
5482 for (;;) {
5483 if (scope == nullptr || scope->id == ScopeIdFnDef) {
5484 break;
5485 } else if (scope->id == ScopeIdBlock || scope->id == ScopeIdLoop) {
5486 Buf *this_block_name = scope->id == ScopeIdBlock ? ((ScopeBlock *)scope)->name : ((ScopeLoop *)scope)->name;
5487 if (this_block_name != nullptr && buf_eql_buf(name, this_block_name)) {
5488 ErrorMsg *msg = add_node_error(g, node, buf_sprintf("redeclaration of label '%s'", buf_ptr(name)));
5489 add_error_note(g, msg, scope->source_node, buf_sprintf("previous declaration is here"));
5490 return true;
5491 }
5492 }
5493 scope = scope->parent;
5494 }
5495 return false;
5496}
5497
5479static IrInstSrc *ir_gen_block(IrBuilderSrc *irb, Scope *parent_scope, AstNode *block_node, LVal lval,5498static IrInstSrc *ir_gen_block(IrBuilderSrc *irb, Scope *parent_scope, AstNode *block_node, LVal lval,
5480 ResultLoc *result_loc)5499 ResultLoc *result_loc)
5481{5500{
...@@ -5484,6 +5503,9 @@ static IrInstSrc *ir_gen_block(IrBuilderSrc *irb, Scope *parent_scope, AstNode *...@@ -5484,6 +5503,9 @@ static IrInstSrc *ir_gen_block(IrBuilderSrc *irb, Scope *parent_scope, AstNode *
5484 ZigList<IrInstSrc *> incoming_values = {0};5503 ZigList<IrInstSrc *> incoming_values = {0};
5485 ZigList<IrBasicBlockSrc *> incoming_blocks = {0};5504 ZigList<IrBasicBlockSrc *> incoming_blocks = {0};
54865505
5506 if (is_duplicate_label(irb->codegen, parent_scope, block_node, block_node->data.block.name))
5507 return irb->codegen->invalid_inst_src;
5508
5487 ScopeBlock *scope_block = create_block_scope(irb->codegen, block_node, parent_scope);5509 ScopeBlock *scope_block = create_block_scope(irb->codegen, block_node, parent_scope);
54885510
5489 Scope *outer_block_scope = &scope_block->base;5511 Scope *outer_block_scope = &scope_block->base;
...@@ -5495,6 +5517,9 @@ static IrInstSrc *ir_gen_block(IrBuilderSrc *irb, Scope *parent_scope, AstNode *...@@ -5495,6 +5517,9 @@ static IrInstSrc *ir_gen_block(IrBuilderSrc *irb, Scope *parent_scope, AstNode *
5495 }5517 }
54965518
5497 if (block_node->data.block.statements.length == 0) {5519 if (block_node->data.block.statements.length == 0) {
5520 if (scope_block->name != nullptr) {
5521 add_node_error(irb->codegen, block_node, buf_sprintf("unused block label"));
5522 }
5498 // {}5523 // {}
5499 return ir_lval_wrap(irb, parent_scope, ir_build_const_void(irb, child_scope, block_node), lval, result_loc);5524 return ir_lval_wrap(irb, parent_scope, ir_build_const_void(irb, child_scope, block_node), lval, result_loc);
5500 }5525 }
...@@ -5552,6 +5577,10 @@ static IrInstSrc *ir_gen_block(IrBuilderSrc *irb, Scope *parent_scope, AstNode *...@@ -5552,6 +5577,10 @@ static IrInstSrc *ir_gen_block(IrBuilderSrc *irb, Scope *parent_scope, AstNode *
5552 }5577 }
5553 }5578 }
55545579
5580 if (scope_block->name != nullptr && scope_block->name_used == false) {
5581 add_node_error(irb->codegen, block_node, buf_sprintf("unused block label"));
5582 }
5583
5555 if (found_invalid_inst)5584 if (found_invalid_inst)
5556 return irb->codegen->invalid_inst_src;5585 return irb->codegen->invalid_inst_src;
55575586
...@@ -8152,6 +8181,9 @@ static IrInstSrc *ir_gen_while_expr(IrBuilderSrc *irb, Scope *scope, AstNode *no...@@ -8152,6 +8181,9 @@ static IrInstSrc *ir_gen_while_expr(IrBuilderSrc *irb, Scope *scope, AstNode *no
8152 ZigList<IrInstSrc *> incoming_values = {0};8181 ZigList<IrInstSrc *> incoming_values = {0};
8153 ZigList<IrBasicBlockSrc *> incoming_blocks = {0};8182 ZigList<IrBasicBlockSrc *> incoming_blocks = {0};
81548183
8184 if (is_duplicate_label(irb->codegen, payload_scope, node, node->data.while_expr.name))
8185 return irb->codegen->invalid_inst_src;
8186
8155 ScopeLoop *loop_scope = create_loop_scope(irb->codegen, node, payload_scope);8187 ScopeLoop *loop_scope = create_loop_scope(irb->codegen, node, payload_scope);
8156 loop_scope->break_block = end_block;8188 loop_scope->break_block = end_block;
8157 loop_scope->continue_block = continue_block;8189 loop_scope->continue_block = continue_block;
...@@ -8169,6 +8201,10 @@ static IrInstSrc *ir_gen_while_expr(IrBuilderSrc *irb, Scope *scope, AstNode *no...@@ -8169,6 +8201,10 @@ static IrInstSrc *ir_gen_while_expr(IrBuilderSrc *irb, Scope *scope, AstNode *no
8169 if (body_result == irb->codegen->invalid_inst_src)8201 if (body_result == irb->codegen->invalid_inst_src)
8170 return body_result;8202 return body_result;
81718203
8204 if (loop_scope->name != nullptr && loop_scope->name_used == false) {
8205 add_node_error(irb->codegen, node, buf_sprintf("unused while label"));
8206 }
8207
8172 if (!instr_is_unreachable(body_result)) {8208 if (!instr_is_unreachable(body_result)) {
8173 ir_mark_gen(ir_build_check_statement_is_void(irb, payload_scope, node->data.while_expr.body, body_result));8209 ir_mark_gen(ir_build_check_statement_is_void(irb, payload_scope, node->data.while_expr.body, body_result));
8174 ir_mark_gen(ir_build_br(irb, payload_scope, node, continue_block, is_comptime));8210 ir_mark_gen(ir_build_br(irb, payload_scope, node, continue_block, is_comptime));
...@@ -8263,6 +8299,9 @@ static IrInstSrc *ir_gen_while_expr(IrBuilderSrc *irb, Scope *scope, AstNode *no...@@ -8263,6 +8299,9 @@ static IrInstSrc *ir_gen_while_expr(IrBuilderSrc *irb, Scope *scope, AstNode *no
8263 ZigList<IrInstSrc *> incoming_values = {0};8299 ZigList<IrInstSrc *> incoming_values = {0};
8264 ZigList<IrBasicBlockSrc *> incoming_blocks = {0};8300 ZigList<IrBasicBlockSrc *> incoming_blocks = {0};
82658301
8302 if (is_duplicate_label(irb->codegen, child_scope, node, node->data.while_expr.name))
8303 return irb->codegen->invalid_inst_src;
8304
8266 ScopeLoop *loop_scope = create_loop_scope(irb->codegen, node, child_scope);8305 ScopeLoop *loop_scope = create_loop_scope(irb->codegen, node, child_scope);
8267 loop_scope->break_block = end_block;8306 loop_scope->break_block = end_block;
8268 loop_scope->continue_block = continue_block;8307 loop_scope->continue_block = continue_block;
...@@ -8280,6 +8319,10 @@ static IrInstSrc *ir_gen_while_expr(IrBuilderSrc *irb, Scope *scope, AstNode *no...@@ -8280,6 +8319,10 @@ static IrInstSrc *ir_gen_while_expr(IrBuilderSrc *irb, Scope *scope, AstNode *no
8280 if (body_result == irb->codegen->invalid_inst_src)8319 if (body_result == irb->codegen->invalid_inst_src)
8281 return body_result;8320 return body_result;
82828321
8322 if (loop_scope->name != nullptr && loop_scope->name_used == false) {
8323 add_node_error(irb->codegen, node, buf_sprintf("unused while label"));
8324 }
8325
8283 if (!instr_is_unreachable(body_result)) {8326 if (!instr_is_unreachable(body_result)) {
8284 ir_mark_gen(ir_build_check_statement_is_void(irb, child_scope, node->data.while_expr.body, body_result));8327 ir_mark_gen(ir_build_check_statement_is_void(irb, child_scope, node->data.while_expr.body, body_result));
8285 ir_mark_gen(ir_build_br(irb, child_scope, node, continue_block, is_comptime));8328 ir_mark_gen(ir_build_br(irb, child_scope, node, continue_block, is_comptime));
...@@ -8353,6 +8396,9 @@ static IrInstSrc *ir_gen_while_expr(IrBuilderSrc *irb, Scope *scope, AstNode *no...@@ -8353,6 +8396,9 @@ static IrInstSrc *ir_gen_while_expr(IrBuilderSrc *irb, Scope *scope, AstNode *no
83538396
8354 Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime);8397 Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime);
83558398
8399 if (is_duplicate_label(irb->codegen, subexpr_scope, node, node->data.while_expr.name))
8400 return irb->codegen->invalid_inst_src;
8401
8356 ScopeLoop *loop_scope = create_loop_scope(irb->codegen, node, subexpr_scope);8402 ScopeLoop *loop_scope = create_loop_scope(irb->codegen, node, subexpr_scope);
8357 loop_scope->break_block = end_block;8403 loop_scope->break_block = end_block;
8358 loop_scope->continue_block = continue_block;8404 loop_scope->continue_block = continue_block;
...@@ -8369,6 +8415,10 @@ static IrInstSrc *ir_gen_while_expr(IrBuilderSrc *irb, Scope *scope, AstNode *no...@@ -8369,6 +8415,10 @@ static IrInstSrc *ir_gen_while_expr(IrBuilderSrc *irb, Scope *scope, AstNode *no
8369 if (body_result == irb->codegen->invalid_inst_src)8415 if (body_result == irb->codegen->invalid_inst_src)
8370 return body_result;8416 return body_result;
83718417
8418 if (loop_scope->name != nullptr && loop_scope->name_used == false) {
8419 add_node_error(irb->codegen, node, buf_sprintf("unused while label"));
8420 }
8421
8372 if (!instr_is_unreachable(body_result)) {8422 if (!instr_is_unreachable(body_result)) {
8373 ir_mark_gen(ir_build_check_statement_is_void(irb, scope, node->data.while_expr.body, body_result));8423 ir_mark_gen(ir_build_check_statement_is_void(irb, scope, node->data.while_expr.body, body_result));
8374 ir_mark_gen(ir_build_br(irb, scope, node, continue_block, is_comptime));8424 ir_mark_gen(ir_build_br(irb, scope, node, continue_block, is_comptime));
...@@ -8501,6 +8551,9 @@ static IrInstSrc *ir_gen_for_expr(IrBuilderSrc *irb, Scope *parent_scope, AstNod...@@ -8501,6 +8551,9 @@ static IrInstSrc *ir_gen_for_expr(IrBuilderSrc *irb, Scope *parent_scope, AstNod
8501 elem_ptr : ir_build_load_ptr(irb, &spill_scope->base, elem_node, elem_ptr);8551 elem_ptr : ir_build_load_ptr(irb, &spill_scope->base, elem_node, elem_ptr);
8502 build_decl_var_and_init(irb, parent_scope, elem_node, elem_var, elem_value, buf_ptr(elem_var_name), is_comptime);8552 build_decl_var_and_init(irb, parent_scope, elem_node, elem_var, elem_value, buf_ptr(elem_var_name), is_comptime);
85038553
8554 if (is_duplicate_label(irb->codegen, child_scope, node, node->data.for_expr.name))
8555 return irb->codegen->invalid_inst_src;
8556
8504 ZigList<IrInstSrc *> incoming_values = {0};8557 ZigList<IrInstSrc *> incoming_values = {0};
8505 ZigList<IrBasicBlockSrc *> incoming_blocks = {0};8558 ZigList<IrBasicBlockSrc *> incoming_blocks = {0};
8506 ScopeLoop *loop_scope = create_loop_scope(irb->codegen, node, child_scope);8559 ScopeLoop *loop_scope = create_loop_scope(irb->codegen, node, child_scope);
...@@ -8520,6 +8573,10 @@ static IrInstSrc *ir_gen_for_expr(IrBuilderSrc *irb, Scope *parent_scope, AstNod...@@ -8520,6 +8573,10 @@ static IrInstSrc *ir_gen_for_expr(IrBuilderSrc *irb, Scope *parent_scope, AstNod
8520 if (body_result == irb->codegen->invalid_inst_src)8573 if (body_result == irb->codegen->invalid_inst_src)
8521 return irb->codegen->invalid_inst_src;8574 return irb->codegen->invalid_inst_src;
85228575
8576 if (loop_scope->name != nullptr && loop_scope->name_used == false) {
8577 add_node_error(irb->codegen, node, buf_sprintf("unused for label"));
8578 }
8579
8523 if (!instr_is_unreachable(body_result)) {8580 if (!instr_is_unreachable(body_result)) {
8524 ir_mark_gen(ir_build_check_statement_is_void(irb, child_scope, node->data.for_expr.body, body_result));8581 ir_mark_gen(ir_build_check_statement_is_void(irb, child_scope, node->data.for_expr.body, body_result));
8525 ir_mark_gen(ir_build_br(irb, child_scope, node, continue_block, is_comptime));8582 ir_mark_gen(ir_build_br(irb, child_scope, node, continue_block, is_comptime));
...@@ -9464,6 +9521,7 @@ static IrInstSrc *ir_gen_break(IrBuilderSrc *irb, Scope *break_scope, AstNode *n...@@ -9464,6 +9521,7 @@ static IrInstSrc *ir_gen_break(IrBuilderSrc *irb, Scope *break_scope, AstNode *n
9464 if (node->data.break_expr.name == nullptr ||9521 if (node->data.break_expr.name == nullptr ||
9465 (this_loop_scope->name != nullptr && buf_eql_buf(node->data.break_expr.name, this_loop_scope->name)))9522 (this_loop_scope->name != nullptr && buf_eql_buf(node->data.break_expr.name, this_loop_scope->name)))
9466 {9523 {
9524 this_loop_scope->name_used = true;
9467 loop_scope = this_loop_scope;9525 loop_scope = this_loop_scope;
9468 break;9526 break;
9469 }9527 }
...@@ -9473,6 +9531,7 @@ static IrInstSrc *ir_gen_break(IrBuilderSrc *irb, Scope *break_scope, AstNode *n...@@ -9473,6 +9531,7 @@ static IrInstSrc *ir_gen_break(IrBuilderSrc *irb, Scope *break_scope, AstNode *n
9473 (this_block_scope->name != nullptr && buf_eql_buf(node->data.break_expr.name, this_block_scope->name)))9531 (this_block_scope->name != nullptr && buf_eql_buf(node->data.break_expr.name, this_block_scope->name)))
9474 {9532 {
9475 assert(this_block_scope->end_block != nullptr);9533 assert(this_block_scope->end_block != nullptr);
9534 this_block_scope->name_used = true;
9476 return ir_gen_return_from_block(irb, break_scope, node, this_block_scope);9535 return ir_gen_return_from_block(irb, break_scope, node, this_block_scope);
9477 }9536 }
9478 } else if (search_scope->id == ScopeIdSuspend) {9537 } else if (search_scope->id == ScopeIdSuspend) {
...@@ -9540,6 +9599,7 @@ static IrInstSrc *ir_gen_continue(IrBuilderSrc *irb, Scope *continue_scope, AstN...@@ -9540,6 +9599,7 @@ static IrInstSrc *ir_gen_continue(IrBuilderSrc *irb, Scope *continue_scope, AstN
9540 if (node->data.continue_expr.name == nullptr ||9599 if (node->data.continue_expr.name == nullptr ||
9541 (this_loop_scope->name != nullptr && buf_eql_buf(node->data.continue_expr.name, this_loop_scope->name)))9600 (this_loop_scope->name != nullptr && buf_eql_buf(node->data.continue_expr.name, this_loop_scope->name)))
9542 {9601 {
9602 this_loop_scope->name_used = true;
9543 loop_scope = this_loop_scope;9603 loop_scope = this_loop_scope;
9544 break;9604 break;
9545 }9605 }
test/compile_errors.zig+23
...@@ -2,6 +2,29 @@ const tests = @import("tests.zig");...@@ -2,6 +2,29 @@ const tests = @import("tests.zig");
2const std = @import("std");2const std = @import("std");
33
4pub fn addCases(cases: *tests.CompileErrorContext) void {4pub fn addCases(cases: *tests.CompileErrorContext) void {
5 cases.addTest("duplicate/unused labels",
6 \\comptime {
7 \\ blk: { blk: while (false) {} }
8 \\ blk: while (false) { blk: for (@as([0]void, undefined)) |_| {} }
9 \\ blk: for (@as([0]void, undefined)) |_| { blk: {} }
10 \\}
11 \\comptime {
12 \\ blk: {}
13 \\ blk: while(false) {}
14 \\ blk: for(@as([0]void, undefined)) |_| {}
15 \\}
16 , &[_][]const u8{
17 "tmp.zig:2:17: error: redeclaration of label 'blk'",
18 "tmp.zig:2:10: note: previous declaration is here",
19 "tmp.zig:3:31: error: redeclaration of label 'blk'",
20 "tmp.zig:3:10: note: previous declaration is here",
21 "tmp.zig:4:51: error: redeclaration of label 'blk'",
22 "tmp.zig:4:10: note: previous declaration is here",
23 "tmp.zig:7:10: error: unused block label",
24 "tmp.zig:8:10: error: unused while label",
25 "tmp.zig:9:10: error: unused for label",
26 });
27
5 cases.addTest("@alignCast of zero sized types",28 cases.addTest("@alignCast of zero sized types",
6 \\export fn foo() void {29 \\export fn foo() void {
7 \\ const a: *void = undefined;30 \\ const a: *void = undefined;