From 704a0ae2906e090ad08834c78d096af0eff9d1f1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Lubo=C5=A1=20Lu=C5=88=C3=A1k?= <l.lunak@suse.cz>
Date: Sun, 30 Jun 2013 13:18:28 +0200
Subject: [PATCH] implement warn_unused attribute (gcc#55203)
---
gcc/c-family/c-common.c | 24 ++++++++++++++++++++++++
gcc/cp/decl.c | 3 ++-
gcc/cp/init.c | 8 ++++++--
gcc/doc/extend.texi | 13 +++++++++++++
gcc/testsuite/g++.dg/warn/warn_unused.C | 22 ++++++++++++++++++++++
5 files changed, 67 insertions(+), 3 deletions(-)
create mode 100644 gcc/testsuite/g++.dg/warn/warn_unused.C
@@ -368,6 +368,7 @@ static tree handle_optimize_attribute (tree *, tree, tree, int, bool *);
static tree ignore_attribute (tree *, tree, tree, int, bool *);
static tree handle_no_split_stack_attribute (tree *, tree, tree, int, bool *);
static tree handle_fnspec_attribute (tree *, tree, tree, int, bool *);
+static tree handle_warn_unused_attribute (tree *, tree, tree, int, bool *);
static void check_function_nonnull (tree, int, tree *);
static void check_nonnull_arg (void *, tree, unsigned HOST_WIDE_INT);
@@ -738,6 +739,8 @@ const struct attribute_spec c_common_attribute_table[] =
The name contains space to prevent its usage in source code. */
{ "fn spec", 1, 1, false, true, true,
handle_fnspec_attribute, false },
+ { "warn_unused", 0, 0, false, false, false,
+ handle_warn_unused_attribute, false },
{ NULL, 0, 0, false, false, false, NULL, false }
};
@@ -7942,6 +7945,27 @@ handle_fnspec_attribute (tree *node ATTRIBUTE_UNUSED, tree ARG_UNUSED (name),
return NULL_TREE;
}
+/* Handle a "warn_unused" attribute; arguments as in
+ struct attribute_spec.handler. */
+
+static tree
+handle_warn_unused_attribute (tree *node, tree name,
+ tree args ATTRIBUTE_UNUSED,
+ int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
+{
+ if (TYPE_P (*node))
+ /* Do nothing else, just set the attribute. We'll get at
+ it later with lookup_attribute. */
+ ;
+ else
+ {
+ warning (OPT_Wattributes, "%qE attribute ignored", name);
+ *no_add_attrs = true;
+ }
+
+ return NULL_TREE;
+}
+
/* Handle a "returns_twice" attribute; arguments as in
struct attribute_spec.handler. */
@@ -630,7 +630,8 @@ poplevel (int keep, int reverse, int functionbody)
&& DECL_NAME (decl) && ! DECL_ARTIFICIAL (decl)
&& type != error_mark_node
&& (!CLASS_TYPE_P (type)
- || !TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)))
+ || !TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
+ || lookup_attribute ("warn_unused", TYPE_ATTRIBUTES (TREE_TYPE (decl)))))
{
if (! TREE_USED (decl))
warning (OPT_Wunused_variable, "unused variable %q+D", decl);
@@ -1505,8 +1505,12 @@ build_aggr_init (tree exp, tree init, int flags, tsubst_flags_t complain)
}
if (VAR_P (exp) || TREE_CODE (exp) == PARM_DECL)
- /* Just know that we've seen something for this node. */
- TREE_USED (exp) = 1;
+ {
+ /* Just know that we've seen something for this node.
+ Merely creating a warn_unused aggregate doesn't make it used though. */
+ if( !lookup_attribute ("warn_unused", TYPE_ATTRIBUTES (type)))
+ TREE_USED (exp) = 1;
+ }
is_global = begin_init_stmts (&stmt_expr, &compound_stmt);
destroy_temps = stmts_are_full_exprs_p ();
@@ -16262,6 +16262,19 @@ only be applied to classes declared within an @code{extern "Java"} block.
Calls to methods declared in this interface are dispatched using GCJ's
interface table mechanism, instead of regular virtual table dispatch.
+@item warn_unused
+@cindex @code{warn_unused} attribute
+
+For C++ types with non-trivial constructors and/or destructors it may be
+difficult or impossible for the compiler to find out whether a variable
+of this type is truly unused if it is not referenced. This type attribute
+informs the compiler that variables of this type should be warned about
+if they appear to be unused, just like variables of basic types would be
+warned about.
+
+Types which would benefit from this type attribute are for example various
+container classes such as std::list or std::string.
+
@end table
See also @ref{Namespace Association}.
new file mode 100644
@@ -0,0 +1,22 @@
+// { dg-do compile }
+// { dg-options -Wunused }
+
+struct __attribute__((warn_unused)) Test
+{
+ Test();
+ ~Test();
+ void use();
+};
+
+struct TestNormal
+{
+ TestNormal();
+};
+
+int main()
+{
+ Test unused; // { dg-warning "unused variable" }
+ Test used; // { dg-bogus "unused variable" }
+ TestNormal normal; // { dg-bogus "unused variable" }
+ used.use();
+}
--
1.8.1.4