commit d52bd579a6f2fc0cfa762553013fb161301018fe
Author: Jason Merrill <jason@redhat.com>
Date: Thu Jul 4 09:03:53 2013 -0700
PR c++/55203
c-family/
* c-common.c (c_common_attribute_table): Add warn_unused.
(handle_warn_unused_attribute): New.
cp/
* init.c (build_aggr_init): Check for warn_unused attribute.
* decl.c (poplevel): Likewise.
@@ -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 }
};
@@ -7950,6 +7953,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,9 @@ 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);
@@ -1504,7 +1504,8 @@ build_aggr_init (tree exp, tree init, int flags, tsubst_flags_t complain)
return stmt_expr;
}
- if (VAR_P (exp) || TREE_CODE (exp) == PARM_DECL)
+ if ((VAR_P (exp) || TREE_CODE (exp) == PARM_DECL)
+ && !lookup_attribute ("warn_unused", TYPE_ATTRIBUTES (type)))
/* Just know that we've seen something for this node. */
TREE_USED (exp) = 1;
@@ -16377,6 +16377,23 @@ 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 is
+impossible for the compiler to determine 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 fundamental
+types.
+
+This attribute is appropriate for types which just represent a value,
+such as @code{std::string}; it is not appropriate for types which
+control a resource, such as @code{std::mutex}.
+
+This attribute is also accepted in C, but it is unnecessary because C
+does not have constructors or destructors.
+
@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();
+}