https://gcc.gnu.org/bugzilla/show_bug.cgi?id=116545
--- Comment #4 from Jakub Jelinek <jakub at gcc dot gnu.org> --- --- gcc/c/c-parser.cc.jj 2025-03-11 22:45:16.638352045 +0100 +++ gcc/c/c-parser.cc 2025-03-12 19:24:45.614217984 +0100 @@ -1820,6 +1820,7 @@ static void c_parser_objc_at_dynamic_dec static bool c_parser_objc_diagnose_bad_element_prefix (c_parser *, struct c_declspecs *); static location_t c_parser_parse_rtl_body (c_parser *, char *); +static tree c_parser_handle_musttail (c_parser *, tree, attr_state &); #if ENABLE_ANALYZER @@ -2519,6 +2520,26 @@ c_parser_declaration_or_fndef (c_parser c_finish_oacc_routine (oacc_routine_data, NULL_TREE, false); return result; } + else if (specs->typespec_kind == ctsk_none + && c_parser_next_token_is_keyword (parser, RID_RETURN)) + { + attr_state astate = {}; + specs->attrs = c_parser_handle_musttail (parser, specs->attrs, astate); + if (astate.musttail_p) + { + if (specs->attrs) + { + auto_urlify_attributes sentinel; + warning_at (c_parser_peek_token (parser)->location, + OPT_Wattributes, + "attribute %<musttail%> mixed with other attributes " + "on %<return%> statement"); + } + c_parser_statement_after_labels (parser, NULL, NULL_TREE, NULL, + astate); + return result; + } + } /* Provide better error recovery. Note that a type name here is usually better diagnosed as a redeclaration. */ @@ -8237,7 +8258,8 @@ c_parser_statement_after_labels (c_parse case RID_ATTRIBUTE: { /* Allow '__attribute__((fallthrough));' or - '__attribute__((assume(cond)));'. */ + '__attribute__((assume(cond)));' or + '__attribute__((musttail))) return'. */ tree attrs = c_parser_gnu_attributes (parser); bool has_assume = lookup_attribute ("assume", attrs); if (has_assume) @@ -8252,6 +8274,20 @@ c_parser_statement_after_labels (c_parse has_assume = false; } } + gcc_assert (!astate.musttail_p); + attrs = c_parser_handle_musttail (parser, attrs, astate); + if (astate.musttail_p) + { + if (attrs) + { + auto_urlify_attributes sentinel; + warning_at (c_parser_peek_token (parser)->location, + OPT_Wattributes, + "attribute %<musttail%> mixed with other " + "attributes on %<return%> statement"); + } + goto restart; + } if (attribute_fallthrough_p (attrs)) { if (c_parser_next_token_is (parser, CPP_SEMICOLON)) does that for C.