From c6f9f83bc8e66feb890dc0c9804b59060b5a108e Mon Sep 17 00:00:00 2001 From: Kriang Lerdsuwanakij Date: Mon, 29 Nov 2004 14:17:33 +0000 Subject: [PATCH] re PR c++/18652 (ICE on invalid redeclaration) PR c++/18652 * name-lookup.c (pushtag): Change return type to tree. * cp-tree.h (pushtag): Adjust declaration. * decl.c (xref_tag, start_enum): Use return value of pushtag. * pt.c (push_template_decl_real): Return immediately if pushdecl_namespace_level returns error_mark_node. * g++.dg/lookup/crash6.C: New test. From-SVN: r91470 --- gcc/cp/ChangeLog | 9 +++++++++ gcc/cp/cp-tree.h | 2 +- gcc/cp/decl.c | 4 ++-- gcc/cp/name-lookup.c | 9 ++++++--- gcc/cp/pt.c | 6 +++++- gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/g++.dg/lookup/crash6.C | 8 ++++++++ 7 files changed, 36 insertions(+), 7 deletions(-) create mode 100644 gcc/testsuite/g++.dg/lookup/crash6.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index e99f280..e2f7dc4 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,12 @@ +2004-11-29 Kriang Lerdsuwanakij + + PR c++/18652 + * name-lookup.c (pushtag): Change return type to tree. + * cp-tree.h (pushtag): Adjust declaration. + * decl.c (xref_tag, start_enum): Use return value of pushtag. + * pt.c (push_template_decl_real): Return immediately if + pushdecl_namespace_level returns error_mark_node. + 2004-11-27 Kazu Hirata * pt.c: Fix a comment typo. diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index eb15258..1dfd52d 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -3707,7 +3707,7 @@ extern void delete_block (tree); extern void add_block_current_level (tree); extern void push_switch (tree); extern void pop_switch (void); -extern void pushtag (tree, tree, int); +extern tree pushtag (tree, tree, int); extern tree make_anon_name (void); extern int decls_match (tree, tree); extern tree duplicate_decls (tree, tree); diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 93c0417..7779080 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -9284,7 +9284,7 @@ xref_tag (enum tag_types tag_code, tree name, t = make_aggr_type (code); TYPE_CONTEXT (t) = context; /* pushtag only cares whether SCOPE is zero or not. */ - pushtag (name, t, scope != ts_current); + t = pushtag (name, t, scope != ts_current); } } else @@ -9539,7 +9539,7 @@ start_enum (tree name) name = make_anon_name (); enumtype = make_node (ENUMERAL_TYPE); - pushtag (name, enumtype, 0); + enumtype = pushtag (name, enumtype, 0); } return enumtype; diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c index ddbd78f..ee0d1a4 100644 --- a/gcc/cp/name-lookup.c +++ b/gcc/cp/name-lookup.c @@ -4566,9 +4566,10 @@ maybe_process_template_type_declaration (tree type, int globalize, /* Push a tag name NAME for struct/class/union/enum type TYPE. Normally put it into the inner-most non-sk_cleanup scope, but if GLOBALIZE is true, put it in the inner-most non-class scope. - The latter is needed for implicit declarations. */ + The latter is needed for implicit declarations. + Returns TYPE upon success and ERROR_MARK_NODE otherwise. */ -void +tree pushtag (tree name, tree type, int globalize) { struct cp_binding_level *b; @@ -4633,6 +4634,8 @@ pushtag (tree name, tree type, int globalize) d = maybe_process_template_type_declaration (type, globalize, b); + if (d == error_mark_node) + return error_mark_node; if (b->kind == sk_class) { @@ -4695,7 +4698,7 @@ pushtag (tree name, tree type, int globalize) tree d = build_decl (TYPE_DECL, NULL_TREE, type); TYPE_STUB_DECL (type) = pushdecl_with_scope (d, b); } - timevar_pop (TV_NAME_LOOKUP); + POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, type); } /* Subroutines for reverting temporarily to top-level for instantiation diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index f8ba33d..fca3f3d 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -3145,7 +3145,11 @@ push_template_decl_real (tree decl, int is_friend) parameters of the class. */ if (new_template_p && !ctx && !(is_friend && template_class_depth (current_class_type) > 0)) - tmpl = pushdecl_namespace_level (tmpl); + { + tmpl = pushdecl_namespace_level (tmpl); + if (tmpl == error_mark_node) + return error_mark_node; + } if (primary) { diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index fa959a4..289d124 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2004-11-29 Kriang Lerdsuwanakij + + PR c++/18652 + * g++.dg/lookup/crash6.C: New test. + 2004-11-29 Hans-Peter Nilsson PR middle-end/18164 diff --git a/gcc/testsuite/g++.dg/lookup/crash6.C b/gcc/testsuite/g++.dg/lookup/crash6.C new file mode 100644 index 0000000..0e49324 --- /dev/null +++ b/gcc/testsuite/g++.dg/lookup/crash6.C @@ -0,0 +1,8 @@ +// { dg-do compile } + +// Origin: Volker Reichelt + +// PR c++/18652: ICE redeclaring variable as template. + +int A; // { dg-error "previous declaration" } +template struct A; // { dg-error "different kind of symbol" } -- 2.7.4