[Rust,front-end,v4,34/46] gccrs: Add unused variable scan

Message ID 20221206101417.778807-35-arthur.cohen@embecosm.com
State Committed
Commit 4d67468d1d40f4d60a3760d47b74912c13621ada
Headers
Series [Rust,front-end,v4,01/46] Use DW_ATE_UTF for the Rust 'char' type |

Commit Message

Arthur Cohen Dec. 6, 2022, 10:14 a.m. UTC
  From: Philip Herron <philip.herron@embecosm.com>

This is a simple walk_tree which acts on the monomorphized code by walking
the compiled translation unit of functions.
---
 gcc/rust/checks/lints/rust-lint-unused-var.cc | 98 +++++++++++++++++++
 gcc/rust/checks/lints/rust-lint-unused-var.h  | 36 +++++++
 2 files changed, 134 insertions(+)
 create mode 100644 gcc/rust/checks/lints/rust-lint-unused-var.cc
 create mode 100644 gcc/rust/checks/lints/rust-lint-unused-var.h
  

Patch

diff --git a/gcc/rust/checks/lints/rust-lint-unused-var.cc b/gcc/rust/checks/lints/rust-lint-unused-var.cc
new file mode 100644
index 00000000000..d4317e53280
--- /dev/null
+++ b/gcc/rust/checks/lints/rust-lint-unused-var.cc
@@ -0,0 +1,98 @@ 
+// Copyright (C) 2021-2022 Free Software Foundation, Inc.
+
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#include "rust-lint-unused-var.h"
+#include "print-tree.h"
+
+namespace Rust {
+namespace Analysis {
+
+static void
+check_decl (tree *t)
+{
+  rust_assert (TREE_CODE (*t) == VAR_DECL || TREE_CODE (*t) == PARM_DECL
+	       || TREE_CODE (*t) == CONST_DECL);
+
+  tree var_name = DECL_NAME (*t);
+  const char *var_name_ptr = IDENTIFIER_POINTER (var_name);
+  bool starts_with_under_score = strncmp (var_name_ptr, "_", 1) == 0;
+
+  bool is_constant = TREE_CODE (*t) == CONST_DECL;
+  // if (!is_constant)
+  //   {
+  //     debug_tree (*t);
+  //     rust_debug ("found var-decl: used %s artifical %s underscore %s name
+  //     %s",
+  //       	  TREE_USED (*t) ? "true" : "false",
+  //       	  DECL_ARTIFICIAL (*t) ? "true" : "false",
+  //       	  starts_with_under_score ? "true" : "false", var_name_ptr);
+  //   }
+
+  if (!TREE_USED (*t) && !DECL_ARTIFICIAL (*t) && !starts_with_under_score)
+    {
+      warning_at (DECL_SOURCE_LOCATION (*t),
+		  is_constant ? OPT_Wunused_const_variable_
+			      : OPT_Wunused_variable,
+		  "unused name %qE", *t);
+    }
+}
+
+static tree
+unused_var_walk_fn (tree *t, int *walk_subtrees, void *closure)
+{
+  switch (TREE_CODE (*t))
+    {
+    case VAR_DECL:
+    case CONST_DECL:
+      check_decl (t);
+      break;
+
+    default:
+      break;
+    }
+  return NULL_TREE;
+}
+
+void
+UnusedVariables::Lint (Compile::Context &ctx)
+{
+  for (auto &fndecl : ctx.get_func_decls ())
+    {
+      for (tree p = DECL_ARGUMENTS (fndecl); p != NULL_TREE; p = DECL_CHAIN (p))
+	{
+	  check_decl (&p);
+	}
+
+      walk_tree_without_duplicates (&DECL_SAVED_TREE (fndecl),
+				    &unused_var_walk_fn, &ctx);
+    }
+
+  for (auto &var : ctx.get_var_decls ())
+    {
+      tree t = ctx.get_backend ()->var_expression (var, Location ());
+      check_decl (&t);
+    }
+
+  for (auto &const_decl : ctx.get_const_decls ())
+    {
+      check_decl (&const_decl);
+    }
+}
+
+} // namespace Analysis
+} // namespace Rust
diff --git a/gcc/rust/checks/lints/rust-lint-unused-var.h b/gcc/rust/checks/lints/rust-lint-unused-var.h
new file mode 100644
index 00000000000..6fabfeff01b
--- /dev/null
+++ b/gcc/rust/checks/lints/rust-lint-unused-var.h
@@ -0,0 +1,36 @@ 
+// Copyright (C) 2021-2022 Free Software Foundation, Inc.
+
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#ifndef RUST_LINT_UNUSED_VAR
+#define RUST_LINT_UNUSED_VAR
+
+#include "rust-compile-context.h"
+
+namespace Rust {
+namespace Analysis {
+
+class UnusedVariables
+{
+public:
+  static void Lint (Compile::Context &ctx);
+};
+
+} // namespace Analysis
+} // namespace Rust
+
+#endif // RUST_LINT_UNUSED_VAR