mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-19 03:40:26 +08:00
Implement DR 209
cp: Implement DR 209 * cp-tree.h (skip_type_access_control, reset_type_access_control): Prototype. * decl.c (grokdeclarator): Access of friends is not checked. * parse.y (component_decl_list): Reset type access control. * semantics.c (decl_type_access_control): Clear current_type_lookups. (save_type_access_control): Don't save if not deferring. (skip_type_access_control, reset_type_access_control): New functions. (begin_class_definition): Do type access control for basetypes. Start deferred access control. (finish_class_definition): Resume immediate access control if this is a local class. testsuite: * g++.old-deja/g++.other/friend12.C: New test. * g++.old-deja/g++.other/friend9.C: Expect no errors. * g++.old-deja/g++.robertl/eb56.C: Make typedef public. From-SVN: r40841
This commit is contained in:
parent
04c5433d68
commit
788bf0e34e
@ -1,3 +1,20 @@
|
||||
2001-03-26 Nathan Sidwell <nathan@codesourcery.com>
|
||||
|
||||
Implement DR 209
|
||||
* cp-tree.h (skip_type_access_control,
|
||||
reset_type_access_control): Prototype.
|
||||
* decl.c (grokdeclarator): Access of friends is not checked.
|
||||
* parse.y (component_decl_list): Reset type access control.
|
||||
* semantics.c (decl_type_access_control): Clear
|
||||
current_type_lookups.
|
||||
(save_type_access_control): Don't save if not deferring.
|
||||
(skip_type_access_control, reset_type_access_control): New
|
||||
functions.
|
||||
(begin_class_definition): Do type access control for basetypes.
|
||||
Start deferred access control.
|
||||
(finish_class_definition): Resume immediate access control if
|
||||
this is a local class.
|
||||
|
||||
2001-03-25 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
|
||||
|
||||
* class.c (add_method): Use memcpy/memmove, not bcopy.
|
||||
|
@ -4175,6 +4175,8 @@ extern tree get_binfo PARAMS ((tree, tree, int));
|
||||
extern int get_base_distance PARAMS ((tree, tree, int, tree *));
|
||||
extern tree get_dynamic_cast_base_type PARAMS ((tree, tree));
|
||||
extern void type_access_control PARAMS ((tree, tree));
|
||||
extern void skip_type_access_control PARAMS ((void));
|
||||
extern void reset_type_access_control PARAMS ((void));
|
||||
extern int accessible_p PARAMS ((tree, tree));
|
||||
extern tree lookup_field PARAMS ((tree, tree, int, int));
|
||||
extern int lookup_fnfields_1 PARAMS ((tree, tree));
|
||||
|
@ -11131,7 +11131,9 @@ friend declaration requires class-key, i.e. `friend %#T'",
|
||||
/* Only try to do this stuff if we didn't already give up. */
|
||||
if (type != integer_type_node)
|
||||
{
|
||||
decl_type_access_control (TYPE_NAME (type));
|
||||
/* DR 209. The friendly class does not need to be accessible
|
||||
in the scope of the class granting friendship. */
|
||||
skip_type_access_control ();
|
||||
|
||||
/* A friendly class? */
|
||||
if (current_class_type)
|
||||
@ -11393,32 +11395,33 @@ friend declaration requires class-key, i.e. `friend %#T'",
|
||||
if (friendp)
|
||||
{
|
||||
/* Friends are treated specially. */
|
||||
tree t = NULL_TREE;
|
||||
|
||||
/* DR 209. The friend does not need to be accessible at this
|
||||
point. */
|
||||
skip_type_access_control ();
|
||||
|
||||
if (ctype == current_class_type)
|
||||
warning ("member functions are implicitly friends of their class");
|
||||
else
|
||||
{
|
||||
tree t = NULL_TREE;
|
||||
if (decl && DECL_NAME (decl))
|
||||
{
|
||||
if (template_class_depth (current_class_type) == 0)
|
||||
{
|
||||
decl
|
||||
= check_explicit_specialization
|
||||
(declarator, decl,
|
||||
template_count, 2 * (funcdef_flag != 0) + 4);
|
||||
if (decl == error_mark_node)
|
||||
return error_mark_node;
|
||||
}
|
||||
|
||||
t = do_friend (ctype, declarator, decl,
|
||||
last_function_parms, attrlist, flags, quals,
|
||||
funcdef_flag);
|
||||
}
|
||||
if (t && funcdef_flag)
|
||||
return t;
|
||||
|
||||
return void_type_node;
|
||||
}
|
||||
if (decl && DECL_NAME (decl))
|
||||
{
|
||||
if (template_class_depth (current_class_type) == 0)
|
||||
{
|
||||
decl = check_explicit_specialization
|
||||
(declarator, decl,
|
||||
template_count, 2 * (funcdef_flag != 0) + 4);
|
||||
if (decl == error_mark_node)
|
||||
return error_mark_node;
|
||||
}
|
||||
|
||||
t = do_friend (ctype, declarator, decl,
|
||||
last_function_parms, attrlist, flags, quals,
|
||||
funcdef_flag);
|
||||
}
|
||||
if (t && funcdef_flag)
|
||||
return t;
|
||||
return void_type_node;
|
||||
}
|
||||
|
||||
/* Structure field. It may not be a function, except for C++ */
|
||||
|
@ -2548,11 +2548,13 @@ component_decl_list:
|
||||
{
|
||||
finish_member_declaration ($1);
|
||||
current_aggr = NULL_TREE;
|
||||
reset_type_access_control ();
|
||||
}
|
||||
| component_decl_list component_decl
|
||||
{
|
||||
finish_member_declaration ($2);
|
||||
current_aggr = NULL_TREE;
|
||||
reset_type_access_control ();
|
||||
}
|
||||
;
|
||||
|
||||
|
@ -1593,13 +1593,41 @@ decl_type_access_control (decl)
|
||||
added to type_lookups after typed_declspecs saved the copy that
|
||||
ended up in current_type_lookups. */
|
||||
type_lookups = current_type_lookups;
|
||||
|
||||
current_type_lookups = NULL_TREE;
|
||||
}
|
||||
|
||||
/* Record the lookups, if we're doing deferred access control. */
|
||||
|
||||
void
|
||||
save_type_access_control (lookups)
|
||||
tree lookups;
|
||||
{
|
||||
current_type_lookups = lookups;
|
||||
if (type_lookups != error_mark_node)
|
||||
{
|
||||
my_friendly_assert (!current_type_lookups, 20010301);
|
||||
current_type_lookups = lookups;
|
||||
}
|
||||
else
|
||||
my_friendly_assert (!lookups || lookups == error_mark_node, 20010301);
|
||||
}
|
||||
|
||||
/* Set things up so that the next deferred access control will succeed.
|
||||
This is needed for friend declarations see grokdeclarator for details. */
|
||||
|
||||
void
|
||||
skip_type_access_control ()
|
||||
{
|
||||
type_lookups = NULL_TREE;
|
||||
}
|
||||
|
||||
/* Reset the deferred access control. */
|
||||
|
||||
void
|
||||
reset_type_access_control ()
|
||||
{
|
||||
type_lookups = NULL_TREE;
|
||||
current_type_lookups = NULL_TREE;
|
||||
}
|
||||
|
||||
/* Begin a function definition declared with DECL_SPECS and
|
||||
@ -1732,6 +1760,10 @@ tree
|
||||
begin_class_definition (t)
|
||||
tree t;
|
||||
{
|
||||
/* Check the bases are accessible. */
|
||||
decl_type_access_control (TYPE_NAME (t));
|
||||
reset_type_access_control ();
|
||||
|
||||
if (processing_template_parmlist)
|
||||
{
|
||||
cp_error ("definition of `%#T' inside template parameter list", t);
|
||||
@ -1953,6 +1985,8 @@ finish_class_definition (t, attributes, semi, pop_scope_p)
|
||||
check_for_missing_semicolon (t);
|
||||
if (pop_scope_p)
|
||||
pop_scope (CP_DECL_CONTEXT (TYPE_MAIN_DECL (t)));
|
||||
if (current_function_decl)
|
||||
type_lookups = error_mark_node;
|
||||
if (current_scope () == current_function_decl)
|
||||
do_pending_defargs ();
|
||||
|
||||
|
@ -1,3 +1,9 @@
|
||||
2001-03-26 Nathan Sidwell <nathan@codesourcery.com>
|
||||
|
||||
* g++.old-deja/g++.other/friend12.C: New test.
|
||||
* g++.old-deja/g++.other/friend9.C: Expect no errors.
|
||||
* g++.old-deja/g++.robertl/eb56.C: Make typedef public.
|
||||
|
||||
2001-03-25 Joseph S. Myers <jsm28@cam.ac.uk>
|
||||
|
||||
* gcc.c-torture/execute/20010325-1.c: New test.
|
||||
|
71
gcc/testsuite/g++.old-deja/g++.other/friend12.C
Normal file
71
gcc/testsuite/g++.old-deja/g++.other/friend12.C
Normal file
@ -0,0 +1,71 @@
|
||||
// Build don't link:
|
||||
|
||||
// Copyright (C) 2001 Free Software Foundation, Inc.
|
||||
// Contributed by Nathan Sidwell 1 Mar 2001 <nathan@codesourcery.com>
|
||||
|
||||
// DR 209. friend access is not checked.
|
||||
|
||||
class Z;
|
||||
class A
|
||||
{
|
||||
class Inner {}; // ERROR - private
|
||||
Inner f (Inner);
|
||||
public:
|
||||
A ();
|
||||
friend class Z;
|
||||
};
|
||||
|
||||
class B
|
||||
{
|
||||
A::Inner j (); // ERROR - private
|
||||
A::Inner k (); // ERROR - private
|
||||
friend A::Inner A::f (Inner);
|
||||
int t;
|
||||
friend class A::Inner;
|
||||
};
|
||||
|
||||
A::Inner l (); // ERROR - private
|
||||
A::Inner m (); // ERROR - private
|
||||
A::Inner a, // ERROR - private
|
||||
b; // ERROR - private
|
||||
A::Inner a1; // ERROR - private
|
||||
int b2;
|
||||
|
||||
A::Inner A::f (Inner)
|
||||
{
|
||||
B b;
|
||||
b.t = 1;
|
||||
return A::Inner ();
|
||||
}
|
||||
|
||||
void Foo ()
|
||||
{
|
||||
A::Inner i; // ERROR - private
|
||||
class Local
|
||||
{
|
||||
friend A::Inner A::f (Inner);
|
||||
A::Inner k; // ERROR - private
|
||||
};
|
||||
class Local1 : A::Inner
|
||||
{ // ERROR - private
|
||||
|
||||
};
|
||||
A::Inner k; // ERROR - private
|
||||
}
|
||||
|
||||
class X : A::Inner
|
||||
{ // ERROR - private
|
||||
class I : A::Inner
|
||||
{ // ERROR - private
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
class Z : A::Inner
|
||||
{ // ERROR - private
|
||||
class I : A::Inner
|
||||
{ // ok, the base A::Inner is in the scope of Z which is a friend of A
|
||||
|
||||
};
|
||||
};
|
||||
int b4;
|
@ -5,14 +5,16 @@
|
||||
|
||||
// Bug 853: We reported the wrong line no for a friend access violation
|
||||
|
||||
// Since DR 209, friend declaration access is not checked.
|
||||
|
||||
class F
|
||||
{
|
||||
class Internal; // ERROR - is private
|
||||
class Internal;
|
||||
};
|
||||
|
||||
class C
|
||||
{
|
||||
friend class F::Internal; // ERROR - in this context
|
||||
friend class F::Internal;
|
||||
public:
|
||||
typedef enum { A, B } e;
|
||||
|
||||
|
@ -2,6 +2,7 @@
|
||||
// Build don't link:
|
||||
|
||||
class foo {
|
||||
public:
|
||||
typedef int sometype;
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user