@@ -31453,7 +31453,7 @@ contains_error_p (tree t)
31453
31453
return type is known.
31454
31454
31455
31455
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
31457
31457
deduced), so we don't need to parse the postcondition in terms of a
31458
31458
placeholder. */
31459
31459
@@ -31785,17 +31785,9 @@ cp_parser_function_contract_specifier (cp_parser *parser)
31785
31785
location_t loc = token->location;
31786
31786
bool postcondition_p = is_attribute_p ("post", contract_name);
31787
31787
31788
- /* Decide if the contract needs to be constified */
31789
- bool should_constify = true;
31790
-
31791
31788
/* 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);
31799
31791
31800
31792
matching_parens parens;
31801
31793
parens.require_open (parser);
@@ -31804,13 +31796,25 @@ cp_parser_function_contract_specifier (cp_parser *parser)
31804
31796
cp_expr identifier;
31805
31797
if (postcondition_p && cp_lexer_next_token_is (parser->lexer, CPP_NAME)
31806
31798
&& cp_lexer_peek_nth_token (parser->lexer, 2)->type == CPP_COLON)
31807
- identifier = cp_parser_identifier (parser);
31799
+ identifier = cp_parser_identifier (parser);
31800
+
31808
31801
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)
31811
31810
cp_parser_require (parser, CPP_COLON, RT_COLON);
31812
31811
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;
31814
31818
31815
31819
tree contract;
31816
31820
if (current_class_type &&
@@ -31838,9 +31842,9 @@ cp_parser_function_contract_specifier (cp_parser *parser)
31838
31842
31839
31843
/* And its corresponding contract. */
31840
31844
if (identifier)
31841
- identifier.maybe_add_location_wrapper ();
31845
+ identifier.maybe_add_location_wrapper ();
31842
31846
contract = grok_contract (contract_name, /*mode*/NULL_TREE, identifier,
31843
- condition, loc);
31847
+ condition, loc);
31844
31848
}
31845
31849
else
31846
31850
{
@@ -31862,40 +31866,40 @@ cp_parser_function_contract_specifier (cp_parser *parser)
31862
31866
should_constify_contract = should_constify;
31863
31867
tree result = NULL_TREE;
31864
31868
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
+ }
31870
31874
cp_expr condition = cp_parser_conditional_expression (parser);
31871
31875
/* Build the contract. */
31872
31876
contract = grok_contract (contract_name, /*mode*/NULL_TREE, result,
31873
- condition, loc);
31877
+ condition, loc);
31874
31878
if (identifier)
31875
- --processing_template_decl;
31879
+ --processing_template_decl;
31876
31880
processing_postcondition = old_pc;
31877
31881
should_constify_contract = old_const;
31878
31882
gcc_checking_assert (scope_chain && scope_chain->bindings
31879
- && scope_chain->bindings->kind == sk_contract);
31883
+ && scope_chain->bindings->kind == sk_contract);
31880
31884
pop_bindings_and_leave_scope ();
31881
31885
31882
31886
/* Revert (any) constification of the current class object. */
31883
31887
current_class_ref = current_class_ref_copy;
31884
31888
31885
31889
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
+ }
31891
31895
31892
31896
parens.require_close (parser);
31893
31897
}
31894
31898
31895
31899
if (!flag_contracts || !flag_contracts_nonattr)
31896
31900
{
31897
31901
error_at (loc, "P2900 contracts are only available with %<-fcontracts%>"
31898
- " and %<-- fcontracts-nonattr%>");
31902
+ " and %<-fcontracts-nonattr%>");
31899
31903
return error_mark_node;
31900
31904
}
31901
31905
0 commit comments