aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/decl.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cp/decl.c')
-rw-r--r--gcc/cp/decl.c58
1 files changed, 46 insertions, 12 deletions
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index bd37faa..4b18d4e 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -9490,6 +9490,11 @@ grokdeclarator (const cp_declarator *declarator,
if (initialized > 1)
funcdef_flag = true;
+ location_t typespec_loc = smallest_type_quals_location (type_quals,
+ declspecs->locations);
+ if (typespec_loc == UNKNOWN_LOCATION)
+ typespec_loc = declspecs->locations[ds_type_spec];
+
/* Look inside a declarator for the name being declared
and get it as a string, for an error message. */
for (id_declarator = declarator;
@@ -10011,6 +10016,16 @@ grokdeclarator (const cp_declarator *declarator,
/* We might have ignored or rejected some of the qualifiers. */
type_quals = cp_type_quals (type);
+ if (cxx_dialect >= cxx1z && type && is_auto (type)
+ && innermost_code != cdk_function
+ && id_declarator && declarator != id_declarator)
+ if (tree tmpl = CLASS_PLACEHOLDER_TEMPLATE (type))
+ {
+ error_at (typespec_loc, "template placeholder type %qT must be followed "
+ "by a simple declarator-id", type);
+ inform (DECL_SOURCE_LOCATION (tmpl), "%qD declared here", tmpl);
+ }
+
staticp = 0;
inlinep = decl_spec_seq_has_spec_p (declspecs, ds_inline);
virtualp = decl_spec_seq_has_spec_p (declspecs, ds_virtual);
@@ -10247,12 +10262,7 @@ grokdeclarator (const cp_declarator *declarator,
{
if (SCALAR_TYPE_P (type) || VOID_TYPE_P (type))
{
- location_t loc;
- loc = smallest_type_quals_location (type_quals,
- declspecs->locations);
- if (loc == UNKNOWN_LOCATION)
- loc = declspecs->locations[ds_type_spec];
- warning_at (loc, OPT_Wignored_qualifiers, "type "
+ warning_at (typespec_loc, OPT_Wignored_qualifiers, "type "
"qualifiers ignored on function return type");
}
/* We now know that the TYPE_QUALS don't apply to the
@@ -10301,11 +10311,12 @@ grokdeclarator (const cp_declarator *declarator,
funcdecl_p = inner_declarator && inner_declarator->kind == cdk_id;
/* Handle a late-specified return type. */
+ tree late_return_type = declarator->u.function.late_return_type;
if (funcdecl_p)
{
- if (type_uses_auto (type))
+ if (tree auto_node = type_uses_auto (type))
{
- if (!declarator->u.function.late_return_type)
+ if (!late_return_type)
{
if (current_class_type
&& LAMBDA_TYPE_P (current_class_type))
@@ -10333,8 +10344,32 @@ grokdeclarator (const cp_declarator *declarator,
name, type);
return error_mark_node;
}
+ if (tree tmpl = CLASS_PLACEHOLDER_TEMPLATE (auto_node))
+ {
+ if (!late_return_type)
+ {
+ if (dguide_name_p (unqualified_id))
+ error_at (typespec_loc, "deduction guide for "
+ "%qT must have trailing return type",
+ TREE_TYPE (tmpl));
+ else
+ error_at (typespec_loc, "deduced class type %qT "
+ "in function return type", type);
+ inform (DECL_SOURCE_LOCATION (tmpl),
+ "%qD declared here", tmpl);
+ }
+ else if (CLASS_TYPE_P (late_return_type)
+ && CLASSTYPE_TEMPLATE_INFO (late_return_type)
+ && (CLASSTYPE_TI_TEMPLATE (late_return_type)
+ == tmpl))
+ /* OK */;
+ else
+ error ("trailing return type %qT of deduction guide "
+ "is not a specialization of %qT",
+ late_return_type, TREE_TYPE (tmpl));
+ }
}
- else if (declarator->u.function.late_return_type
+ else if (late_return_type
&& sfk != sfk_conversion)
{
if (cxx_dialect < cxx11)
@@ -10348,12 +10383,11 @@ grokdeclarator (const cp_declarator *declarator,
return error_mark_node;
}
}
- type = splice_late_return_type
- (type, declarator->u.function.late_return_type);
+ type = splice_late_return_type (type, late_return_type);
if (type == error_mark_node)
return error_mark_node;
- if (declarator->u.function.late_return_type)
+ if (late_return_type)
late_return_type_p = true;
if (ctype == NULL_TREE