From: Lucas Ly Ba <[email protected]>

Warn on a labeled `break` whose value is a loop expression, as it is
easy to confuse with an unlabeled `break` of a labeled value.

gcc/rust/ChangeLog:

        * checks/lints/unused/rust-unused-checker.cc (UnusedChecker::visit):
        New.
        * checks/lints/unused/rust-unused-checker.h (UnusedChecker::visit):
        New.
        * rust-lang.cc (grs_langhook_init_options_struct): Enable warn_unused.

gcc/testsuite/ChangeLog:

        * rust/compile/break-with-label-and-loop_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/adf05734d896265d69cf64ec53bf8147556e1a77

The commit has NOT been mentioned in any issue.

The commit has been mentioned in the following pull-request(s):
 - https://github.com/Rust-GCC/gccrs/pull/4640

 gcc/rust/checks/lints/unused/rust-unused-checker.cc | 13 +++++++++++++
 gcc/rust/checks/lints/unused/rust-unused-checker.h  |  1 +
 .../rust/compile/break-with-label-and-loop_0.rs     | 10 ++++++++++
 3 files changed, 24 insertions(+)
 create mode 100644 gcc/testsuite/rust/compile/break-with-label-and-loop_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 c9c906338..023cba0c9 100644
--- a/gcc/rust/checks/lints/unused/rust-unused-checker.cc
+++ b/gcc/rust/checks/lints/unused/rust-unused-checker.cc
@@ -400,5 +400,18 @@ UnusedChecker::visit (HIR::NegationExpr &expr)
   walk (expr);
 }
 
+void
+UnusedChecker::visit (HIR::BreakExpr &expr)
+{
+  if (expr.has_label () && expr.has_break_expr ()
+      && expr.get_expr ().get_expression_type ()
+          == HIR::Expr::ExprType::BaseLoop)
+    rust_warning_at (
+      expr.get_locus (), OPT_Wunused,
+      "this labeled %<break%> expression is easy to confuse with "
+      "an unlabeled %<break%> with a labeled value expression");
+  walk (expr);
+}
+
 } // 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 659087a57..f5a31b3df 100644
--- a/gcc/rust/checks/lints/unused/rust-unused-checker.h
+++ b/gcc/rust/checks/lints/unused/rust-unused-checker.h
@@ -54,6 +54,7 @@ private:
   virtual void visit (HIR::LetStmt &stmt) override;
   virtual void visit (HIR::BorrowExpr &expr) override;
   virtual void visit (HIR::NegationExpr &expr) override;
+  virtual void visit (HIR::BreakExpr &expr) override;
   virtual void visit_loop_label (HIR::LoopLabel &label) override;
 };
 } // namespace Analysis
diff --git a/gcc/testsuite/rust/compile/break-with-label-and-loop_0.rs 
b/gcc/testsuite/rust/compile/break-with-label-and-loop_0.rs
new file mode 100644
index 000000000..fef2e5231
--- /dev/null
+++ b/gcc/testsuite/rust/compile/break-with-label-and-loop_0.rs
@@ -0,0 +1,10 @@
+// { dg-additional-options "-frust-unused-check-2.0" }
+#![feature(no_core)]
+#![no_core]
+
+pub fn foo() {
+    'a: loop {
+        break 'a loop {};
+// { dg-warning "easy to confuse" "" { target *-*-* } .-1 }
+    }
+}

base-commit: d96a80d4fe72bd86121618937ea5bf319337d57e
-- 
2.54.0

Reply via email to