summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/c-family/ChangeLog6
-rw-r--r--gcc/c-family/c-common.c7
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/warn/Wunused-var-26.C147
4 files changed, 164 insertions, 1 deletions
diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog
index 0a7fef1d3ee..4afb4b8af6e 100644
--- a/gcc/c-family/ChangeLog
+++ b/gcc/c-family/ChangeLog
@@ -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
diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
index 885ea6d2d70..65ffd8cd7bd 100644
--- a/gcc/c-family/c-common.c
+++ b/gcc/c-family/c-common.c
@@ -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;
}
}
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index aa6ec43ebc0..4dbc7197779 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 00000000000..b3e020b6007
--- /dev/null
+++ b/gcc/testsuite/g++.dg/warn/Wunused-var-26.C
@@ -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>();