This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[C++ PATCH] Fix up strip_typedefs (PR debug/56819)
- From: Jakub Jelinek <jakub at redhat dot com>
- To: Jason Merrill <jason at redhat dot com>, Dodji Seketeli <dseketel at redhat dot com>
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Wed, 3 Apr 2013 14:36:00 +0200
- Subject: [C++ PATCH] Fix up strip_typedefs (PR debug/56819)
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
Hi!
On the following testcase we ICE with -fcompare-debug with
--enable-checking=yes, because strip_typedefs copies args to a new TREE_VEC,
but doesn't copy over NON_DEFAULT_TEMPLATE_ARGS_COUNT. For ENABLE_CHECKING
the code requires that it is set, for !ENABLE_CHECKING it would be needed
only if NON_DEFAULT_TEMPLATE_ARGS_COUNT was already non-NULL (otherwise
GET_NON_DEFAULT_TEMPLATE_ARGS_COUNT would use length of the TREE_VEC).
Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk/4.8/4.7?
2013-04-03 Jakub Jelinek <jakub@redhat.com>
PR debug/56819
* tree.c (strip_typedefs): SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT
on new_args.
* g++.dg/debug/pr56819.C: New test.
--- gcc/cp/tree.c.jj 2013-04-02 20:24:34.000000000 +0200
+++ gcc/cp/tree.c 2013-04-03 10:51:56.614548181 +0200
@@ -1255,8 +1255,16 @@ strip_typedefs (tree t)
changed = true;
}
if (changed)
- fullname = lookup_template_function (TREE_OPERAND (fullname, 0),
- new_args);
+ {
+#ifndef ENABLE_CHECKING
+ if (NON_DEFAULT_TEMPLATE_ARGS_COUNT (args))
+#endif
+ SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT
+ (new_args, GET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (args));
+ fullname
+ = lookup_template_function (TREE_OPERAND (fullname, 0),
+ new_args);
+ }
else
ggc_free (new_args);
}
--- gcc/testsuite/g++.dg/debug/pr56819.C.jj 2013-04-03 10:57:55.187410867 +0200
+++ gcc/testsuite/g++.dg/debug/pr56819.C 2013-04-03 10:56:42.000000000 +0200
@@ -0,0 +1,27 @@
+// PR debug/56819
+// { dg-do compile }
+// { dg-options "-fcompare-debug" }
+
+template <typename>
+struct A
+{
+ template <typename>
+ struct B;
+};
+
+template <typename>
+struct C
+{
+ typedef int I;
+};
+
+template <typename T>
+class D
+{
+ typedef A <void> E;
+ typedef typename T::template B <E> F;
+ typedef typename C <F>::I I;
+ A <I> foo () { return A<I> (); }
+};
+
+template class D <A <void> >;
Jakub