@@ -31453,7 +31453,7 @@ contains_error_p (tree t)
3145331453 return type is known.
3145431454
3145531455 For member functions, contracts are in the complete-class context, so the
31456- parse is deferred. We also have the return type avaialable (unless it's
31456+ parse is deferred. We also have the return type available (unless it's
3145731457 deduced), so we don't need to parse the postcondition in terms of a
3145831458 placeholder. */
3145931459
@@ -31785,17 +31785,9 @@ cp_parser_function_contract_specifier (cp_parser *parser)
3178531785 location_t loc = token->location;
3178631786 bool postcondition_p = is_attribute_p ("post", contract_name);
3178731787
31788- /* Decide if the contract needs to be constified */
31789- bool should_constify = true;
31790-
3179131788 /* Parse experimental modifiers on C++26 contracts. */
31792- contract_modifier modifier = cp_parser_function_contract_modifier_opt (
31793- parser);
31794-
31795- if (!modifier.error_p
31796- && (modifier.mutable_p
31797- || (flag_contracts_nonattr_const_keyword && !modifier.const_p)))
31798- should_constify = false;
31789+ contract_modifier modifier
31790+ = cp_parser_function_contract_modifier_opt (parser);
3179931791
3180031792 matching_parens parens;
3180131793 parens.require_open (parser);
@@ -31804,13 +31796,25 @@ cp_parser_function_contract_specifier (cp_parser *parser)
3180431796 cp_expr identifier;
3180531797 if (postcondition_p && cp_lexer_next_token_is (parser->lexer, CPP_NAME)
3180631798 && cp_lexer_peek_nth_token (parser->lexer, 2)->type == CPP_COLON)
31807- identifier = cp_parser_identifier (parser);
31799+ identifier = cp_parser_identifier (parser);
31800+
3180831801 if (identifier == error_mark_node)
31809- return error_mark_node;
31810- else if (identifier)
31802+ {
31803+ cp_parser_skip_to_closing_parenthesis_1 (parser, /*recovering=*/true,
31804+ CPP_CLOSE_PAREN,
31805+ /*consume_paren=*/true);
31806+ return error_mark_node;
31807+ }
31808+
31809+ if (identifier)
3181131810 cp_parser_require (parser, CPP_COLON, RT_COLON);
3181231811
31813- // Todo check what happens if we get error_mark_node in identifier. Do we recover gracefully ?
31812+ /* Do we have an override for const-ification? */
31813+ bool should_constify = !flag_contracts_nonattr_noconst;
31814+ if (!modifier.error_p
31815+ && (modifier.mutable_p
31816+ || (flag_contracts_nonattr_const_keyword && !modifier.const_p)))
31817+ should_constify = false;
3181431818
3181531819 tree contract;
3181631820 if (current_class_type &&
@@ -31838,9 +31842,9 @@ cp_parser_function_contract_specifier (cp_parser *parser)
3183831842
3183931843 /* And its corresponding contract. */
3184031844 if (identifier)
31841- identifier.maybe_add_location_wrapper ();
31845+ identifier.maybe_add_location_wrapper ();
3184231846 contract = grok_contract (contract_name, /*mode*/NULL_TREE, identifier,
31843- condition, loc);
31847+ condition, loc);
3184431848 }
3184531849 else
3184631850 {
@@ -31862,40 +31866,40 @@ cp_parser_function_contract_specifier (cp_parser *parser)
3186231866 should_constify_contract = should_constify;
3186331867 tree result = NULL_TREE;
3186431868 if (identifier)
31865- {
31866- /* Build a fake variable for the result identifier. */
31867- result = make_postcondition_variable (identifier);
31868- ++processing_template_decl;
31869- }
31869+ {
31870+ /* Build a fake variable for the result identifier. */
31871+ result = make_postcondition_variable (identifier);
31872+ ++processing_template_decl;
31873+ }
3187031874 cp_expr condition = cp_parser_conditional_expression (parser);
3187131875 /* Build the contract. */
3187231876 contract = grok_contract (contract_name, /*mode*/NULL_TREE, result,
31873- condition, loc);
31877+ condition, loc);
3187431878 if (identifier)
31875- --processing_template_decl;
31879+ --processing_template_decl;
3187631880 processing_postcondition = old_pc;
3187731881 should_constify_contract = old_const;
3187831882 gcc_checking_assert (scope_chain && scope_chain->bindings
31879- && scope_chain->bindings->kind == sk_contract);
31883+ && scope_chain->bindings->kind == sk_contract);
3188031884 pop_bindings_and_leave_scope ();
3188131885
3188231886 /* Revert (any) constification of the current class object. */
3188331887 current_class_ref = current_class_ref_copy;
3188431888
3188531889 if (contract != error_mark_node)
31886- {
31887- location_t end = cp_lexer_peek_token (parser->lexer)->location;
31888- loc = make_location (loc, loc, end);
31889- SET_EXPR_LOCATION (contract, loc);
31890- }
31890+ {
31891+ location_t end = cp_lexer_peek_token (parser->lexer)->location;
31892+ loc = make_location (loc, loc, end);
31893+ SET_EXPR_LOCATION (contract, loc);
31894+ }
3189131895
3189231896 parens.require_close (parser);
3189331897 }
3189431898
3189531899 if (!flag_contracts || !flag_contracts_nonattr)
3189631900 {
3189731901 error_at (loc, "P2900 contracts are only available with %<-fcontracts%>"
31898- " and %<-- fcontracts-nonattr%>");
31902+ " and %<-fcontracts-nonattr%>");
3189931903 return error_mark_node;
3190031904 }
3190131905
0 commit comments