PR c++/79056 - C++17 ICE with invalid template syntax.

* parser.c (cp_parser_simple_type_specifier): Don't assume that type
	is a TYPE_DECL.
	(cp_parser_check_for_invalid_template_id): Handle TYPE_DECL.
	* pt.c (template_placeholder_p): New.
	* cp-tree.h: Declare it.

From-SVN: r249614
This commit is contained in:
Jason Merrill 2017-06-23 19:29:51 -04:00 committed by Jason Merrill
parent ee444c5f45
commit e2e80f2f3c
5 changed files with 32 additions and 2 deletions

View File

@ -1,3 +1,12 @@
2017-06-23 Jason Merrill <jason@redhat.com>
PR c++/79056 - C++17 ICE with invalid template syntax.
* parser.c (cp_parser_simple_type_specifier): Don't assume that type
is a TYPE_DECL.
(cp_parser_check_for_invalid_template_id): Handle TYPE_DECL.
* pt.c (template_placeholder_p): New.
* cp-tree.h: Declare it.
2017-06-23 Marc Glisse <marc.glisse@inria.fr> 2017-06-23 Marc Glisse <marc.glisse@inria.fr>
* decl.c (duplicate_decls): Use builtin_structptr_types. * decl.c (duplicate_decls): Use builtin_structptr_types.

View File

@ -6413,6 +6413,7 @@ extern void check_template_variable (tree);
extern tree make_auto (void); extern tree make_auto (void);
extern tree make_decltype_auto (void); extern tree make_decltype_auto (void);
extern tree make_template_placeholder (tree); extern tree make_template_placeholder (tree);
extern bool template_placeholder_p (tree);
extern tree do_auto_deduction (tree, tree, tree); extern tree do_auto_deduction (tree, tree, tree);
extern tree do_auto_deduction (tree, tree, tree, extern tree do_auto_deduction (tree, tree, tree,
tsubst_flags_t, tsubst_flags_t,

View File

@ -2983,7 +2983,9 @@ cp_parser_check_for_invalid_template_id (cp_parser* parser,
if (cp_lexer_next_token_is (parser->lexer, CPP_LESS)) if (cp_lexer_next_token_is (parser->lexer, CPP_LESS))
{ {
if (TYPE_P (type)) if (TREE_CODE (type) == TYPE_DECL)
type = TREE_TYPE (type);
if (TYPE_P (type) && !template_placeholder_p (type))
error_at (location, "%qT is not a template", type); error_at (location, "%qT is not a template", type);
else if (identifier_p (type)) else if (identifier_p (type))
{ {
@ -17060,7 +17062,7 @@ cp_parser_simple_type_specifier (cp_parser* parser,
/* There is no valid C++ program where a non-template type is /* There is no valid C++ program where a non-template type is
followed by a "<". That usually indicates that the user followed by a "<". That usually indicates that the user
thought that the type was a template. */ thought that the type was a template. */
cp_parser_check_for_invalid_template_id (parser, TREE_TYPE (type), cp_parser_check_for_invalid_template_id (parser, type,
none_type, none_type,
token->location); token->location);
} }

View File

@ -24799,6 +24799,14 @@ make_template_placeholder (tree tmpl)
return t; return t;
} }
/* True iff T is a C++17 class template deduction placeholder. */
bool
template_placeholder_p (tree t)
{
return is_auto (t) && CLASS_PLACEHOLDER_TEMPLATE (t);
}
/* Make a "constrained auto" type-specifier. This is an /* Make a "constrained auto" type-specifier. This is an
auto type with constraints that must be associated after auto type with constraints that must be associated after
deduction. The constraint is formed from the given deduction. The constraint is formed from the given

View File

@ -0,0 +1,10 @@
// PR c++/79056
template<class> struct A {};
template<class T> void foo(A<T>=A<T>()) {} // { dg-error "" }
void bar()
{
foo(A<int>()); // { dg-error "" }
}