From: Jason Merrill Date: Fri, 23 Jun 2017 23:29:51 +0000 (-0400) Subject: PR c++/79056 - C++17 ICE with invalid template syntax. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=e2e80f2f3c05ebc80ed0489babe527468a99e5a1;p=gcc.git 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 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 92f478a0b48..2d590a5d66f 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,12 @@ +2017-06-23 Jason Merrill + + 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 * decl.c (duplicate_decls): Use builtin_structptr_types. diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 40c113b2c10..33dde158dae 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -6413,6 +6413,7 @@ extern void check_template_variable (tree); extern tree make_auto (void); extern tree make_decltype_auto (void); 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, tsubst_flags_t, diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index ddb1cf3d5d6..97cd9237bf2 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -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 (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); 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 followed by a "<". That usually indicates that the user 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, token->location); } diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index fba7fb1d067..392fba07714 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -24799,6 +24799,14 @@ make_template_placeholder (tree tmpl) 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 auto type with constraints that must be associated after deduction. The constraint is formed from the given diff --git a/gcc/testsuite/g++.dg/parse/template28.C b/gcc/testsuite/g++.dg/parse/template28.C new file mode 100644 index 00000000000..6868bc85285 --- /dev/null +++ b/gcc/testsuite/g++.dg/parse/template28.C @@ -0,0 +1,10 @@ +// PR c++/79056 + +template struct A {}; + +template void foo(A=A()) {} // { dg-error "" } + +void bar() +{ + foo(A()); // { dg-error "" } +}