This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[C++ Patch] PR 3761 (ICE in check_template_shadow)
- From: Scott Brumbaugh <scottb dot lists at verizon dot net>
- To: gcc-patches at gcc dot gnu dot org
- Date: Fri, 22 Aug 2003 16:18:27 -0700 (PDT)
- Subject: [C++ Patch] PR 3761 (ICE in check_template_shadow)
Hi,
Here is an attempt at fixing this bug. My analysis was done on the
test code listed below. The error occurs because a TREE_LIST is passed
as an argument to check_template_shadow. I traced this back to an
ambiguous lookup of the implicit operator= which is defined in both base
classes A and B.
This lookup is done in setup_class_bindings when it calls
lookup_member with the protect parameter = 2. In this case
lookup_member will return a TREE_LIST node with TREE_TYPE set to
error_mark_node and TREE_VALUE set to a chain of ambiguous candidates.
This returned TREE_LIST is then passed to push_class_level_binding
which is the function that calls check_template_shadow.
To fix this I changed check_template_shadow by adding an explicit
check for a TREE_LIST argument with a TREE_TYPE of error_mark_node.
In this case the decl chain of ambiguous names is extracted and the
function continues on.
Here is a patch that implements this fix followed by a test case.
I have done a make bootstrap and make check-g++ on i686-pc-linux-gnu.
Thanks,
Scott Brumbaugh
2003-08-22 Scott Brumbaugh <scottb.lists@verizon.net>
PR C++/3761
* pt.c (check_template_shadow): Look out for a TREE_LIST of
ambiguous names. Handle this list just as an OVERLOAD list.
Index: pt.c
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/cp/pt.c,v
retrieving revision 1.763
diff -c -3 -p -r1.763 pt.c
*** pt.c 21 Aug 2003 05:50:52 -0000 1.763
--- pt.c 22 Aug 2003 00:08:44 -0000
*************** check_template_shadow (tree decl)
*** 1932,1937 ****
--- 1932,1944 ----
/* Figure out what we're shadowing. */
if (TREE_CODE (decl) == OVERLOAD)
decl = OVL_CURRENT (decl);
+ /* lookup_member will return a TREE_LIST if a name is ambiguous, the
+ TREE_TYPE will be error_mark_node, TREE_VALUE will hold all the
+ ambiguous candidates. */
+ else if (TREE_CODE (decl) == TREE_LIST
+ && TREE_TYPE (decl) == error_mark_node)
+ decl = TREE_VALUE (decl);
+
olddecl = IDENTIFIER_VALUE (DECL_NAME (decl));
/* If there's no previous binding for this name, we're not shadowing
// { dg-do compile }
//
// PR 3761
struct A {};
struct B {};
template <class T>
struct Foo : A, B
{
void func(void);
struct Nested
{
friend void Foo::func(void);
};
};