This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[patch] Fix PR c++/26558: ICE on invalid scope in template
- From: Volker Reichelt <reichelt at igpm dot rwth-aachen dot de>
- To: gcc-patches at gcc dot gnu dot org
- Date: Wed, 19 Apr 2006 23:31:06 +0200 (CEST)
- Subject: [patch] Fix PR c++/26558: ICE on invalid scope in template
The C++ frontend currently ICEs on the following invalid testcase:
template<int> struct A
{
template<int> void foo()
{
foo<0>::;
}
};
bug.cc: In member function 'void A<<anonymous> >::foo()':
bug.cc:5: internal compiler error: tree check: expected class 'type', have 'exceptional' (error_mark) in cp_parser_class_name, at cp/parser.c:12813
The problem is that cp_parser_class_name calls make_typename_type
which returns an error_mark_node. Alas, we don't check for the
error_mark_node, but try to get the TYPE_NAME which causes the ICE:
decl = TYPE_NAME (make_typename_type (scope, decl, tag_type, tf_error));
Btw, a couple of lines above we have a similar situation, but here
with an appropriate check:
decl = make_typename_type (scope, decl, typename_type, tf_error);
if (decl != error_mark_node)
decl = TYPE_NAME (decl);
The patch below fixes the ICE by using the same logic also for the
second call to make_typename_type. It also rearranges the code a
little in order to have only one call to cp_parser_error.
Bootstrapped and regtested on x86_64-unknown-linux-gnu.
Ok for mainline, 4.1 branch, and 4.0 branch?
Regards,
Volker
:ADDPATCH C++:
2006-04-19 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
PR c++/26558
* parser.c (cp_parser_class_name): Check for invalid typenames.
Rearrange code.
===================================================================
--- gcc/gcc/cp/parser.c 2006-04-19 12:52:40 +0200
+++ gcc/gcc/cp/parser.c 2006-04-19 13:05:34 +0200
@@ -12810,16 +12810,19 @@ cp_parser_class_name (cp_parser *parser,
standard does not seem to be definitive, but there is no other
valid interpretation of the following `::'. Therefore, those
names are considered class-names. */
- decl = TYPE_NAME (make_typename_type (scope, decl, tag_type, tf_error));
- else if (decl == error_mark_node
- || TREE_CODE (decl) != TYPE_DECL
+ {
+ decl = make_typename_type (scope, decl, tag_type, tf_error);
+ if (decl != error_mark_node)
+ decl = TYPE_NAME (decl);
+ }
+ else if (TREE_CODE (decl) != TYPE_DECL
|| TREE_TYPE (decl) == error_mark_node
|| !IS_AGGR_TYPE (TREE_TYPE (decl)))
- {
- cp_parser_error (parser, "expected class-name");
- return error_mark_node;
- }
+ decl = error_mark_node;
+ if (decl == error_mark_node)
+ cp_parser_error (parser, "expected class-name");
+
return decl;
}
===================================================================
2006-04-19 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
PR c++/26558
* g++.dg/parse/template19.C: New test.
===================================================================
--- gcc/gcc/testsuite/g++.dg/parse/template19.C 2003-09-23 19:59:22 +0200
+++ gcc/gcc/testsuite/g++.dg/parse/template19.C 2006-04-19 13:12:55 +0200
@@ -0,0 +1,11 @@
+// PR c++/26558
+// Origin: Jan Gorski <slimak@yk74.internetdsl.tpnet.pl>
+// { dg-do compile }
+
+template<int> struct A
+{
+ template<int> void foo()
+ {
+ foo<0>::; // { dg-error "before" }
+ }
+};
===================================================================