diff options
author | Patrick Palka <ppalka@gcc.gnu.org> | 2015-07-10 23:21:39 +0000 |
---|---|---|
committer | Patrick Palka <ppalka@gcc.gnu.org> | 2015-07-10 23:21:39 +0000 |
commit | c5540945071f17bed8009e2cfeffd7af8e830ba7 (patch) | |
tree | 6449427b1ab698673633eb97179cc607d0dca792 /gcc | |
parent | 0a73242e1ab3ac00d8fe9a98f10732473a96dc04 (diff) | |
download | gcc-c5540945071f17bed8009e2cfeffd7af8e830ba7.zip gcc-c5540945071f17bed8009e2cfeffd7af8e830ba7.tar.gz gcc-c5540945071f17bed8009e2cfeffd7af8e830ba7.tar.bz2 |
re PR c++/30044 (ICE in tsubst, at cp/pt.c:7359)
Fix PR c++/30044
gcc/cp/ChangeLog:
PR c++/30044
* pt.c (begin_template_parm_list): Add a dummy parameter level
to current_template_parms.
(end_template_parm_list): Remove the dummy parameter level
before adding the real one.
(tsubst): Don't attempt to substitute for template parameters
corresponding to a dummy argument level.
(template_parms_to_args): Remove obsolete hack for
giving template template arguments the proper level.
(splite_late_return_type): Remove obsolete hack for giving
template template arguments the proper level.
* error.c (dump_template_decl): Don't print dummy template
levels.
gcc/testsuite/ChangeLog
PR c++/30044
* g++.dg/cpp0x/auto46.C: New test.
* g++.dg/template/pr30044.C: New test.
* g++.dg/template/shadow2.C: New test.
* g++.dg/template/error55.C: New test.
* g++.dg/template/crash83.C: Accept any error string.
* g++.dg/cpp0x/variadic18.C: Adjust to avoid shadowing template
parameters.
* g++.dg/cpp0x/variadic18.C: Likewise
* g++.dg/template/canon-type-13.C: Likewise.
* g++.old-deja/g++.pt/ttp42.C: Likewise.
* g++.dg/torture/20070621-1.C: Likewise.
From-SVN: r225706
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 16 | ||||
-rw-r--r-- | gcc/cp/error.c | 8 | ||||
-rw-r--r-- | gcc/cp/pt.c | 32 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 15 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/auto46.C | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/variadic18.C | 2 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/variadic19.C | 2 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/canon-type-13.C | 2 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/crash83.C | 2 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/error55.C | 8 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/pr30044.C | 14 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/shadow2.C | 3 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/torture/20070621-1.C | 2 | ||||
-rw-r--r-- | gcc/testsuite/g++.old-deja/g++.pt/ttp42.C | 2 |
14 files changed, 86 insertions, 27 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 9d9e0c1..2b46fbd 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,19 @@ +2015-07-10 Patrick Palka <ppalka@gcc.gnu.org> + + PR c++/30044 + * pt.c (begin_template_parm_list): Add a dummy parameter level + to current_template_parms. + (end_template_parm_list): Remove the dummy parameter level + before adding the real one. + (tsubst): Don't attempt to substitute for template parameters + corresponding to a dummy argument level. + (template_parms_to_args): Remove obsolete hack for + giving template template arguments the proper level. + (splite_late_return_type): Remove obsolete hack for giving + template template arguments the proper level. + * error.c (dump_template_decl): Don't print dummy template + levels. + 2015-07-10 Paolo Carlini <paolo.carlini@oracle.com> PR c++/54521 diff --git a/gcc/cp/error.c b/gcc/cp/error.c index b2b0638..b811df2 100644 --- a/gcc/cp/error.c +++ b/gcc/cp/error.c @@ -1295,6 +1295,14 @@ dump_template_decl (cxx_pretty_printer *pp, tree t, int flags) tree inner_parms = INNERMOST_TEMPLATE_PARMS (parms); int len = TREE_VEC_LENGTH (inner_parms); + if (len == 0) + { + /* Skip over the dummy template levels of a template template + parm. */ + gcc_assert (TREE_CODE (TREE_TYPE (t)) == TEMPLATE_TEMPLATE_PARM); + continue; + } + pp_cxx_ws_string (pp, "template"); pp_cxx_begin_template_argument_list (pp); diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 8c72a61..064cbfd 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -657,6 +657,12 @@ begin_template_parm_list (void) ++processing_template_decl; ++processing_template_parmlist; note_template_header (0); + + /* Add a dummy parameter level while we process the parameter list. */ + current_template_parms + = tree_cons (size_int (processing_template_decl), + make_tree_vec (0), + current_template_parms); } /* This routine is called when a specialization is declared. If it is @@ -3888,6 +3894,9 @@ end_template_parm_list (tree parms) tree parm, next; tree saved_parmlist = make_tree_vec (list_length (parms)); + /* Pop the dummy parameter level and add the real one. */ + current_template_parms = TREE_CHAIN (current_template_parms); + current_template_parms = tree_cons (size_int (processing_template_decl), saved_parmlist, current_template_parms); @@ -4023,21 +4032,6 @@ template_parms_to_args (tree parms) args = a; } - if (length > 1 && TREE_VEC_ELT (args, 0) == NULL_TREE) - /* This can happen for template parms of a template template - parameter, e.g: - - template<template<class T, class U> class TT> struct S; - - Consider the level of the parms of TT; T and U both have - level 2; TT has no template parm of level 1. So in this case - the first element of full_template_args is NULL_TREE. If we - leave it like this TMPL_ARGS_DEPTH on args returns 1 instead - of 2. This will make tsubst wrongly consider that T and U - have level 1. Instead, let's create a dummy vector as the - first element of full_template_args so that TMPL_ARGS_DEPTH - returns the correct depth for args. */ - TREE_VEC_ELT (args, 0) = make_tree_vec (1); return args; } @@ -12073,7 +12067,8 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) template_parm_level_and_index (t, &level, &idx); levels = TMPL_ARGS_DEPTH (args); - if (level <= levels) + if (level <= levels + && TREE_VEC_LENGTH (TMPL_ARGS_LEVEL (args, level)) > 0) { arg = TMPL_ARG (args, level, idx); @@ -22440,11 +22435,6 @@ splice_late_return_type (tree type, tree late_return_type) return type; argvec = make_tree_vec (1); TREE_VEC_ELT (argvec, 0) = late_return_type; - if (processing_template_parmlist) - /* For a late-specified return type in a template type-parameter, we - need to add a dummy argument level for its parmlist. */ - argvec = add_to_template_args - (make_tree_vec (processing_template_parmlist), argvec); if (current_template_parms) argvec = add_to_template_args (current_template_args (), argvec); return tsubst (type, argvec, tf_warning_or_error, NULL_TREE); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index dde2803..fae1def 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,18 @@ +2015-07-10 Patrick Palka <ppalka@gcc.gnu.org> + + PR c++/30044 + * g++.dg/cpp0x/auto46.C: New test. + * g++.dg/template/pr30044.C: New test. + * g++.dg/template/shadow2.C: New test. + * g++.dg/template/error55.C: New test. + * g++.dg/template/crash83.C: Accept any error string. + * g++.dg/cpp0x/variadic18.C: Adjust to avoid shadowing template + parameters. + * g++.dg/cpp0x/variadic18.C: Likewise + * g++.dg/template/canon-type-13.C: Likewise. + * g++.old-deja/g++.pt/ttp42.C: Likewise. + * g++.dg/torture/20070621-1.C: Likewise. + 2015-07-10 Paolo Carlini <paolo.carlini@oracle.com> PR c++/54521 diff --git a/gcc/testsuite/g++.dg/cpp0x/auto46.C b/gcc/testsuite/g++.dg/cpp0x/auto46.C new file mode 100644 index 0000000..09e9f44 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/auto46.C @@ -0,0 +1,5 @@ +// Addendum to auto23.C, now with nested template parameter lists +// { dg-do compile { target c++11 } } + +template<template <auto f()->int> class> struct A { }; +template<template <template <auto f()->int> class> class> struct B { }; diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic18.C b/gcc/testsuite/g++.dg/cpp0x/variadic18.C index fc0e2dd..57fdc86 100644 --- a/gcc/testsuite/g++.dg/cpp0x/variadic18.C +++ b/gcc/testsuite/g++.dg/cpp0x/variadic18.C @@ -1,7 +1,7 @@ // { dg-do compile { target c++11 } } template<typename...> class tuple { }; -template<typename T, template<typename T> class... Metafunctions> +template<typename T, template<typename U> class... Metafunctions> struct apply_all { typedef tuple<typename Metafunctions<T>::type...> type; diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic19.C b/gcc/testsuite/g++.dg/cpp0x/variadic19.C index 0ae2672..3be9bb0 100644 --- a/gcc/testsuite/g++.dg/cpp0x/variadic19.C +++ b/gcc/testsuite/g++.dg/cpp0x/variadic19.C @@ -4,7 +4,7 @@ struct tuple { static const int value = 0; }; -template<typename T, template<class T> class... Metafunctions> +template<typename T, template<class U> class... Metafunctions> struct tuple<Metafunctions<T>...> { static const int value = 1; }; diff --git a/gcc/testsuite/g++.dg/template/canon-type-13.C b/gcc/testsuite/g++.dg/template/canon-type-13.C index 4f3702b..5a8d37d 100644 --- a/gcc/testsuite/g++.dg/template/canon-type-13.C +++ b/gcc/testsuite/g++.dg/template/canon-type-13.C @@ -11,7 +11,7 @@ struct S1 { }; -template<class T, template<class T> class A, template<class T> class B = A> +template<class T, template<class U> class A, template<class U> class B = A> struct C { B<T> m; diff --git a/gcc/testsuite/g++.dg/template/crash83.C b/gcc/testsuite/g++.dg/template/crash83.C index b83dd21..7dcbed9 100644 --- a/gcc/testsuite/g++.dg/template/crash83.C +++ b/gcc/testsuite/g++.dg/template/crash83.C @@ -2,4 +2,4 @@ template<int> struct A {}; -template<typename = class A<0>: > struct B {}; // { dg-error "explicit specialization|expected" } +template<typename = class A<0>: > struct B {}; // { dg-error "" } diff --git a/gcc/testsuite/g++.dg/template/error55.C b/gcc/testsuite/g++.dg/template/error55.C new file mode 100644 index 0000000..41f9595 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/error55.C @@ -0,0 +1,8 @@ +// Check that template template parameters get printed properly in error +// messages. + +template <template <class A> class B> +struct Y +{ + B<5> y; // { dg-error "for 'template<class A> class B'" } +}; diff --git a/gcc/testsuite/g++.dg/template/pr30044.C b/gcc/testsuite/g++.dg/template/pr30044.C new file mode 100644 index 0000000..415e6f0 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/pr30044.C @@ -0,0 +1,14 @@ +// PR c++/30044 + +template <typename T1, typename T2, template <T2> class Comp, class Result = Comp<1> > +struct sort { }; + + +template <typename Type, template <Type, Type> class Comp, class Result = Comp<1, 2> > +struct sort2 { }; + +template <typename Type, template <int, Type> class Comp, class Result = Comp<1, 2> > +struct sort3 { }; + +template <template <typename T1, typename T2, template <T2> class Comp, class Result = Comp<1> > class Foo> +struct sort4 { }; diff --git a/gcc/testsuite/g++.dg/template/shadow2.C b/gcc/testsuite/g++.dg/template/shadow2.C new file mode 100644 index 0000000..7f6a6dc --- /dev/null +++ b/gcc/testsuite/g++.dg/template/shadow2.C @@ -0,0 +1,3 @@ +template <class A, // { dg-error "shadows template parm 'class A'" } + template <class A> class B> // { dg-error "declaration of 'class A'" } +class X; diff --git a/gcc/testsuite/g++.dg/torture/20070621-1.C b/gcc/testsuite/g++.dg/torture/20070621-1.C index 15d1ac7..9bd8cc3 100644 --- a/gcc/testsuite/g++.dg/torture/20070621-1.C +++ b/gcc/testsuite/g++.dg/torture/20070621-1.C @@ -89,7 +89,7 @@ namespace __gnu_test { SharedInfo->first=ptr; } }; - template <class T, template<class T> class ItType> struct test_container { + template <class T, template<class U> class ItType> struct test_container { typename ItType<T>::ContainerType bounds; test_container(T* _first, T* _last):bounds(_first, _last) { } diff --git a/gcc/testsuite/g++.old-deja/g++.pt/ttp42.C b/gcc/testsuite/g++.old-deja/g++.pt/ttp42.C index 53bdae1..a2ac239 100644 --- a/gcc/testsuite/g++.old-deja/g++.pt/ttp42.C +++ b/gcc/testsuite/g++.old-deja/g++.pt/ttp42.C @@ -1,5 +1,5 @@ // { dg-do run } -template <class T, template <class T> class C> +template <class T, template <class U> class C> struct X {}; |