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]

[PATCH] PR c++/43327


Hello,

Here is what I think is happening in this PR.

In the first test/example below, fold_non_dependent_expr does not fold a 
static const variable into its constant value, but just returns the 
variable as is.

Later when we try to find the most specialized class template of 
A<C>::B<1,4> (in most_specialized_class), get_class_bindings fails when 
calling unify.

It fails because unify doesn't expect the non-folded VAR_DECL C::m as a 
template parameter of
template<> template<int_N> struct A<C>::B<_N, C::m> but rather expects 
the C::m parm to be folded into 4.

This patch fixes tsubst_copy_and_build so that fold_non_dependent_expr 
folds constant VAR_DECLs into their constant values.

The second hunk prevents unify to crash whenever a VAR_DECL sleeps 
through. This situation can happen in the second example in the patch 
below. In that case, unification should fail without crashing.

Tested on x86_64-unknown-linux-gnu against trunk.

        Dodji

commit 65a606c2b667ab51f50d9568e7ad5e7df3c20e8c
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 (tsubst_copy_and_build): Fold const variables into their
    	values.
    	(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..03a46cf 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -12714,7 +12714,14 @@ tsubst_copy_and_build (tree t,
 
     case VAR_DECL:
       if (!args)
-	return t;
+	{
+	  /* If the variable is a constant, fold it into its value.  */
+	  if (TREE_CONSTANT (t)
+	      && !dependent_type_p (TREE_TYPE (t))
+	      && !value_dependent_expression_p DECL_INITIAL (t))
+	    return DECL_INITIAL (t);
+	  return t;
+	}
       /* Fall through */
 
     case PARM_DECL:
@@ -15035,6 +15042,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:
       {
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]