diff options
author | Nathan Sidwell <nathan@codesourcery.com> | 2001-03-26 08:37:27 +0000 |
---|---|---|
committer | Nathan Sidwell <nathan@gcc.gnu.org> | 2001-03-26 08:37:27 +0000 |
commit | 788bf0e34ebec318ef42f6a7ffd9e8632756908a (patch) | |
tree | e80deebc6a447417a1ef0f9eae56f55fd7dabfbb /gcc | |
parent | 04c5433d684a6e22d266a2bd067eb42e28ee9d60 (diff) | |
download | gcc-788bf0e34ebec318ef42f6a7ffd9e8632756908a.zip gcc-788bf0e34ebec318ef42f6a7ffd9e8632756908a.tar.gz gcc-788bf0e34ebec318ef42f6a7ffd9e8632756908a.tar.bz2 |
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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 17 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 2 | ||||
-rw-r--r-- | gcc/cp/decl.c | 51 | ||||
-rw-r--r-- | gcc/cp/parse.y | 2 | ||||
-rw-r--r-- | gcc/cp/semantics.c | 36 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/g++.old-deja/g++.other/friend12.C | 71 | ||||
-rw-r--r-- | gcc/testsuite/g++.old-deja/g++.other/friend9.C | 6 | ||||
-rw-r--r-- | gcc/testsuite/g++.old-deja/g++.robertl/eb56.C | 1 |
9 files changed, 165 insertions, 27 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 63ce6c9..3b89a97 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -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. diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 28f519d..5015349 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -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)); diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 04d4c4f..03f94a3 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -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++ */ diff --git a/gcc/cp/parse.y b/gcc/cp/parse.y index 3d4ab44..f13614b 100644 --- a/gcc/cp/parse.y +++ b/gcc/cp/parse.y @@ -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 (); } ; diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 6e037f4..c99a0db4 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -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 (); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index d8d96339..86736d3 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -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. diff --git a/gcc/testsuite/g++.old-deja/g++.other/friend12.C b/gcc/testsuite/g++.old-deja/g++.other/friend12.C new file mode 100644 index 0000000..df767b3 --- /dev/null +++ b/gcc/testsuite/g++.old-deja/g++.other/friend12.C @@ -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; diff --git a/gcc/testsuite/g++.old-deja/g++.other/friend9.C b/gcc/testsuite/g++.old-deja/g++.other/friend9.C index 442d989..e51b027 100644 --- a/gcc/testsuite/g++.old-deja/g++.other/friend9.C +++ b/gcc/testsuite/g++.old-deja/g++.other/friend9.C @@ -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; diff --git a/gcc/testsuite/g++.old-deja/g++.robertl/eb56.C b/gcc/testsuite/g++.old-deja/g++.robertl/eb56.C index 2d497f8b..2249a40 100644 --- a/gcc/testsuite/g++.old-deja/g++.robertl/eb56.C +++ b/gcc/testsuite/g++.old-deja/g++.robertl/eb56.C @@ -2,6 +2,7 @@ // Build don't link: class foo { + public: typedef int sometype; }; |