This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
C++ PATCH for c++/53816 (ICE with local reference in template)
- From: Jason Merrill <jason at redhat dot com>
- To: gcc-patches List <gcc-patches at gcc dot gnu dot org>
- Date: Mon, 02 Jul 2012 23:26:59 -0400
- Subject: C++ PATCH for c++/53816 (ICE with local reference in template)
resolves_to_fixed_type_p has caused a lot of ICEs in templates over the
years because it wants to look inside the DECL_INITIAL of variables with
non-constant initializers which are still in pre-tsubst form. Checking
processing_template_decl to prevent this isn't strong enough, because
fold_non_dependent_expr clears processing_template_decl in order to do
its tsubst folding. But instead we can test whether the current
function is not completely instantiated.
Tested x86_64-pc-linux-gnu, applying to trunk and 4.7 (more conservative
version).
commit 6eaedcae2947349c61f4129f0112a2d510949c46
Author: Jason Merrill <jason@redhat.com>
Date: Mon Jul 2 16:44:12 2012 -0400
PR c++/53816
* class.c (resolves_to_fixed_type_p): Check uses_template_parms
(current_function_decl) instead of processing_template_decl.
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index 264258c..e70e674 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -6521,7 +6521,10 @@ resolves_to_fixed_type_p (tree instance, int* nonnull)
int cdtorp = 0;
tree fixed;
- if (processing_template_decl)
+ /* processing_template_decl can be false in a template if we're in
+ fold_non_dependent_expr, but we still want to suppress this check. */
+ if (current_function_decl
+ && uses_template_parms (current_function_decl))
{
/* In a template we only care about the type of the result. */
if (nonnull)
diff --git a/gcc/testsuite/g++.dg/template/ref6.C b/gcc/testsuite/g++.dg/template/ref6.C
new file mode 100644
index 0000000..2e1254a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/ref6.C
@@ -0,0 +1,15 @@
+// PR c++/53816
+
+template <typename T>
+struct S { int v () const; };
+template <typename T>
+struct V : public S<T> {};
+struct U
+{
+ V<int> v;
+ template<typename T>
+ struct W
+ {
+ W (U const &x) { V<int> const &v = x.v; v.v(); }
+ };
+};
commit a4d190b1380fe956f7758994e7de27366dbcc0bb
Author: Jason Merrill <jason@redhat.com>
Date: Mon Jul 2 16:44:12 2012 -0400
PR c++/53816
* class.c (resolves_to_fixed_type_p): Check uses_template_parms
(current_function_decl) instead of processing_template_decl.
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index 503a01e..633bff3 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -6479,7 +6479,11 @@ resolves_to_fixed_type_p (tree instance, int* nonnull)
int cdtorp = 0;
tree fixed;
- if (processing_template_decl)
+ /* processing_template_decl can be false in a template if we're in
+ fold_non_dependent_expr, but we still want to suppress this check. */
+ if (processing_template_decl
+ || (current_function_decl
+ && uses_template_parms (current_function_decl)))
{
/* In a template we only care about the type of the result. */
if (nonnull)
diff --git a/gcc/testsuite/g++.dg/template/ref6.C b/gcc/testsuite/g++.dg/template/ref6.C
new file mode 100644
index 0000000..2e1254a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/ref6.C
@@ -0,0 +1,15 @@
+// PR c++/53816
+
+template <typename T>
+struct S { int v () const; };
+template <typename T>
+struct V : public S<T> {};
+struct U
+{
+ V<int> v;
+ template<typename T>
+ struct W
+ {
+ W (U const &x) { V<int> const &v = x.v; v.v(); }
+ };
+};