diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/cp/pt.c | 22 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/other/crash-10.C | 24 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/other/crash-11.C | 27 |
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; + |