C++ PATCH: PR c++/10428
Mark Mitchell
mark@codesourcery.com
Tue Apr 22 21:09:00 GMT 2003
This patch fixes a C++ regression whereby we accepted, but crashed, on
the (invalid) use of a typedef-name in an elaborated-type-specifier.
--
Mark Mitchell
CodeSourcery, LLC
mark@codesourcery.com
2003-04-22 Mark Mitchell <mark@codesourcery.com>
PR c++/10428
* g++.dg/parse/elab1.C: New test.
2003-04-22 Mark Mitchell <mark@codesourcery.com>
PR c++/10428
* decl.c (check_elaborated_type_specifier): New function, split
out from ...
(xref_tag): ... here. Use the new function in more places.
Index: cp/decl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/decl.c,v
retrieving revision 1.1038
diff -c -5 -p -r1.1038 decl.c
*** cp/decl.c 22 Apr 2003 05:44:08 -0000 1.1038
--- cp/decl.c 22 Apr 2003 21:01:24 -0000
*************** tag_name (enum tag_types code)
*** 12523,12532 ****
--- 12523,12564 ----
default:
abort ();
}
}
+ /* 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.
C++: If a class derivation is given, process it here, and report
an error if multiple derivation declarations are not identical.
*************** xref_tag (enum tag_types tag_code, tree
*** 12609,12632 ****
}
else
{
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));
}
else
ref = lookup_tag (code, name, b, 0);
if (! ref)
--- 12641,12653 ----
}
else
{
if (t)
{
! 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);
if (! ref)
*************** xref_tag (enum tag_types tag_code, tree
*** 12641,12653 ****
&& template_class_depth (current_class_type) == 0)
/* Since GLOBALIZE is true, we're declaring a global
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);
else
ref = NULL_TREE;
}
if (ref && current_class_type
--- 12662,12680 ----
&& template_class_depth (current_class_type) == 0)
/* Since GLOBALIZE is true, we're declaring a global
template, so we want this type. */
ref = DECL_TEMPLATE_RESULT (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;
}
if (ref && current_class_type
Index: testsuite/g++.dg/parse/elab1.C
===================================================================
RCS file: testsuite/g++.dg/parse/elab1.C
diff -N testsuite/g++.dg/parse/elab1.C
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- testsuite/g++.dg/parse/elab1.C 22 Apr 2003 21:01:31 -0000
***************
*** 0 ****
--- 1,9 ----
+ namespace Name {
+
+ typedef void *(*Function)( void *, int );
+
+ struct Foo {
+ struct Function xyz[5]; // { dg-error "" }
+ };
+
+ }
More information about the Gcc-patches
mailing list