// Copyright (C) 2021-2023 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 *, void *) { 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