aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorMark Mitchell <mark@markmitchell.com>1998-09-22 11:58:41 +0000
committerMark Mitchell <mmitchel@gcc.gnu.org>1998-09-22 11:58:41 +0000
commit3ddfb0e62449e59f035da4fc651a58c1cc467e4b (patch)
treead09fd54f0a5d9d938dd37d62c9eba117dbaef98 /gcc
parenta105e36f8cf5a403da2def2712cf85c476a975b6 (diff)
downloadgcc-3ddfb0e62449e59f035da4fc651a58c1cc467e4b.zip
gcc-3ddfb0e62449e59f035da4fc651a58c1cc467e4b.tar.gz
gcc-3ddfb0e62449e59f035da4fc651a58c1cc467e4b.tar.bz2
decl.c (grokfndecl): Improve error-recovery.
* decl.c (grokfndecl): Improve error-recovery. * decl2.c (grokfield): Likewise. * pt.c (finish_member_template_decl): Likewise. From-SVN: r22549
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog6
-rw-r--r--gcc/cp/decl.c11
-rw-r--r--gcc/cp/decl2.c3
-rw-r--r--gcc/cp/pt.c7
-rw-r--r--gcc/testsuite/g++.old-deja/g++.other/friend4.C6
5 files changed, 24 insertions, 9 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 6ccd3bf..360dcb0 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,9 @@
+1998-09-22 Mark Mitchell <mark@markmitchell.com>
+
+ * decl.c (grokfndecl): Improve error-recovery.
+ * decl2.c (grokfield): Likewise.
+ * pt.c (finish_member_template_decl): Likewise.
+
1998-09-20 Martin von Löwis <loewis@informatik.hu-berlin.de>
* method.c (hack_identifier): Finding multiple members is always
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index ee094e5..17078e0 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -7866,7 +7866,10 @@ bad_specifiers (object, type, virtualp, quals, inlinep, friendp, raises)
or `volatile'.
RAISES is a list of exceptions that this function can raise.
CHECK is 1 if we must find this method in CTYPE, 0 if we should
- not look, and -1 if we should not call `grokclassfn' at all. */
+ not look, and -1 if we should not call `grokclassfn' at all.
+
+ Returns `error_mark_node' if something goes wrong, after issuing
+ applicable error messages. */
static tree
grokfndecl (ctype, type, declarator, orig_declarator, virtualp, flags, quals,
@@ -8046,7 +8049,7 @@ grokfndecl (ctype, type, declarator, orig_declarator, virtualp, flags, quals,
return tmp;
}
if (! grok_ctor_properties (ctype, decl))
- return NULL_TREE;
+ return error_mark_node;
if (check == 0 && ! current_function_decl)
{
@@ -10342,8 +10345,8 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
virtualp, flags, quals, raises, attrlist,
friendp ? -1 : 0, friendp, publicp, inlinep,
funcdef_flag, template_count, in_namespace);
- if (decl == NULL_TREE)
- return NULL_TREE;
+ if (decl == NULL_TREE || decl == error_mark_node)
+ return decl;
#if 0
/* This clobbers the attrs stored in `decl' from `attrlist'. */
/* The decl and setting of decl_machine_attr is also turned off. */
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index be8689c..9d9e7ad 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -1607,7 +1607,8 @@ grokfield (declarator, declspecs, init, asmspec_tree, attrlist)
value = grokdeclarator (declarator, declspecs, FIELD, init != 0, NULL_TREE);
if (! value || value == error_mark_node)
- return NULL_TREE; /* friend or constructor went bad. */
+ /* friend or constructor went bad. */
+ return value;
/* Pass friendly classes back. */
if (TREE_CODE (value) == VOID_TYPE)
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index de6794f..47cb0c3 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -204,6 +204,10 @@ finish_member_template_decl (template_parameters, decl)
if (decl == NULL_TREE || decl == void_type_node)
return NULL_TREE;
+ else if (decl == error_mark_node)
+ /* By returning NULL_TREE, the parser will just ignore this
+ declaration. We have already issued the error. */
+ return NULL_TREE;
else if (TREE_CODE (decl) == TREE_LIST)
{
/* Assume that the class is the only declspec. */
@@ -229,7 +233,6 @@ finish_member_template_decl (template_parameters, decl)
}
else
cp_error ("invalid member template declaration `%D'", decl);
-
return error_mark_node;
}
@@ -584,6 +587,7 @@ void
check_specialization_scope ()
{
tree scope = current_scope ();
+
/* [temp.expl.spec]
An explicit specialization shall be declared in the namespace of
@@ -596,6 +600,7 @@ check_specialization_scope ()
if (scope && TREE_CODE (scope) != NAMESPACE_DECL)
cp_error ("explicit specialization in non-namespace scope `%D'",
scope);
+
/* [temp.expl.spec]
In an explicit specialization declaration for a member of a class
diff --git a/gcc/testsuite/g++.old-deja/g++.other/friend4.C b/gcc/testsuite/g++.old-deja/g++.other/friend4.C
index a208f5f..468340f 100644
--- a/gcc/testsuite/g++.old-deja/g++.other/friend4.C
+++ b/gcc/testsuite/g++.old-deja/g++.other/friend4.C
@@ -11,11 +11,11 @@
template <class A, class B> void foo();
template <class C> class bar {
int i;
- template <class B> friend void foo<C,B>();
+ template <class B> friend void foo<C,B>(); // ERROR - bogus declaration
};
template <class A, class B> void foo() {
- bar<A> baz; baz.i = 1;
- bar<int> buz; buz.i = 1; // ERROR - foo<void,void> cannot access bar<int>::i - XFAIL *-*-*
+ bar<A> baz; baz.i = 1; // ERROR - foo cannot access bar<int>::i
+ bar<int> buz; buz.i = 1; // ERROR - foo cannot access bar<int>::i
}
int main() {
foo<void,void>();