Commit 056a3b12 by Mark Mitchell Committed by Mark Mitchell

* class.c (maybe_warn_about_overly_private_class): Reformat.

From-SVN: r22502
parent 3add5845
1998-09-20 Mark Mitchell <mark@markmitchell.com>
* class.c (maybe_warn_about_overly_private_class): Reformat.
1998-09-17 Andrew MacLeod <amacleod@cygnus.com> 1998-09-17 Andrew MacLeod <amacleod@cygnus.com>
* exception.cc (__cplus_type_matcher): realign some code. * exception.cc (__cplus_type_matcher): realign some code.
......
...@@ -1910,129 +1910,132 @@ static void ...@@ -1910,129 +1910,132 @@ static void
maybe_warn_about_overly_private_class (t) maybe_warn_about_overly_private_class (t)
tree t; tree t;
{ {
if (warn_ctor_dtor_privacy int has_member_fn = 0;
int has_nonprivate_method = 0;
tree fn;
if (!warn_ctor_dtor_privacy
/* If the class has friends, those entities might create and /* If the class has friends, those entities might create and
access instances, so we should not warn. */ access instances, so we should not warn. */
&& !(CLASSTYPE_FRIEND_CLASSES (t) || (CLASSTYPE_FRIEND_CLASSES (t)
|| DECL_FRIENDLIST (TYPE_MAIN_DECL (t))) || DECL_FRIENDLIST (TYPE_MAIN_DECL (t)))
/* We will have warned when the template was declared; there's /* We will have warned when the template was declared; there's
no need to warn on every instantiation. */ no need to warn on every instantiation. */
&& !CLASSTYPE_TEMPLATE_INSTANTIATION (t)) || CLASSTYPE_TEMPLATE_INSTANTIATION (t))
{ /* There's no reason to even consider warning about this
/* We only issue one warning, if more than one applies, because class. */
otherwise, on code like: return;
class A { /* We only issue one warning, if more than one applies, because
// Oops - forgot `public:' otherwise, on code like:
A();
A(const A&); class A {
~A(); // Oops - forgot `public:'
}; A();
A(const A&);
we warn several times about essentially the same problem. */ ~A();
};
int has_member_fn = 0;
int has_nonprivate_method = 0; we warn several times about essentially the same problem. */
tree fn;
/* Check to see if all (non-constructor, non-destructor) member
/* Check to see if all (non-constructor, non-destructor) member functions are private. (Since there are no friends or
functions are private. (Since there are no friends or non-private statics, we can't ever call any of the private member
non-private statics, we can't ever call any of the private functions.) */
member functions.) */ for (fn = TYPE_METHODS (t); fn; fn = TREE_CHAIN (fn))
for (fn = TYPE_METHODS (t); fn; fn = TREE_CHAIN (fn)) /* We're not interested in compiler-generated methods; they don't
/* We're not interested in compiler-generated methods; they provide any way to call private members. */
don't provide any way to call private members. */ if (!DECL_ARTIFICIAL (fn))
if (!DECL_ARTIFICIAL (fn)) {
if (!TREE_PRIVATE (fn))
{ {
if (!TREE_PRIVATE (fn)) if (DECL_STATIC_FUNCTION_P (fn))
{ /* A non-private static member function is just like a
if (DECL_STATIC_FUNCTION_P (fn)) friend; it can create and invoke private member
/* A non-private static member function is just like a functions, and be accessed without a class
friend; it can create and invoke private member instance. */
functions, and be accessed without a class return;
instance. */
return;
has_nonprivate_method = 1; has_nonprivate_method = 1;
break; break;
} }
else else
has_member_fn = 1; has_member_fn = 1;
} }
if (!has_nonprivate_method && has_member_fn) if (!has_nonprivate_method && has_member_fn)
{
int i;
tree binfos = BINFO_BASETYPES (TYPE_BINFO (t));
for (i = 0; i < CLASSTYPE_N_BASECLASSES (t); i++)
if (TREE_VIA_PUBLIC (TREE_VEC_ELT (binfos, i))
|| TREE_VIA_PROTECTED (TREE_VEC_ELT (binfos, i)))
{
has_nonprivate_method = 1;
break;
}
if (!has_nonprivate_method)
{ {
int i; cp_warning ("all member functions in class `%T' are private", t);
tree binfos = BINFO_BASETYPES (TYPE_BINFO (t)); return;
for (i = 0; i < CLASSTYPE_N_BASECLASSES (t); i++)
if (TREE_VIA_PUBLIC (TREE_VEC_ELT (binfos, i))
|| TREE_VIA_PROTECTED (TREE_VEC_ELT (binfos, i)))
{
has_nonprivate_method = 1;
break;
}
if (!has_nonprivate_method)
{
cp_warning ("all member functions in class `%T' are private", t);
return;
}
} }
}
/* Even if some of the member functions are non-private, the /* Even if some of the member functions are non-private, the class
class won't be useful for much if all the constructors or won't be useful for much if all the constructors or destructors
destructors are private: such an object can never be created are private: such an object can never be created or destroyed. */
or destroyed. */ if (TYPE_HAS_DESTRUCTOR (t))
if (TYPE_HAS_DESTRUCTOR (t)) {
{ tree dtor = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (t), 1);
tree dtor = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (t), 1);
if (TREE_PRIVATE (dtor)) if (TREE_PRIVATE (dtor))
{ {
cp_warning ("`%#T' only defines a private destructor and has no friends", cp_warning ("`%#T' only defines a private destructor and has no friends",
t); t);
return; return;
}
} }
}
if (TYPE_HAS_CONSTRUCTOR (t)) if (TYPE_HAS_CONSTRUCTOR (t))
{ {
int nonprivate_ctor = 0; int nonprivate_ctor = 0;
/* If a non-template class does not define a copy /* If a non-template class does not define a copy
constructor, one is defined for it, enabling it to avoid constructor, one is defined for it, enabling it to avoid
this warning. For a template class, this does not this warning. For a template class, this does not
happen, and so we would normally get a warning on: happen, and so we would normally get a warning on:
template <class T> class C { private: C(); }; template <class T> class C { private: C(); };
To avoid this asymmetry, we check TYPE_HAS_INIT_REF. */ To avoid this asymmetry, we check TYPE_HAS_INIT_REF. All
if (!TYPE_HAS_INIT_REF (t)) complete non-template or fully instantiated classes have this
nonprivate_ctor = 1; flag set. */
else if (!TYPE_HAS_INIT_REF (t))
for (fn = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (t), 0); nonprivate_ctor = 1;
fn; else
fn = OVL_NEXT (fn)) for (fn = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (t), 0);
fn;
fn = OVL_NEXT (fn))
{
tree ctor = OVL_CURRENT (fn);
/* 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 (ctor))
{ {
tree ctor = OVL_CURRENT (fn); nonprivate_ctor = 1;
/* Ideally, we wouldn't count copy constructors (or, in break;
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 (ctor))
{
nonprivate_ctor = 1;
break;
}
} }
}
if (nonprivate_ctor == 0) if (nonprivate_ctor == 0)
{ {
cp_warning ("`%#T' only defines private constructors and has no friends", cp_warning ("`%#T' only defines private constructors and has no friends",
t); t);
return; return;
}
} }
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment