re PR c++/55203 (No unused warning for variables of non-trivial types)
authorLubos Lunak <l.lunak@suse.cz>
Sat, 13 Jul 2013 23:16:18 +0000 (01:16 +0200)
committerJason Merrill <jason@gcc.gnu.org>
Sat, 13 Jul 2013 23:16:18 +0000 (19:16 -0400)
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.

From-SVN: r200941

gcc/c-family/ChangeLog
gcc/c-family/c-common.c
gcc/cp/ChangeLog
gcc/cp/decl.c
gcc/cp/init.c
gcc/doc/extend.texi
gcc/testsuite/g++.dg/warn/warn_unused.C [new file with mode: 0644]

index 5aeb338b4d5f10b234a1f7994ae3911699df1b81..27b22a19fbdd8670976b713a748e522e7834e379 100644 (file)
@@ -1,3 +1,9 @@
+2013-07-13  Lubos Lunak  <l.lunak@suse.cz>
+
+       PR c++/55203
+       * c-common.c (c_common_attribute_table): Add warn_unused.
+       (handle_warn_unused_attribute): New.
+
 2013-07-10  Jakub Jelinek  <jakub@redhat.com>
 
        * c-ppoutput.c (scan_translation_unit): Call account_for_newlines
index 61300cd05c75f9b065433b2dfbb68d7771b2c536..970f9f20a08e2ca9b268a972e0edd439b424965a 100644 (file)
@@ -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.  */
 
index 4e4663058298dfdeb93225eb0c91ad6f0ef78991..3cf5e7797913f60e80a7ad5409ecacb7362236a8 100644 (file)
@@ -1,3 +1,9 @@
+2013-07-13  Lubos Lunak  <l.lunak@suse.cz>
+
+       PR c++/55203
+       * init.c (build_aggr_init): Check for warn_unused attribute.
+       * decl.c (poplevel): Likewise.
+
 2013-07-13  Jason Merrill  <jason@redhat.com>
 
        PR c++/57402
index 54bede00bb1d88881eb20cccf78cb5e75d999baa..c97134c5c406d0c13b81f28cfaaf0798f4f4901d 100644 (file)
@@ -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);
index 808803d6524abc33add8f47f0219933e890d8ed2..3bff509b3967fee5374762cde735c0d5ad63e5d5 100644 (file)
@@ -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;
 
index 1c85a3e738272e5d04fd031487be79b194214902..721c9b10daf5523fd3a187985e5e3302b4184446 100644 (file)
@@ -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}.
diff --git a/gcc/testsuite/g++.dg/warn/warn_unused.C b/gcc/testsuite/g++.dg/warn/warn_unused.C
new file mode 100644 (file)
index 0000000..af687fc
--- /dev/null
@@ -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();
+}