aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorKriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>2004-11-29 14:17:33 +0000
committerKriang Lerdsuwanakij <lerdsuwa@gcc.gnu.org>2004-11-29 14:17:33 +0000
commitc6f9f83bc8e66feb890dc0c9804b59060b5a108e (patch)
tree21a12e4b14b7728e3120b2ee3c55077458e781b7 /gcc
parent4f70f9d237bd16869e6f6146b3709cbefa3dffe9 (diff)
downloadgcc-c6f9f83bc8e66feb890dc0c9804b59060b5a108e.zip
gcc-c6f9f83bc8e66feb890dc0c9804b59060b5a108e.tar.gz
gcc-c6f9f83bc8e66feb890dc0c9804b59060b5a108e.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog9
-rw-r--r--gcc/cp/cp-tree.h2
-rw-r--r--gcc/cp/decl.c4
-rw-r--r--gcc/cp/name-lookup.c9
-rw-r--r--gcc/cp/pt.c6
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/lookup/crash6.C8
7 files changed, 36 insertions, 7 deletions
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 <lerdsuwa@users.sourceforge.net>
+
+ 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 <kazu@cs.umass.edu>
* 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 <lerdsuwa@users.sourceforge.net>
+
+ PR c++/18652
+ * g++.dg/lookup/crash6.C: New test.
+
2004-11-29 Hans-Peter Nilsson <hp@bitrange.com>
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 <reichelt@gcc.gnu.org>
+
+// PR c++/18652: ICE redeclaring variable as template.
+
+int A; // { dg-error "previous declaration" }
+template<int> struct A; // { dg-error "different kind of symbol" }