1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
|
// 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
|