]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
PR c++/29028 - Missed unused warning on using declaration
authorDodji Seketeli <dodji@redhat.com>
Fri, 28 Sep 2012 12:51:30 +0000 (12:51 +0000)
committerDodji Seketeli <dodji@gcc.gnu.org>
Fri, 28 Sep 2012 12:51:30 +0000 (14:51 +0200)
In the example of the patch, g++ fails to warn that the variable N::i
(introduced via a using declaration) is unused.

This is because as we want to emit the warning in poplevel, when we
walk the local bindings returned by getdecls, we forget that a
VAR_DECL introduced by a using declaration is represented by a
TREE_LIST which TREE_VALUE is the VAR_DECL, and we wrongly look for a
bare VAR_DECL.

Fixed thus and tested on x86_64-unknown-linux-gnu against trunk.

gcc/cp/

* decl.c (poplevel<warn_unused*>): Do not forget that some local
bindings are represented by a TREE_LIST.

gcc/testsuite/

* g++.dg/warn/Wunused-var-18.C: New test.

From-SVN: r191829

gcc/cp/ChangeLog
gcc/cp/decl.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/warn/Wunused-var-18.C [new file with mode: 0644]

index 78325900c8943c1557c2fbd081d277e5dc2e98da..3ba5de4eb7a5e22413b499dba06d4d6cb2c28216 100644 (file)
@@ -1,3 +1,9 @@
+2012-09-25  Dodji Seketeli  <dodji@redhat.com>
+
+       PR c++/29028 - Missed unused warning on using declaration
+       * decl.c (poplevel<warn_unused*>): Do not forget that some local
+       bindings are represented by a TREE_LIST.
+
 2012-09-25  Dodji Seketeli  <dodji@redhat.com>
 
        PR c++/53551 - -Wunused-local-typedefs misses uses
index a7bb9379c3626ad3a07c5c57bc15aa4f4e66fae5..078b1486615e519ebe2bbbd27006c3b7bad5dc0a 100644 (file)
@@ -617,26 +617,32 @@ poplevel (int keep, int reverse, int functionbody)
   /* Before we remove the declarations first check for unused variables.  */
   if ((warn_unused_variable || warn_unused_but_set_variable)
       && !processing_template_decl)
-    for (decl = getdecls (); decl; decl = TREE_CHAIN (decl))
-      if (TREE_CODE (decl) == VAR_DECL
-         && (! TREE_USED (decl) || !DECL_READ_P (decl))
-         && ! DECL_IN_SYSTEM_HEADER (decl)
-         && DECL_NAME (decl) && ! DECL_ARTIFICIAL (decl)
-         && TREE_TYPE (decl) != error_mark_node
-         && (!CLASS_TYPE_P (TREE_TYPE (decl))
-             || !TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (decl))))
-       {
-         if (! TREE_USED (decl))
-           warning (OPT_Wunused_variable, "unused variable %q+D", decl);
-         else if (DECL_CONTEXT (decl) == current_function_decl
-                  && TREE_CODE (TREE_TYPE (decl)) != REFERENCE_TYPE
-                  && errorcount == unused_but_set_errorcount)
-           {
-             warning (OPT_Wunused_but_set_variable,
-                      "variable %q+D set but not used", decl); 
-             unused_but_set_errorcount = errorcount;
-           }
-       }
+    for (tree d = getdecls (); d; d = TREE_CHAIN (d))
+      {
+       /* There are cases where D itself is a TREE_LIST.  See in
+          push_local_binding where the list of decls returned by
+          getdecls is built.  */
+       decl = TREE_CODE (d) == TREE_LIST ? TREE_VALUE (d) : d;
+       if (TREE_CODE (decl) == VAR_DECL
+           && (! TREE_USED (decl) || !DECL_READ_P (decl))
+           && ! DECL_IN_SYSTEM_HEADER (decl)
+           && DECL_NAME (decl) && ! DECL_ARTIFICIAL (decl)
+           && TREE_TYPE (decl) != error_mark_node
+           && (!CLASS_TYPE_P (TREE_TYPE (decl))
+               || !TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (decl))))
+         {
+           if (! TREE_USED (decl))
+             warning (OPT_Wunused_variable, "unused variable %q+D", decl);
+           else if (DECL_CONTEXT (decl) == current_function_decl
+                    && TREE_CODE (TREE_TYPE (decl)) != REFERENCE_TYPE
+                    && errorcount == unused_but_set_errorcount)
+             {
+               warning (OPT_Wunused_but_set_variable,
+                        "variable %q+D set but not used", decl);
+               unused_but_set_errorcount = errorcount;
+             }
+         }
+      }
 
   /* Remove declarations for all the DECLs in this level.  */
   for (link = decls; link; link = TREE_CHAIN (link))
index e9bd0b3f0724b1b869a8fc7a590bcbeb6f199323..407184d17bedb1897d884cb3c81adbedbd21abcb 100644 (file)
@@ -1,3 +1,8 @@
+2012-09-25  Dodji Seketeli  <dodji@redhat.com>
+
+       PR c++/29028 - Missed unused warning on using declaration
+       * g++.dg/warn/Wunused-var-18.C: New test.
+
 2012-09-25  Dodji Seketeli  <dodji@redhat.com>
 
        PR c++/53551 - -Wunused-local-typedefs misses uses
diff --git a/gcc/testsuite/g++.dg/warn/Wunused-var-18.C b/gcc/testsuite/g++.dg/warn/Wunused-var-18.C
new file mode 100644 (file)
index 0000000..0339663
--- /dev/null
@@ -0,0 +1,14 @@
+// Origin: PR c++/29028
+// { dg-options "-Wunused" }
+// { dg-do compile }
+
+namespace N
+{
+    int i; // { dg-warning "unused variable" }
+}
+
+void
+f ()
+{
+    using N::i;
+}