[gccrs COMMIT] gccrs: add break with label and loop lint

[email protected]
Newsgroups gmane.comp.gcc.rust,gmane.comp.gcc.patches
Message-ID <[email protected]>
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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.