[COMMITTED 41/77] gccrs: add static mut refs lint

[email protected]
Newsgroups gmane.comp.gcc.rust,gmane.comp.gcc.patches
Message-ID <[email protected]>
From: Lucas Ly Ba <[email protected]>

Warn on taking a reference to a mutable static, which is discouraged as
it can easily lead to undefined behaviour.

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/static-mut-refs_0.rs: New test.

Signed-off-by: Lucas Ly Ba <[email protected]>
---
 .../lints/unused/rust-unused-checker.cc       | 20 +++++++++++++++++++
 .../checks/lints/unused/rust-unused-checker.h |  1 +
 .../rust/compile/static-mut-refs_0.rs         | 13 ++++++++++++
 3 files changed, 34 insertions(+)
 create mode 100644 gcc/testsuite/rust/compile/static-mut-refs_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 0d091e6473a..fffe61dd129 100644
--- a/gcc/rust/checks/lints/unused/rust-unused-checker.cc
+++ b/gcc/rust/checks/lints/unused/rust-unused-checker.cc
@@ -347,5 +347,25 @@ UnusedChecker::visit (HIR::LetStmt &stmt)
   walk (stmt);
 }
 
+void
+UnusedChecker::visit (HIR::BorrowExpr &expr)
+{
+  // The static_mut_refs lint: taking a reference to a mutable static is
+  // discouraged as it can easily lead to undefined behaviour.
+  NodeId ast_node_id = expr.get_expr ().get_mappings ().get_nodeid ();
+  if (auto def
+      = nr_context.lookup (ast_node_id, Resolver2_0::Namespace::Values))
+    if (auto id = mappings.lookup_node_to_hir (*def))
+      if (auto item = mappings.lookup_hir_item (*id))
+	if (item.value ()->get_item_kind () == HIR::Item::ItemKind::Static)
+	  {
+	    auto &static_item = static_cast<HIR::StaticItem &> (*item.value ());
+	    if (static_item.is_mut ())
+	      rust_warning_at (expr.get_locus (), OPT_Wunused,
+			       "creating a reference to a mutable static");
+	  }
+  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 46e012e7907..161f59b8a66 100644
--- a/gcc/rust/checks/lints/unused/rust-unused-checker.h
+++ b/gcc/rust/checks/lints/unused/rust-unused-checker.h
@@ -52,6 +52,7 @@ private:
   virtual void visit (HIR::MatchExpr &expr) override;
   virtual void visit (HIR::ExternBlock &block) override;
   virtual void visit (HIR::LetStmt &stmt) override;
+  virtual void visit (HIR::BorrowExpr &expr) override;
   virtual void visit_loop_label (HIR::LoopLabel &label) override;
 };
 } // namespace Analysis
diff --git a/gcc/testsuite/rust/compile/static-mut-refs_0.rs b/gcc/testsuite/rust/compile/static-mut-refs_0.rs
new file mode 100644
index 00000000000..5dcc5978a74
--- /dev/null
+++ b/gcc/testsuite/rust/compile/static-mut-refs_0.rs
@@ -0,0 +1,13 @@
+// { dg-additional-options "-frust-unused-check-2.0" }
+#![feature(no_core, lang_items)]
+#![no_core]
+
+#[lang = "sized"]
+pub trait Sized {}
+
+static mut S: i32 = 0;
+
+pub unsafe fn f() {
+    let _y = &S;
+// { dg-warning "reference to a mutable static" "" { target *-*-* } .-1 }
+}
-- 
2.50.1
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.