From befcd99bcb1e93983abf4cd20e408a0b963be4e5 Mon Sep 17 00:00:00 2001 From: Mark Mitchell Date: Tue, 22 Apr 2003 21:05:58 +0000 Subject: [PATCH] re PR c++/10428 (struct causes ICE in write_unscoped_name) PR c++/10428 * g++.dg/parse/elab1.C: New test. PR c++/10428 * decl.c (check_elaborated_type_specifier): New function, split out from ... (xref_tag): ... here. Use the new function in more places. From-SVN: r65956 --- gcc/cp/ChangeLog | 5 ++++ gcc/cp/decl.c | 61 +++++++++++++++++++++++++++----------- gcc/testsuite/ChangeLog | 4 +++ gcc/testsuite/g++.dg/parse/elab1.C | 9 ++++++ 4 files changed, 62 insertions(+), 17 deletions(-) create mode 100644 gcc/testsuite/g++.dg/parse/elab1.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index e5940ff..ec4684d 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,10 @@ 2003-04-22 Mark Mitchell + PR c++/10428 + * decl.c (check_elaborated_type_specifier): New function, split + out from ... + (xref_tag): ... here. Use the new function in more places. + * rtti.c (throw_bad_typeid): Use build_cxx_call. 2003-04-21 Mark Mitchell diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index a14389f..84e267e 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -12525,6 +12525,38 @@ tag_name (enum tag_types code) } } +/* Name lookup in an elaborated-type-specifier (after the keyword + indicated by TAG_CODE) has found TYPE. If the + elaborated-type-specifier is invalid, issue a diagnostic and return + error_mark_node; otherwise, return TYPE itself. */ + +static tree +check_elaborated_type_specifier (enum tag_types tag_code, + tree type) +{ + tree t; + + t = follow_tag_typedef (type); + + /* [dcl.type.elab] If the identifier resolves to a typedef-name or a + template type-parameter, the elaborated-type-specifier is + ill-formed. */ + if (!t) + { + error ("using typedef-name `%D' after `%s'", + TYPE_NAME (type), tag_name (tag_code)); + t = error_mark_node; + } + else if (TREE_CODE (type) == TEMPLATE_TYPE_PARM) + { + error ("using template type parameter `%T' after `%s'", + type, tag_name (tag_code)); + t = error_mark_node; + } + + return t; +} + /* Get the struct, enum or union (CODE says which) with tag NAME. Define the tag as a forward-reference if it is not defined. @@ -12611,20 +12643,9 @@ xref_tag (enum tag_types tag_code, tree name, tree attributes, { if (t) { - ref = follow_tag_typedef (t); - - /* [dcl.type.elab] If the identifier resolves to a - typedef-name or a template type-parameter, the - elaborated-type-specifier is ill-formed. */ - if (!ref) - { - pedwarn ("using typedef-name `%D' after `%s'", - TYPE_NAME (t), tag_name (tag_code)); - ref = t; - } - else if (TREE_CODE (t) == TEMPLATE_TYPE_PARM) - error ("using template type parameter `%T' after `%s'", - t, tag_name (tag_code)); + ref = check_elaborated_type_specifier (tag_code, t); + if (ref == error_mark_node) + POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node); } else ref = lookup_tag (code, name, b, 0); @@ -12643,9 +12664,15 @@ xref_tag (enum tag_types tag_code, tree name, tree attributes, template, so we want this type. */ ref = DECL_TEMPLATE_RESULT (ref); - if (ref && TREE_CODE (ref) == TYPE_DECL - && TREE_CODE (TREE_TYPE (ref)) == code) - ref = TREE_TYPE (ref); + if (ref && TREE_CODE (ref) == TYPE_DECL) + { + ref = check_elaborated_type_specifier (tag_code, + TREE_TYPE (ref)); + if (ref == error_mark_node) + POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node); + if (ref && TREE_CODE (ref) != code) + ref = NULL_TREE; + } else ref = NULL_TREE; } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 3face0f..35bbeb9 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2003-04-22 Mark Mitchell + + PR c++/10428 + * g++.dg/parse/elab1.C: New test. 2003-04-22 Devang Patel diff --git a/gcc/testsuite/g++.dg/parse/elab1.C b/gcc/testsuite/g++.dg/parse/elab1.C new file mode 100644 index 0000000..2997eef --- /dev/null +++ b/gcc/testsuite/g++.dg/parse/elab1.C @@ -0,0 +1,9 @@ +namespace Name { + + typedef void *(*Function)( void *, int ); + + struct Foo { + struct Function xyz[5]; // { dg-error "" } + }; + +} -- 2.7.4