aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2009-11-13 09:40:13 -0500
committerJason Merrill <jason@gcc.gnu.org>2009-11-13 09:40:13 -0500
commitfc1e08468e6e828266648443e01c61e213aa33a8 (patch)
tree90d7953a7498a3ee4c4554636ecc5116b2ea716d /gcc/cp
parent268bab853ddd5736056a371fd33aedd68e81cff9 (diff)
downloadgcc-fc1e08468e6e828266648443e01c61e213aa33a8.zip
gcc-fc1e08468e6e828266648443e01c61e213aa33a8.tar.gz
gcc-fc1e08468e6e828266648443e01c61e213aa33a8.tar.bz2
re PR c++/11987 (Accepts-invalid with inherited nested type)
PR c++/11987 * parser.c (cp_parser_direct_declarator): Give helpful error about trying to define member of a dependent typedef. * pt.c (resolve_typename_type): Don't resolve a typedef typename. * tree.c (typedef_variant_p): New. * cp-tree.h: Declare it. From-SVN: r154149
Diffstat (limited to 'gcc/cp')
-rw-r--r--gcc/cp/ChangeLog9
-rw-r--r--gcc/cp/cp-tree.h1
-rw-r--r--gcc/cp/parser.c15
-rw-r--r--gcc/cp/pt.c3
-rw-r--r--gcc/cp/tree.c8
5 files changed, 32 insertions, 4 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 988b602..1ffa86a 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,12 @@
+2009-11-13 Jason Merrill <jason@redhat.com>
+
+ PR c++/11987
+ * parser.c (cp_parser_direct_declarator): Give helpful error about
+ trying to define member of a dependent typedef.
+ * pt.c (resolve_typename_type): Don't resolve a typedef typename.
+ * tree.c (typedef_variant_p): New.
+ * cp-tree.h: Declare it.
+
2009-11-12 Jason Merrill <jason@redhat.com>
PR c++/27078
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index f66a009..a71dc73 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -5098,6 +5098,7 @@ extern bool type_has_nontrivial_copy_init (const_tree);
extern bool class_tmpl_impl_spec_p (const_tree);
extern int zero_init_p (const_tree);
extern tree strip_typedefs (tree);
+extern bool typedef_variant_p (tree);
extern tree copy_binfo (tree, tree, tree,
tree *, int);
extern int member_p (const_tree);
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index f77ec55..05def24 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -14191,10 +14191,17 @@ cp_parser_direct_declarator (cp_parser* parser,
/*only_current_p=*/false);
/* If that failed, the declarator is invalid. */
if (TREE_CODE (type) == TYPENAME_TYPE)
- error_at (declarator_id_start_token->location,
- "%<%T::%E%> is not a type",
- TYPE_CONTEXT (qualifying_scope),
- TYPE_IDENTIFIER (qualifying_scope));
+ {
+ if (typedef_variant_p (type))
+ error_at (declarator_id_start_token->location,
+ "cannot define member of dependent typedef "
+ "%qT", type);
+ else
+ error_at (declarator_id_start_token->location,
+ "%<%T::%E%> is not a type",
+ TYPE_CONTEXT (qualifying_scope),
+ TYPE_IDENTIFIER (qualifying_scope));
+ }
qualifying_scope = type;
}
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 0e688bf..85d9fff 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -17689,6 +17689,9 @@ resolve_typename_type (tree type, bool only_current_p)
to look inside it. */
if (only_current_p && !currently_open_class (scope))
return type;
+ /* If this is a typedef, we don't want to look inside (c++/11987). */
+ if (typedef_variant_p (type))
+ return type;
/* If SCOPE isn't the template itself, it will not have a valid
TYPE_FIELDS list. */
if (same_type_p (scope, CLASSTYPE_PRIMARY_TEMPLATE_TYPE (scope)))
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index 9dae184..f9e1cd7 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -1067,6 +1067,14 @@ strip_typedefs (tree t)
return cp_build_qualified_type (result, cp_type_quals (t));
}
+/* Returns true iff TYPE is a type variant created for a typedef. */
+
+bool
+typedef_variant_p (tree type)
+{
+ return is_typedef_decl (TYPE_NAME (type));
+}
+
/* Makes a copy of BINFO and TYPE, which is to be inherited into a
graph dominated by T. If BINFO is NULL, TYPE is a dependent base,