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>
* call.c (add_function_candidate): Check for proper number of args
......
......@@ -3029,28 +3029,30 @@ build_op_delete_call (code, addr, size, flags, placement)
}
/* 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)
tree basetype_path, decl;
tree basetype_path;
tree decl;
{
tree access = compute_access (basetype_path, decl);
int accessible;
if (access == access_private_node)
{
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)
accessible = accessible_p (basetype_path, decl);
if (!accessible)
{
cp_error_at ("`%+#D' %s", decl,
TREE_PROTECTED (decl) ? "is protected"
: "has protected accessibility");
error ("within this context");
if (TREE_PRIVATE (decl))
cp_error_at ("`%+#D' is private", decl);
else if (TREE_PROTECTED (decl))
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. */
......
......@@ -1440,7 +1440,6 @@ alter_access (t, binfo, fdecl, access)
else
{
enforce_access (binfo, fdecl);
DECL_ACCESS (fdecl) = tree_cons (t, access, DECL_ACCESS (fdecl));
return 1;
}
......@@ -5548,18 +5547,24 @@ maybe_push_cache_obstack ()
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. */
tree
void
build_self_reference ()
{
tree name = constructor_name (current_class_type);
tree value = build_lang_decl (TYPE_DECL, name, current_class_type);
tree saved_cas;
DECL_NONLOCAL (value) = 1;
DECL_CONTEXT (value) = current_class_type;
DECL_CLASS_CONTEXT (value) = current_class_type;
DECL_ARTIFICIAL (value) = 1;
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. */
......
......@@ -549,6 +549,11 @@ extern int flag_vtable_gc;
/* Nonzero means make the default pedwarns warnings instead of errors.
The value of this flag is ignored if -pedantic is specified. */
extern int flag_permissive;
/* Nonzero if we want to obey access control semantics. */
extern int flag_access_control;
/* C++ language-specific tree codes. */
#define DEFTREECODE(SYM, NAME, TYPE, LENGTH) SYM,
......@@ -1086,11 +1091,16 @@ struct lang_type
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
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
depth-first order via TREE_CHAIN. Other than that, TREE_CHAIN is
unused. */
We use TREE_VIA_PROTECTED and TREE_VIA_PUBLIC, but private
inheritance is indicated by the absence of the other two flags, not
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
by `get_binfo' and `get_base_distance'. */
......@@ -1299,6 +1309,12 @@ struct lang_decl
has `this' as volatile X *const. */
#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
is mutable. */
#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));
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_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_arg_to_ellipsis PROTO((tree));
......@@ -2680,7 +2696,7 @@ extern tree instantiate_type PROTO((tree, tree, int));
extern void print_class_statistics PROTO((void));
extern void maybe_push_cache_obstack PROTO((void));
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 tree get_enclosing_class PROTO((tree));
int is_base_of_enclosing_class 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_binfo PROTO((tree, tree, int));
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_nested_field PROTO((tree, int));
extern int lookup_fnfields_1 PROTO((tree, tree));
......@@ -3153,9 +3169,12 @@ extern void reinit_search_statistics PROTO((void));
extern tree current_scope PROTO((void));
extern tree lookup_conversions PROTO((tree));
extern tree binfo_for_vtable PROTO((tree));
extern void dfs_walk PROTO((tree, void (*) (tree), int (*) (tree)));
extern void dfs_unmark PROTO((tree));
extern int markedp PROTO((tree));
extern tree dfs_walk PROTO((tree,
tree (*)(tree, void *),
tree (*) (tree, void *),
void *));
extern tree dfs_unmark PROTO((tree, void *));
extern tree markedp PROTO((tree, void *));
/* in semantics.c */
extern void finish_expr_stmt PROTO((tree));
......
......@@ -12383,6 +12383,8 @@ xref_basetypes (code_type_node, name, ref, binfo)
/* In the declaration `A : X, Y, ... Z' we mark all the types
(A, X, Y, ..., Z) so we can check for duplicates. */
tree binfos;
tree base;
int i, len;
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)
len = list_length (binfo);
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);
BINFO_BASETYPES (TYPE_BINFO (ref)) = binfos = make_tree_vec (len);
......@@ -12433,16 +12442,14 @@ xref_basetypes (code_type_node, name, ref, binfo)
GNU_xref_hier (name, basetype, via_public, via_virtual, 0);
#if 1
/* This code replaces similar code in layout_basetypes.
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)))
{
cp_error ("base class `%T' has incomplete type", basetype);
continue;
}
#endif
else
{
if (CLASSTYPE_MARKED (basetype))
......
......@@ -1490,7 +1490,8 @@ tree
build_offset_ref (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 orig_name = name;
......@@ -1558,17 +1559,17 @@ build_offset_ref (type, name)
decl = maybe_dummy_object (type, &basebinfo);
fnfields = lookup_fnfields (basebinfo, name, 1);
fields = lookup_field (basebinfo, name, 0, 0);
member = lookup_member (basebinfo, name, 1, 0);
if (fields == error_mark_node || fnfields == error_mark_node)
if (member == error_mark_node)
return error_mark_node;
/* A lot of this logic is now handled in lookup_field and
lookup_fnfield. */
if (fnfields)
if (member && TREE_CODE (member) == TREE_LIST)
{
/* Go from the TREE_BASELINK to the member function info. */
tree fnfields = member;
t = TREE_VALUE (fnfields);
if (TREE_CODE (orig_name) == TEMPLATE_ID_EXPR)
......@@ -1596,26 +1597,13 @@ build_offset_ref (type, name)
if (!really_overloaded_fn (t))
{
tree access;
/* Get rid of a potential OVERLOAD around it */
t = OVL_CURRENT (t);
/* unique functions are handled easily. */
basebinfo = TREE_PURPOSE (fnfields);
access = compute_access (basebinfo, t);
if (access == access_protected_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;
}
if (!enforce_access (basebinfo, t))
return error_mark_node;
mark_used (t);
if (DECL_STATIC_FUNCTION_P (t))
return t;
......@@ -1638,14 +1626,7 @@ build_offset_ref (type, name)
return t;
}
/* Now that we know we are looking for a field, see if we
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;
t = member;
if (t == NULL_TREE)
{
......@@ -1754,7 +1735,6 @@ resolve_offset_ref (exp)
&& (base == current_class_ref || is_dummy_object (base)))
{
tree basetype_path;
tree access;
tree expr;
if (TREE_CODE (exp) == OFFSET_REF && TREE_CODE (type) == OFFSET_TYPE)
......@@ -1771,19 +1751,9 @@ resolve_offset_ref (exp)
}
/* Kludge: we need to use basetype_path now, because
convert_pointer_to will bash it. */
access = compute_access (basetype_path, member);
enforce_access (basetype_path, member);
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
COMPONENT_REF; that will allow better error recovery than
just feeding back error_mark_node. */
......
......@@ -3043,14 +3043,9 @@ do_identifier (token, parsing, args)
/* TREE_USED is set in `hack_identifier'. */
if (TREE_CODE (id) == CONST_DECL)
{
/* Check access. */
if (IDENTIFIER_CLASS_VALUE (token) == 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'. */
}
enforce_access (current_class_type, id);
if (!processing_template_decl || DECL_TEMPLATE_PARM_P (id))
id = DECL_INITIAL (id);
}
......
......@@ -1994,29 +1994,15 @@ hack_identifier (value, name)
if (DECL_LANG_SPECIFIC (value)
&& DECL_CLASS_CONTEXT (value) != current_class_type)
{
tree path, access;
tree path;
register tree context
= (TREE_CODE (value) == FUNCTION_DECL && DECL_VIRTUAL_P (value))
? DECL_CLASS_CONTEXT (value)
: DECL_CONTEXT (value);
get_base_distance (context, current_class_type, 0, &path);
if (path)
{
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;
}
}
if (path && !enforce_access (current_class_type, value))
return error_mark_node;
}
}
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:
{ $<ttype>0 = begin_class_definition ($<ttype>0); }
;
self_reference:
/* empty */
{
finish_member_declaration (build_self_reference ());
}
;
opt.component_decl_list:
self_reference
| self_reference component_decl_list
| component_decl_list
| opt.component_decl_list access_specifier component_decl_list
| opt.component_decl_list access_specifier
;
......
......@@ -900,7 +900,10 @@ print_candidates (fns)
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 = " ";
}
}
......@@ -4807,7 +4810,7 @@ instantiate_class_template (type)
access = access_public_virtual_node;
else if (TREE_VIA_PROTECTED (pbase))
access = access_protected_virtual_node;
else if (TREE_VIA_PRIVATE (pbase))
else
access = access_private_virtual_node;
}
else
......@@ -4816,7 +4819,7 @@ instantiate_class_template (type)
access = access_public_node;
else if (TREE_VIA_PROTECTED (pbase))
access = access_protected_node;
else if (TREE_VIA_PRIVATE (pbase))
else
access = access_private_node;
}
......@@ -7840,7 +7843,7 @@ get_template_base (tparms, targs, parm, arg)
/* Since get_template_base_recursive marks the bases classes, we
must unmark them here. */
dfs_walk (arg_binfo, dfs_unmark, markedp);
dfs_walk (arg_binfo, dfs_unmark, markedp, 0);
return rval;
}
......
......@@ -3,8 +3,8 @@
extern "C" void printf (char *, ...);
class A {
int i;
int j;
int i; // ERROR - private
int j; // ERROR - private
public:
int h;
A() { i=10; j=20; }
......
......@@ -151,8 +151,8 @@ struct __streambuf {
char* _gptr;
char* _egptr;
char* _eback;
char* _pbase;
char* _pptr;
char* _pbase; // ERROR - inacessible
char* _pptr; // ERROR - inacessible
char* _epptr;
char* _base;
char* _ebuf;
......
......@@ -2,7 +2,7 @@
// GROUPS passed enums
class X {
private:
enum E1 {a1, b1};
enum E1 {a1, b1}; // ERROR - private
public:
enum E2 {a2, b2};
};
......@@ -12,5 +12,5 @@ void h(X* p) {
int x2 = X::a2;
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 @@
// GROUPS passed visibility
class foo {
protected:
int i;
int i; // ERROR - protected
};
class bar : public foo {
......
......@@ -3,7 +3,7 @@
class bottom
{
public:
int b;
int b; // ERROR - private
};
class middle : private bottom
{
......
......@@ -5,7 +5,7 @@
class foo
{
public:
static int y;
static int y; // ERROR - private
};
class foo1 : private foo
{ };
......
......@@ -3,7 +3,7 @@
struct A {
protected:
int i;
int i; // ERROR - private
int f (); // ERROR -
};
......
......@@ -16,24 +16,24 @@ public:
int PUB_A;
protected:
union {
long B;
void *pY;
long B; // ERROR - protected
void *pY; // ERROR - protected
} ;
union Y {
long B;
void *pY;
} PRT;
int PRT_A;
} PRT; // ERROR - protected
int PRT_A; // ERROR - protected
private:
union {
long C;
void *pZ;
long C; // ERROR - private
void *pZ; // ERROR - private
};
union Z {
long C;
long C;
void *pZ;
} PRV;
int PRV_A;
} PRV; // ERROR - private
int PRV_A; // ERROR - private
};
struct Bar : public Foo {
......
......@@ -9,7 +9,7 @@
class X {
private:
enum E1 {a1, b1};
enum E1 {a1, b1}; // ERROR - private
public:
enum E2 {a2, b2};
};
......
......@@ -10,9 +10,9 @@ class A {
public:
int x;
private:
int y;
int y; // ERROR - private
union {
int z;
int z; // ERROR - private
};
};
......
......@@ -6,7 +6,7 @@
// Subject: member access rule bug
// Message-ID: <9306300528.AA17185@coda.mel.dit.CSIRO.AU>
struct a {
int aa;
int aa; // ERROR - private
};
class b : private a {
......
......@@ -23,8 +23,8 @@ public:
virtual Type& operator[](int ix) { return ia[ix]; }
private:
void init(const Type*, int);
int size;
int *ia;
int size; // ERROR - private
int *ia; // ERROR - private
};
template <class Type>
......
......@@ -7,9 +7,9 @@
// Message-ID: <9308051553.AA07639@nwd2sun1.analog.com>
class A {
protected:
int astuff;
int astuff; // ERROR - protected
A() {
astuff = 3;
astuff = 3;
}
};
......
......@@ -7,7 +7,7 @@
// Message-ID: <9308061142.AA08533@iiserv>
struct T1 { int i; };
struct T2 { int j; };
struct T2 { int j; }; // ERROR - private
struct T3 : public T1, private T2 {
} x;
......
......@@ -7,7 +7,7 @@
// Message-ID: <9308252030.AA02352@tnt.acsys.com>
class B {
protected:
int i;
int i; // ERROR - protected
};
class D1 : public B {
......
......@@ -8,7 +8,7 @@
class A {
public:
int b;
int b; // ERROR - private
};
class C : private A { // NOTE WELL. private, not public
......
......@@ -7,7 +7,7 @@
// Message-ID: <m0nof3E-0021ifC@jts.com
class t1 {
protected:
int a;
int a; // ERROR - protected
};
......
......@@ -8,7 +8,7 @@
class A {
protected:
int a;
int a; // ERROR - protected
};
class B : public A {
......
......@@ -3,7 +3,7 @@
class Outer {
private:
int x;
int x; // ERROR - private
public:
struct Inner {
int y;
......
// Build don't link:
// 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
// us access.
struct A
{
void f (); // gets bogus error - ref below XFAIL *-*-*
void f ();
};
struct B: private virtual A
......@@ -21,5 +22,5 @@ main ()
{
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:
struct A {
int operator ++();
void operator ()();
void operator delete(void*);
int operator ++(); // ERROR - candidates
void operator ()(); // ERROR - candidates
void operator delete(void*); // ERROR - candidates
};
struct B {
int operator ++(int);
void operator ()();
void operator delete(void*);
int operator ++(int); // ERROR - candidates
void operator ()(); // ERROR - candidates
void operator delete(void*); // ERROR - candidates
void f();
};
......
......@@ -4,8 +4,8 @@ void f()
{
union {
private:
int i;
int i; // ERROR - private
} u;
u.i = 3; // ERROR - private
u.i = 3; // ERROR - within this context
}
......@@ -12,8 +12,8 @@
class B {
protected:
int i;
static int j;
int i; // ERROR - in this context
static int j; // gets bogus error - XFAIL *-*-*
};
class D : public B {
......
......@@ -10,7 +10,7 @@
template <class A, class B> void foo();
template <class C> class bar {
int i;
int i; // ERROR - private
template <class B> friend void foo<C,B>(); // ERROR - bogus declaration
};
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
template <class U>
friend void S<T>::f(U);
int i;
int i; // ERROR - private
};
......
......@@ -7,7 +7,7 @@ template <class T> struct A {
template <class T> class B
{
friend class A<T>;
static int i;
static int i; // ERROR - private
};
template <class T> class C
......
......@@ -7,7 +7,7 @@ class C
{
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