diff options
author | Mark Mitchell <mark@markmitchell.com> | 1998-09-22 11:58:41 +0000 |
---|---|---|
committer | Mark Mitchell <mmitchel@gcc.gnu.org> | 1998-09-22 11:58:41 +0000 |
commit | 3ddfb0e62449e59f035da4fc651a58c1cc467e4b (patch) | |
tree | ad09fd54f0a5d9d938dd37d62c9eba117dbaef98 /gcc | |
parent | a105e36f8cf5a403da2def2712cf85c476a975b6 (diff) | |
download | gcc-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/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/cp/decl.c | 11 | ||||
-rw-r--r-- | gcc/cp/decl2.c | 3 | ||||
-rw-r--r-- | gcc/cp/pt.c | 7 | ||||
-rw-r--r-- | gcc/testsuite/g++.old-deja/g++.other/friend4.C | 6 |
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>(); |