summaryrefslogtreecommitdiff
path: root/gcc/c-family
diff options
context:
space:
mode:
authorbstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4>2011-09-12 08:35:31 +0000
committerbstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4>2011-09-12 08:35:31 +0000
commitc1101b9458abe61a35d2d5cbb9607220b429d2f8 (patch)
treeec929600612a7e1eae30170255d852528936e1e1 /gcc/c-family
parent9f10fded025299c52fdf30f726883f4678050e68 (diff)
downloadgcc-c1101b9458abe61a35d2d5cbb9607220b429d2f8.tar.gz
2011-09-12 Basile Starynkevitch <basile@starynkevitch.net>
MELT branch merged with trunk rev 178775 using svnmerge. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/melt-branch@178776 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/c-family')
-rw-r--r--gcc/c-family/ChangeLog12
-rw-r--r--gcc/c-family/c-common.c73
-rw-r--r--gcc/c-family/c-common.h7
-rw-r--r--gcc/c-family/c.opt4
4 files changed, 95 insertions, 1 deletions
diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog
index 347d904205f..080d42ac340 100644
--- a/gcc/c-family/ChangeLog
+++ b/gcc/c-family/ChangeLog
@@ -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
diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
index d8028d34878..e2852b66328 100644
--- a/gcc/c-family/c-common.c
+++ b/gcc/c-family/c-common.c
@@ -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. */
diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h
index 7ad82c009c8..7241d666d22 100644
--- a/gcc/c-family/c-common.h
+++ b/gcc/c-family/c-common.h
@@ -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);
diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt
index 617ea2d8905..e6ac5dca2ef 100644
--- a/gcc/c-family/c.opt
+++ b/gcc/c-family/c.opt
@@ -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