From daa3b6bfa32e3be1c434b20ba91f6a519304c81c Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Sat, 5 Dec 2015 21:04:57 -0700 Subject: [PATCH] add unused label error --- README.md | 2 -- src/analyze.cpp | 18 ++++++++++++++++++ src/semantic_info.hpp | 1 + test/run_tests.cpp | 5 +++++ 4 files changed, 24 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 4bb149bbc53c5ada80d01daebfdd607c142ea61b..c63a8232a039b1c498021ebab71aeccd3f2a3f10 100644 --- a/README.md +++ b/README.md @@ -42,8 +42,6 @@ make ## Roadmap - * parseh: unreachable <--> noreturn attribute - * unused label error * loops * structs * tagged enums diff --git a/src/analyze.cpp b/src/analyze.cpp index 82d37de109103a7e64aea5a2ceb4f7a7c7a3fc09..e53cda3b13f1497436df51a1fba09e85c1b785de 100644 --- a/src/analyze.cpp +++ b/src/analyze.cpp @@ -471,6 +471,7 @@ static TypeTableEntry * analyze_expression(CodeGen *g, ImportTableEntry *import, assert(!node->codegen_node); node->codegen_node = allocate(1); node->codegen_node->data.label_entry = table_entry->value; + table_entry->value->used = true; } else { add_node_error(g, node, buf_sprintf("use of undeclared label '%s'", buf_ptr(&node->data.go_to.name))); @@ -758,6 +759,23 @@ static void analyze_top_level_declaration(CodeGen *g, ImportTableEntry *import, node->codegen_node = allocate(1); node->codegen_node->data.fn_def_node.implicit_return_type = block_return_type; node->codegen_node->data.fn_def_node.block_context = context; + + { + FnTableEntry *fn_table_entry = fn_proto_node->codegen_node->data.fn_proto_node.fn_table_entry; + auto it = fn_table_entry->label_table.entry_iterator(); + for (;;) { + auto *entry = it.next(); + if (!entry) + break; + + LabelTableEntry *label_entry = entry->value; + if (!label_entry->used) { + add_node_error(g, label_entry->label_node, + buf_sprintf("label '%s' defined but not used", + buf_ptr(&label_entry->label_node->data.label.name))); + } + } + } } break; diff --git a/src/semantic_info.hpp b/src/semantic_info.hpp index 6f4b7da8b385997f943be9ebede1690286461d3c..3e3e87084a059985d84eed780cf59e78d927cedb 100644 --- a/src/semantic_info.hpp +++ b/src/semantic_info.hpp @@ -41,6 +41,7 @@ struct ImportTableEntry { struct LabelTableEntry { AstNode *label_node; LLVMBasicBlockRef basic_block; + bool used; }; struct FnTableEntry { diff --git a/test/run_tests.cpp b/test/run_tests.cpp index b37a4d17f43b5dfd4f103d3125999af2b58a7652..8c33cc1b8f2bbbf24311748a9f83ebb533a36881 100644 --- a/test/run_tests.cpp +++ b/test/run_tests.cpp @@ -466,6 +466,11 @@ fn f(a : unreachable) {} export fn f(a : void) {} )SOURCE", 1, ".tmp_source.zig:2:17: error: parameter of type 'void' not allowed on exported functions"); + add_compile_fail_case("unused label", R"SOURCE( +export fn f() { +a_label: +} + )SOURCE", 1, ".tmp_source.zig:3:1: error: label 'a_label' defined but not used"); } static void print_compiler_invocation(TestCase *test_case, Buf *zig_stderr) { -- 2.54.0