Commit d6479fe7 by Mark Mitchell Committed by Mark Mitchell

cp-tree.h (flag_access_control): Declare.

	* cp-tree.h (flag_access_control): Declare.
	(TREE_VIA_PPUBLIC): Document.
	(DECL_NONSTATIC_MEMBER_P): New macro.
	(enforce_access): Return an indication of whether or not access
	was permitted.
	(build_self_reference): Change prototype.
	(compute_access): Replace with ...
	(accessible_p): New function.
	(dfs_walk): Change prototype.
	(dfs_unmark): Likewise.
	(markedp): Likewise.
	* call.c (enforce_access): Use accessible_p.
	* class.c (build_self_reference): Insert the declaration into the
	list of members for this type, and make it public.
	* decl.c (xref_basetypes): Avoid ill-timed recursion.
	* init.c (build_offset_ref): Use lookup_member, not three separate
	name-lookups.  Call enforce_access rather than checking for
	illegal accesses here.
	(resolve_offset_ref): Likewise.
	* lex.c (do_identifier): Likewise.
	* method.c (hack_identifier): Likewise.
	* parse.y (self_reference): Remove.
	(opt_component_decl_list): Don't use it.
	* parse.c: Regenerated.
	* pt.c (print_candidates): Generalize to handle lists of
	overloaded functions.
	(instantiate_class_template): Don't rely on TREE_VIA_PRIVATE; it's
	not set.
	(get_template_base): Use new calling convention for dfs_walk.
	* search.c: Include varray.h.  Add prototypes.
	(dfs_walk): Accept a data pointer to pass to the work functions.
	All callers changed.  All work functions changed.
	(breadth_first_search): Rename to bfs_walk, and make consistent
	with dfs_walk.
	(dfs_walk_real): New function.
	(canonical_binfo): New function.
	(context_for_name_lookup): Likewise.
	(shared_marked_p): Likewise.
	(shared_unmarked_p): Likewise.
	(lokup_field_queue_p): Likewise.
	(lookup_field_r): Generalize to handle both functions and fields.
	(lookup_field): Just call lookup_member.
	(lookup_fnfields): Likewise.
	(lookup_member): Move body of lookup_field here and generalize.
	(dfs_accessible_queue_p): Likewise.
	(dfs_accessible_p): Likewise.
	(dfs_access_in_type): Likewise.
	(access_in_type): Likewise.
	(compute_access): Remove, and replace with ...
	(accessible_p): New function.
	(vbase_types): Remove.
	(vbase_decl_ptr_intermediate): Likewise.
	(vbase_decl_ptr): Likewise.
	(vbase_init_result): Likewise.
	(closed_envelopes): Likewise.
	(bvtable): Likewise.

From-SVN: r25661
parent 8f96c7ac
1999-03-09 Mark Mitchell <mark@markmitchell.com>
* cp-tree.h (flag_access_control): Declare.
(TREE_VIA_PPUBLIC): Document.
(DECL_NONSTATIC_MEMBER_P): New macro.
(enforce_access): Return an indication of whether or not access
was permitted.
(build_self_reference): Change prototype.
(compute_access): Replace with ...
(accessible_p): New function.
(dfs_walk): Change prototype.
(dfs_unmark): Likewise.
(markedp): Likewise.
* call.c (enforce_access): Use accessible_p.
* class.c (build_self_reference): Insert the declaration into the
list of members for this type, and make it public.
* decl.c (xref_basetypes): Avoid ill-timed recursion.
* init.c (build_offset_ref): Use lookup_member, not three separate
name-lookups. Call enforce_access rather than checking for
illegal accesses here.
(resolve_offset_ref): Likewise.
* lex.c (do_identifier): Likewise.
* method.c (hack_identifier): Likewise.
* parse.y (self_reference): Remove.
(opt_component_decl_list): Don't use it.
* parse.c: Regenerated.
* pt.c (print_candidates): Generalize to handle lists of
overloaded functions.
(instantiate_class_template): Don't rely on TREE_VIA_PRIVATE; it's
not set.
(get_template_base): Use new calling convention for dfs_walk.
* search.c: Include varray.h. Add prototypes.
(dfs_walk): Accept a data pointer to pass to the work functions.
All callers changed. All work functions changed.
(breadth_first_search): Rename to bfs_walk, and make consistent
with dfs_walk.
(dfs_walk_real): New function.
(canonical_binfo): New function.
(context_for_name_lookup): Likewise.
(shared_marked_p): Likewise.
(shared_unmarked_p): Likewise.
(lokup_field_queue_p): Likewise.
(lookup_field_r): Generalize to handle both functions and fields.
(lookup_field): Just call lookup_member.
(lookup_fnfields): Likewise.
(lookup_member): Move body of lookup_field here and generalize.
(dfs_accessible_queue_p): Likewise.
(dfs_accessible_p): Likewise.
(dfs_access_in_type): Likewise.
(access_in_type): Likewise.
(compute_access): Remove, and replace with ...
(accessible_p): New function.
(vbase_types): Remove.
(vbase_decl_ptr_intermediate): Likewise.
(vbase_decl_ptr): Likewise.
(vbase_init_result): Likewise.
(closed_envelopes): Likewise.
(bvtable): Likewise.
1999-03-09 Jason Merrill <jason@yorick.cygnus.com> 1999-03-09 Jason Merrill <jason@yorick.cygnus.com>
* call.c (add_function_candidate): Check for proper number of args * call.c (add_function_candidate): Check for proper number of args
......
...@@ -3029,28 +3029,30 @@ build_op_delete_call (code, addr, size, flags, placement) ...@@ -3029,28 +3029,30 @@ build_op_delete_call (code, addr, size, flags, placement)
} }
/* If the current scope isn't allowed to access DECL along /* If the current scope isn't allowed to access DECL along
BASETYPE_PATH, give an error. */ BASETYPE_PATH, give an error. The most derived class in
BASETYPE_PATH is the one used to qualify DECL. */
void int
enforce_access (basetype_path, decl) enforce_access (basetype_path, decl)
tree basetype_path, decl; tree basetype_path;
tree decl;
{ {
tree access = compute_access (basetype_path, decl); int accessible;
if (access == access_private_node) accessible = accessible_p (basetype_path, decl);
{ if (!accessible)
cp_error_at ("`%+#D' is %s", decl,
TREE_PRIVATE (decl) ? "private"
: "from private base class");
error ("within this context");
}
else if (access == access_protected_node)
{ {
cp_error_at ("`%+#D' %s", decl, if (TREE_PRIVATE (decl))
TREE_PROTECTED (decl) ? "is protected" cp_error_at ("`%+#D' is private", decl);
: "has protected accessibility"); else if (TREE_PROTECTED (decl))
error ("within this context"); cp_error_at ("`%+#D' is protected", decl);
else
cp_error_at ("`%+#D' is inaccessible", decl);
cp_error ("within this context");
return 0;
} }
return 1;
} }
/* Perform the conversions in CONVS on the expression EXPR. */ /* Perform the conversions in CONVS on the expression EXPR. */
......
...@@ -1440,7 +1440,6 @@ alter_access (t, binfo, fdecl, access) ...@@ -1440,7 +1440,6 @@ alter_access (t, binfo, fdecl, access)
else else
{ {
enforce_access (binfo, fdecl); enforce_access (binfo, fdecl);
DECL_ACCESS (fdecl) = tree_cons (t, access, DECL_ACCESS (fdecl)); DECL_ACCESS (fdecl) = tree_cons (t, access, DECL_ACCESS (fdecl));
return 1; return 1;
} }
...@@ -5548,18 +5547,24 @@ maybe_push_cache_obstack () ...@@ -5548,18 +5547,24 @@ maybe_push_cache_obstack ()
into the scope of the class itself. For purposes of access checking, into the scope of the class itself. For purposes of access checking,
the inserted class name is treated as if it were a public member name. */ the inserted class name is treated as if it were a public member name. */
tree void
build_self_reference () build_self_reference ()
{ {
tree name = constructor_name (current_class_type); tree name = constructor_name (current_class_type);
tree value = build_lang_decl (TYPE_DECL, name, current_class_type); tree value = build_lang_decl (TYPE_DECL, name, current_class_type);
tree saved_cas;
DECL_NONLOCAL (value) = 1; DECL_NONLOCAL (value) = 1;
DECL_CONTEXT (value) = current_class_type; DECL_CONTEXT (value) = current_class_type;
DECL_CLASS_CONTEXT (value) = current_class_type; DECL_CLASS_CONTEXT (value) = current_class_type;
DECL_ARTIFICIAL (value) = 1; DECL_ARTIFICIAL (value) = 1;
pushdecl_class_level (value); pushdecl_class_level (value);
return value;
saved_cas = current_access_specifier;
current_access_specifier = access_public_node;
finish_member_declaration (value);
current_access_specifier = saved_cas;
} }
/* Returns 1 if TYPE contains only padding bytes. */ /* Returns 1 if TYPE contains only padding bytes. */
......
...@@ -549,6 +549,11 @@ extern int flag_vtable_gc; ...@@ -549,6 +549,11 @@ extern int flag_vtable_gc;
/* Nonzero means make the default pedwarns warnings instead of errors. /* Nonzero means make the default pedwarns warnings instead of errors.
The value of this flag is ignored if -pedantic is specified. */ The value of this flag is ignored if -pedantic is specified. */
extern int flag_permissive; extern int flag_permissive;
/* Nonzero if we want to obey access control semantics. */
extern int flag_access_control;
/* C++ language-specific tree codes. */ /* C++ language-specific tree codes. */
#define DEFTREECODE(SYM, NAME, TYPE, LENGTH) SYM, #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) SYM,
...@@ -1086,11 +1091,16 @@ struct lang_type ...@@ -1086,11 +1091,16 @@ struct lang_type
gcc/tree.h. In particular if D is derived from B then the BINFO gcc/tree.h. In particular if D is derived from B then the BINFO
for B (in D) will have a BINFO_INHERITANCE_CHAIN pointing to for B (in D) will have a BINFO_INHERITANCE_CHAIN pointing to
D. In tree.h, this pointer is described as pointing in other D. In tree.h, this pointer is described as pointing in other
direction. direction. There is a different BINFO for each path to a virtual
base; BINFOs for virtual bases are not shared. In addition, shared
versions of each of the virtual class BINFOs are stored in
CLASSTYPE_VBASECLASSES.
After a call to get_vbase_types, the vbases are chained together in We use TREE_VIA_PROTECTED and TREE_VIA_PUBLIC, but private
depth-first order via TREE_CHAIN. Other than that, TREE_CHAIN is inheritance is indicated by the absence of the other two flags, not
unused. */ by TREE_VIAR_PRIVATE, which is unused.
The TREE_CHAIN is for scratch space in search.c. */
/* Nonzero means marked by DFS or BFS search, including searches /* Nonzero means marked by DFS or BFS search, including searches
by `get_binfo' and `get_base_distance'. */ by `get_binfo' and `get_base_distance'. */
...@@ -1299,6 +1309,12 @@ struct lang_decl ...@@ -1299,6 +1309,12 @@ struct lang_decl
has `this' as volatile X *const. */ has `this' as volatile X *const. */
#define DECL_VOLATILE_MEMFUNC_P(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.volatile_memfunc) #define DECL_VOLATILE_MEMFUNC_P(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.volatile_memfunc)
/* Nonzero for a DECL means that this member is a non-static member. */
#define DECL_NONSTATIC_MEMBER_P(NODE) \
((TREE_CODE (NODE) == FUNCTION_DECL \
&& DECL_NONSTATIC_MEMBER_FUNCTION_P (NODE)) \
|| TREE_CODE (NODE) == FIELD_DECL)
/* Nonzero for _DECL means that this member object type /* Nonzero for _DECL means that this member object type
is mutable. */ is mutable. */
#define DECL_MUTABLE_P(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.mutable_flag) #define DECL_MUTABLE_P(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.mutable_flag)
...@@ -2653,7 +2669,7 @@ extern tree build_op_new_call PROTO((enum tree_code, tree, tree, int)); ...@@ -2653,7 +2669,7 @@ extern tree build_op_new_call PROTO((enum tree_code, tree, tree, int));
extern tree build_op_delete_call PROTO((enum tree_code, tree, tree, int, tree)); extern tree build_op_delete_call PROTO((enum tree_code, tree, tree, int, tree));
extern int can_convert PROTO((tree, tree)); extern int can_convert PROTO((tree, tree));
extern int can_convert_arg PROTO((tree, tree, tree)); extern int can_convert_arg PROTO((tree, tree, tree));
extern void enforce_access PROTO((tree, tree)); extern int enforce_access PROTO((tree, tree));
extern tree convert_default_arg PROTO((tree, tree, tree)); extern tree convert_default_arg PROTO((tree, tree, tree));
extern tree convert_arg_to_ellipsis PROTO((tree)); extern tree convert_arg_to_ellipsis PROTO((tree));
...@@ -2680,7 +2696,7 @@ extern tree instantiate_type PROTO((tree, tree, int)); ...@@ -2680,7 +2696,7 @@ extern tree instantiate_type PROTO((tree, tree, int));
extern void print_class_statistics PROTO((void)); extern void print_class_statistics PROTO((void));
extern void maybe_push_cache_obstack PROTO((void)); extern void maybe_push_cache_obstack PROTO((void));
extern unsigned HOST_WIDE_INT skip_rtti_stuff PROTO((tree *)); extern unsigned HOST_WIDE_INT skip_rtti_stuff PROTO((tree *));
extern tree build_self_reference PROTO((void)); extern void build_self_reference PROTO((void));
extern void warn_hidden PROTO((tree)); extern void warn_hidden PROTO((tree));
extern tree get_enclosing_class PROTO((tree)); extern tree get_enclosing_class PROTO((tree));
int is_base_of_enclosing_class PROTO((tree, tree)); int is_base_of_enclosing_class PROTO((tree, tree));
...@@ -3128,7 +3144,7 @@ extern int types_overlap_p PROTO((tree, tree)); ...@@ -3128,7 +3144,7 @@ extern int types_overlap_p PROTO((tree, tree));
extern tree get_vbase PROTO((tree, tree)); extern tree get_vbase PROTO((tree, tree));
extern tree get_binfo PROTO((tree, tree, int)); extern tree get_binfo PROTO((tree, tree, int));
extern int get_base_distance PROTO((tree, tree, int, tree *)); extern int get_base_distance PROTO((tree, tree, int, tree *));
extern tree compute_access PROTO((tree, tree)); extern int accessible_p PROTO((tree, tree));
extern tree lookup_field PROTO((tree, tree, int, int)); extern tree lookup_field PROTO((tree, tree, int, int));
extern tree lookup_nested_field PROTO((tree, int)); extern tree lookup_nested_field PROTO((tree, int));
extern int lookup_fnfields_1 PROTO((tree, tree)); extern int lookup_fnfields_1 PROTO((tree, tree));
...@@ -3153,9 +3169,12 @@ extern void reinit_search_statistics PROTO((void)); ...@@ -3153,9 +3169,12 @@ extern void reinit_search_statistics PROTO((void));
extern tree current_scope PROTO((void)); extern tree current_scope PROTO((void));
extern tree lookup_conversions PROTO((tree)); extern tree lookup_conversions PROTO((tree));
extern tree binfo_for_vtable PROTO((tree)); extern tree binfo_for_vtable PROTO((tree));
extern void dfs_walk PROTO((tree, void (*) (tree), int (*) (tree))); extern tree dfs_walk PROTO((tree,
extern void dfs_unmark PROTO((tree)); tree (*)(tree, void *),
extern int markedp PROTO((tree)); tree (*) (tree, void *),
void *));
extern tree dfs_unmark PROTO((tree, void *));
extern tree markedp PROTO((tree, void *));
/* in semantics.c */ /* in semantics.c */
extern void finish_expr_stmt PROTO((tree)); extern void finish_expr_stmt PROTO((tree));
......
...@@ -12383,6 +12383,8 @@ xref_basetypes (code_type_node, name, ref, binfo) ...@@ -12383,6 +12383,8 @@ xref_basetypes (code_type_node, name, ref, binfo)
/* In the declaration `A : X, Y, ... Z' we mark all the types /* In the declaration `A : X, Y, ... Z' we mark all the types
(A, X, Y, ..., Z) so we can check for duplicates. */ (A, X, Y, ..., Z) so we can check for duplicates. */
tree binfos; tree binfos;
tree base;
int i, len; int i, len;
enum tag_types tag_code = (enum tag_types) TREE_INT_CST_LOW (code_type_node); enum tag_types tag_code = (enum tag_types) TREE_INT_CST_LOW (code_type_node);
...@@ -12395,6 +12397,13 @@ xref_basetypes (code_type_node, name, ref, binfo) ...@@ -12395,6 +12397,13 @@ xref_basetypes (code_type_node, name, ref, binfo)
len = list_length (binfo); len = list_length (binfo);
push_obstacks (TYPE_OBSTACK (ref), TYPE_OBSTACK (ref)); push_obstacks (TYPE_OBSTACK (ref), TYPE_OBSTACK (ref));
/* First, make sure that any templates in base-classes are
instantiated. This ensures that if we call ourselves recursively
we do not get confused about which classes are marked and which
are not. */
for (base = binfo; base; base = TREE_CHAIN (base))
complete_type (TREE_VALUE (base));
SET_CLASSTYPE_MARKED (ref); SET_CLASSTYPE_MARKED (ref);
BINFO_BASETYPES (TYPE_BINFO (ref)) = binfos = make_tree_vec (len); BINFO_BASETYPES (TYPE_BINFO (ref)) = binfos = make_tree_vec (len);
...@@ -12433,16 +12442,14 @@ xref_basetypes (code_type_node, name, ref, binfo) ...@@ -12433,16 +12442,14 @@ xref_basetypes (code_type_node, name, ref, binfo)
GNU_xref_hier (name, basetype, via_public, via_virtual, 0); GNU_xref_hier (name, basetype, via_public, via_virtual, 0);
#if 1
/* This code replaces similar code in layout_basetypes. /* This code replaces similar code in layout_basetypes.
We put the complete_type first for implicit `typename'. */ We put the complete_type first for implicit `typename'. */
if (TYPE_SIZE (complete_type (basetype)) == NULL_TREE if (TYPE_SIZE (basetype) == NULL_TREE
&& ! (current_template_parms && uses_template_parms (basetype))) && ! (current_template_parms && uses_template_parms (basetype)))
{ {
cp_error ("base class `%T' has incomplete type", basetype); cp_error ("base class `%T' has incomplete type", basetype);
continue; continue;
} }
#endif
else else
{ {
if (CLASSTYPE_MARKED (basetype)) if (CLASSTYPE_MARKED (basetype))
......
...@@ -1490,7 +1490,8 @@ tree ...@@ -1490,7 +1490,8 @@ tree
build_offset_ref (type, name) build_offset_ref (type, name)
tree type, name; tree type, name;
{ {
tree decl, fnfields, fields, t = error_mark_node; tree decl, t = error_mark_node;
tree member;
tree basebinfo = NULL_TREE; tree basebinfo = NULL_TREE;
tree orig_name = name; tree orig_name = name;
...@@ -1558,17 +1559,17 @@ build_offset_ref (type, name) ...@@ -1558,17 +1559,17 @@ build_offset_ref (type, name)
decl = maybe_dummy_object (type, &basebinfo); decl = maybe_dummy_object (type, &basebinfo);
fnfields = lookup_fnfields (basebinfo, name, 1); member = lookup_member (basebinfo, name, 1, 0);
fields = lookup_field (basebinfo, name, 0, 0);
if (fields == error_mark_node || fnfields == error_mark_node) if (member == error_mark_node)
return error_mark_node; return error_mark_node;
/* A lot of this logic is now handled in lookup_field and /* A lot of this logic is now handled in lookup_field and
lookup_fnfield. */ lookup_fnfield. */
if (fnfields) if (member && TREE_CODE (member) == TREE_LIST)
{ {
/* Go from the TREE_BASELINK to the member function info. */ /* Go from the TREE_BASELINK to the member function info. */
tree fnfields = member;
t = TREE_VALUE (fnfields); t = TREE_VALUE (fnfields);
if (TREE_CODE (orig_name) == TEMPLATE_ID_EXPR) if (TREE_CODE (orig_name) == TEMPLATE_ID_EXPR)
...@@ -1596,26 +1597,13 @@ build_offset_ref (type, name) ...@@ -1596,26 +1597,13 @@ build_offset_ref (type, name)
if (!really_overloaded_fn (t)) if (!really_overloaded_fn (t))
{ {
tree access;
/* Get rid of a potential OVERLOAD around it */ /* Get rid of a potential OVERLOAD around it */
t = OVL_CURRENT (t); t = OVL_CURRENT (t);
/* unique functions are handled easily. */ /* unique functions are handled easily. */
basebinfo = TREE_PURPOSE (fnfields); basebinfo = TREE_PURPOSE (fnfields);
access = compute_access (basebinfo, t); if (!enforce_access (basebinfo, t))
if (access == access_protected_node) return error_mark_node;
{
cp_error_at ("member function `%#D' is protected", t);
error ("in this context");
return error_mark_node;
}
if (access == access_private_node)
{
cp_error_at ("member function `%#D' is private", t);
error ("in this context");
return error_mark_node;
}
mark_used (t); mark_used (t);
if (DECL_STATIC_FUNCTION_P (t)) if (DECL_STATIC_FUNCTION_P (t))
return t; return t;
...@@ -1638,14 +1626,7 @@ build_offset_ref (type, name) ...@@ -1638,14 +1626,7 @@ build_offset_ref (type, name)
return t; return t;
} }
/* Now that we know we are looking for a field, see if we t = member;
have access to that field. Lookup_field will give us the
error message. */
t = lookup_field (basebinfo, name, 1, 0);
if (t == error_mark_node)
return error_mark_node;
if (t == NULL_TREE) if (t == NULL_TREE)
{ {
...@@ -1754,7 +1735,6 @@ resolve_offset_ref (exp) ...@@ -1754,7 +1735,6 @@ resolve_offset_ref (exp)
&& (base == current_class_ref || is_dummy_object (base))) && (base == current_class_ref || is_dummy_object (base)))
{ {
tree basetype_path; tree basetype_path;
tree access;
tree expr; tree expr;
if (TREE_CODE (exp) == OFFSET_REF && TREE_CODE (type) == OFFSET_TYPE) if (TREE_CODE (exp) == OFFSET_REF && TREE_CODE (type) == OFFSET_TYPE)
...@@ -1771,19 +1751,9 @@ resolve_offset_ref (exp) ...@@ -1771,19 +1751,9 @@ resolve_offset_ref (exp)
} }
/* Kludge: we need to use basetype_path now, because /* Kludge: we need to use basetype_path now, because
convert_pointer_to will bash it. */ convert_pointer_to will bash it. */
access = compute_access (basetype_path, member); enforce_access (basetype_path, member);
addr = convert_pointer_to (basetype, base); addr = convert_pointer_to (basetype, base);
/* Issue errors if there was an access violation. */
if (access != access_public_node)
{
cp_error_at ("member `%D' is %s",
access == access_private_node
? "private" : "protected",
member);
cp_error ("in this context");
}
/* Even in the case of illegal access, we form the /* Even in the case of illegal access, we form the
COMPONENT_REF; that will allow better error recovery than COMPONENT_REF; that will allow better error recovery than
just feeding back error_mark_node. */ just feeding back error_mark_node. */
......
...@@ -3043,14 +3043,9 @@ do_identifier (token, parsing, args) ...@@ -3043,14 +3043,9 @@ do_identifier (token, parsing, args)
/* TREE_USED is set in `hack_identifier'. */ /* TREE_USED is set in `hack_identifier'. */
if (TREE_CODE (id) == CONST_DECL) if (TREE_CODE (id) == CONST_DECL)
{ {
/* Check access. */
if (IDENTIFIER_CLASS_VALUE (token) == id) if (IDENTIFIER_CLASS_VALUE (token) == id)
{ enforce_access (current_class_type, id);
/* Check access. */
tree access = compute_access (TYPE_BINFO (current_class_type), id);
if (access == access_private_node)
cp_error ("enum `%D' is private", id);
/* protected is OK, since it's an enum of `this'. */
}
if (!processing_template_decl || DECL_TEMPLATE_PARM_P (id)) if (!processing_template_decl || DECL_TEMPLATE_PARM_P (id))
id = DECL_INITIAL (id); id = DECL_INITIAL (id);
} }
......
...@@ -1994,29 +1994,15 @@ hack_identifier (value, name) ...@@ -1994,29 +1994,15 @@ hack_identifier (value, name)
if (DECL_LANG_SPECIFIC (value) if (DECL_LANG_SPECIFIC (value)
&& DECL_CLASS_CONTEXT (value) != current_class_type) && DECL_CLASS_CONTEXT (value) != current_class_type)
{ {
tree path, access; tree path;
register tree context register tree context
= (TREE_CODE (value) == FUNCTION_DECL && DECL_VIRTUAL_P (value)) = (TREE_CODE (value) == FUNCTION_DECL && DECL_VIRTUAL_P (value))
? DECL_CLASS_CONTEXT (value) ? DECL_CLASS_CONTEXT (value)
: DECL_CONTEXT (value); : DECL_CONTEXT (value);
get_base_distance (context, current_class_type, 0, &path); get_base_distance (context, current_class_type, 0, &path);
if (path) if (path && !enforce_access (current_class_type, value))
{ return error_mark_node;
access = compute_access (path, value);
if (access != access_public_node)
{
if (TREE_CODE (value) == VAR_DECL)
error ("static member `%s' is %s",
IDENTIFIER_POINTER (name),
TREE_PRIVATE (value) ? "private"
: "from a private base class");
else
error ("enum `%s' is from private base class",
IDENTIFIER_POINTER (name));
return error_mark_node;
}
}
} }
} }
else if (TREE_CODE (value) == TREE_LIST && TREE_NONLOCAL_FLAG (value)) else if (TREE_CODE (value) == TREE_LIST && TREE_NONLOCAL_FLAG (value))
......
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -2388,16 +2388,8 @@ left_curly: ...@@ -2388,16 +2388,8 @@ left_curly:
{ $<ttype>0 = begin_class_definition ($<ttype>0); } { $<ttype>0 = begin_class_definition ($<ttype>0); }
; ;
self_reference:
/* empty */
{
finish_member_declaration (build_self_reference ());
}
;
opt.component_decl_list: opt.component_decl_list:
self_reference | component_decl_list
| self_reference component_decl_list
| opt.component_decl_list access_specifier component_decl_list | opt.component_decl_list access_specifier component_decl_list
| opt.component_decl_list access_specifier | opt.component_decl_list access_specifier
; ;
......
...@@ -900,7 +900,10 @@ print_candidates (fns) ...@@ -900,7 +900,10 @@ print_candidates (fns)
for (fn = fns; fn != NULL_TREE; fn = TREE_CHAIN (fn)) for (fn = fns; fn != NULL_TREE; fn = TREE_CHAIN (fn))
{ {
cp_error_at ("%s %+#D", str, TREE_VALUE (fn)); tree f;
for (f = TREE_VALUE (fn); f; f = OVL_NEXT (f))
cp_error_at ("%s %+#D", str, OVL_CURRENT (f));
str = " "; str = " ";
} }
} }
...@@ -4807,7 +4810,7 @@ instantiate_class_template (type) ...@@ -4807,7 +4810,7 @@ instantiate_class_template (type)
access = access_public_virtual_node; access = access_public_virtual_node;
else if (TREE_VIA_PROTECTED (pbase)) else if (TREE_VIA_PROTECTED (pbase))
access = access_protected_virtual_node; access = access_protected_virtual_node;
else if (TREE_VIA_PRIVATE (pbase)) else
access = access_private_virtual_node; access = access_private_virtual_node;
} }
else else
...@@ -4816,7 +4819,7 @@ instantiate_class_template (type) ...@@ -4816,7 +4819,7 @@ instantiate_class_template (type)
access = access_public_node; access = access_public_node;
else if (TREE_VIA_PROTECTED (pbase)) else if (TREE_VIA_PROTECTED (pbase))
access = access_protected_node; access = access_protected_node;
else if (TREE_VIA_PRIVATE (pbase)) else
access = access_private_node; access = access_private_node;
} }
...@@ -7840,7 +7843,7 @@ get_template_base (tparms, targs, parm, arg) ...@@ -7840,7 +7843,7 @@ get_template_base (tparms, targs, parm, arg)
/* Since get_template_base_recursive marks the bases classes, we /* Since get_template_base_recursive marks the bases classes, we
must unmark them here. */ must unmark them here. */
dfs_walk (arg_binfo, dfs_unmark, markedp); dfs_walk (arg_binfo, dfs_unmark, markedp, 0);
return rval; return rval;
} }
......
...@@ -3,8 +3,8 @@ ...@@ -3,8 +3,8 @@
extern "C" void printf (char *, ...); extern "C" void printf (char *, ...);
class A { class A {
int i; int i; // ERROR - private
int j; int j; // ERROR - private
public: public:
int h; int h;
A() { i=10; j=20; } A() { i=10; j=20; }
......
...@@ -151,8 +151,8 @@ struct __streambuf { ...@@ -151,8 +151,8 @@ struct __streambuf {
char* _gptr; char* _gptr;
char* _egptr; char* _egptr;
char* _eback; char* _eback;
char* _pbase; char* _pbase; // ERROR - inacessible
char* _pptr; char* _pptr; // ERROR - inacessible
char* _epptr; char* _epptr;
char* _base; char* _base;
char* _ebuf; char* _ebuf;
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
// GROUPS passed enums // GROUPS passed enums
class X { class X {
private: private:
enum E1 {a1, b1}; enum E1 {a1, b1}; // ERROR - private
public: public:
enum E2 {a2, b2}; enum E2 {a2, b2};
}; };
...@@ -12,5 +12,5 @@ void h(X* p) { ...@@ -12,5 +12,5 @@ void h(X* p) {
int x2 = X::a2; int x2 = X::a2;
X::E1 e1; X::E1 e1;
int x1 = X::a1; // Should be rejected, and is.// ERROR - .* int x1 = X::a1; // ERROR - within this context
} }
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
// GROUPS passed visibility // GROUPS passed visibility
class foo { class foo {
protected: protected:
int i; int i; // ERROR - protected
}; };
class bar : public foo { class bar : public foo {
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
class bottom class bottom
{ {
public: public:
int b; int b; // ERROR - private
}; };
class middle : private bottom class middle : private bottom
{ {
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
class foo class foo
{ {
public: public:
static int y; static int y; // ERROR - private
}; };
class foo1 : private foo class foo1 : private foo
{ }; { };
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
struct A { struct A {
protected: protected:
int i; int i; // ERROR - private
int f (); // ERROR - int f (); // ERROR -
}; };
......
...@@ -16,24 +16,24 @@ public: ...@@ -16,24 +16,24 @@ public:
int PUB_A; int PUB_A;
protected: protected:
union { union {
long B; long B; // ERROR - protected
void *pY; void *pY; // ERROR - protected
} ; } ;
union Y { union Y {
long B; long B;
void *pY; void *pY;
} PRT; } PRT; // ERROR - protected
int PRT_A; int PRT_A; // ERROR - protected
private: private:
union { union {
long C; long C; // ERROR - private
void *pZ; void *pZ; // ERROR - private
}; };
union Z { union Z {
long C; long C;
void *pZ; void *pZ;
} PRV; } PRV; // ERROR - private
int PRV_A; int PRV_A; // ERROR - private
}; };
struct Bar : public Foo { struct Bar : public Foo {
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
class X { class X {
private: private:
enum E1 {a1, b1}; enum E1 {a1, b1}; // ERROR - private
public: public:
enum E2 {a2, b2}; enum E2 {a2, b2};
}; };
......
...@@ -10,9 +10,9 @@ class A { ...@@ -10,9 +10,9 @@ class A {
public: public:
int x; int x;
private: private:
int y; int y; // ERROR - private
union { union {
int z; int z; // ERROR - private
}; };
}; };
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
// Subject: member access rule bug // Subject: member access rule bug
// Message-ID: <9306300528.AA17185@coda.mel.dit.CSIRO.AU> // Message-ID: <9306300528.AA17185@coda.mel.dit.CSIRO.AU>
struct a { struct a {
int aa; int aa; // ERROR - private
}; };
class b : private a { class b : private a {
......
...@@ -23,8 +23,8 @@ public: ...@@ -23,8 +23,8 @@ public:
virtual Type& operator[](int ix) { return ia[ix]; } virtual Type& operator[](int ix) { return ia[ix]; }
private: private:
void init(const Type*, int); void init(const Type*, int);
int size; int size; // ERROR - private
int *ia; int *ia; // ERROR - private
}; };
template <class Type> template <class Type>
......
...@@ -7,9 +7,9 @@ ...@@ -7,9 +7,9 @@
// Message-ID: <9308051553.AA07639@nwd2sun1.analog.com> // Message-ID: <9308051553.AA07639@nwd2sun1.analog.com>
class A { class A {
protected: protected:
int astuff; int astuff; // ERROR - protected
A() { A() {
astuff = 3; astuff = 3;
} }
}; };
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
// Message-ID: <9308061142.AA08533@iiserv> // Message-ID: <9308061142.AA08533@iiserv>
struct T1 { int i; }; struct T1 { int i; };
struct T2 { int j; }; struct T2 { int j; }; // ERROR - private
struct T3 : public T1, private T2 { struct T3 : public T1, private T2 {
} x; } x;
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
// Message-ID: <9308252030.AA02352@tnt.acsys.com> // Message-ID: <9308252030.AA02352@tnt.acsys.com>
class B { class B {
protected: protected:
int i; int i; // ERROR - protected
}; };
class D1 : public B { class D1 : public B {
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
class A { class A {
public: public:
int b; int b; // ERROR - private
}; };
class C : private A { // NOTE WELL. private, not public class C : private A { // NOTE WELL. private, not public
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
// Message-ID: <m0nof3E-0021ifC@jts.com // Message-ID: <m0nof3E-0021ifC@jts.com
class t1 { class t1 {
protected: protected:
int a; int a; // ERROR - protected
}; };
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
class A { class A {
protected: protected:
int a; int a; // ERROR - protected
}; };
class B : public A { class B : public A {
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
class Outer { class Outer {
private: private:
int x; int x; // ERROR - private
public: public:
struct Inner { struct Inner {
int y; int y;
......
// Build don't link:
// The standard sez that a use of a name gets the most access it can through // The standard sez that a use of a name gets the most access it can through
// the various paths that can reach it. Here, the access decl in B gives // the various paths that can reach it. Here, the access decl in B gives
// us access. // us access.
struct A struct A
{ {
void f (); // gets bogus error - ref below XFAIL *-*-* void f ();
}; };
struct B: private virtual A struct B: private virtual A
...@@ -21,5 +22,5 @@ main () ...@@ -21,5 +22,5 @@ main ()
{ {
C c; C c;
c.f (); // gets bogus error - private XFAIL *-*-* c.f ();
} }
// Build don't link:
struct A {
static int i;
};
struct B : private A { };
struct C : public B {
int f () { return A::i; }
};
// Build don't link:
class A
{
protected:
int i;
};
class B : private A
{
protected:
A::i;
};
struct C : public B {
friend int f(C *p);
};
int f(C *p) {
return p->i;
}
// Build don't link:
template <int I>
struct S {
void g();
};
class C {
static const int i = 3; // gets bogus error - private - XFAIL *-*-*
public:
S<C::i>* f(); // gets bogus error - redeclared - XFAIL *-*-*
};
S<C::i>* C::f() { // gets bogus error - private - XFAIL *-*-*
return 0;
}
// Build don't link: // Build don't link:
struct A { struct A {
int operator ++(); int operator ++(); // ERROR - candidates
void operator ()(); void operator ()(); // ERROR - candidates
void operator delete(void*); void operator delete(void*); // ERROR - candidates
}; };
struct B { struct B {
int operator ++(int); int operator ++(int); // ERROR - candidates
void operator ()(); void operator ()(); // ERROR - candidates
void operator delete(void*); void operator delete(void*); // ERROR - candidates
void f(); void f();
}; };
......
...@@ -4,8 +4,8 @@ void f() ...@@ -4,8 +4,8 @@ void f()
{ {
union { union {
private: private:
int i; int i; // ERROR - private
} u; } u;
u.i = 3; // ERROR - private u.i = 3; // ERROR - within this context
} }
...@@ -12,8 +12,8 @@ ...@@ -12,8 +12,8 @@
class B { class B {
protected: protected:
int i; int i; // ERROR - in this context
static int j; static int j; // gets bogus error - XFAIL *-*-*
}; };
class D : public B { class D : public B {
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
template <class A, class B> void foo(); template <class A, class B> void foo();
template <class C> class bar { template <class C> class bar {
int i; int i; // ERROR - private
template <class B> friend void foo<C,B>(); // ERROR - bogus declaration template <class B> friend void foo<C,B>(); // ERROR - bogus declaration
}; };
template <class A, class B> void foo() { template <class A, class B> void foo() {
......
// Build don't link:
// Special g++ Options:
template <typename T>
void f(T);
template <>
void f(int) {}
struct B {
typedef int I;
};
template <typename T>
struct D1 : virtual public B {
typedef T I;
};
template <typename T>
struct D : virtual public B, public D1<T>
{
void g()
{
I i;
f(i);
}
};
int
main()
{
D<double> d;
d.g();
}
...@@ -20,7 +20,7 @@ class C ...@@ -20,7 +20,7 @@ class C
template <class U> template <class U>
friend void S<T>::f(U); friend void S<T>::f(U);
int i; int i; // ERROR - private
}; };
......
...@@ -7,7 +7,7 @@ template <class T> struct A { ...@@ -7,7 +7,7 @@ template <class T> struct A {
template <class T> class B template <class T> class B
{ {
friend class A<T>; friend class A<T>;
static int i; static int i; // ERROR - private
}; };
template <class T> class C template <class T> class C
......
...@@ -7,7 +7,7 @@ class C ...@@ -7,7 +7,7 @@ class C
{ {
friend void f<>(double); friend void f<>(double);
int i; int i; // ERROR - private
}; };
......
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