@@ -11815,7 +11815,9 @@ cp_parser_lambda_introducer (cp_parser* parser, tree lambda_expr)
11815
11815
cp_lexer_consume_token (parser->lexer);
11816
11816
first = false;
11817
11817
11818
- if (!(at_function_scope_p () || parsing_nsdmi ()))
11818
+ if (!(at_function_scope_p ()
11819
+ || parsing_nsdmi ()
11820
+ || current_binding_level->kind == sk_contract))
11819
11821
error ("non-local lambda expression cannot have a capture-default");
11820
11822
}
11821
11823
@@ -13120,16 +13122,12 @@ cp_parser_statement (cp_parser* parser, tree in_statement_expr,
13120
13122
0);
13121
13123
13122
13124
/* Do we have an override for const-ification? */
13123
- bool old_flag_contracts_nonattr_noconst
13124
- = flag_contracts_nonattr_noconst;
13125
-
13126
13125
bool should_constify = !flag_contracts_nonattr_noconst;
13127
13126
if (!modifier.error_p
13128
13127
&& (modifier.mutable_p
13129
13128
|| (flag_contracts_nonattr_const_keyword
13130
13129
&& !modifier.const_p)))
13131
13130
should_constify = false;
13132
- flag_contracts_nonattr_noconst = !should_constify;
13133
13131
13134
13132
/* If we have a current class object, see if we need to consider
13135
13133
it const when processing the contract condition. */
@@ -13138,24 +13136,30 @@ cp_parser_statement (cp_parser* parser, tree in_statement_expr,
13138
13136
current_class_ref = view_as_const (current_class_ref_copy);
13139
13137
13140
13138
/* Parse the condition. */
13141
- ++processing_contract_condition;
13139
+ tree contract = error_mark_node;
13140
+ begin_scope (sk_contract, current_function_decl);
13141
+ bool old_pc = processing_postcondition;
13142
+ bool old_const = should_constify_contract;
13143
+ processing_postcondition = false;
13144
+ should_constify_contract = should_constify;
13142
13145
cp_expr condition = cp_parser_conditional_expression (parser);
13143
- --processing_contract_condition;
13146
+ gcc_checking_assert (scope_chain && scope_chain->bindings
13147
+ && scope_chain->bindings->kind == sk_contract);
13148
+ /* Build the contract. */
13149
+ contract
13150
+ = grok_contract (cont_assert, /*mode*/NULL_TREE,
13151
+ /*result*/NULL_TREE, condition, loc);
13152
+ processing_postcondition = old_pc;
13153
+ should_constify_contract = old_const;
13154
+ pop_bindings_and_leave_scope ();
13144
13155
13145
13156
/* Revert (any) constification of the current class object. */
13146
13157
current_class_ref = current_class_ref_copy;
13147
13158
13148
- flag_contracts_nonattr_noconst
13149
- = old_flag_contracts_nonattr_noconst;
13150
-
13151
13159
parens.require_close (parser);
13152
- /* Build the contract. */
13153
- tree contract
13154
- = grok_contract (cont_assert, /*mode*/NULL_TREE,
13155
- /*result*/NULL_TREE, condition, loc);
13160
+
13156
13161
if (contract != error_mark_node)
13157
13162
set_contract_const (contract, should_constify);
13158
-
13159
13163
std_attrs = finish_contract_attribute (cont_assert, contract);
13160
13164
13161
13165
/* If there are errors in the contract, we do not create the
@@ -31372,19 +31376,6 @@ cp_parser_contract_attribute_spec (cp_parser *parser, tree attribute,
31372
31376
/* Enable location wrappers when parsing contracts. */
31373
31377
auto suppression = make_temp_override (suppress_location_wrappers, 0);
31374
31378
31375
- /* Build a fake variable for the result identifier. */
31376
- tree result = NULL_TREE;
31377
- if (identifier)
31378
- {
31379
- begin_scope (sk_block, NULL_TREE);
31380
- result = make_postcondition_variable (identifier);
31381
- ++processing_template_decl;
31382
- }
31383
-
31384
- bool old_flag_contracts_nonattr_noconst = flag_contracts_nonattr_noconst;
31385
- /* The should_constify value should account for all the mixed flags. */
31386
- flag_contracts_nonattr_noconst = !should_constify;
31387
-
31388
31379
/* If we have a current class object, see if we need to consider
31389
31380
it const when processing the contract condition. */
31390
31381
tree current_class_ref_copy = current_class_ref;
@@ -31393,16 +31384,31 @@ cp_parser_contract_attribute_spec (cp_parser *parser, tree attribute,
31393
31384
31394
31385
/* Parse the condition, ensuring that parameters or the return variable
31395
31386
aren't flagged for use outside the body of a function. */
31396
- ++processing_contract_condition;
31397
- if (postcondition_p)
31398
- ++processing_contract_postcondition;
31387
+ begin_scope (sk_contract, current_function_decl);
31388
+ bool old_pc = processing_postcondition;
31389
+ bool old_const = should_constify_contract;
31390
+ processing_postcondition = postcondition_p;
31391
+ should_constify_contract = should_constify;
31392
+ tree result = NULL_TREE;
31393
+ if (identifier)
31394
+ {
31395
+ /* Build a fake variable for the result identifier. */
31396
+ result = make_postcondition_variable (identifier);
31397
+ ++processing_template_decl;
31398
+ }
31399
31399
cp_expr condition = cp_parser_conditional_expression (parser);
31400
- if (postcondition_p)
31401
- --processing_contract_postcondition;
31400
+ /* Build the contract. */
31401
+ contract = grok_contract (attribute, mode, result, condition, loc);
31402
+ if (identifier)
31403
+ --processing_template_decl;
31404
+ processing_postcondition = old_pc;
31405
+ should_constify_contract = old_const;
31406
+ gcc_checking_assert (scope_chain && scope_chain->bindings
31407
+ && scope_chain->bindings->kind == sk_contract);
31408
+ pop_bindings_and_leave_scope ();
31409
+
31402
31410
/* Revert (any) constification of the current class object. */
31403
31411
current_class_ref = current_class_ref_copy;
31404
- flag_contracts_nonattr_noconst = old_flag_contracts_nonattr_noconst;
31405
- --processing_contract_condition;
31406
31412
31407
31413
/* For natural syntax, we eat the parens here. For the attribute
31408
31414
syntax, it will be done one level up, we just need to skip to it. */
@@ -31413,15 +31419,6 @@ cp_parser_contract_attribute_spec (cp_parser *parser, tree attribute,
31413
31419
we need to search the condition for errors. */
31414
31420
else if (contains_error_p (condition))
31415
31421
cp_parser_skip_up_to_closing_square_bracket (parser);
31416
-
31417
- /* Build the contract. */
31418
- contract = grok_contract (attribute, mode, result, condition, loc);
31419
- /* Leave our temporary scope for the postcondition result. */
31420
- if (result)
31421
- {
31422
- --processing_template_decl;
31423
- pop_bindings_and_leave_scope ();
31424
- }
31425
31422
}
31426
31423
31427
31424
if (!flag_contracts)
@@ -31455,22 +31452,16 @@ void cp_parser_late_contract_condition (cp_parser *parser,
31455
31452
if (TREE_CODE (contract) == POSTCONDITION_STMT)
31456
31453
identifier = POSTCONDITION_IDENTIFIER (contract);
31457
31454
31458
- /* Build a fake variable for the result identifier. */
31459
- tree result = NULL_TREE;
31455
+ tree type = TREE_TYPE (TREE_TYPE (fn));
31460
31456
if (identifier)
31461
31457
{
31462
31458
/* TODO: Can we guarantee that the identifier has a location? */
31463
31459
location_t loc = cp_expr_location (contract);
31464
- tree type = TREE_TYPE (TREE_TYPE (fn));
31465
31460
if (!check_postcondition_result (fn, type, loc))
31466
31461
{
31467
31462
invalidate_contract (contract);
31468
31463
return;
31469
31464
}
31470
-
31471
- begin_scope (sk_block, NULL_TREE);
31472
- result = make_postcondition_variable (identifier, type);
31473
- ++processing_template_decl;
31474
31465
}
31475
31466
31476
31467
/* In C++20 contracts, 'this' is not allowed in preconditions of
@@ -31502,7 +31493,6 @@ void cp_parser_late_contract_condition (cp_parser *parser,
31502
31493
cp_token_cache *tokens = DEFPARSE_TOKENS (condition);
31503
31494
cp_parser_push_lexer_for_tokens (parser, tokens);
31504
31495
31505
- bool old_flag_contracts_nonattr_noconst = flag_contracts_nonattr_noconst;
31506
31496
bool should_constify = get_contract_const (contract);
31507
31497
/* If we have a current class object, see if we need to consider
31508
31498
it const when processing the contract condition. */
@@ -31512,17 +31502,32 @@ void cp_parser_late_contract_condition (cp_parser *parser,
31512
31502
31513
31503
/* Parse the condition, ensuring that parameters or the return variable
31514
31504
aren't flagged for use outside the body of a function. */
31515
- ++processing_contract_condition;
31516
- if (POSTCONDITION_P (contract))
31517
- ++processing_contract_postcondition;
31505
+ begin_scope (sk_contract, fn);
31506
+ bool old_pc = processing_postcondition;
31507
+ bool old_const = should_constify_contract;
31508
+ processing_postcondition = POSTCONDITION_P (contract);
31509
+ should_constify_contract = should_constify;
31510
+ /* Build a fake variable for the result identifier. */
31511
+ tree result = NULL_TREE;
31512
+ if (identifier)
31513
+ {
31514
+ result = make_postcondition_variable (identifier, type);
31515
+ ++processing_template_decl;
31516
+ }
31518
31517
condition = cp_parser_conditional_expression (parser);
31519
- if (POSTCONDITION_P (contract))
31520
- --processing_contract_postcondition;
31521
- --processing_contract_condition;
31518
+ /* Commit to changes. */
31519
+ update_late_contract (contract, result, condition);
31520
+ /* Leave our temporary scope for the postcondition result. */
31521
+ if (identifier)
31522
+ --processing_template_decl;
31523
+ processing_postcondition = old_pc;
31524
+ should_constify_contract = old_const;
31525
+ gcc_checking_assert (scope_chain && scope_chain->bindings
31526
+ && scope_chain->bindings->kind == sk_contract);
31527
+ pop_bindings_and_leave_scope ();
31522
31528
31523
31529
if (cp_lexer_next_token_is_not (parser->lexer, CPP_EOF))
31524
- error_at (input_location,
31525
- "expected conditional-expression");
31530
+ error_at (input_location, "expected conditional-expression");
31526
31531
31527
31532
/* Revert to the main lexer. */
31528
31533
cp_parser_pop_lexer (parser);
@@ -31533,17 +31538,6 @@ void cp_parser_late_contract_condition (cp_parser *parser,
31533
31538
current_class_ref = saved_ccr;
31534
31539
current_class_ptr = saved_ccp;
31535
31540
contract_class_ptr = saved_contract_ccp;
31536
-
31537
- /* Commit to changes. */
31538
- update_late_contract (contract, result, condition);
31539
- flag_contracts_nonattr_noconst = old_flag_contracts_nonattr_noconst;
31540
-
31541
- /* Leave our temporary scope for the postcondition result. */
31542
- if (result)
31543
- {
31544
- --processing_template_decl;
31545
- pop_bindings_and_leave_scope ();
31546
- }
31547
31541
}
31548
31542
31549
31543
static contract_modifier
0 commit comments