mirror of
https://codeberg.org/ziglang/zig.git
synced 2025-12-09 23:29:03 +00:00
add error for unused/duplicate block labels
This commit is contained in:
parent
67d684d89a
commit
3734881577
7 changed files with 97 additions and 11 deletions
|
|
@ -322,7 +322,7 @@ fn parseFormValue(allocator: *mem.Allocator, in_stream: anytype, form_id: u64, e
|
||||||
FORM_block1 => parseFormValueBlock(allocator, in_stream, endian, 1),
|
FORM_block1 => parseFormValueBlock(allocator, in_stream, endian, 1),
|
||||||
FORM_block2 => parseFormValueBlock(allocator, in_stream, endian, 2),
|
FORM_block2 => parseFormValueBlock(allocator, in_stream, endian, 2),
|
||||||
FORM_block4 => parseFormValueBlock(allocator, in_stream, endian, 4),
|
FORM_block4 => parseFormValueBlock(allocator, in_stream, endian, 4),
|
||||||
FORM_block => x: {
|
FORM_block => {
|
||||||
const block_len = try nosuspend leb.readULEB128(usize, in_stream);
|
const block_len = try nosuspend leb.readULEB128(usize, in_stream);
|
||||||
return parseFormValueBlockLen(allocator, in_stream, block_len);
|
return parseFormValueBlockLen(allocator, in_stream, block_len);
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -536,7 +536,7 @@ fn generic_fmod(comptime T: type, x: T, y: T) T {
|
||||||
// normalize x and y
|
// normalize x and y
|
||||||
if (ex == 0) {
|
if (ex == 0) {
|
||||||
i = ux << exp_bits;
|
i = ux << exp_bits;
|
||||||
while (i >> bits_minus_1 == 0) : (b: {
|
while (i >> bits_minus_1 == 0) : ({
|
||||||
ex -= 1;
|
ex -= 1;
|
||||||
i <<= 1;
|
i <<= 1;
|
||||||
}) {}
|
}) {}
|
||||||
|
|
@ -547,7 +547,7 @@ fn generic_fmod(comptime T: type, x: T, y: T) T {
|
||||||
}
|
}
|
||||||
if (ey == 0) {
|
if (ey == 0) {
|
||||||
i = uy << exp_bits;
|
i = uy << exp_bits;
|
||||||
while (i >> bits_minus_1 == 0) : (b: {
|
while (i >> bits_minus_1 == 0) : ({
|
||||||
ey -= 1;
|
ey -= 1;
|
||||||
i <<= 1;
|
i <<= 1;
|
||||||
}) {}
|
}) {}
|
||||||
|
|
@ -573,7 +573,7 @@ fn generic_fmod(comptime T: type, x: T, y: T) T {
|
||||||
return 0 * x;
|
return 0 * x;
|
||||||
ux = i;
|
ux = i;
|
||||||
}
|
}
|
||||||
while (ux >> digits == 0) : (b: {
|
while (ux >> digits == 0) : ({
|
||||||
ux <<= 1;
|
ux <<= 1;
|
||||||
ex -= 1;
|
ex -= 1;
|
||||||
}) {}
|
}) {}
|
||||||
|
|
|
||||||
|
|
@ -2385,7 +2385,7 @@ fn renderTokenOffset(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (next_token_id != .LineComment) blk: {
|
if (next_token_id != .LineComment) {
|
||||||
switch (space) {
|
switch (space) {
|
||||||
Space.None, Space.NoNewline => return,
|
Space.None, Space.NoNewline => return,
|
||||||
Space.Newline => {
|
Space.Newline => {
|
||||||
|
|
|
||||||
|
|
@ -931,7 +931,7 @@ fn transRecordDecl(c: *Context, record_decl: *const ZigClangRecordDecl) Error!?*
|
||||||
else => |e| return e,
|
else => |e| return e,
|
||||||
};
|
};
|
||||||
|
|
||||||
const align_expr = blk: {
|
const align_expr = blk_2: {
|
||||||
const alignment = ZigClangFieldDecl_getAlignedAttribute(field_decl, rp.c.clang_context);
|
const alignment = ZigClangFieldDecl_getAlignedAttribute(field_decl, rp.c.clang_context);
|
||||||
if (alignment != 0) {
|
if (alignment != 0) {
|
||||||
_ = try appendToken(rp.c, .Keyword_align, "align");
|
_ = try appendToken(rp.c, .Keyword_align, "align");
|
||||||
|
|
@ -940,9 +940,9 @@ fn transRecordDecl(c: *Context, record_decl: *const ZigClangRecordDecl) Error!?*
|
||||||
const expr = try transCreateNodeInt(rp.c, alignment / 8);
|
const expr = try transCreateNodeInt(rp.c, alignment / 8);
|
||||||
_ = try appendToken(rp.c, .RParen, ")");
|
_ = try appendToken(rp.c, .RParen, ")");
|
||||||
|
|
||||||
break :blk expr;
|
break :blk_2 expr;
|
||||||
}
|
}
|
||||||
break :blk null;
|
break :blk_2 null;
|
||||||
};
|
};
|
||||||
|
|
||||||
const field_node = try c.arena.create(ast.Node.ContainerField);
|
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
|
||||||
|
|
||||||
const field_name_tok = try appendIdentifier(c, field_name);
|
const field_name_tok = try appendIdentifier(c, field_name);
|
||||||
|
|
||||||
const int_node = if (!pure_enum) blk: {
|
const int_node = if (!pure_enum) blk_2: {
|
||||||
_ = try appendToken(c, .Colon, "=");
|
_ = try appendToken(c, .Colon, "=");
|
||||||
break :blk try transCreateNodeAPInt(c, ZigClangEnumConstantDecl_getInitVal(enum_const));
|
break :blk_2 try transCreateNodeAPInt(c, ZigClangEnumConstantDecl_getInitVal(enum_const));
|
||||||
} else
|
} else
|
||||||
null;
|
null;
|
||||||
|
|
||||||
|
|
@ -2388,7 +2388,7 @@ fn transZeroInitExpr(
|
||||||
ty: *const ZigClangType,
|
ty: *const ZigClangType,
|
||||||
) TransError!*ast.Node {
|
) TransError!*ast.Node {
|
||||||
switch (ZigClangType_getTypeClass(ty)) {
|
switch (ZigClangType_getTypeClass(ty)) {
|
||||||
.Builtin => blk: {
|
.Builtin => {
|
||||||
const builtin_ty = @ptrCast(*const ZigClangBuiltinType, ty);
|
const builtin_ty = @ptrCast(*const ZigClangBuiltinType, ty);
|
||||||
switch (ZigClangBuiltinType_getKind(builtin_ty)) {
|
switch (ZigClangBuiltinType_getKind(builtin_ty)) {
|
||||||
.Bool => return try transCreateNodeBoolLiteral(rp.c, false),
|
.Bool => return try transCreateNodeBoolLiteral(rp.c, false),
|
||||||
|
|
|
||||||
|
|
@ -2438,6 +2438,7 @@ struct ScopeBlock {
|
||||||
LVal lval;
|
LVal lval;
|
||||||
bool safety_off;
|
bool safety_off;
|
||||||
bool fast_math_on;
|
bool fast_math_on;
|
||||||
|
bool name_used;
|
||||||
};
|
};
|
||||||
|
|
||||||
// This scope is created from every defer expression.
|
// This scope is created from every defer expression.
|
||||||
|
|
@ -2488,6 +2489,8 @@ struct ScopeLoop {
|
||||||
ZigList<IrBasicBlockSrc *> *incoming_blocks;
|
ZigList<IrBasicBlockSrc *> *incoming_blocks;
|
||||||
ResultLocPeerParent *peer_parent;
|
ResultLocPeerParent *peer_parent;
|
||||||
ScopeExpr *spill_scope;
|
ScopeExpr *spill_scope;
|
||||||
|
|
||||||
|
bool name_used;
|
||||||
};
|
};
|
||||||
|
|
||||||
// This scope blocks certain things from working such as comptime continue
|
// This scope blocks certain things from working such as comptime continue
|
||||||
|
|
|
||||||
60
src/ir.cpp
60
src/ir.cpp
|
|
@ -5476,6 +5476,25 @@ static ResultLocPeer *create_peer_result(ResultLocPeerParent *peer_parent) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool is_duplicate_label(CodeGen *g, Scope *scope, AstNode *node, Buf *name) {
|
||||||
|
if (name == nullptr) return false;
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
if (scope == nullptr || scope->id == ScopeIdFnDef) {
|
||||||
|
break;
|
||||||
|
} else if (scope->id == ScopeIdBlock || scope->id == ScopeIdLoop) {
|
||||||
|
Buf *this_block_name = scope->id == ScopeIdBlock ? ((ScopeBlock *)scope)->name : ((ScopeLoop *)scope)->name;
|
||||||
|
if (this_block_name != nullptr && buf_eql_buf(name, this_block_name)) {
|
||||||
|
ErrorMsg *msg = add_node_error(g, node, buf_sprintf("redeclaration of label '%s'", buf_ptr(name)));
|
||||||
|
add_error_note(g, msg, scope->source_node, buf_sprintf("previous declaration is here"));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
scope = scope->parent;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
static IrInstSrc *ir_gen_block(IrBuilderSrc *irb, Scope *parent_scope, AstNode *block_node, LVal lval,
|
static IrInstSrc *ir_gen_block(IrBuilderSrc *irb, Scope *parent_scope, AstNode *block_node, LVal lval,
|
||||||
ResultLoc *result_loc)
|
ResultLoc *result_loc)
|
||||||
{
|
{
|
||||||
|
|
@ -5484,6 +5503,9 @@ static IrInstSrc *ir_gen_block(IrBuilderSrc *irb, Scope *parent_scope, AstNode *
|
||||||
ZigList<IrInstSrc *> incoming_values = {0};
|
ZigList<IrInstSrc *> incoming_values = {0};
|
||||||
ZigList<IrBasicBlockSrc *> incoming_blocks = {0};
|
ZigList<IrBasicBlockSrc *> incoming_blocks = {0};
|
||||||
|
|
||||||
|
if (is_duplicate_label(irb->codegen, parent_scope, block_node, block_node->data.block.name))
|
||||||
|
return irb->codegen->invalid_inst_src;
|
||||||
|
|
||||||
ScopeBlock *scope_block = create_block_scope(irb->codegen, block_node, parent_scope);
|
ScopeBlock *scope_block = create_block_scope(irb->codegen, block_node, parent_scope);
|
||||||
|
|
||||||
Scope *outer_block_scope = &scope_block->base;
|
Scope *outer_block_scope = &scope_block->base;
|
||||||
|
|
@ -5495,6 +5517,9 @@ static IrInstSrc *ir_gen_block(IrBuilderSrc *irb, Scope *parent_scope, AstNode *
|
||||||
}
|
}
|
||||||
|
|
||||||
if (block_node->data.block.statements.length == 0) {
|
if (block_node->data.block.statements.length == 0) {
|
||||||
|
if (scope_block->name != nullptr) {
|
||||||
|
add_node_error(irb->codegen, block_node, buf_sprintf("unused block label"));
|
||||||
|
}
|
||||||
// {}
|
// {}
|
||||||
return ir_lval_wrap(irb, parent_scope, ir_build_const_void(irb, child_scope, block_node), lval, result_loc);
|
return ir_lval_wrap(irb, parent_scope, ir_build_const_void(irb, child_scope, block_node), lval, result_loc);
|
||||||
}
|
}
|
||||||
|
|
@ -5552,6 +5577,10 @@ static IrInstSrc *ir_gen_block(IrBuilderSrc *irb, Scope *parent_scope, AstNode *
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (scope_block->name != nullptr && scope_block->name_used == false) {
|
||||||
|
add_node_error(irb->codegen, block_node, buf_sprintf("unused block label"));
|
||||||
|
}
|
||||||
|
|
||||||
if (found_invalid_inst)
|
if (found_invalid_inst)
|
||||||
return irb->codegen->invalid_inst_src;
|
return irb->codegen->invalid_inst_src;
|
||||||
|
|
||||||
|
|
@ -8152,6 +8181,9 @@ static IrInstSrc *ir_gen_while_expr(IrBuilderSrc *irb, Scope *scope, AstNode *no
|
||||||
ZigList<IrInstSrc *> incoming_values = {0};
|
ZigList<IrInstSrc *> incoming_values = {0};
|
||||||
ZigList<IrBasicBlockSrc *> incoming_blocks = {0};
|
ZigList<IrBasicBlockSrc *> incoming_blocks = {0};
|
||||||
|
|
||||||
|
if (is_duplicate_label(irb->codegen, payload_scope, node, node->data.while_expr.name))
|
||||||
|
return irb->codegen->invalid_inst_src;
|
||||||
|
|
||||||
ScopeLoop *loop_scope = create_loop_scope(irb->codegen, node, payload_scope);
|
ScopeLoop *loop_scope = create_loop_scope(irb->codegen, node, payload_scope);
|
||||||
loop_scope->break_block = end_block;
|
loop_scope->break_block = end_block;
|
||||||
loop_scope->continue_block = continue_block;
|
loop_scope->continue_block = continue_block;
|
||||||
|
|
@ -8169,6 +8201,10 @@ static IrInstSrc *ir_gen_while_expr(IrBuilderSrc *irb, Scope *scope, AstNode *no
|
||||||
if (body_result == irb->codegen->invalid_inst_src)
|
if (body_result == irb->codegen->invalid_inst_src)
|
||||||
return body_result;
|
return body_result;
|
||||||
|
|
||||||
|
if (loop_scope->name != nullptr && loop_scope->name_used == false) {
|
||||||
|
add_node_error(irb->codegen, node, buf_sprintf("unused while label"));
|
||||||
|
}
|
||||||
|
|
||||||
if (!instr_is_unreachable(body_result)) {
|
if (!instr_is_unreachable(body_result)) {
|
||||||
ir_mark_gen(ir_build_check_statement_is_void(irb, payload_scope, node->data.while_expr.body, body_result));
|
ir_mark_gen(ir_build_check_statement_is_void(irb, payload_scope, node->data.while_expr.body, body_result));
|
||||||
ir_mark_gen(ir_build_br(irb, payload_scope, node, continue_block, is_comptime));
|
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
|
||||||
ZigList<IrInstSrc *> incoming_values = {0};
|
ZigList<IrInstSrc *> incoming_values = {0};
|
||||||
ZigList<IrBasicBlockSrc *> incoming_blocks = {0};
|
ZigList<IrBasicBlockSrc *> incoming_blocks = {0};
|
||||||
|
|
||||||
|
if (is_duplicate_label(irb->codegen, child_scope, node, node->data.while_expr.name))
|
||||||
|
return irb->codegen->invalid_inst_src;
|
||||||
|
|
||||||
ScopeLoop *loop_scope = create_loop_scope(irb->codegen, node, child_scope);
|
ScopeLoop *loop_scope = create_loop_scope(irb->codegen, node, child_scope);
|
||||||
loop_scope->break_block = end_block;
|
loop_scope->break_block = end_block;
|
||||||
loop_scope->continue_block = continue_block;
|
loop_scope->continue_block = continue_block;
|
||||||
|
|
@ -8280,6 +8319,10 @@ static IrInstSrc *ir_gen_while_expr(IrBuilderSrc *irb, Scope *scope, AstNode *no
|
||||||
if (body_result == irb->codegen->invalid_inst_src)
|
if (body_result == irb->codegen->invalid_inst_src)
|
||||||
return body_result;
|
return body_result;
|
||||||
|
|
||||||
|
if (loop_scope->name != nullptr && loop_scope->name_used == false) {
|
||||||
|
add_node_error(irb->codegen, node, buf_sprintf("unused while label"));
|
||||||
|
}
|
||||||
|
|
||||||
if (!instr_is_unreachable(body_result)) {
|
if (!instr_is_unreachable(body_result)) {
|
||||||
ir_mark_gen(ir_build_check_statement_is_void(irb, child_scope, node->data.while_expr.body, body_result));
|
ir_mark_gen(ir_build_check_statement_is_void(irb, child_scope, node->data.while_expr.body, body_result));
|
||||||
ir_mark_gen(ir_build_br(irb, child_scope, node, continue_block, is_comptime));
|
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
|
||||||
|
|
||||||
Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime);
|
Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime);
|
||||||
|
|
||||||
|
if (is_duplicate_label(irb->codegen, subexpr_scope, node, node->data.while_expr.name))
|
||||||
|
return irb->codegen->invalid_inst_src;
|
||||||
|
|
||||||
ScopeLoop *loop_scope = create_loop_scope(irb->codegen, node, subexpr_scope);
|
ScopeLoop *loop_scope = create_loop_scope(irb->codegen, node, subexpr_scope);
|
||||||
loop_scope->break_block = end_block;
|
loop_scope->break_block = end_block;
|
||||||
loop_scope->continue_block = continue_block;
|
loop_scope->continue_block = continue_block;
|
||||||
|
|
@ -8369,6 +8415,10 @@ static IrInstSrc *ir_gen_while_expr(IrBuilderSrc *irb, Scope *scope, AstNode *no
|
||||||
if (body_result == irb->codegen->invalid_inst_src)
|
if (body_result == irb->codegen->invalid_inst_src)
|
||||||
return body_result;
|
return body_result;
|
||||||
|
|
||||||
|
if (loop_scope->name != nullptr && loop_scope->name_used == false) {
|
||||||
|
add_node_error(irb->codegen, node, buf_sprintf("unused while label"));
|
||||||
|
}
|
||||||
|
|
||||||
if (!instr_is_unreachable(body_result)) {
|
if (!instr_is_unreachable(body_result)) {
|
||||||
ir_mark_gen(ir_build_check_statement_is_void(irb, scope, node->data.while_expr.body, body_result));
|
ir_mark_gen(ir_build_check_statement_is_void(irb, scope, node->data.while_expr.body, body_result));
|
||||||
ir_mark_gen(ir_build_br(irb, scope, node, continue_block, is_comptime));
|
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
|
||||||
elem_ptr : ir_build_load_ptr(irb, &spill_scope->base, elem_node, elem_ptr);
|
elem_ptr : ir_build_load_ptr(irb, &spill_scope->base, elem_node, elem_ptr);
|
||||||
build_decl_var_and_init(irb, parent_scope, elem_node, elem_var, elem_value, buf_ptr(elem_var_name), is_comptime);
|
build_decl_var_and_init(irb, parent_scope, elem_node, elem_var, elem_value, buf_ptr(elem_var_name), is_comptime);
|
||||||
|
|
||||||
|
if (is_duplicate_label(irb->codegen, child_scope, node, node->data.for_expr.name))
|
||||||
|
return irb->codegen->invalid_inst_src;
|
||||||
|
|
||||||
ZigList<IrInstSrc *> incoming_values = {0};
|
ZigList<IrInstSrc *> incoming_values = {0};
|
||||||
ZigList<IrBasicBlockSrc *> incoming_blocks = {0};
|
ZigList<IrBasicBlockSrc *> incoming_blocks = {0};
|
||||||
ScopeLoop *loop_scope = create_loop_scope(irb->codegen, node, child_scope);
|
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
|
||||||
if (body_result == irb->codegen->invalid_inst_src)
|
if (body_result == irb->codegen->invalid_inst_src)
|
||||||
return irb->codegen->invalid_inst_src;
|
return irb->codegen->invalid_inst_src;
|
||||||
|
|
||||||
|
if (loop_scope->name != nullptr && loop_scope->name_used == false) {
|
||||||
|
add_node_error(irb->codegen, node, buf_sprintf("unused for label"));
|
||||||
|
}
|
||||||
|
|
||||||
if (!instr_is_unreachable(body_result)) {
|
if (!instr_is_unreachable(body_result)) {
|
||||||
ir_mark_gen(ir_build_check_statement_is_void(irb, child_scope, node->data.for_expr.body, body_result));
|
ir_mark_gen(ir_build_check_statement_is_void(irb, child_scope, node->data.for_expr.body, body_result));
|
||||||
ir_mark_gen(ir_build_br(irb, child_scope, node, continue_block, is_comptime));
|
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
|
||||||
if (node->data.break_expr.name == nullptr ||
|
if (node->data.break_expr.name == nullptr ||
|
||||||
(this_loop_scope->name != nullptr && buf_eql_buf(node->data.break_expr.name, this_loop_scope->name)))
|
(this_loop_scope->name != nullptr && buf_eql_buf(node->data.break_expr.name, this_loop_scope->name)))
|
||||||
{
|
{
|
||||||
|
this_loop_scope->name_used = true;
|
||||||
loop_scope = this_loop_scope;
|
loop_scope = this_loop_scope;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -9473,6 +9531,7 @@ static IrInstSrc *ir_gen_break(IrBuilderSrc *irb, Scope *break_scope, AstNode *n
|
||||||
(this_block_scope->name != nullptr && buf_eql_buf(node->data.break_expr.name, this_block_scope->name)))
|
(this_block_scope->name != nullptr && buf_eql_buf(node->data.break_expr.name, this_block_scope->name)))
|
||||||
{
|
{
|
||||||
assert(this_block_scope->end_block != nullptr);
|
assert(this_block_scope->end_block != nullptr);
|
||||||
|
this_block_scope->name_used = true;
|
||||||
return ir_gen_return_from_block(irb, break_scope, node, this_block_scope);
|
return ir_gen_return_from_block(irb, break_scope, node, this_block_scope);
|
||||||
}
|
}
|
||||||
} else if (search_scope->id == ScopeIdSuspend) {
|
} else if (search_scope->id == ScopeIdSuspend) {
|
||||||
|
|
@ -9540,6 +9599,7 @@ static IrInstSrc *ir_gen_continue(IrBuilderSrc *irb, Scope *continue_scope, AstN
|
||||||
if (node->data.continue_expr.name == nullptr ||
|
if (node->data.continue_expr.name == nullptr ||
|
||||||
(this_loop_scope->name != nullptr && buf_eql_buf(node->data.continue_expr.name, this_loop_scope->name)))
|
(this_loop_scope->name != nullptr && buf_eql_buf(node->data.continue_expr.name, this_loop_scope->name)))
|
||||||
{
|
{
|
||||||
|
this_loop_scope->name_used = true;
|
||||||
loop_scope = this_loop_scope;
|
loop_scope = this_loop_scope;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,29 @@ const tests = @import("tests.zig");
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
|
|
||||||
pub fn addCases(cases: *tests.CompileErrorContext) void {
|
pub fn addCases(cases: *tests.CompileErrorContext) void {
|
||||||
|
cases.addTest("duplicate/unused labels",
|
||||||
|
\\comptime {
|
||||||
|
\\ blk: { blk: while (false) {} }
|
||||||
|
\\ blk: while (false) { blk: for (@as([0]void, undefined)) |_| {} }
|
||||||
|
\\ blk: for (@as([0]void, undefined)) |_| { blk: {} }
|
||||||
|
\\}
|
||||||
|
\\comptime {
|
||||||
|
\\ blk: {}
|
||||||
|
\\ blk: while(false) {}
|
||||||
|
\\ blk: for(@as([0]void, undefined)) |_| {}
|
||||||
|
\\}
|
||||||
|
, &[_][]const u8{
|
||||||
|
"tmp.zig:2:17: error: redeclaration of label 'blk'",
|
||||||
|
"tmp.zig:2:10: note: previous declaration is here",
|
||||||
|
"tmp.zig:3:31: error: redeclaration of label 'blk'",
|
||||||
|
"tmp.zig:3:10: note: previous declaration is here",
|
||||||
|
"tmp.zig:4:51: error: redeclaration of label 'blk'",
|
||||||
|
"tmp.zig:4:10: note: previous declaration is here",
|
||||||
|
"tmp.zig:7:10: error: unused block label",
|
||||||
|
"tmp.zig:8:10: error: unused while label",
|
||||||
|
"tmp.zig:9:10: error: unused for label",
|
||||||
|
});
|
||||||
|
|
||||||
cases.addTest("@alignCast of zero sized types",
|
cases.addTest("@alignCast of zero sized types",
|
||||||
\\export fn foo() void {
|
\\export fn foo() void {
|
||||||
\\ const a: *void = undefined;
|
\\ const a: *void = undefined;
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue