diff options
Diffstat (limited to 'gcc/cp/decl.c')
-rw-r--r-- | gcc/cp/decl.c | 58 |
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 |