diff options
Diffstat (limited to 'gcc/cp/class.c')
-rw-r--r-- | gcc/cp/class.c | 24 |
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; } } |