mirror of git://gcc.gnu.org/git/gcc.git
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
This commit is contained in:
parent
0a73242e1a
commit
c554094507
|
|
@ -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>
|
2015-07-10 Paolo Carlini <paolo.carlini@oracle.com>
|
||||||
|
|
||||||
PR c++/54521
|
PR c++/54521
|
||||||
|
|
|
||||||
|
|
@ -1295,6 +1295,14 @@ dump_template_decl (cxx_pretty_printer *pp, tree t, int flags)
|
||||||
tree inner_parms = INNERMOST_TEMPLATE_PARMS (parms);
|
tree inner_parms = INNERMOST_TEMPLATE_PARMS (parms);
|
||||||
int len = TREE_VEC_LENGTH (inner_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_ws_string (pp, "template");
|
||||||
pp_cxx_begin_template_argument_list (pp);
|
pp_cxx_begin_template_argument_list (pp);
|
||||||
|
|
||||||
|
|
|
||||||
32
gcc/cp/pt.c
32
gcc/cp/pt.c
|
|
@ -657,6 +657,12 @@ begin_template_parm_list (void)
|
||||||
++processing_template_decl;
|
++processing_template_decl;
|
||||||
++processing_template_parmlist;
|
++processing_template_parmlist;
|
||||||
note_template_header (0);
|
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
|
/* 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 parm, next;
|
||||||
tree saved_parmlist = make_tree_vec (list_length (parms));
|
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
|
current_template_parms
|
||||||
= tree_cons (size_int (processing_template_decl),
|
= tree_cons (size_int (processing_template_decl),
|
||||||
saved_parmlist, current_template_parms);
|
saved_parmlist, current_template_parms);
|
||||||
|
|
@ -4023,21 +4032,6 @@ template_parms_to_args (tree parms)
|
||||||
args = a;
|
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;
|
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);
|
template_parm_level_and_index (t, &level, &idx);
|
||||||
|
|
||||||
levels = TMPL_ARGS_DEPTH (args);
|
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);
|
arg = TMPL_ARG (args, level, idx);
|
||||||
|
|
||||||
|
|
@ -22440,11 +22435,6 @@ splice_late_return_type (tree type, tree late_return_type)
|
||||||
return type;
|
return type;
|
||||||
argvec = make_tree_vec (1);
|
argvec = make_tree_vec (1);
|
||||||
TREE_VEC_ELT (argvec, 0) = late_return_type;
|
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)
|
if (current_template_parms)
|
||||||
argvec = add_to_template_args (current_template_args (), argvec);
|
argvec = add_to_template_args (current_template_args (), argvec);
|
||||||
return tsubst (type, argvec, tf_warning_or_error, NULL_TREE);
|
return tsubst (type, argvec, tf_warning_or_error, NULL_TREE);
|
||||||
|
|
|
||||||
|
|
@ -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>
|
2015-07-10 Paolo Carlini <paolo.carlini@oracle.com>
|
||||||
|
|
||||||
PR c++/54521
|
PR c++/54521
|
||||||
|
|
|
||||||
|
|
@ -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 { };
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
// { dg-do compile { target c++11 } }
|
// { dg-do compile { target c++11 } }
|
||||||
template<typename...> class tuple { };
|
template<typename...> class tuple { };
|
||||||
|
|
||||||
template<typename T, template<typename T> class... Metafunctions>
|
template<typename T, template<typename U> class... Metafunctions>
|
||||||
struct apply_all
|
struct apply_all
|
||||||
{
|
{
|
||||||
typedef tuple<typename Metafunctions<T>::type...> type;
|
typedef tuple<typename Metafunctions<T>::type...> type;
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ struct tuple {
|
||||||
static const int value = 0;
|
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>...> {
|
struct tuple<Metafunctions<T>...> {
|
||||||
static const int value = 1;
|
static const int value = 1;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -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
|
struct C
|
||||||
{
|
{
|
||||||
B<T> m;
|
B<T> m;
|
||||||
|
|
|
||||||
|
|
@ -2,4 +2,4 @@
|
||||||
|
|
||||||
template<int> struct A {};
|
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 "" }
|
||||||
|
|
|
||||||
|
|
@ -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'" }
|
||||||
|
};
|
||||||
|
|
@ -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 { };
|
||||||
|
|
@ -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;
|
||||||
|
|
@ -89,7 +89,7 @@ namespace __gnu_test {
|
||||||
SharedInfo->first=ptr;
|
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;
|
typename ItType<T>::ContainerType bounds;
|
||||||
test_container(T* _first, T* _last):bounds(_first, _last) {
|
test_container(T* _first, T* _last):bounds(_first, _last) {
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
// { dg-do run }
|
// { dg-do run }
|
||||||
template <class T, template <class T> class C>
|
template <class T, template <class U> class C>
|
||||||
struct X
|
struct X
|
||||||
{};
|
{};
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue