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]

Re: [PATCH] PR c++/43327


On Tue, Mar 23, 2010 at 12:10:36PM -0400, Jason Merrill wrote:
> It seems like the problem is that we aren't calling
> convert_template_argument after doing the substitution.

Yes, that does the folding. I totally overlooked that function.
I have updated the patch to use it and tested it on 
x86_64-unknown-linux-gnu against trunk.

Thanks.

        Dodji

commit 851edede0fe1b473277812b92efad374cd08369d
Author: Dodji Seketeli <dodji@redhat.com>
Date:   Tue Mar 16 11:28:37 2010 +0100

    Draft fix for PR c++/43327
    
    gcc/cp/ChangeLog:
    	PR c++/43327
    	pt.c (most_specialized_class): call convert_template_argument on
    	each template argument passed to get_class_bindings.
    	(unify): Handle VAR_DECLs.
    
    gcc/testsuite/ChangeLog:
    	PR c++/43327
    	g++.dg/other/crash-10.C: New test.
    	g++.dg/other/crash-11.C: New test.

diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 66e7d73..40ac17c 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -15035,6 +15035,12 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
       /* Matched cases are handled by the ARG == PARM test above.  */
       return 1;
 
+    case VAR_DECL:
+      /* A non-type template parameter that is a variable should be a
+         an integral constant, in which case, it whould have been
+	 folded into its value. So we should not be getting a variable here.  */
+      return 1;
+
     case TYPE_ARGUMENT_PACK:
     case NONTYPE_ARGUMENT_PACK:
       {
@@ -15917,6 +15923,21 @@ most_specialized_class (tree type, tree tmpl)
 
 	  --processing_template_decl;
 	}
+
+	{
+	  tree tmpl_parms = DECL_INNERMOST_TEMPLATE_PARMS (tmpl);
+	  int i;
+	  for (i = 0; i < TREE_VEC_LENGTH (partial_spec_args); ++i)
+	    {
+	      TREE_VEC_ELT (partial_spec_args, i) =
+		convert_template_argument (TREE_VALUE (TREE_VEC_ELT
+							 (tmpl_parms, i)),
+					   TREE_VEC_ELT (partial_spec_args, i),
+					   partial_spec_args,
+					   tf_none, i, NULL_TREE);
+	    }
+	}
+
       spec_args = get_class_bindings (parms,
 				      partial_spec_args,
 				      args);
diff --git a/gcc/testsuite/g++.dg/other/crash-10.C b/gcc/testsuite/g++.dg/other/crash-10.C
new file mode 100644
index 0000000..6dcd791
--- /dev/null
+++ b/gcc/testsuite/g++.dg/other/crash-10.C
@@ -0,0 +1,24 @@
+// Origin: PR c++/43327
+// { dg-do compile }
+
+template <typename _T>
+struct A
+{
+  template <int _N, int _M> struct B;
+
+  template <int _N>
+  struct B<_N, _T::m>
+  {
+     static void f();
+  };
+};
+
+struct C
+{
+  static const int m = 4;
+};
+
+void m()
+{
+  A<C>::B<1, 4>::f();
+}
diff --git a/gcc/testsuite/g++.dg/other/crash-11.C b/gcc/testsuite/g++.dg/other/crash-11.C
new file mode 100644
index 0000000..f2037f4
--- /dev/null
+++ b/gcc/testsuite/g++.dg/other/crash-11.C
@@ -0,0 +1,27 @@
+// Origin: PR c++/43327
+// { dg-do compile }
+
+template <typename _T>
+struct A
+{
+  template <int _N, int _M> struct B;
+
+  template <int _N>
+  struct B<_N, _T::m>
+  {
+     static void f();
+  };
+};
+
+struct C
+{
+  static int m;
+};
+
+void m()
+{
+  A<C>::B<1, 4>::f(); // { dg-error "incomplete type 'A<C>\:\:B<1, 4>'" }
+}
+
+int C::m = 4;
+


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