This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[patch] Fix PR c++/26739: ICE on template redefinition as friend
- 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 11:29:52 +0200 (CEST)
- Subject: [patch] Fix PR c++/26739: ICE on template redefinition as friend
Mainline currently ICEs on the following invalid code snippet:
template<char> void foo() {}
template<int> struct A
{
template<char> friend void foo() {}
};
A<0> a;
The error message is:
PR26739.cc: In instantiation of 'A<0>':
PR26739.cc:8: instantiated from here
PR26739.cc:5: error: redefinition of 'template<char <anonymous> > void foo()'
PR26739.cc:1: error: 'template<char <anonymous> > void foo()' previously declared here
PR26739.cc:5: internal compiler error: tree check: expected var_decl or function_decl or type_decl or template_decl, have error_mark in tsubst_friend_function, at cp/pt.c:5286
The offending code is indeed in tsubst_friend_function which
(apart from the comments) looks like this:
old_decl = pushdecl_namespace_level (new_friend, /*is_friend=*/true);
pop_nested_namespace (ns);
if (old_decl != new_friend)
{
if (!new_friend_is_defn)
;
else
{
DECL_TEMPLATE_INFO (old_decl) = new_friend_template_info;
The problem is that pushdecl_namespace_level returns an error_mark_node
for the testcase above. This causes the ICE when the compiler tries to
access DECL_TEMPLATE_INFO (old_decl).
The patch below fixes this by returning early if pushdecl_namespace_level
fails.
Bootstrapped and regtested on x86_64-unknown-linux-gnu.
Ok for mainline?
However, I'm unsure about a testcase, because I'm not familiar with
g++.old-deja: The ICE was triggered by g++.old-deja/g++.pt/friend36.C,
but the test still passed (I only found the ICE in the logs).
Is it possible to modify the original testcase to trigger on the ICE
or should I rather add a new test with appropriate error markers to
g++.dg?
Regards,
Volker
:ADDPATCH C++:
2006-04-18 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
PR c++/26739
* pt.c (tsubst_friend_function): Return early if
pushdecl_namespace_level fails.
===================================================================
--- gcc/gcc/cp/pt.c 2006-04-18 19:20:10 +0200
+++ gcc/gcc/cp/pt.c 2006-04-18 19:13:01 +0200
@@ -5236,6 +5236,9 @@ tsubst_friend_function (tree decl, tree
old_decl = pushdecl_namespace_level (new_friend, /*is_friend=*/true);
pop_nested_namespace (ns);
+ if (old_decl == error_mark_node)
+ return error_mark_node;
+
if (old_decl != new_friend)
{
/* This new friend declaration matched an existing
===================================================================