aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
authorKriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>2002-07-22 14:23:37 +0000
committerKriang Lerdsuwanakij <lerdsuwa@gcc.gnu.org>2002-07-22 14:23:37 +0000
commit0e902d98aee5f7d4f4ac9baf639d2fad0eaa848e (patch)
tree03d4d4ae02f393f6f7171d9364e1ec68a2ced3fd /gcc/cp
parent0d541696aa1fce80cf0d521be3e1664391526c28 (diff)
downloadgcc-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/cp')
-rw-r--r--gcc/cp/ChangeLog21
-rw-r--r--gcc/cp/cp-tree.h4
-rw-r--r--gcc/cp/decl.c22
-rw-r--r--gcc/cp/parse.y20
-rw-r--r--gcc/cp/pt.c18
-rw-r--r--gcc/cp/search.c7
6 files changed, 66 insertions, 26 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;