summaryrefslogtreecommitdiff
path: root/gcc/cp/class.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cp/class.c')
-rw-r--r--gcc/cp/class.c24
1 files changed, 15 insertions, 9 deletions
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;
}
}