This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: PATCH RFA: Patch for c++/3478
Gabriel Dos Reis <gdr@integrable-solutions.net> writes:
> I believe something about "invalid type" in a declaration sounds
> less obscure than saying that the decl-specifier is invalid.
Makes sense. Here is a version of the patch which changes the error
message to ``invalid type in declaration''.
Ian
cp/ChangeLog:
2004-01-11 Ian Lance Taylor <ian@wasabisystems.com>
* parser.c (cp_parser_decl_specifier_seq): If the first decl_spec
is error_mark_node, don't add any more decl_specs.
(cp_parser_init_declarator): After committing to a declaration, if
the decl_specifiers start with error_mark_node, issue an error and
change the type to "int".
testsuite/ChangeLog:
2004-01-11 Ian Lance Taylor <ian@wasabisystems.com>
* g++.dg/parse/error10.C: New test.
* g++.dg/template/arg2.C: Accept "invalid type" error.
Index: cp/parser.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/parser.c,v
retrieving revision 1.148
diff -p -u -r1.148 parser.c
--- cp/parser.c 8 Jan 2004 07:50:42 -0000 1.148
+++ cp/parser.c 11 Jan 2004 18:30:11 -0000
@@ -6717,7 +6717,8 @@ cp_parser_decl_specifier_seq (cp_parser*
}
/* Add the DECL_SPEC to the list of specifiers. */
- decl_specs = tree_cons (NULL_TREE, decl_spec, decl_specs);
+ if (decl_specs == NULL || TREE_VALUE (decl_specs) != error_mark_node)
+ decl_specs = tree_cons (NULL_TREE, decl_spec, decl_specs);
/* After we see one decl-specifier, further decl-specifiers are
always optional. */
@@ -9817,6 +9818,17 @@ cp_parser_init_declarator (cp_parser* pa
know we're going ahead. By this point, we know that we cannot
possibly be looking at any other construct. */
cp_parser_commit_to_tentative_parse (parser);
+
+ /* If the decl specifiers were bad, issue an error now that we're
+ sure this was intended to be a declarator. Then continue
+ declaring the variable(s), as int, to try to cut down on further
+ errors. */
+ if (decl_specifiers != NULL
+ && TREE_VALUE (decl_specifiers) == error_mark_node)
+ {
+ cp_parser_error (parser, "invalid type in declaration");
+ TREE_VALUE (decl_specifiers) = integer_type_node;
+ }
/* Check to see whether or not this declaration is a friend. */
friend_p = cp_parser_friend_p (decl_specifiers);
Index: testsuite/g++.dg/parse/error10.C
===================================================================
RCS file: testsuite/g++.dg/parse/error10.C
diff -N testsuite/g++.dg/parse/error10.C
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ testsuite/g++.dg/parse/error10.C 11 Jan 2004 18:30:19 -0000
@@ -0,0 +1,15 @@
+// PR c++/3478
+// { dg-options "" }
+
+template <typename> struct A
+{
+ enum E {};
+};
+
+template <typename T> void foo()
+{
+ enum A<void>::E e1;
+ typename A<T>::E e2;
+ enum A<T>::E e3;
+ enum typename A<T>::E e4; // { dg-error "" }
+}
Index: testsuite/g++.dg/template/arg2.C
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/g++.dg/template/arg2.C,v
retrieving revision 1.2
diff -p -u -r1.2 arg2.C
--- testsuite/g++.dg/template/arg2.C 15 Dec 2003 06:28:22 -0000 1.2
+++ testsuite/g++.dg/template/arg2.C 11 Jan 2004 18:30:19 -0000
@@ -10,5 +10,5 @@ template <typename T> class X {};
void fn ()
{
class L {};
- X<L> f; // { dg-error "uses local type|trying to instantiate|no type" "" }
+ X<L> f; // { dg-error "uses local type|trying to instantiate|no type|invalid type" "" }
}