From: Lucas Ly Ba <[email protected]>

gcc/rust/ChangeLog:

        * checks/lints/unused/rust-unused-checker.cc 
(UnusedChecker::visit_loop_label):
        Add warning for unused label in LoopLabel expr.
        * checks/lints/unused/rust-unused-checker.h: Likewise.
        * checks/lints/unused/rust-unused-collector.cc (UnusedCollector::visit):
        Check in BreakExpr and ContinueExpr if a label is used.
        * checks/lints/unused/rust-unused-collector.h: Likewise.
        * checks/lints/unused/rust-unused-context.cc (UnusedContext::add_label):
        Method helper.
        (UnusedContext::is_label_used): Likewise
        * checks/lints/unused/rust-unused-context.h: Likewise.

gcc/testsuite/ChangeLog:

        * rust/compile/unused-label_0.rs: New test.

Signed-off-by: Lucas Ly Ba <[email protected]>
---
This change was merged into the gccrs repository and is posted here for
upstream visibility and potential drive-by review, as requested by GCC
release managers.
Each commit email contains a link to its details on github from where you can
find the Pull-Request and associated discussions.


Commit on github: 
https://github.com/Rust-GCC/gccrs/commit/8e0858dfb29db614cc865a503a53a1846f08b5f2
The commit is not linked to any pull-request

 .../lints/unused/rust-unused-checker.cc       | 11 ++++++++
 .../checks/lints/unused/rust-unused-checker.h |  1 +
 .../lints/unused/rust-unused-collector.cc     | 18 ++++++++++++
 .../lints/unused/rust-unused-collector.h      | 10 +++++++
 .../lints/unused/rust-unused-context.cc       | 13 +++++++++
 .../checks/lints/unused/rust-unused-context.h |  6 ++++
 gcc/testsuite/rust/compile/unused-label_0.rs  | 28 +++++++++++++++++++
 7 files changed, 87 insertions(+)
 create mode 100644 gcc/testsuite/rust/compile/unused-label_0.rs

diff --git a/gcc/rust/checks/lints/unused/rust-unused-checker.cc 
b/gcc/rust/checks/lints/unused/rust-unused-checker.cc
index 235acd6a4..751306171 100644
--- a/gcc/rust/checks/lints/unused/rust-unused-checker.cc
+++ b/gcc/rust/checks/lints/unused/rust-unused-checker.cc
@@ -124,5 +124,16 @@ UnusedChecker::visit (HIR::EmptyStmt &stmt)
                   "unnecessary trailing semicolons");
 }
 
+void
+UnusedChecker::visit_loop_label (HIR::LoopLabel &label)
+{
+  auto lifetime = label.get_lifetime ();
+  std::string var_name = lifetime.to_string ();
+  auto id = lifetime.get_mappings ().get_hirid ();
+  if (!unused_context.is_label_used (id) && var_name[0] != '_')
+    rust_warning_at (lifetime.get_locus (), OPT_Wunused_variable,
+                    "unused label %qs", lifetime.to_string ().c_str ());
+}
+
 } // namespace Analysis
 } // namespace Rust
diff --git a/gcc/rust/checks/lints/unused/rust-unused-checker.h 
b/gcc/rust/checks/lints/unused/rust-unused-checker.h
index 061d0c6f0..eeb94679d 100644
--- a/gcc/rust/checks/lints/unused/rust-unused-checker.h
+++ b/gcc/rust/checks/lints/unused/rust-unused-checker.h
@@ -44,6 +44,7 @@ private:
   virtual void visit (HIR::AssignmentExpr &identifier) override;
   virtual void visit (HIR::StructPatternFieldIdent &identifier) override;
   virtual void visit (HIR::EmptyStmt &stmt) override;
+  virtual void visit_loop_label (HIR::LoopLabel &label) override;
 };
 } // namespace Analysis
 } // namespace Rust
diff --git a/gcc/rust/checks/lints/unused/rust-unused-collector.cc 
b/gcc/rust/checks/lints/unused/rust-unused-collector.cc
index b00fa84ff..6767678c6 100644
--- a/gcc/rust/checks/lints/unused/rust-unused-collector.cc
+++ b/gcc/rust/checks/lints/unused/rust-unused-collector.cc
@@ -88,5 +88,23 @@ UnusedCollector::visit (HIR::StructPatternFieldIdent 
&pattern)
   walk (pattern);
 }
 
+void
+UnusedCollector::visit (HIR::BreakExpr &expr)
+{
+  if (!expr.has_label ())
+    return;
+  mark_label_used (expr.get_label ());
+  walk (expr);
+}
+
+void
+UnusedCollector::visit (HIR::ContinueExpr &expr)
+{
+  if (!expr.has_label ())
+    return;
+  mark_label_used (expr.get_label ());
+  walk (expr);
+}
+
 } // namespace Analysis
 } // namespace Rust
diff --git a/gcc/rust/checks/lints/unused/rust-unused-collector.h 
b/gcc/rust/checks/lints/unused/rust-unused-collector.h
index 6bcdcb868..1944089d1 100644
--- a/gcc/rust/checks/lints/unused/rust-unused-collector.h
+++ b/gcc/rust/checks/lints/unused/rust-unused-collector.h
@@ -51,6 +51,10 @@ private:
   virtual void visit (HIR::IdentifierPattern &pattern) override;
   virtual void visit (HIR::StructPatternFieldIdent &pattern) override;
 
+  // Unused label
+  virtual void visit (HIR::BreakExpr &expr) override;
+  virtual void visit (HIR::ContinueExpr &expr) override;
+
   template <typename T> HirId get_def_id (T &path_expr)
   {
     NodeId ast_node_id = path_expr.get_mappings ().get_nodeid ();
@@ -65,6 +69,12 @@ private:
     unused_context.add_variable (def_id);
     unused_context.remove_assign (def_id);
   }
+
+  template <typename T> void mark_label_used (T &path_expr)
+  {
+    auto def_id = get_def_id (path_expr);
+    unused_context.add_label (def_id);
+  }
 };
 } // namespace Analysis
 } // namespace Rust
diff --git a/gcc/rust/checks/lints/unused/rust-unused-context.cc 
b/gcc/rust/checks/lints/unused/rust-unused-context.cc
index 40862edc3..9b26e01bc 100644
--- a/gcc/rust/checks/lints/unused/rust-unused-context.cc
+++ b/gcc/rust/checks/lints/unused/rust-unused-context.cc
@@ -73,6 +73,19 @@ UnusedContext::is_mut_used (HirId id) const
   return mutable_vars.find (id) == mutable_vars.end ();
 }
 
+void
+UnusedContext::add_label (HirId id)
+
+{
+  used_labels.emplace (id);
+}
+
+bool
+UnusedContext::is_label_used (HirId id) const
+{
+  return used_labels.find (id) != used_labels.end ();
+}
+
 std::string
 UnusedContext::as_string () const
 {
diff --git a/gcc/rust/checks/lints/unused/rust-unused-context.h 
b/gcc/rust/checks/lints/unused/rust-unused-context.h
index 9ab67ff35..1405ebb64 100644
--- a/gcc/rust/checks/lints/unused/rust-unused-context.h
+++ b/gcc/rust/checks/lints/unused/rust-unused-context.h
@@ -37,12 +37,18 @@ public:
   void add_mut (HirId id);
   void remove_mut (HirId id);
   bool is_mut_used (HirId id) const;
+
+  // Unused label
+  void add_label (HirId id);
+  bool is_label_used (HirId id) const;
+
   std::string as_string () const;
 
 private:
   std::unordered_set<HirId> used_vars;
   std::unordered_set<HirId> mutable_vars;
   std::map<HirId, std::vector<HirId>> assigned_vars;
+  std::unordered_set<HirId> used_labels;
 };
 
 } // namespace Analysis
diff --git a/gcc/testsuite/rust/compile/unused-label_0.rs 
b/gcc/testsuite/rust/compile/unused-label_0.rs
new file mode 100644
index 000000000..3c868976d
--- /dev/null
+++ b/gcc/testsuite/rust/compile/unused-label_0.rs
@@ -0,0 +1,28 @@
+// { dg-additional-options "-frust-unused-check-2.0" }
+
+pub fn foo_1() {
+    'a: loop {
+        break 'a;
+    }
+}
+
+pub fn foo_2() {
+    'a: loop {
+// { dg-warning "unused label ..a." "" { target *-*-* } .-1 }
+        break;
+    }
+}
+
+
+pub fn bar_1() {
+    'a: loop {
+        continue 'a;
+    }
+}
+
+pub fn bar_2() {
+    'a: loop {
+// { dg-warning "unused label ..a." "" { target *-*-* } .-1 }
+        continue;
+    }
+}

base-commit: 53e34519b36613d9e59bd2d8ffa0a768b638ab36
-- 
2.52.0

Reply via email to