[C++ PATCH]: Fix 2137
Nathan Sidwell
nathan@codesourcery.com
Mon Mar 26 00:41:00 GMT 2001
Hi,
I've installed this patch to the mainline which fixes bug 2137.
We were neglecting to check the access for a friend function declaration
with the result that we'd have accesses to check lying about til some
later time. However, the proposed resolution of DR209
http://anubis.dkuug.dk/JTC1/SC22/WG21/docs/cwg_defects.html#209
is that the friend class/function does not need to be accessible at the
friend declaration. So this patch removes such access checks.
built & tested on i686-pc-linux-gnu, approved by Mark.
nathan
--
Dr Nathan Sidwell :: http://www.codesourcery.com :: CodeSourcery LLC
'But that's a lie.' - 'Yes it is. What's your point?'
nathan@codesourcery.com : http://www.cs.bris.ac.uk/~nathan/ : nathan@acm.org
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-26 Nathan Sidwell <nathan@codesourcery.com>
* g++.old-deja/g++.other/friend9.C: Expect no errors.
* g++.old-deja/g++.robertl/eb56.C: Make typedef public.
Index: cp/cp-tree.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/cp-tree.h,v
retrieving revision 1.582
diff -c -3 -p -r1.582 cp-tree.h
*** cp-tree.h 2001/02/27 13:12:16 1.582
--- cp-tree.h 2001/03/01 16:38:20
*************** extern tree get_binfo PARAMS ((tree,
*** 4184,4189 ****
--- 4184,4191 ----
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));
Index: cp/decl.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/decl.c,v
retrieving revision 1.755
diff -c -3 -p -r1.755 decl.c
*** decl.c 2001/02/26 11:01:44 1.755
--- decl.c 2001/03/01 16:38:25
*************** friend declaration requires class-key, i
*** 11104,11110 ****
/* 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));
/* A friendly class? */
if (current_class_type)
--- 11104,11112 ----
/* Only try to do this stuff if we didn't already give up. */
if (type != integer_type_node)
{
! /* 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)
*************** friend declaration requires class-key, i
*** 11366,11397 ****
if (friendp)
{
/* Friends are treated specially. */
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;
! }
}
/* Structure field. It may not be a function, except for C++ */
--- 11368,11400 ----
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");
! 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++ */
Index: cp/parse.y
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/parse.y,v
retrieving revision 1.214
diff -c -3 -p -r1.214 parse.y
*** parse.y 2001/02/14 13:58:49 1.214
--- parse.y 2001/03/01 16:38:27
*************** component_decl_list:
*** 2547,2557 ****
--- 2547,2559 ----
{
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 ();
}
;
Index: cp/semantics.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/semantics.c,v
retrieving revision 1.191
diff -c -3 -p -r1.191 semantics.c
*** semantics.c 2001/02/18 05:59:45 1.191
--- semantics.c 2001/03/01 16:38:27
*************** decl_type_access_control (decl)
*** 1596,1608 ****
added to type_lookups after typed_declspecs saved the copy that
ended up in current_type_lookups. */
type_lookups = current_type_lookups;
}
void
save_type_access_control (lookups)
tree lookups;
{
! current_type_lookups = lookups;
}
/* Begin a function definition declared with DECL_SPECS and
--- 1596,1636 ----
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;
+ {
+ 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
*************** tree
*** 1735,1740 ****
--- 1763,1772 ----
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);
*************** finish_class_definition (t, attributes,
*** 1962,1967 ****
--- 1994,2001 ----
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 ();
Index: testsuite/g++.old-deja/g++.other/friend9.C
===================================================================
RCS file: /cvs/gcc/egcs/gcc/testsuite/g++.old-deja/g++.other/friend9.C,v
retrieving revision 1.1
diff -c -3 -p -r1.1 friend9.C
*** friend9.C 2000/11/28 10:06:16 1.1
--- friend9.C 2001/03/01 16:38:18
***************
*** 5,18 ****
// Bug 853: We reported the wrong line no for a friend access violation
class F
{
! class Internal; // ERROR - is private
};
class C
{
! friend class F::Internal; // ERROR - in this context
public:
typedef enum { A, B } e;
--- 5,20 ----
// 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;
};
class C
{
! friend class F::Internal;
public:
typedef enum { A, B } e;
Index: testsuite/g++.old-deja/g++.robertl/eb56.C
===================================================================
RCS file: /cvs/gcc/egcs/gcc/testsuite/g++.old-deja/g++.robertl/eb56.C,v
retrieving revision 1.3
diff -c -3 -p -r1.3 eb56.C
*** eb56.C 1998/12/16 22:04:13 1.3
--- eb56.C 2001/03/01 16:38:18
***************
*** 2,7 ****
--- 2,8 ----
// Build don't link:
class foo {
+ public:
typedef int sometype;
};
More information about the Gcc-patches
mailing list