PR c++/33255 - Support -Wunused-local-typedefs warning

gcc/

	* c-decl.c (lookup_name): Use the new
	maybe_record_typedef_use.
	(pushdecl): Use the new
	record_locally_defined_typedef.
	(store_parm_decls): Allocate cfun->language.
	(finish_function): Use the new maybe_warn_unused_local_typedefs,
	and free cfun->language.
	(c_push_function_context): Allocate cfun->language here only if
	needed.
	(c_pop_function_context): Likewise, mark cfun->language
	for collection only when it should be done.
	* c-common.c (handle_used_attribute): Don't ignore TYPE_DECL
	nodes.
	* c-typeck.c (c_expr_sizeof_type, c_cast_expr): Use the new
	maybe_record_local_typedef_use.

gcc/c-family

	* c-common.h (struct c_language_function::local_typedefs): New
	field.
	(record_locally_defined_typedef, maybe_record_typedef_use)
	(maybe_warn_unused_local_typedefs): Declare new functions.
	* c-common.c (record_locally_defined_typedef)
	(maybe_record_typedef_use)
	(maybe_warn_unused_local_typedefs): Define new functions.
	* c.opt: Declare new -Wunused-local-typedefs flag.

gcc/cp

	* name-lookup.c (pushdecl_maybe_friend_1): Use the new
	record_locally_defined_typedef.
	* decl.c (finish_function): Use the new
	maybe_warn_unused_local_typedefs.
	(grokfield): Use the new record_locally_defined_typedef.
	* parser.c (lookup_name): Use the new maybe_record_typedef_use.

gcc/doc/

	* invoke.texi: Update documentation for -Wunused-local-typedefs.

gcc/testsuite/

	* g++.dg/warn/Wunused-local-typedefs.C: New test file.
	* c-c++-common/Wunused-local-typedefs.c: Likewise.

libstdc++-v3/

	* include/ext/bitmap_allocator.h
	(__detail::__mini_vector::__lower_bound): Remove unused typedef.
	* src/istream.cc (std::operator>>(basic_istream<char>& __in,
	basic_string<char>& __str)): Likewise.
	(std::getline): Likewise.
	* src/valarray.cc (__valarray_product): Likewise.

From-SVN: r178692
This commit is contained in:
Dodji Seketeli 2011-09-08 13:54:24 +00:00 committed by Dodji Seketeli
parent d275ab8b80
commit 3797cb21ff
19 changed files with 388 additions and 15 deletions

View File

@ -1,3 +1,23 @@
2011-09-08 Dodji Seketeli <dodji@redhat.com>
PR c++/33255 - Support -Wunused-local-typedefs warning
* c-decl.c (lookup_name): Use the new maybe_record_typedef_use.
(pushdecl): Use the new
record_locally_defined_typedef.
(store_parm_decls): Allocate cfun->language.
(finish_function): Use the new maybe_warn_unused_local_typedefs,
and free cfun->language.
(c_push_function_context): Allocate cfun->language here only if
needed.
(c_pop_function_context): Likewise, mark cfun->language
for collection only when it should be done.
* c-common.c (handle_used_attribute): Don't ignore TYPE_DECL
nodes.
* c-typeck.c (c_expr_sizeof_type, c_cast_expr): Use the new
maybe_record_local_typedef_use.
* doc/invoke.texi: Update documentation for
-Wunused-local-typedefs.
2011-09-08 Enkovich Ilya <ilya.enkovich@intel.com>
* config/i386/i386-protos.h (ix86_lea_outperforms): New.

View File

@ -2769,7 +2769,15 @@ pushdecl (tree x)
skip_external_and_shadow_checks:
if (TREE_CODE (x) == TYPE_DECL)
set_underlying_type (x);
{
/* So this is a typedef, set its underlying type. */
set_underlying_type (x);
/* If X is a typedef defined in the current function, record it
for the purpose of implementing the -Wunused-local-typedefs
warning. */
record_locally_defined_typedef (x);
}
bind (name, x, scope, /*invisible=*/false, nested, locus);
@ -3435,7 +3443,10 @@ lookup_name (tree name)
{
struct c_binding *b = I_SYMBOL_BINDING (name);
if (b && !b->invisible)
return b->decl;
{
maybe_record_typedef_use (b->decl);
return b->decl;
}
return 0;
}
@ -8192,6 +8203,9 @@ store_parm_decls (void)
/* Initialize the RTL code for the function. */
allocate_struct_function (fndecl, false);
if (warn_unused_local_typedefs)
cfun->language = ggc_alloc_cleared_language_function ();
/* Begin the statement tree for this function. */
DECL_SAVED_TREE (fndecl) = push_stmt_list ();
@ -8299,6 +8313,10 @@ finish_function (void)
"parameter %qD set but not used", decl);
}
/* Complain about locally defined typedefs that are not used in this
function. */
maybe_warn_unused_local_typedefs ();
/* Store the end of the function, so that we get good line number
info for the epilogue. */
cfun->function_end_locus = input_location;
@ -8344,6 +8362,12 @@ finish_function (void)
if (!decl_function_context (fndecl))
undef_nested_function = false;
if (cfun->language != NULL)
{
ggc_free (cfun->language);
cfun->language = NULL;
}
/* We're leaving the context of this function, so zap cfun.
It's still in DECL_STRUCT_FUNCTION, and we'll restore it in
tree_rest_of_compilation. */
@ -8455,9 +8479,11 @@ check_for_loop_decls (location_t loc, bool turn_off_iso_c99_error)
void
c_push_function_context (void)
{
struct language_function *p;
p = ggc_alloc_language_function ();
cfun->language = p;
struct language_function *p = cfun->language;
/* cfun->language might have been already allocated by the use of
-Wunused-local-typedefs. In that case, just re-use it. */
if (p == NULL)
cfun->language = p = ggc_alloc_cleared_language_function ();
p->base.x_stmt_tree = c_stmt_tree;
c_stmt_tree.x_cur_stmt_list
@ -8483,7 +8509,11 @@ c_pop_function_context (void)
pop_function_context ();
p = cfun->language;
cfun->language = NULL;
/* When -Wunused-local-typedefs is in effect, cfun->languages is
used to store data throughout the life time of the current cfun,
So don't deallocate it. */
if (!warn_unused_local_typedefs)
cfun->language = NULL;
if (DECL_STRUCT_FUNCTION (current_function_decl) == 0
&& DECL_SAVED_TREE (current_function_decl) == NULL_TREE)

View File

@ -1,3 +1,15 @@
2011-09-08 Dodji Seketeli <dodji@redhat.com>
PR c++/33255 - Support -Wunused-local-typedefs warning
* c-common.h (struct c_language_function::local_typedefs): New
field.
(record_locally_defined_typedef, maybe_record_typedef_use)
(maybe_warn_unused_local_typedefs): Declare new functions.
* c-common.c (record_locally_defined_typedef)
(maybe_record_typedef_use)
(maybe_warn_unused_local_typedefs): Define new functions.
* c.opt: Declare new -Wunused-local-typedefs flag.
2011-09-06 Eric Botcazou <ebotcazou@adacore.com>
PR middle-end/50266

View File

@ -6133,7 +6133,8 @@ handle_used_attribute (tree *pnode, tree name, tree ARG_UNUSED (args),
tree node = *pnode;
if (TREE_CODE (node) == FUNCTION_DECL
|| (TREE_CODE (node) == VAR_DECL && TREE_STATIC (node)))
|| (TREE_CODE (node) == VAR_DECL && TREE_STATIC (node))
|| (TREE_CODE (node) == TYPE_DECL))
{
TREE_USED (node) = 1;
DECL_PRESERVE_P (node) = 1;
@ -9646,6 +9647,76 @@ record_types_used_by_current_var_decl (tree decl)
}
}
/* If DECL is a typedef that is declared in the current function,
record it for the purpose of -Wunused-local-typedefs. */
void
record_locally_defined_typedef (tree decl)
{
struct c_language_function *l;
if (!warn_unused_local_typedefs
|| cfun == NULL
/* if this is not a locally defined typedef then we are not
interested. */
|| !is_typedef_decl (decl)
|| !decl_function_context (decl))
return;
l = (struct c_language_function *) cfun->language;
VEC_safe_push (tree, gc, l->local_typedefs, decl);
}
/* If T is a TYPE_DECL declared locally, mark it as used. */
void
maybe_record_typedef_use (tree t)
{
if (!is_typedef_decl (t))
return;
TREE_USED (t) = true;
}
/* Warn if there are some unused locally defined typedefs in the
current function. */
void
maybe_warn_unused_local_typedefs (void)
{
int i;
tree decl;
/* The number of times we have emitted -Wunused-local-typedefs
warnings. If this is different from errorcount, that means some
unrelated errors have been issued. In which case, we'll avoid
emitting "unused-local-typedefs" warnings. */
static int unused_local_typedefs_warn_count;
struct c_language_function *l;
if (cfun == NULL)
return;
if ((l = (struct c_language_function *) cfun->language) == NULL)
return;
if (warn_unused_local_typedefs
&& errorcount == unused_local_typedefs_warn_count)
{
FOR_EACH_VEC_ELT (tree, l->local_typedefs, i, decl)
if (!TREE_USED (decl))
warning_at (DECL_SOURCE_LOCATION (decl),
OPT_Wunused_local_typedefs,
"typedef %qD locally defined but not used", decl);
unused_local_typedefs_warn_count = errorcount;
}
if (l->local_typedefs)
{
VEC_free (tree, gc, l->local_typedefs);
l->local_typedefs = NULL;
}
}
/* The C and C++ parsers both use vectors to hold function arguments.
For efficiency, we keep a cache of unused vectors. This is the
cache. */

View File

@ -506,6 +506,10 @@ struct GTY(()) c_language_function {
/* While we are parsing the function, this contains information
about the statement-tree that we are building. */
struct stmt_tree_s x_stmt_tree;
/* Vector of locally defined typedefs, for
-Wunused-local-typedefs. */
VEC(tree,gc) *local_typedefs;
};
#define stmt_list_stack (current_stmt_tree ()->x_cur_stmt_list)
@ -988,6 +992,9 @@ extern void warn_for_sign_compare (location_t,
extern void do_warn_double_promotion (tree, tree, tree, const char *,
location_t);
extern void set_underlying_type (tree);
extern void record_locally_defined_typedef (tree);
extern void maybe_record_typedef_use (tree);
extern void maybe_warn_unused_local_typedefs (void);
extern VEC(tree,gc) *make_tree_vector (void);
extern void release_tree_vector (VEC(tree,gc) *);
extern VEC(tree,gc) *make_tree_vector_single (tree);

View File

@ -653,6 +653,10 @@ Wunsuffixed-float-constants
C ObjC Var(warn_unsuffixed_float_constants) Warning
Warn about unsuffixed float constants
Wunused-local-typedefs
C ObjC C++ ObjC++ Var(warn_unused_local_typedefs) Warning
Warn about
Wunused-macros
C ObjC C++ ObjC++ Warning
Warn about macros defined in the main file that are not used

View File

@ -1,3 +1,13 @@
2011-09-08 Dodji Seketeli <dodji@redhat.com>
PR c++/33255 - Support -Wunused-local-typedefs warning
* name-lookup.c (pushdecl_maybe_friend_1): Use the new
record_locally_defined_typedef.
* decl.c (finish_function): Use the new
maybe_warn_unused_local_typedefs.
(grokfield): Use the new record_locally_defined_typedef.
* parser.c (lookup_name): Use the new maybe_record_typedef_use.
2011-09-07 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/50309

View File

@ -13392,6 +13392,10 @@ finish_function (int flags)
unused_but_set_errorcount = errorcount;
}
/* Complain about locally defined typedefs that are not used in this
function. */
maybe_warn_unused_local_typedefs ();
/* Genericize before inlining. */
if (!processing_template_decl)
{

View File

@ -868,6 +868,7 @@ grokfield (const cp_declarator *declarator,
&& TYPE_NAME (TYPE_MAIN_VARIANT (TREE_TYPE (value))) != value)
set_underlying_type (value);
record_locally_defined_typedef (value);
return value;
}

View File

@ -868,6 +868,13 @@ pushdecl_maybe_friend_1 (tree x, bool is_friend)
&& TYPE_NAME (type)
&& TYPE_IDENTIFIER (type))
set_identifier_type_value (DECL_NAME (x), x);
/* If this is a locally defined typedef in a function that
is not a template instantation, record it to implement
-Wunused-local-typedefs. */
if (current_instantiation () == NULL
|| (current_instantiation ()->decl != current_function_decl))
record_locally_defined_typedef (x);
}
/* Multiple external decls of the same identifier ought to match.

View File

@ -19587,6 +19587,8 @@ cp_parser_lookup_name (cp_parser *parser, tree name,
if (DECL_P (decl))
check_accessibility_of_qualified_id (decl, object_type, parser->scope);
maybe_record_typedef_use (decl);
return decl;
}

View File

@ -268,8 +268,9 @@ Objective-C and Objective-C++ Dialects}.
-Wsystem-headers -Wtrampolines -Wtrigraphs -Wtype-limits -Wundef @gol
-Wuninitialized -Wunknown-pragmas -Wno-pragmas @gol
-Wunsuffixed-float-constants -Wunused -Wunused-function @gol
-Wunused-label -Wunused-parameter -Wno-unused-result -Wunused-value @gol
-Wunused-variable -Wunused-but-set-parameter -Wunused-but-set-variable @gol
-Wunused-label -Wunused-local-typedefs -Wunused-parameter @gol
-Wno-unused-result -Wunused-value @gol -Wunused-variable @gol
-Wunused-but-set-parameter -Wunused-but-set-variable @gol
-Wvariadic-macros -Wvla -Wvolatile-register-var -Wwrite-strings}
@item C and Objective-C-only Warning Options
@ -3501,6 +3502,10 @@ This warning is enabled by @option{-Wall}.
To suppress this warning use the @samp{unused} attribute
(@pxref{Variable Attributes}).
@item -Wunused-local-typedefs @r{(C, Objective-C, C++ and Objective-C++ only)}
@opindex Wunused-local-typedefs
Warn when a typedef locally defined in a function is not used.
@item -Wunused-parameter
@opindex Wunused-parameter
@opindex Wno-unused-parameter

View File

@ -1,3 +1,9 @@
2011-09-08 Dodji Seketeli <dodji@redhat.com>
PR c++/33255 - Support -Wunused-local-typedefs warning
* g++.dg/warn/Wunused-local-typedefs.C: New test file.
* c-c++-common/Wunused-local-typedefs.c: Likewise.
2011-09-08 Martin Jambor <mjambor@suse.cz>
PR tree-optimization/50287

View File

@ -0,0 +1,44 @@
/* Origin PR c++/33255
{ dg-options "-Wunused-local-typedefs" }
{ dg-do compile }
*/
void
test_warn ()
{
typedef int foo; // { dg-warning "locally defined but not used" }
}
void
test0 ()
{
typedef int foo;
foo var __attribute__((unused));
}
void
test1 ()
{
typedef int foo;
const foo *var = 0;
}
void
test2 ()
{
typedef int foo;
void func(foo);
}
void
test7 (void)
{
typedef int foo;
int vec[1] = {sizeof (foo)};
}
void
test8 (void)
{
typedef int foo __attribute__((used));
}

View File

@ -0,0 +1,146 @@
// Origin PR c++/33255
// { dg-options "-Wunused-local-typedefs" }
// { dg-do compile }
void
test_warn()
{
typedef int foo; // { dg-warning "locally defined but not used" }
}
struct S
{
typedef int T;
S() {}
S(int) {}
};
template<class T>
struct ST
{
typedef T type;
ST (int) {}
ST () {}
};
template<class T>
void
test0_tmpl(void)
{
typedef struct ST<T> foo;
foo(2);
}
int
test0(void)
{
test0_tmpl<int>();
}
void
test1(void)
{
typedef int foo;
ST<foo> a;
}
int
test2(void)
{
typedef S foo;
foo::T i = 0;
return i;
}
template<class T>
void
test3_tmpl(void)
{
typedef struct ST<int> foo;
ST<int> v;
const foo &var = v;
}
void
test3(void)
{
test3_tmpl<int>();
}
void
test4(void)
{
typedef int foo;
int vec[1] = {sizeof (foo)};
}
void
test5(void)
{
typedef int T0;
typedef char T1;
typedef int* T2;
typedef unsigned T3;
struct C0 { virtual void f(void) {}};
struct C1 : C0 {};
typedef C0 T4;
int v0 = (T0) 2;
char v1 = static_cast<T1> (0);
reinterpret_cast<T2> (&v0);
unsigned* const c = 0;
unsigned* v2 = const_cast<T3* const> (c);
C0 *p0 = 0;
C1 *p1 = 0;
p0 = dynamic_cast<T4*> (p1);
}
void
test6(void)
{
struct C0 {};
typedef C0 foo;
C0 *v = new foo;
}
template<class T, class U>
struct S7
{
void
f()
{
typedef int foo;
sizeof(foo);
}
};
template<class T>
void
test7(void)
{
typedef typename ST<T>::T bar; // { dg-warning "locally defined but not used" }
typedef typename ST<T>::T foo; // We shouldn't warn for this one, as
// it's used below.
S7<int, foo> v;
}
template<class T, class U>
void
test8(void)
{
int f(S7<T, U>);
void g(int);
typedef T foo;
g(f(S7<foo, U>()));
}
int
test9(void)
{
struct s { typedef int foo;}; // { dg-warning "locally defined but not used" }
struct t { typedef int bar;};
t::bar b = 0;
return b;
}

View File

@ -1,3 +1,13 @@
2011-09-08 Dodji Seketeli <dodji@redhat.com>
PR c++/33255 - Support -Wunused-local-typedefs warning
* include/ext/bitmap_allocator.h
(__detail::__mini_vector::__lower_bound): Remove unused typedef.
* src/istream.cc (std::operator>>(basic_istream<char>& __in,
basic_string<char>& __str)): Likewise.
(std::getline): Likewise.
* src/valarray.cc (__valarray_product): Likewise.
2011-09-07 François Dumont <francois.cppdevs@free.fr>
* testsuite/23_containers/array/at.cc: Revert to...

View File

@ -237,8 +237,6 @@ namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
__lower_bound(_ForwardIterator __first, _ForwardIterator __last,
const _Tp& __val, _Compare __comp)
{
typedef typename __mv_iter_traits<_ForwardIterator>::value_type
_ValueType;
typedef typename __mv_iter_traits<_ForwardIterator>::difference_type
_DistanceType;

View File

@ -280,7 +280,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{
typedef basic_istream<char> __istream_type;
typedef __istream_type::int_type __int_type;
typedef __istream_type::char_type __char_type;
typedef __istream_type::traits_type __traits_type;
typedef __istream_type::__streambuf_type __streambuf_type;
typedef __istream_type::__ctype_type __ctype_type;
@ -364,7 +363,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
typedef __istream_type::char_type __char_type;
typedef __istream_type::traits_type __traits_type;
typedef __istream_type::__streambuf_type __streambuf_type;
typedef __istream_type::__ctype_type __ctype_type;
typedef basic_string<char> __string_type;
typedef __string_type::size_type __size_type;
@ -610,7 +608,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
typedef __istream_type::char_type __char_type;
typedef __istream_type::traits_type __traits_type;
typedef __istream_type::__streambuf_type __streambuf_type;
typedef __istream_type::__ctype_type __ctype_type;
typedef basic_string<wchar_t> __string_type;
typedef __string_type::size_type __size_type;

View File

@ -49,7 +49,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
inline size_t
__valarray_product(const valarray<size_t>& __a)
{
typedef const size_t* __restrict__ _Tp;
const size_t __n = __a.size();
// XXX: This ugly cast is necessary because
// valarray::operator[]() const return a VALUE!