-Wctor-dtor-privacy thinks it can see all the constructors in a class template, but inheriting constructors still look like a USING_DECL there, so we need to look for that.
Tested x86_64-pc-linux-gnu, applying to trunk and 8.
commit 4b974abbaaaeb214f52824d990d0966b3b80fc36 Author: Jason Merrill <ja...@redhat.com> Date: Mon Jun 11 17:26:34 2018 -0400 PR c++/85792 -Wctor-dtor-privacy and inherited constructor. * class.c (maybe_warn_about_overly_private_class): Handle inherited constructors. diff --git a/gcc/cp/class.c b/gcc/cp/class.c index ab68b9be42a..fbf39035e18 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -2034,6 +2034,7 @@ maybe_warn_about_overly_private_class (tree t) { int has_member_fn = 0; int has_nonprivate_method = 0; + bool nonprivate_ctor = false; if (!warn_ctor_dtor_privacy /* If the class has friends, those entities might create and @@ -2064,7 +2065,11 @@ maybe_warn_about_overly_private_class (tree t) non-private statics, we can't ever call any of the private member functions.) */ for (tree fn = TYPE_FIELDS (t); fn; fn = DECL_CHAIN (fn)) - if (!DECL_DECLARES_FUNCTION_P (fn)) + if (TREE_CODE (fn) == USING_DECL + && DECL_NAME (fn) == ctor_identifier + && !TREE_PRIVATE (fn)) + nonprivate_ctor = true; + else if (!DECL_DECLARES_FUNCTION_P (fn)) /* Not a function. */; else if (DECL_ARTIFICIAL (fn)) /* We're not interested in compiler-generated methods; they don't @@ -2126,7 +2131,6 @@ maybe_warn_about_overly_private_class (tree t) /* Implicitly generated constructors are always public. */ && !CLASSTYPE_LAZY_DEFAULT_CTOR (t)) { - bool nonprivate_ctor = false; tree copy_or_move = NULL_TREE; /* If a non-template class does not define a copy diff --git a/gcc/testsuite/g++.dg/warn/Wctor-dtor2.C b/gcc/testsuite/g++.dg/warn/Wctor-dtor2.C new file mode 100644 index 00000000000..48137851f05 --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Wctor-dtor2.C @@ -0,0 +1,11 @@ +// PR c++/85792 +// { dg-do compile { target c++11 } } +// { dg-additional-options -Wctor-dtor-privacy } + +template<typename T> struct A { }; + +template<typename T> struct B : A<T> { + using A<T>::A; + + B(const B&) { } +};