diff options
author | Jason Merrill <jason@redhat.com> | 2009-11-13 09:40:13 -0500 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2009-11-13 09:40:13 -0500 |
commit | fc1e08468e6e828266648443e01c61e213aa33a8 (patch) | |
tree | 90d7953a7498a3ee4c4554636ecc5116b2ea716d /gcc/cp | |
parent | 268bab853ddd5736056a371fd33aedd68e81cff9 (diff) | |
download | gcc-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/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 1 | ||||
-rw-r--r-- | gcc/cp/parser.c | 15 | ||||
-rw-r--r-- | gcc/cp/pt.c | 3 | ||||
-rw-r--r-- | gcc/cp/tree.c | 8 |
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, |