This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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(); }
+  };
+};

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]