[PATCH] Fix PR c++/30044

gcc/cp/ChangeLog:

	* parser.c (cp_parser_template_parameter_list): Update
	current_template_parms right after processing a paramater.
	* pt.c (template_parms_to_args): Remove obsolete hack for
	giving template template arguments the proper level.
	(check_default_tmpl_args): Account for tested template
	parameter_lists.
	(splite_late_return_type): Remove obsolete hack for giving
	template template arguments the proper level.

gcc/testsuite/ChangeLog

	* g++.dg/cpp0x/auto45.C: New test.
	* g++.dg/template/pr30044.C: New test.
	* g++.dg/template/crash83.C: Accept any error string.
	* g++.dg/cpp0x/variadic18.C: Adjust to not shadow template
	parameters.
	* g++.dg/cpp0x/variadic18.C: Likewise
	* g++.dg/template/canon-type-13.C: Likewise.
	* g++.old-deja/g++.pt/ttp42.C: Likewise.

From-SVN: r224859
This commit is contained in:
Patrick Palka 2015-06-23 23:41:51 +00:00
parent 8289f048f0
commit 1a8f8908d2
12 changed files with 83 additions and 30 deletions

View File

@ -1,3 +1,14 @@
2015-06-23 Patrick Palka <ppalka@gcc.gnu.org>
* parser.c (cp_parser_template_parameter_list): Update
current_template_parms right after processing a paramater.
* pt.c (template_parms_to_args): Remove obsolete hack for
giving template template arguments the proper level.
(check_default_tmpl_args): Account for tested template
parameter_lists.
(splite_late_return_type): Remove obsolete hack for giving
template template arguments the proper level.
2015-06-23 Jason Merrill <jason@redhat.com>
PR c++/65879

View File

@ -13273,6 +13273,11 @@ cp_parser_template_parameter_list (cp_parser* parser)
begin_template_parm_list ();
current_template_parms
= tree_cons (size_int (processing_template_decl),
make_tree_vec (0),
current_template_parms);
/* The loop below parses the template parms. We first need to know
the total number of template parms to be able to compute proper
canonical types of each dependent type. So after the loop, when
@ -13285,6 +13290,7 @@ cp_parser_template_parameter_list (cp_parser* parser)
bool is_non_type;
bool is_parameter_pack;
location_t parm_loc;
tree parameter_vec;
/* Parse the template-parameter. */
parm_loc = cp_lexer_peek_token (parser->lexer)->location;
@ -13309,8 +13315,27 @@ cp_parser_template_parameter_list (cp_parser* parser)
break;
/* Otherwise, consume the `,' token. */
cp_lexer_consume_token (parser->lexer);
/* Add the parameter we just processed to current_template_parms. */
parameter_vec = make_tree_vec
(TREE_VEC_LENGTH (TREE_VALUE (current_template_parms)) + 1);
for (int i = 0; i < TREE_VEC_LENGTH (parameter_vec) - 1; i++)
TREE_VEC_ELT (parameter_vec, i)
= TREE_VEC_ELT (TREE_VALUE (current_template_parms), i);
TREE_VEC_ELT (parameter_vec, TREE_VEC_LENGTH (parameter_vec) - 1)
= tree_last (parameter_list);
current_template_parms
= tree_cons (TREE_PURPOSE (current_template_parms),
parameter_vec,
TREE_CHAIN (current_template_parms));
}
current_template_parms = TREE_CHAIN (current_template_parms);
return end_template_parm_list (parameter_list);
}

View File

@ -3989,21 +3989,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;
}
@ -4646,6 +4631,9 @@ check_default_tmpl_args (tree decl, tree parms, bool is_primary,
else
msg = G_("default argument for template parameter for class enclosing %qD");
/* By default check everything. */
last_level_to_check = 1;
if (current_class_type && TYPE_BEING_DEFINED (current_class_type))
/* If we're inside a class definition, there's no need to
examine the parameters to the class itself. On the one
@ -4655,10 +4643,12 @@ check_default_tmpl_args (tree decl, tree parms, bool is_primary,
struct S { template <class U> void f(U); };
Here the default argument for `S' has no bearing on the
declaration of `f'. */
last_level_to_check = template_class_depth (current_class_type) + 1;
else
/* Check everything. */
last_level_to_check = 0;
last_level_to_check += template_class_depth (current_class_type);
if (processing_template_parmlist)
/* Likewise for parameters outside of the nested parameter list we have
just finished defining. */
last_level_to_check += processing_template_parmlist;
for (parm_level = parms;
parm_level && TMPL_PARMS_DEPTH (parm_level) >= last_level_to_check;
@ -22392,11 +22382,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);

View File

@ -1,3 +1,14 @@
2015-06-23 Patrick Palka <ppalka@gcc.gnu.org>
* g++.dg/cpp0x/auto45.C: New test.
* g++.dg/template/pr30044.C: New test.
* g++.dg/template/crash83.C: Accept any error string.
* g++.dg/cpp0x/variadic18.C: Adjust to not shadow template
parameters.
* g++.dg/cpp0x/variadic18.C: Likewise
* g++.dg/template/canon-type-13.C: Likewise.
* g++.old-deja/g++.pt/ttp42.C: Likewise.
2015-06-23 Marek Polacek <polacek@redhat.com>
* c-c++-common/Wlogical-op-3.c: New test.

View File

@ -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 { };

View File

@ -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;

View File

@ -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;
};

View File

@ -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;

View File

@ -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 "" }

View File

@ -0,0 +1,16 @@
// 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 { };

View File

@ -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) {
}

View File

@ -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
{};