diff options
-rw-r--r-- | gcc/cp/ChangeLog | 3 | ||||
-rw-r--r-- | gcc/cp/class.c | 24 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/warn/ctor-dtor-privacy-3.C | 20 |
4 files changed, 42 insertions, 9 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index acf179b0c84..fef4c21871d 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,8 @@ 2017-07-17 Nathan Sidwell <nathan@acm.org> + * class.c (maybe_warn_about_overly_private_class): Ignore public + copy ctors. + * class.c (type_has_user_declared_move_constructor, type_has_user_declared_move_assign): Combine into ... (classtype_has_user_move_assign_or_move_ctor_p): ... this new function. diff --git a/gcc/cp/class.c b/gcc/cp/class.c index b2175864e52..0336ae5f143 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -2240,10 +2240,10 @@ maybe_warn_about_overly_private_class (tree t) /* Warn about classes that have private constructors and no friends. */ if (TYPE_HAS_USER_CONSTRUCTOR (t) /* Implicitly generated constructors are always public. */ - && (!CLASSTYPE_LAZY_DEFAULT_CTOR (t) - || !CLASSTYPE_LAZY_COPY_CTOR (t))) + && !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 constructor, one is defined for it, enabling it to avoid @@ -2260,13 +2260,15 @@ maybe_warn_about_overly_private_class (tree t) else for (ovl_iterator iter (CLASSTYPE_CONSTRUCTORS (t)); !nonprivate_ctor && iter; ++iter) - /* Ideally, we wouldn't count copy constructors (or, in - fact, any constructor that takes an argument of the class - type as a parameter) because such things cannot be used - to construct an instance of the class unless you already - have one. But, for now at least, we're more - generous. */ - if (! TREE_PRIVATE (*iter)) + if (TREE_PRIVATE (*iter)) + continue; + else if (copy_fn_p (*iter) || move_fn_p (*iter)) + /* Ideally, we wouldn't count any constructor that takes + an argument of the class type as a parameter, because + such things cannot be used to construct an instance of + the class unless you already have one. */ + copy_or_move = *iter; + else nonprivate_ctor = true; if (!nonprivate_ctor) @@ -2274,6 +2276,10 @@ maybe_warn_about_overly_private_class (tree t) warning (OPT_Wctor_dtor_privacy, "%q#T only defines private constructors and has no friends", t); + if (copy_or_move) + inform (DECL_SOURCE_LOCATION (copy_or_move), + "%q#D is public, but requires an existing %q#T object", + copy_or_move, t); return; } } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 5ff0141dde5..a0ca5143155 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2017-07-17 Nathan Sidwell <nathan@acm.org> + + * g++.dg/warn/ctor-dtor-privacy-3.C: New. + 2017-07-17 Bernd Edlinger <bernd.edlinger@hotmail.de> * lib/gcc-dg.exp: Increase expect's match buffer size. diff --git a/gcc/testsuite/g++.dg/warn/ctor-dtor-privacy-3.C b/gcc/testsuite/g++.dg/warn/ctor-dtor-privacy-3.C new file mode 100644 index 00000000000..93a42eac08d --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/ctor-dtor-privacy-3.C @@ -0,0 +1,20 @@ +// { dg-do compile { target c++11 } } +// { dg-additional-options "-Wctor-dtor-privacy" } + +class X // { dg-message "only defines private" } +{ +public: + X (X const &); // { dg-message "requires an existing" } +}; + +class Y // { dg-message "only defines private" } +{ +public: + Y (Y &&); // { dg-message "requires an existing" } +}; + +class Z +{ +public: + Z (int); +}; |