PR c++/79548 - missing -Wunused-variable on a typedef'd variable in a function template
authorMartin Sebor <msebor@redhat.com>
Tue, 21 Mar 2017 22:33:39 +0000 (22:33 +0000)
committerMartin Sebor <msebor@gcc.gnu.org>
Tue, 21 Mar 2017 22:33:39 +0000 (16:33 -0600)
gcc/c-family/ChangeLog:

PR c++/79548
* c-common.c (set_underlying_type): Mark type used only when
original del is declared unused.

gcc/testsuite/ChangeLog:

PR c++/79548
* g++.dg/warn/Wunused-var-26.C: New test.

From-SVN: r246335

gcc/c-family/ChangeLog
gcc/c-family/c-common.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/warn/Wunused-var-26.C [new file with mode: 0644]

index 0a7fef1d3ee4597cafde786af8c7644fbf66e1e2..4afb4b8af6ec6d391494d01e1da6495a0f99cc04 100644 (file)
@@ -1,3 +1,9 @@
+2017-03-21  Martin Sebor  <msebor@redhat.com>
+
+       PR c++/79548
+       * c-common.c (set_underlying_type): Mark type used only when
+       original del is declared unused.
+
 2017-03-10  David Malcolm  <dmalcolm@redhat.com>
 
        PR translation/79848
index 885ea6d2d70e22c900f3299635b179b3488142ad..65ffd8cd7bdb3510f2d67809483828777456ca56 100644 (file)
@@ -7476,7 +7476,12 @@ set_underlying_type (tree x)
       tt = build_variant_type_copy (tt);
       TYPE_STUB_DECL (tt) = TYPE_STUB_DECL (DECL_ORIGINAL_TYPE (x));
       TYPE_NAME (tt) = x;
-      TREE_USED (tt) = TREE_USED (x);
+
+      /* Mark the type as used only when its type decl is decorated
+        with attribute unused.  */
+      if (lookup_attribute ("unused", DECL_ATTRIBUTES (x)))
+       TREE_USED (tt) = 1;
+
       TREE_TYPE (x) = tt;
     }
 }
index aa6ec43ebc0eb3b389871212b1f6ddd865ef884a..4dbc719777915ee3c400103e5294835aacc57822 100644 (file)
@@ -1,3 +1,8 @@
+2017-03-21  Martin Sebor  <msebor@redhat.com>
+
+       PR c++/79548
+       * g++.dg/warn/Wunused-var-26.C: New test.
+
 2017-03-21  Bill Schmidt  <wschmidt@linux.vnet.ibm.com>
 
        PR tree-optimization/79908
diff --git a/gcc/testsuite/g++.dg/warn/Wunused-var-26.C b/gcc/testsuite/g++.dg/warn/Wunused-var-26.C
new file mode 100644 (file)
index 0000000..b3e020b
--- /dev/null
@@ -0,0 +1,147 @@
+// PR c++/79548 - missing -Wunused-variable on a typedef'd variable
+// in a function template
+// { dg-do compile }
+// { dg-options "-Wunused" }
+
+
+#define UNUSED __attribute__ ((unused))
+
+template <class T>
+void f_int ()
+{
+  T t;                        // { dg-warning "unused variable" }
+
+  typedef T U;
+  U u;                        // { dg-warning "unused variable" }
+}
+
+template void f_int<int>();
+
+
+template <class T>
+void f_intptr ()
+{
+  T *t = 0;                   // { dg-warning "unused variable" }
+
+  typedef T U;
+  U *u = 0;                   // { dg-warning "unused variable" }
+}
+
+template void f_intptr<int>();
+
+
+template <class T>
+void f_var_unused ()
+{
+  // The variable is marked unused.
+  T t UNUSED;
+
+  typedef T U;
+  U u UNUSED;
+}
+
+template void f_var_unused<int>();
+
+
+template <class T>
+void f_var_type_unused ()
+{
+  // The variable's type is marked unused.
+  T* UNUSED t = new T;   // { dg-bogus "unused variable" "bug 79585" { xfail *-*-* } }
+
+  typedef T U;
+  U* UNUSED u = new U;   // { dg-bogus "unused variable" "bug 79585" { xfail *-*-* } }
+
+  typedef T UNUSED U;
+  U v = U ();   // { dg-bogus "unused variable" "bug 79585" }
+}
+
+template void f_var_type_unused<int>();
+
+
+struct A { int i; };
+
+template <class T>
+void f_A ()
+{
+  T t;                        // { dg-warning "unused variable" }
+
+  typedef T U;
+  U u;                        // { dg-warning "unused variable" }
+}
+
+template void f_A<A>();
+
+
+template <class T>
+void f_A_unused ()
+{
+  T t UNUSED;
+
+  typedef T U;
+  U u UNUSED;
+}
+
+template void f_A_unused<A>();
+
+
+struct B { B (); };
+
+template <class T>
+void f_B ()
+{
+  T t;
+
+  typedef T U;
+  U u;
+}
+
+template void f_B<B>();
+
+
+struct NonTrivialDtor { ~NonTrivialDtor (); };
+
+template <class T>
+void f_with_NonTrivialDtor ()
+{
+  // Expect no warnings when instantiated on a type with a non-trivial
+  // destructor.
+  T t;
+
+  typedef T U;
+  U u;
+}
+
+template void f_with_NonTrivialDtor<NonTrivialDtor>();
+
+
+struct D { NonTrivialDtor b; };
+
+template <class T>
+void f_D ()
+{
+  // Same as f_with_NonTrivialDtor but with a class that has a member
+  // with a non-trivial dtor.
+  T t;
+
+  typedef T U;
+  U u;
+}
+
+template void f_D<D>();
+
+
+struct UNUSED DeclaredUnused { };
+
+template <class T>
+void f_with_unused ()
+{
+  // Expect no warnings when instantiatiated on a type declared
+  // with attribute unused.
+  T t;
+
+  typedef T U;
+  U u;
+}
+
+template void f_with_unused<DeclaredUnused>();