Commit aed7b2a6 by Mark Mitchell

cp-tree.h (lang_type): Add has_non_private_static_mem_fn.

	* cp-tree.h (lang_type): Add has_non_private_static_mem_fn.
	(CLASSTYPE_HAS_NON_PRIVATE_STATIC_MEM_FN): New macro, to access it.
	* class.c (maybe_class_too_private_p): New function.
	(finish_struct_methods): Use it.
	(finish_struct_1): Likewise.
	(finish_struct): Set CLASSTYPE_HAS_NON_PRIVATE_STATIC_MEM_FN if
	appropriate.

From-SVN: r22415
parent fd4de5ff
...@@ -100,6 +100,7 @@ static void modify_all_indirect_vtables PROTO((tree, int, int, tree, ...@@ -100,6 +100,7 @@ static void modify_all_indirect_vtables PROTO((tree, int, int, tree,
tree, tree)); tree, tree));
static void build_class_init_list PROTO((tree)); static void build_class_init_list PROTO((tree));
static int finish_base_struct PROTO((tree, struct base_info *)); static int finish_base_struct PROTO((tree, struct base_info *));
static int maybe_class_too_private_p PROTO((tree));
/* Way of stacking language names. */ /* Way of stacking language names. */
tree *current_lang_base, *current_lang_stack; tree *current_lang_base, *current_lang_stack;
...@@ -1897,6 +1898,32 @@ grow_method (fndecl, method_vec_ptr) ...@@ -1897,6 +1898,32 @@ grow_method (fndecl, method_vec_ptr)
} }
} }
/* Returns non-zero if T is the sort of class for which we should
check issue warnings like "all constructors are private". */
static int
maybe_class_too_private_p (t)
tree t;
{
if (!warn_ctor_dtor_privacy)
/* The user doesn't want to here these warnings. */
return 0;
if (CLASSTYPE_FRIEND_CLASSES (t)
|| DECL_FRIENDLIST (TYPE_MAIN_DECL (t)))
/* The class has friends. Maybe they can make use of the class,
even though it's very private. */
return 0;
if (CLASSTYPE_HAS_NON_PRIVATE_STATIC_MEM_FN (t))
/* The class has a non-private static member function. Such a
thing might be used, like a friend, to create instances of the
class. */
return 0;
return 1;
}
/* Warn about duplicate methods in fn_fields. Also compact method /* Warn about duplicate methods in fn_fields. Also compact method
lists so that lookup can be made faster. lists so that lookup can be made faster.
...@@ -2023,9 +2050,7 @@ finish_struct_methods (t, fn_fields, nonprivate_method) ...@@ -2023,9 +2050,7 @@ finish_struct_methods (t, fn_fields, nonprivate_method)
obstack_finish (&class_obstack); obstack_finish (&class_obstack);
CLASSTYPE_METHOD_VEC (t) = method_vec; CLASSTYPE_METHOD_VEC (t) = method_vec;
if (nonprivate_method == 0 if (nonprivate_method == 0 && maybe_class_too_private_p (t))
&& CLASSTYPE_FRIEND_CLASSES (t) == NULL_TREE
&& DECL_FRIENDLIST (TYPE_MAIN_DECL (t)) == NULL_TREE)
{ {
tree binfos = BINFO_BASETYPES (TYPE_BINFO (t)); tree binfos = BINFO_BASETYPES (TYPE_BINFO (t));
for (i = 0; i < n_baseclasses; i++) for (i = 0; i < n_baseclasses; i++)
...@@ -2035,8 +2060,7 @@ finish_struct_methods (t, fn_fields, nonprivate_method) ...@@ -2035,8 +2060,7 @@ finish_struct_methods (t, fn_fields, nonprivate_method)
nonprivate_method = 1; nonprivate_method = 1;
break; break;
} }
if (nonprivate_method == 0 if (nonprivate_method == 0)
&& warn_ctor_dtor_privacy)
cp_warning ("all member functions in class `%T' are private", t); cp_warning ("all member functions in class `%T' are private", t);
} }
...@@ -2049,10 +2073,7 @@ finish_struct_methods (t, fn_fields, nonprivate_method) ...@@ -2049,10 +2073,7 @@ finish_struct_methods (t, fn_fields, nonprivate_method)
/* Wild parse errors can cause this to happen. */ /* Wild parse errors can cause this to happen. */
if (dtor == NULL_TREE) if (dtor == NULL_TREE)
TYPE_HAS_DESTRUCTOR (t) = 0; TYPE_HAS_DESTRUCTOR (t) = 0;
else if (TREE_PRIVATE (dtor) else if (TREE_PRIVATE (dtor) && maybe_class_too_private_p (t))
&& CLASSTYPE_FRIEND_CLASSES (t) == NULL_TREE
&& DECL_FRIENDLIST (TYPE_MAIN_DECL (t)) == NULL_TREE
&& warn_ctor_dtor_privacy)
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);
} }
...@@ -3629,7 +3650,7 @@ finish_struct_1 (t, warn_anon) ...@@ -3629,7 +3650,7 @@ finish_struct_1 (t, warn_anon)
break; break;
} }
if (nonprivate_ctor == 0 && warn_ctor_dtor_privacy) if (nonprivate_ctor == 0 && maybe_class_too_private_p (t))
cp_warning ("`%#T' only defines private constructors and has no friends", cp_warning ("`%#T' only defines private constructors and has no friends",
t); t);
} }
...@@ -4208,6 +4229,12 @@ finish_struct (t, list_of_fieldlists, attributes, warn_anon) ...@@ -4208,6 +4229,12 @@ finish_struct (t, list_of_fieldlists, attributes, warn_anon)
TREE_PRIVATE (x) = access == access_private_node; TREE_PRIVATE (x) = access == access_private_node;
TREE_PROTECTED (x) = access == access_protected_node; TREE_PROTECTED (x) = access == access_protected_node;
if (!TREE_PRIVATE (x)
&& TREE_CODE (x) == FUNCTION_DECL
&& DECL_LANG_SPECIFIC (x)
&& DECL_STATIC_FUNCTION_P (x))
CLASSTYPE_HAS_NON_PRIVATE_STATIC_MEM_FN (t) = 1;
if (TREE_CODE (x) == TEMPLATE_DECL) if (TREE_CODE (x) == TEMPLATE_DECL)
{ {
TREE_PRIVATE (DECL_RESULT (x)) = TREE_PRIVATE (x); TREE_PRIVATE (DECL_RESULT (x)) = TREE_PRIVATE (x);
......
...@@ -621,11 +621,12 @@ struct lang_type ...@@ -621,11 +621,12 @@ struct lang_type
unsigned has_complex_assign_ref : 1; unsigned has_complex_assign_ref : 1;
unsigned has_abstract_assign_ref : 1; unsigned has_abstract_assign_ref : 1;
unsigned non_aggregate : 1; unsigned non_aggregate : 1;
unsigned has_non_private_static_mem_fn : 1;
/* The MIPS compiler gets it wrong if this struct also /* The MIPS compiler gets it wrong if this struct also
does not fill out to a multiple of 4 bytes. Add a does not fill out to a multiple of 4 bytes. Add a
member `dummy' with new bits if you go over the edge. */ member `dummy' with new bits if you go over the edge. */
unsigned dummy : 11; unsigned dummy : 10;
} type_flags; } type_flags;
int n_ancestors; int n_ancestors;
...@@ -1451,6 +1452,10 @@ extern int flag_new_for_scope; ...@@ -1451,6 +1452,10 @@ extern int flag_new_for_scope;
#define TYPE_NON_AGGREGATE_CLASS(NODE) \ #define TYPE_NON_AGGREGATE_CLASS(NODE) \
(IS_AGGR_TYPE (NODE) && CLASSTYPE_NON_AGGREGATE (NODE)) (IS_AGGR_TYPE (NODE) && CLASSTYPE_NON_AGGREGATE (NODE))
/* Nonzero if NODE has a non-private static member function. */
#define CLASSTYPE_HAS_NON_PRIVATE_STATIC_MEM_FN(NODE) \
(TYPE_LANG_SPECIFIC (NODE)->type_flags.has_non_private_static_mem_fn)
/* Nonzero if there is a user-defined X::op=(x&) for this class. */ /* Nonzero if there is a user-defined X::op=(x&) for this class. */
#define TYPE_HAS_REAL_ASSIGN_REF(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.has_real_assign_ref) #define TYPE_HAS_REAL_ASSIGN_REF(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.has_real_assign_ref)
#define TYPE_HAS_COMPLEX_ASSIGN_REF(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.has_complex_assign_ref) #define TYPE_HAS_COMPLEX_ASSIGN_REF(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.has_complex_assign_ref)
......
...@@ -24,7 +24,7 @@ private: ...@@ -24,7 +24,7 @@ private:
void operator=( const singleton& rhs ); void operator=( const singleton& rhs );
int initialized; int initialized;
static int counter; static int counter;
}; // gets bogus error - class is not useless XFAIL *-*-* };
int singleton::counter; int singleton::counter;
......
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