aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/parser.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cp/parser.c')
-rw-r--r--gcc/cp/parser.c52
1 files changed, 31 insertions, 21 deletions
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index e443648..7b95dba 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -16596,7 +16596,8 @@ cp_parser_simple_type_specifier (cp_parser* parser,
/*ambiguous_decls=*/NULL,
token->location);
if (tmpl && tmpl != error_mark_node
- && DECL_CLASS_TEMPLATE_P (tmpl))
+ && (DECL_CLASS_TEMPLATE_P (tmpl)
+ || DECL_TEMPLATE_TEMPLATE_PARM_P (tmpl)))
type = make_template_placeholder (tmpl);
else
{
@@ -20311,26 +20312,35 @@ cp_parser_type_id_1 (cp_parser* parser, bool is_template_arg,
&& (!flag_concepts || parser->in_type_id_in_expr_p)
/* None of the valid uses of 'auto' in C++14 involve the type-id
nonterminal, but it is valid in a trailing-return-type. */
- && !(cxx_dialect >= cxx14 && is_trailing_return)
- && type_uses_auto (type_specifier_seq.type))
- {
- /* A type-id with type 'auto' is only ok if the abstract declarator
- is a function declarator with a late-specified return type.
-
- A type-id with 'auto' is also valid in a trailing-return-type
- in a compound-requirement. */
- if (abstract_declarator
- && abstract_declarator->kind == cdk_function
- && abstract_declarator->u.function.late_return_type)
- /* OK */;
- else if (parser->in_result_type_constraint_p)
- /* OK */;
- else
- {
- error ("invalid use of %<auto%>");
- return error_mark_node;
- }
- }
+ && !(cxx_dialect >= cxx14 && is_trailing_return))
+ if (tree auto_node = type_uses_auto (type_specifier_seq.type))
+ {
+ /* A type-id with type 'auto' is only ok if the abstract declarator
+ is a function declarator with a late-specified return type.
+
+ A type-id with 'auto' is also valid in a trailing-return-type
+ in a compound-requirement. */
+ if (abstract_declarator
+ && abstract_declarator->kind == cdk_function
+ && abstract_declarator->u.function.late_return_type)
+ /* OK */;
+ else if (parser->in_result_type_constraint_p)
+ /* OK */;
+ else
+ {
+ location_t loc = type_specifier_seq.locations[ds_type_spec];
+ if (tree tmpl = CLASS_PLACEHOLDER_TEMPLATE (auto_node))
+ {
+ error_at (loc, "missing template arguments after %qT",
+ auto_node);
+ inform (DECL_SOURCE_LOCATION (tmpl), "%qD declared here",
+ tmpl);
+ }
+ else
+ error_at (loc, "invalid use of %qT", auto_node);
+ return error_mark_node;
+ }
+ }
return groktypename (&type_specifier_seq, abstract_declarator,
is_template_arg);