This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
C++ PATCH to retrieve_specialization
- From: Jason Merrill <jason at redhat dot com>
- To: gcc-patches List <gcc-patches at gcc dot gnu dot org>
- Date: Sat, 04 Jul 2009 22:07:46 -0400
- Subject: C++ PATCH to retrieve_specialization
Richard Guenther called my attention to a new crash on the testcase for
PR 29433. This turned out to be a latent bug in the optimized class
template member function lookup code in retrieve_specialization: the
code walks the method vec to find an instance of the right template, but
if the class template instance has another instance of the same class
template as a base, that can choose the wrong one.
Tested x86_64-pc-linux-gnu, applied to trunk.
2009-07-04 Jason Merrill <jason@redhat.com>
* pt.c (retrieve_specialization): Don't get confused by a
using-declaration that brings in another instance of this template
from a base class.
* ptree.c (cxx_print_type): Fix logic.
*** gcc/cp/pt.c
--- gcc/cp/pt.c 2009-07-04 20:54:38.527726981 -0400
*************** retrieve_specialization (tree tmpl, tree
*** 974,980 ****
for (fns = VEC_index (tree, methods, idx); fns; fns = OVL_NEXT (fns))
{
tree fn = OVL_CURRENT (fns);
! if (DECL_TEMPLATE_INFO (fn) && DECL_TI_TEMPLATE (fn) == tmpl)
return fn;
}
return NULL_TREE;
--- 974,981 ----
for (fns = VEC_index (tree, methods, idx); fns; fns = OVL_NEXT (fns))
{
tree fn = OVL_CURRENT (fns);
! if (DECL_TEMPLATE_INFO (fn) && DECL_TI_TEMPLATE (fn) == tmpl
! && DECL_CONTEXT (fn) == class_specialization)
return fn;
}
return NULL_TREE;
*** gcc/cp/ptree.c
--- gcc/cp/ptree.c 2009-07-04 15:33:13.037721899 -0400
*************** cxx_print_type (FILE *file, tree node, i
*** 91,96 ****
--- 91,100 ----
print_node (file, "throws", TYPE_RAISES_EXCEPTIONS (node), indent + 4);
return;
+ case RECORD_TYPE:
+ case UNION_TYPE:
+ break;
+
default:
return;
}
*** gcc/testsuite/g++.dg/template/using15.C
--- gcc/testsuite/g++.dg/template/using15.C 2009-07-04 21:22:32.812473946 -0400
***************
*** 0 ****
--- 1,25 ----
+ // Reduced from the testcase for c++/29433
+
+ template <class T>
+ struct A: T
+ {
+ void f(typename T::type);
+ using T::f;
+ void g() { f(1); }
+ };
+
+ template <class T>
+ struct B: T
+ { typedef int type; };
+
+ struct C
+ {
+ typedef double type;
+ void f();
+ };
+
+ int main()
+ {
+ A<B<A<C> > > a;
+ a.g();
+ }