Line data Source code
1 : // Copyright (C) 2021-2026 Free Software Foundation, Inc.
2 :
3 : // This file is part of GCC.
4 :
5 : // GCC is free software; you can redistribute it and/or modify it under
6 : // the terms of the GNU General Public License as published by the Free
7 : // Software Foundation; either version 3, or (at your option) any later
8 : // version.
9 :
10 : // GCC is distributed in the hope that it will be useful, but WITHOUT ANY
11 : // WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 : // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 : // for more details.
14 :
15 : // You should have received a copy of the GNU General Public License
16 : // along with GCC; see the file COPYING3. If not see
17 : // <http://www.gnu.org/licenses/>.
18 :
19 : #include "rust-lint-unused-var.h"
20 : #include "rust-gcc.h"
21 :
22 : namespace Rust {
23 : namespace Analysis {
24 :
25 : static bool
26 52565 : starts_with_underscore (const char *var_name)
27 : {
28 52565 : auto pos = std::string (var_name).find_last_of (':');
29 52565 : if (pos == std::string::npos)
30 51636 : return strncmp (var_name, "_", 1) == 0;
31 929 : return strncmp (var_name + pos + 1, "_", 1) == 0;
32 : }
33 :
34 : static void
35 52565 : check_decl (tree *t)
36 : {
37 52565 : rust_assert (TREE_CODE (*t) == VAR_DECL || TREE_CODE (*t) == PARM_DECL
38 : || TREE_CODE (*t) == CONST_DECL);
39 :
40 52565 : tree var_name = DECL_NAME (*t);
41 52565 : const char *var_name_ptr = IDENTIFIER_POINTER (var_name);
42 52565 : bool starts_with_under_score = starts_with_underscore (var_name_ptr);
43 52565 : bool is_self = strcmp (var_name_ptr, "self") == 0;
44 :
45 52565 : bool is_constant = TREE_CODE (*t) == CONST_DECL;
46 : // if (!is_constant)
47 : // {
48 : // debug_tree (*t);
49 : // rust_debug ("found var-decl: used %s artifical %s underscore %s name
50 : // %s",
51 : // TREE_USED (*t) ? "true" : "false",
52 : // DECL_ARTIFICIAL (*t) ? "true" : "false",
53 : // starts_with_under_score ? "true" : "false", var_name_ptr);
54 : // }
55 :
56 2818 : if (!TREE_USED (*t) && !DECL_ARTIFICIAL (*t) && !starts_with_under_score
57 55344 : && !is_self)
58 : {
59 1959 : warning_at (DECL_SOURCE_LOCATION (*t),
60 3891 : is_constant ? OPT_Wunused_const_variable_
61 : : OPT_Wunused_variable,
62 : "unused name %qE", *t);
63 : }
64 52565 : }
65 :
66 : static tree
67 378831 : unused_var_walk_fn (tree *t, int *, void *)
68 : {
69 378831 : switch (TREE_CODE (*t))
70 : {
71 37219 : case VAR_DECL:
72 37219 : case CONST_DECL:
73 37219 : check_decl (t);
74 37219 : break;
75 :
76 : default:
77 : break;
78 : }
79 378831 : return NULL_TREE;
80 : }
81 :
82 : void
83 4023 : UnusedVariables::Lint (Compile::Context &ctx)
84 : {
85 18797 : for (auto &fndecl : ctx.get_func_decls ())
86 : {
87 29578 : for (tree p = DECL_ARGUMENTS (fndecl); p != NULL_TREE; p = DECL_CHAIN (p))
88 : {
89 14804 : check_decl (&p);
90 : }
91 :
92 14774 : walk_tree_without_duplicates (&DECL_SAVED_TREE (fndecl),
93 : &unused_var_walk_fn, &ctx);
94 : }
95 :
96 4069 : for (auto &var : ctx.get_var_decls ())
97 : {
98 46 : tree decl = var->get_decl ();
99 46 : check_decl (&decl);
100 : }
101 :
102 4519 : for (auto &const_decl : ctx.get_const_decls ())
103 : {
104 496 : check_decl (&const_decl);
105 : }
106 4023 : }
107 :
108 : } // namespace Analysis
109 : } // namespace Rust
|