aboutsummaryrefslogtreecommitdiff
path: root/gcc/rust/lint/rust-lint-unused-var.cc
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2022-03-07 12:17:40 +0000
committerGitHub <noreply@github.com>2022-03-07 12:17:40 +0000
commit865b6090a8f8981cdfc050ea2ee44abbe92de141 (patch)
tree33ca33f20795707b58b694fab16039d0c2c7374a /gcc/rust/lint/rust-lint-unused-var.cc
parent366c53371ad40025984a98e01b02d452d49816aa (diff)
parent7820ff8b8b14e1309aade205e50ef30bb08cb3e5 (diff)
downloadgcc-865b6090a8f8981cdfc050ea2ee44abbe92de141.zip
gcc-865b6090a8f8981cdfc050ea2ee44abbe92de141.tar.gz
gcc-865b6090a8f8981cdfc050ea2ee44abbe92de141.tar.bz2
Merge #992
992: Cleanup bad unused code warnings r=philberty a=philberty This patchset contains 4 distinct fixes: When a constant is declared after where it is used the code-generation pass falls back to a query compilation of the HIR::Item this did not contain a check to verify if it was already compiled and results in duplicate CONST_DECLS being generated if query compilation was used. We were using a zero precision integer to contain unit-type expressions this results in VAR_DECLS being lost in the GENERIC graph which does not allow us to perform any static analysis upon the DECL. This changes the unit type to use an empty struct and for initialization of a VAR_DECL we can simply pass an empty constructor and let GCC optimize this code for us. Update our DEAD_CODE scan to take into account modules of items and also respect if structures are prefixed with an underscore we can ignore generating an unused warning. Remove our AST scan for unused code and reuse GCC TREE_USED to track wether VAR_DECL, PARM_DECL, CONST_DECL are actually used or not. We reuse the GCC walk_tree functions to have this as nice separate lint. Fixes #676 Co-authored-by: Philip Herron <philip.herron@embecosm.com>
Diffstat (limited to 'gcc/rust/lint/rust-lint-unused-var.cc')
-rw-r--r--gcc/rust/lint/rust-lint-unused-var.cc98
1 files changed, 98 insertions, 0 deletions
diff --git a/gcc/rust/lint/rust-lint-unused-var.cc b/gcc/rust/lint/rust-lint-unused-var.cc
new file mode 100644
index 0000000..d4317e5
--- /dev/null
+++ b/gcc/rust/lint/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