diff options
author | Jakub Jelinek <jakub@redhat.com> | 2010-04-07 22:33:36 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2010-04-07 22:33:36 +0200 |
commit | ebfbbdc556443d1ea95923b596f59411256bd9b5 (patch) | |
tree | 2559870c4c1dbe82ba98485de0b41abd6bed7ca2 /gcc/c-decl.c | |
parent | 0bb8c1342ffedb0d012f007342f802e0fb692e4d (diff) | |
download | gcc-ebfbbdc556443d1ea95923b596f59411256bd9b5.tar.gz |
re PR c/18624 (GCC does not detect local variable set but never used)
PR c/18624
* tree.h (DECL_READ_P): Define.
(struct tree_decl_common): Add decl_read_flag.
* c-decl.c (pop_scope): If TREE_USED but !DECL_READ_P, issue
a set but not used warning.
(merge_decls): Merge DECL_READ_P flag.
(finish_decl, build_compound_literal): Set DECL_READ_P flag.
(finish_function): Issue -Wunused-but-set-parameter diagnostics.
* c-common.c (handle_used_attribute, handle_unused_attribute):
Likewise.
* c-tree.h (default_function_array_read_conversion, mark_exp_read):
New prototypes.
* c-typeck.c (default_function_array_read_conversion, mark_exp_read):
New functions.
(default_conversion, c_process_expr_stmt): Call mark_exp_read.
* c-parser.c (c_parser_initializer, c_parser_expr_no_commas,
c_parser_binary_expression, c_parser_cast_expression,
c_parser_expr_list, c_parser_omp_atomic, c_parser_omp_for_loop):
Call default_function_array_read_conversion instead of
default_function_array_conversion where needed.
(c_parser_unary_expression, c_parser_conditional_expression,
c_parser_postfix_expression_after_primary, c_parser_initelt):
Likewise. Call mark_exp_read where needed.
(c_parser_statement_after_labels, c_parser_asm_operands,
c_parser_typeof_specifier, c_parser_sizeof_expression,
c_parser_alignof_expression, c_parser_initval): Call mark_exp_read
where needed.
* common.opt (Wunused-but-set-variable, Wunused-but-set-parameter):
New.
* toplev.c (warn_unused_but_set_variable): Default to warn_unused.
(warn_unused_but_set_parameter): Default to warn_unused
&& extra_warnings.
* doc/invoke.texi: Document -Wunused-but-set-variable and
-Wunused-but-set-parameter.
* objc-act.c (finish_var_decl, objc_begin_catch_clause,
really_start_method, get_super_receiver, handle_class_ref): Set
DECL_READ_P in addition to TREE_USED.
* gcc.dg/Wunused-var-1.c: New test.
* gcc.dg/Wunused-var-2.c: New test.
* gcc.dg/Wunused-var-3.c: New test.
* gcc.dg/Wunused-var-4.c: New test.
* gcc.dg/Wunused-var-5.c: New test.
* gcc.dg/Wunused-var-6.c: New test.
* gcc.dg/Wunused-parm-1.c: New test.
From-SVN: r158086
Diffstat (limited to 'gcc/c-decl.c')
-rw-r--r-- | gcc/c-decl.c | 39 |
1 files changed, 36 insertions, 3 deletions
diff --git a/gcc/c-decl.c b/gcc/c-decl.c index b6ff3f476e6..bc90fdd38dd 100644 --- a/gcc/c-decl.c +++ b/gcc/c-decl.c @@ -1164,14 +1164,21 @@ pop_scope (void) case VAR_DECL: /* Warnings for unused variables. */ - if (!TREE_USED (p) + if ((!TREE_USED (p) || !DECL_READ_P (p)) && !TREE_NO_WARNING (p) && !DECL_IN_SYSTEM_HEADER (p) && DECL_NAME (p) && !DECL_ARTIFICIAL (p) && scope != file_scope && scope != external_scope) - warning (OPT_Wunused_variable, "unused variable %q+D", p); + { + if (!TREE_USED (p)) + warning (OPT_Wunused_variable, "unused variable %q+D", p); + else if (DECL_CONTEXT (p) == current_function_decl) + warning_at (DECL_SOURCE_LOCATION (p), + OPT_Wunused_but_set_variable, + "variable %qD set but not used", p); + } if (b->inner_comp) { @@ -2387,6 +2394,8 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype) TREE_USED (newdecl) = 1; else if (TREE_USED (newdecl)) TREE_USED (olddecl) = 1; + if (TREE_CODE (olddecl) == VAR_DECL || TREE_CODE (olddecl) == PARM_DECL) + DECL_READ_P (newdecl) |= DECL_READ_P (olddecl); if (DECL_PRESERVE_P (olddecl)) DECL_PRESERVE_P (newdecl) = 1; else if (DECL_PRESERVE_P (newdecl)) @@ -4232,7 +4241,10 @@ finish_decl (tree decl, location_t init_loc, tree init, } if (TREE_USED (type)) - TREE_USED (decl) = 1; + { + TREE_USED (decl) = 1; + DECL_READ_P (decl) = 1; + } } /* If this is a function and an assembler name is specified, reset DECL_RTL @@ -4380,6 +4392,7 @@ finish_decl (tree decl, location_t init_loc, tree init, /* Don't warn about decl unused; the cleanup uses it. */ TREE_USED (decl) = 1; TREE_USED (cleanup_decl) = 1; + DECL_READ_P (decl) = 1; push_cleanup (decl, cleanup, false); } @@ -4472,6 +4485,7 @@ build_compound_literal (location_t loc, tree type, tree init, bool non_const) TREE_STATIC (decl) = (current_scope == file_scope); DECL_CONTEXT (decl) = current_function_decl; TREE_USED (decl) = 1; + DECL_READ_P (decl) = 1; TREE_TYPE (decl) = type; TREE_READONLY (decl) = TYPE_READONLY (type); store_init_value (loc, decl, init, NULL_TREE); @@ -8060,6 +8074,25 @@ finish_function (void) TREE_NO_WARNING (fndecl) = 1; } + /* Complain about parameters that are only set, but never otherwise used. */ + if (warn_unused_but_set_parameter) + { + tree decl; + + for (decl = DECL_ARGUMENTS (fndecl); + decl; + decl = TREE_CHAIN (decl)) + if (TREE_USED (decl) + && TREE_CODE (decl) == PARM_DECL + && !DECL_READ_P (decl) + && DECL_NAME (decl) + && !DECL_ARTIFICIAL (decl) + && !TREE_NO_WARNING (decl)) + warning_at (DECL_SOURCE_LOCATION (decl), + OPT_Wunused_but_set_parameter, + "parameter %qD set but not used", decl); + } + /* Store the end of the function, so that we get good line number info for the epilogue. */ cfun->function_end_locus = input_location; |