diff options
author | Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net> | 2002-07-22 14:23:37 +0000 |
---|---|---|
committer | Kriang Lerdsuwanakij <lerdsuwa@gcc.gnu.org> | 2002-07-22 14:23:37 +0000 |
commit | 0e902d98aee5f7d4f4ac9baf639d2fad0eaa848e (patch) | |
tree | 03d4d4ae02f393f6f7171d9364e1ec68a2ced3fd /gcc | |
parent | 0d541696aa1fce80cf0d521be3e1664391526c28 (diff) | |
download | gcc-0e902d98aee5f7d4f4ac9baf639d2fad0eaa848e.zip gcc-0e902d98aee5f7d4f4ac9baf639d2fad0eaa848e.tar.gz gcc-0e902d98aee5f7d4f4ac9baf639d2fad0eaa848e.tar.bz2 |
PR c++/7347, c++/7348
PR c++/7347, c++/7348
* cp-tree.h (tsubst_flags_t): Add tf_parsing.
* decl.c (make_typename_type): Use it.
(make_unbound_class_template): Likewise.
(lookup_name_real): Don't call type_access_control if scope is
template parameter dependent.
* parse.y (template_arg): Call make_unbound_class_template with
tf_parsing set.
(nest_name_specifier): Call make_typename_type with tf_parsing set.
(typename_sub0): Likewise.
(typename_sub1): Likewise.
(instantiate_decl): Push class scope.
* pt.c (regenerate_decl_from_template): Call pushclass and popclass
for both static variable and member function template.
(instantiate_decl) Call pushclass and popclass when tsubst'ing type
and arguments.
* search.c (type_access_control): Do type access for TEMPLATE_DECL
too.
* g++.dg/template/access4.C: New test.
* g++.dg/template/access5.C: New test.
* g++.old-deja/g++.pt/memtemp85.C: Fix access problem.
* g++.old-deja/g++.pt/memtemp86.C: Likewise.
* g++.old-deja/g++.pt/ttp58.C: Likewise.
* g++.old-deja/g++.pt/memtemp89.C: Remove XFAIL.
From-SVN: r55649
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 21 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 4 | ||||
-rw-r--r-- | gcc/cp/decl.c | 22 | ||||
-rw-r--r-- | gcc/cp/parse.y | 20 | ||||
-rw-r--r-- | gcc/cp/pt.c | 18 | ||||
-rw-r--r-- | gcc/cp/search.c | 7 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 10 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/access4.C | 18 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/access5.C | 21 | ||||
-rw-r--r-- | gcc/testsuite/g++.old-deja/g++.pt/memtemp85.C | 2 | ||||
-rw-r--r-- | gcc/testsuite/g++.old-deja/g++.pt/memtemp86.C | 2 | ||||
-rw-r--r-- | gcc/testsuite/g++.old-deja/g++.pt/memtemp89.C | 6 | ||||
-rw-r--r-- | gcc/testsuite/g++.old-deja/g++.pt/ttp58.C | 2 |
13 files changed, 121 insertions, 32 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 57effa9..fc54180 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,24 @@ +2002-07-22 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net> + + PR c++/7347, c++/7348 + * cp-tree.h (tsubst_flags_t): Add tf_parsing. + * decl.c (make_typename_type): Use it. + (make_unbound_class_template): Likewise. + (lookup_name_real): Don't call type_access_control if scope is + template parameter dependent. + * parse.y (template_arg): Call make_unbound_class_template with + tf_parsing set. + (nest_name_specifier): Call make_typename_type with tf_parsing set. + (typename_sub0): Likewise. + (typename_sub1): Likewise. + (instantiate_decl): Push class scope. + * pt.c (regenerate_decl_from_template): Call pushclass and popclass + for both static variable and member function template. + (instantiate_decl) Call pushclass and popclass when tsubst'ing type + and arguments. + * search.c (type_access_control): Do type access for TEMPLATE_DECL + too. + 2002-07-20 Roger Sayle <roger@eyesopen.com> * decl2.c (cxx_decode_option): Simplify -fhandle-exceptions diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 15a5aff..0f4bf90 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -3187,8 +3187,10 @@ typedef enum tsubst_flags_t { tf_ignore_bad_quals = 1 << 3, /* ignore bad cvr qualifiers */ tf_keep_type_decl = 1 << 4, /* retain typedef type decls (make_typename_type use) */ - tf_ptrmem_ok = 1 << 5 /* pointers to member ok (internal + tf_ptrmem_ok = 1 << 5, /* pointers to member ok (internal instantiate_type use) */ + tf_parsing = 1 << 6 /* called from parser + (make_typename_type use) */ } tsubst_flags_t; /* The kind of checking we can do looking in a class hierarchy. */ diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index f280384..e489795 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -5659,8 +5659,10 @@ make_typename_type (context, name, complain) return error_mark_node; } - if (!enforce_access (context, tmpl)) - return error_mark_node; + if (complain & tf_parsing) + type_access_control (context, tmpl); + else + enforce_access (context, tmpl); return lookup_template_class (tmpl, TREE_OPERAND (fullname, 1), @@ -5682,8 +5684,10 @@ make_typename_type (context, name, complain) t = lookup_field (context, name, 0, 1); if (t) { - if (!enforce_access (context, t)) - return error_mark_node; + if (complain & tf_parsing) + type_access_control (context, t); + else + enforce_access (context, t); if (DECL_ARTIFICIAL (t) || !(complain & tf_keep_type_decl)) t = TREE_TYPE (t); @@ -5712,7 +5716,6 @@ make_typename_type (context, name, complain) return error_mark_node; } - return build_typename_type (context, name, fullname, NULL_TREE); } @@ -5752,8 +5755,10 @@ make_unbound_class_template (context, name, complain) return error_mark_node; } - if (!enforce_access (context, tmpl)) - return error_mark_node; + if (complain & tf_parsing) + type_access_control (context, tmpl); + else + enforce_access (context, tmpl); return tmpl; } @@ -6078,7 +6083,8 @@ lookup_name_real (name, prefer_type, nonclass, namespaces_only) else { val = lookup_member (type, name, 0, prefer_type); - type_access_control (type, val); + if (!uses_template_parms (type)) + type_access_control (type, val); /* Restore the containing TYPENAME_TYPE if we looked through it before. */ diff --git a/gcc/cp/parse.y b/gcc/cp/parse.y index 386c808..94314e5 100644 --- a/gcc/cp/parse.y +++ b/gcc/cp/parse.y @@ -1159,7 +1159,7 @@ template_arg: $$ = error_mark_node; } else - $$ = make_unbound_class_template ($1, $3, 1); + $$ = make_unbound_class_template ($1, $3, tf_error | tf_parsing); } ; @@ -3071,14 +3071,14 @@ nested_name_specifier: { $$ = $2; } | nested_name_specifier TEMPLATE explicit_template_type SCOPE { got_scope = $$ - = make_typename_type ($1, $3, tf_error); } + = make_typename_type ($1, $3, tf_error | tf_parsing); } /* Error handling per Core 125. */ | nested_name_specifier IDENTIFIER SCOPE { got_scope = $$ - = make_typename_type ($1, $2, tf_error); } + = make_typename_type ($1, $2, tf_error | tf_parsing); } | nested_name_specifier PTYPENAME SCOPE { got_scope = $$ - = make_typename_type ($1, $2, tf_error); } + = make_typename_type ($1, $2, tf_error | tf_parsing); } ; /* Why the @#$%^& do type_name and notype_identifier need to be expanded @@ -3120,7 +3120,7 @@ typename_sub0: typename_sub1 identifier %prec EMPTY { if (TYPE_P ($1)) - $$ = make_typename_type ($1, $2, tf_error); + $$ = make_typename_type ($1, $2, tf_error | tf_parsing); else if (TREE_CODE ($2) == IDENTIFIER_NODE) error ("`%T' is not a class or namespace", $2); else @@ -3133,9 +3133,9 @@ typename_sub0: | typename_sub1 template_type %prec EMPTY { $$ = TREE_TYPE ($2); } | typename_sub1 explicit_template_type %prec EMPTY - { $$ = make_typename_type ($1, $2, tf_error); } + { $$ = make_typename_type ($1, $2, tf_error | tf_parsing); } | typename_sub1 TEMPLATE explicit_template_type %prec EMPTY - { $$ = make_typename_type ($1, $3, tf_error); } + { $$ = make_typename_type ($1, $3, tf_error | tf_parsing); } ; typename_sub1: @@ -3149,7 +3149,7 @@ typename_sub1: | typename_sub1 typename_sub2 { if (TYPE_P ($1)) - $$ = make_typename_type ($1, $2, tf_error); + $$ = make_typename_type ($1, $2, tf_error | tf_parsing); else if (TREE_CODE ($2) == IDENTIFIER_NODE) error ("`%T' is not a class or namespace", $2); else @@ -3161,10 +3161,10 @@ typename_sub1: } | typename_sub1 explicit_template_type SCOPE { got_scope = $$ - = make_typename_type ($1, $2, tf_error); } + = make_typename_type ($1, $2, tf_error | tf_parsing); } | typename_sub1 TEMPLATE explicit_template_type SCOPE { got_scope = $$ - = make_typename_type ($1, $3, tf_error); } + = make_typename_type ($1, $3, tf_error | tf_parsing); } ; /* This needs to return a TYPE_DECL for simple names so that we don't diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 8caf0a0..52554a9 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -9844,10 +9844,10 @@ regenerate_decl_from_template (decl, tmpl) register_specialization for it. */ my_friendly_assert (unregistered, 0); - if (TREE_CODE (decl) == VAR_DECL) + if (DECL_CLASS_SCOPE_P (decl)) /* Make sure that we can see identifiers, and compute access correctly, for the class members used in the declaration of - this static variable. */ + this static variable or function. */ pushclass (DECL_CONTEXT (decl), 2); /* Do the substitution to get the new declaration. */ @@ -9859,8 +9859,6 @@ regenerate_decl_from_template (decl, tmpl) DECL_INITIAL (new_decl) = tsubst_expr (DECL_INITIAL (code_pattern), args, tf_error, DECL_TI_TEMPLATE (decl)); - /* Pop the class context we pushed above. */ - popclass (); } else if (TREE_CODE (decl) == FUNCTION_DECL) { @@ -9871,6 +9869,10 @@ regenerate_decl_from_template (decl, tmpl) DECL_INITIAL (decl) = NULL_TREE; } + /* Pop the class context we pushed above. */ + if (DECL_CLASS_SCOPE_P (decl)) + popclass (); + /* The immediate parent of the new template is still whatever it was before, even though tsubst sets DECL_TI_TEMPLATE up as the most general template. We also reset the DECL_ASSEMBLER_NAME since @@ -10052,6 +10054,11 @@ instantiate_decl (d, defer_ok) tree gen = DECL_TEMPLATE_RESULT (gen_tmpl); tree type = TREE_TYPE (gen); + /* Make sure that we can see identifiers, and compute access + correctly. */ + if (DECL_CLASS_SCOPE_P (d)) + pushclass (DECL_CONTEXT (d), 1); + if (TREE_CODE (gen) == FUNCTION_DECL) { tsubst (DECL_ARGUMENTS (gen), args, tf_error | tf_warning, d); @@ -10064,6 +10071,9 @@ instantiate_decl (d, defer_ok) type = TREE_TYPE (type); } tsubst (type, args, tf_error | tf_warning, d); + + if (DECL_CLASS_SCOPE_P (d)) + popclass (); } if (TREE_CODE (d) == VAR_DECL && DECL_INITIALIZED_IN_CLASS_P (d) diff --git a/gcc/cp/search.c b/gcc/cp/search.c index b7ba0bc..95d5dde 100644 --- a/gcc/cp/search.c +++ b/gcc/cp/search.c @@ -971,8 +971,8 @@ friend_accessible_p (scope, decl, binfo) return 0; } -/* Perform access control on TYPE_DECL VAL, which was looked up in TYPE. - This is fairly complex, so here's the design: +/* Perform access control on TYPE_DECL or TEMPLATE_DECL VAL, which was + looked up in TYPE. This is fairly complex, so here's the design: The lang_extdef nonterminal sets type_lookups to NULL_TREE before we start to process a top-level declaration. @@ -995,7 +995,8 @@ void type_access_control (type, val) tree type, val; { - if (val == NULL_TREE || TREE_CODE (val) != TYPE_DECL + if (val == NULL_TREE + || (TREE_CODE (val) != TEMPLATE_DECL && TREE_CODE (val) != TYPE_DECL) || ! DECL_CLASS_SCOPE_P (val)) return; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 37d9e47..41b879c 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,13 @@ +2002-07-22 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net> + + PR c++/7347, c++/7348 + * g++.dg/template/access4.C: New test. + * g++.dg/template/access5.C: New test. + * g++.old-deja/g++.pt/memtemp85.C: Fix access problem. + * g++.old-deja/g++.pt/memtemp86.C: Likewise. + * g++.old-deja/g++.pt/ttp58.C: Likewise. + * g++.old-deja/g++.pt/memtemp89.C: Remove XFAIL. + 2002-07-22 Jakub Jelinek <jakub@redhat.com> * gcc.dg/gnu89-init-2.c: New test. diff --git a/gcc/testsuite/g++.dg/template/access4.C b/gcc/testsuite/g++.dg/template/access4.C new file mode 100644 index 0000000..9451ecc --- /dev/null +++ b/gcc/testsuite/g++.dg/template/access4.C @@ -0,0 +1,18 @@ +// { dg-do compile } +// Origin: Wolfgang Bangerth <wolfgang.bangerth@iwr.uni-heidelberg.de> + +// PR c++/7347 +// Access control for typename during instantiation + +template <int dim> class Base { + protected: + typedef int T; +}; + +template <int dim> class D : public Base<dim> { + public: + typedef typename Base<dim>::T T1; + D (T1 t); +}; + +D<2> d(1); diff --git a/gcc/testsuite/g++.dg/template/access5.C b/gcc/testsuite/g++.dg/template/access5.C new file mode 100644 index 0000000..a9cb8a5 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/access5.C @@ -0,0 +1,21 @@ +// { dg-do compile } +// Origin: Wolfgang Bangerth <wolfgang.bangerth@iwr.uni-heidelberg.de> + +// PR c++/7348 +// Access control for typename in function return type + +class Outer { + template <int dim> struct Inner { + typedef int T; + T foo (); + }; + public: + Outer(); +}; + +template <int dim> +typename Outer::Inner<dim>::T Outer::Inner<dim>::foo () { + return 1; +}; + +template Outer::Inner<2>; diff --git a/gcc/testsuite/g++.old-deja/g++.pt/memtemp85.C b/gcc/testsuite/g++.old-deja/g++.pt/memtemp85.C index ef8f048..ab9b9f6 100644 --- a/gcc/testsuite/g++.old-deja/g++.pt/memtemp85.C +++ b/gcc/testsuite/g++.old-deja/g++.pt/memtemp85.C @@ -4,7 +4,7 @@ // by Paul Burchard <burchard@pobox.com>, Level Set Systems, Inc. // Copyright (C) 1999 Free Software Foundation -class Q { +struct Q { template<class> class X { }; diff --git a/gcc/testsuite/g++.old-deja/g++.pt/memtemp86.C b/gcc/testsuite/g++.old-deja/g++.pt/memtemp86.C index 47a587f..fe06dae 100644 --- a/gcc/testsuite/g++.old-deja/g++.pt/memtemp86.C +++ b/gcc/testsuite/g++.old-deja/g++.pt/memtemp86.C @@ -4,7 +4,7 @@ // by Paul Burchard <burchard@pobox.com>, Level Set Systems, Inc. // Copyright (C) 1999 Free Software Foundation -class Q { +struct Q { template<class> class X { }; diff --git a/gcc/testsuite/g++.old-deja/g++.pt/memtemp89.C b/gcc/testsuite/g++.old-deja/g++.pt/memtemp89.C index 6db9b4b..8564221 100644 --- a/gcc/testsuite/g++.old-deja/g++.pt/memtemp89.C +++ b/gcc/testsuite/g++.old-deja/g++.pt/memtemp89.C @@ -5,11 +5,11 @@ class Q { template<class T> - class X { + class X { // ERROR - Q::X private }; }; template<template<class> class XX> class Y { - XX<int> x_; // ERROR - Q::X inaccessible XFAIL *-*-* + XX<int> x_; }; -Y<Q::X> y; // ERROR - instantiated from here XFAIL *-*-* +Y<Q::X> y; // ERROR - instantiated from here diff --git a/gcc/testsuite/g++.old-deja/g++.pt/ttp58.C b/gcc/testsuite/g++.old-deja/g++.pt/ttp58.C index 6620580..729996f 100644 --- a/gcc/testsuite/g++.old-deja/g++.pt/ttp58.C +++ b/gcc/testsuite/g++.old-deja/g++.pt/ttp58.C @@ -15,7 +15,7 @@ struct Z const static int value_ = false; }; -class Outer +struct Outer { template <class T> struct A : |