aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog9
-rw-r--r--gcc/cp/pt.c22
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/g++.dg/other/crash-10.C24
-rw-r--r--gcc/testsuite/g++.dg/other/crash-11.C27
5 files changed, 88 insertions, 0 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 25ed7d0..81e9772 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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.
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 6e62292..3bd45f7 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -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);
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index dfbf449..5edd590 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
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..29ee231
--- /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|not a valid" }
+}
+
+int C::m = 4;
+