OSDN Git Service

Fix for PR c++/43327
authordodji <dodji@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 26 Mar 2010 09:20:58 +0000 (09:20 +0000)
committerdodji <dodji@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 26 Mar 2010 09:20:58 +0000 (09:20 +0000)
gcc/cp/ChangeLog:
PR c++/43327
* pt.c (add_to_template_args): Support NULL ARGS;
(most_specialized_class): call coerce_template_parms on
template arguments passed to get_class_bindings. Use
add_to_template_args.
(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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@157745 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/cp/ChangeLog
gcc/cp/pt.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/other/crash-10.C [new file with mode: 0644]
gcc/testsuite/g++.dg/other/crash-11.C [new file with mode: 0644]

index 25ed7d0..81e9772 100644 (file)
@@ -1,5 +1,14 @@
 2010-03-26  Dodji Seketeli  <dodji@redhat.com>
 
+       PR c++/43327
+       * pt.c (add_to_template_args): Support NULL ARGS;
+       (most_specialized_class): call coerce_template_parms on
+       template arguments passed to get_class_bindings. Use
+       add_to_template_args.
+       (unify): Handle VAR_DECLs.
+
+2010-03-26  Dodji Seketeli  <dodji@redhat.com>
+
        * cp-tree.h (get_template_parms_at_level): Change unsigned parm
        into int.
        * pt.c (get_template_parms_at_level): Adjust.
index 6e62292..3bd45f7 100644 (file)
@@ -493,6 +493,9 @@ add_to_template_args (tree args, tree extra_args)
   int i;
   int j;
 
+  if (args == NULL_TREE)
+    return extra_args;
+
   extra_depth = TMPL_ARGS_DEPTH (extra_args);
   new_args = make_tree_vec (TMPL_ARGS_DEPTH (args) + extra_depth);
 
@@ -15055,6 +15058,13 @@ 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 (constant) value. So we should not be getting
+        a variable here.  */
+      gcc_unreachable ();
+
     case TYPE_ARGUMENT_PACK:
     case NONTYPE_ARGUMENT_PACK:
       {
@@ -15937,6 +15947,18 @@ most_specialized_class (tree type, tree tmpl)
 
          --processing_template_decl;
        }
+
+      partial_spec_args =
+         coerce_template_parms (DECL_INNERMOST_TEMPLATE_PARMS (tmpl),
+                                add_to_template_args (outer_args,
+                                                      partial_spec_args),
+                                tmpl, tf_none,
+                                /*require_all_args=*/true,
+                                /*use_default_args=*/true);
+
+      if (partial_spec_args == error_mark_node)
+       return error_mark_node;
+
       spec_args = get_class_bindings (parms,
                                      partial_spec_args,
                                      args);
index dfbf449..5edd590 100644 (file)
@@ -1,3 +1,9 @@
+2010-03-26  Dodji Seketeli  <dodji@redhat.com>
+
+       PR c++/43327
+       * g++.dg/other/crash-10.C: New test.
+       * g++.dg/other/crash-11.C: New test.
+
 2010-03-25  Jerry DeLisle  <jvdelisle@gcc.gnu.org>
 
        PR libfortran/43517
diff --git a/gcc/testsuite/g++.dg/other/crash-10.C b/gcc/testsuite/g++.dg/other/crash-10.C
new file mode 100644 (file)
index 0000000..6dcd791
--- /dev/null
@@ -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 (file)
index 0000000..29ee231
--- /dev/null
@@ -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|not a valid" }
+}
+
+int C::m = 4;
+