@@ -13249,19 +13249,17 @@ cp_parser_statement (cp_parser* parser, tree in_statement_expr,
13249
13249
13250
13250
parens.require_close (parser);
13251
13251
/* Build the contract. */
13252
- tree contract = grok_contract (cont_assert, NULL_TREE /*mode*/,
13253
- NULL_TREE /*result*/, condition, loc);
13254
- if (contract != error_mark_node && !modifier.error_p)
13255
- {
13256
- set_contract_mutable (contract, modifier.mutable_p);
13257
- set_contract_const (contract, modifier.const_p);
13258
- }
13252
+ tree contract
13253
+ = grok_contract (cont_assert, /*mode*/NULL_TREE,
13254
+ /*result*/NULL_TREE, condition, loc);
13255
+ if (contract != error_mark_node)
13256
+ set_contract_const (contract, should_constify);
13259
13257
13260
13258
std_attrs = finish_contract_attribute (cont_assert, contract);
13261
13259
13262
13260
/* If there are errors in the contract, we do not create the
13263
- attribute tree. This assumes no attributes on
13264
- 'contract_assert' */
13261
+ attribute tree. This assumes no attributes on
13262
+ 'contract_assert'. */
13265
13263
if (std_attrs == error_mark_node)
13266
13264
std_attrs = NULL_TREE;
13267
13265
else if (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON))
@@ -31448,27 +31446,40 @@ cp_parser_contract_attribute_spec (cp_parser *parser, tree attribute,
31448
31446
if (attr_mode || identifier)
31449
31447
cp_parser_require (parser, CPP_COLON, RT_COLON);
31450
31448
31451
- /* Defer the parsing of pre/post contracts inside class definitions. */
31449
+ bool should_constify = false;
31450
+ /* When we have P2900 semantics in force.
31451
+ Do we have an override for const-ification? This applies equally to
31452
+ deferred or immediate parses. */
31453
+ if (flag_contracts_nonattr)
31454
+ {
31455
+ should_constify = !flag_contracts_nonattr_noconst;
31456
+ if (!modifier.error_p
31457
+ && (modifier.mutable_p
31458
+ || (flag_contracts_nonattr_const_keyword && !modifier.const_p)))
31459
+ should_constify = false;
31460
+ }
31461
+
31452
31462
tree contract;
31453
31463
if (!assertion_p &&
31454
31464
current_class_type &&
31455
31465
TYPE_BEING_DEFINED (current_class_type))
31456
31466
{
31457
- /* Skip until we reach an unenclose ']'. If we ran into an unnested ']'
31458
- that doesn't close the attribute, return an error and let the attribute
31459
- handling code emit an error for missing ']]'. */
31467
+ /* Defer the parsing of pre/post contracts inside class definitions. */
31460
31468
cp_token *first = cp_lexer_peek_token (parser->lexer);
31461
31469
if (attr_mode)
31462
31470
{
31471
+ /* Skip until we reach a closing token ]. */
31463
31472
cp_parser_skip_to_closing_parenthesis_1 (parser,
31464
31473
/*recovering=*/false,
31465
31474
CPP_CLOSE_SQUARE,
31466
31475
/*consume_paren=*/false);
31467
31476
if (cp_lexer_peek_token (parser->lexer)->type != CPP_CLOSE_SQUARE
31468
31477
|| cp_lexer_peek_nth_token (parser->lexer, 2)->type != CPP_CLOSE_SQUARE)
31469
31478
return error_mark_node;
31479
+ /* Otherwise the closing ]] will be consumed by the caller. */
31470
31480
}
31471
31481
else
31482
+ /* Skip until we reach a closing token ). */
31472
31483
cp_parser_skip_to_closing_parenthesis_1 (parser,
31473
31484
/*recovering=*/false,
31474
31485
CPP_CLOSE_PAREN,
@@ -31502,19 +31513,13 @@ cp_parser_contract_attribute_spec (cp_parser *parser, tree attribute,
31502
31513
}
31503
31514
31504
31515
bool old_flag_contracts_nonattr_noconst = flag_contracts_nonattr_noconst;
31505
-
31506
- /* Do we have an override for const-ification? */
31507
- bool should_constify = !flag_contracts_nonattr_noconst;
31508
- if (!modifier.error_p
31509
- && (modifier.mutable_p
31510
- || (flag_contracts_nonattr_const_keyword && !modifier.const_p)))
31511
- should_constify = false;
31516
+ /* The should_constify value should account for all the mixed flags. */
31512
31517
flag_contracts_nonattr_noconst = !should_constify;
31513
31518
31514
31519
/* If we have a current class object, see if we need to consider
31515
31520
it const when processing the contract condition. */
31516
31521
tree current_class_ref_copy = current_class_ref;
31517
- if (flag_contracts_nonattr && should_constify && current_class_ref_copy)
31522
+ if (should_constify && current_class_ref_copy)
31518
31523
current_class_ref = view_as_const (current_class_ref_copy);
31519
31524
31520
31525
/* Parse the condition, ensuring that parameters or the return variable
@@ -31556,21 +31561,9 @@ cp_parser_contract_attribute_spec (cp_parser *parser, tree attribute,
31556
31561
return error_mark_node;
31557
31562
}
31558
31563
31564
+ /* Save the decision about const-ification. */
31559
31565
if (contract != error_mark_node)
31560
- {
31561
- set_contract_mutable (contract, false);
31562
- set_contract_const (contract, false);
31563
- if (flag_contracts_nonattr && !attr_mode)
31564
- {
31565
- if (!modifier.error_p)
31566
- {
31567
- set_contract_mutable (contract, modifier.mutable_p);
31568
- set_contract_const (contract, modifier.const_p);
31569
- }
31570
- else
31571
- set_contract_const (contract, !flag_contracts_nonattr_noconst);
31572
- }
31573
- }
31566
+ set_contract_const (contract, should_constify);
31574
31567
31575
31568
return finish_contract_attribute (attribute, contract);
31576
31569
}
@@ -31611,15 +31604,7 @@ void cp_parser_late_contract_condition (cp_parser *parser,
31611
31604
++processing_template_decl;
31612
31605
}
31613
31606
31614
- bool mutable_p = get_contract_mutable (contract);
31615
- bool const_p = get_contract_const (contract);
31616
- bool old_flag_contracts_nonattr_noconst = flag_contracts_nonattr_noconst;
31617
- if (flag_contracts_nonattr
31618
- && (mutable_p
31619
- || (flag_contracts_nonattr_const_keyword && !const_p)))
31620
- flag_contracts_nonattr_noconst = true;
31621
-
31622
- /* In C++"0 contracts, 'this' is not allowed in preconditions of
31607
+ /* In C++20 contracts, 'this' is not allowed in preconditions of
31623
31608
constructors or in postconditions of destructors. Note that the
31624
31609
previous value of this variable is established by the calling function,
31625
31610
so we need to save it here. P2900 contracts allow access to members
@@ -31640,22 +31625,21 @@ void cp_parser_late_contract_condition (cp_parser *parser,
31640
31625
}
31641
31626
}
31642
31627
else
31643
- {
31644
- contract_class_ptr = NULL_TREE;
31645
- }
31628
+ contract_class_ptr = NULL_TREE;
31646
31629
31647
31630
push_unparsed_function_queues (parser);
31648
31631
31649
31632
/* Push the saved tokens onto the parser's lexer stack. */
31650
31633
cp_token_cache *tokens = DEFPARSE_TOKENS (condition);
31651
31634
cp_parser_push_lexer_for_tokens (parser, tokens);
31652
31635
31653
- /* if we have a current class object, constify it before processing
31654
- * the contract condition */
31655
- if (flag_contracts_nonattr
31656
- && !flag_contracts_nonattr_noconst
31657
- && current_class_ref)
31658
- current_class_ref = view_as_const (current_class_ref);
31636
+ bool old_flag_contracts_nonattr_noconst = flag_contracts_nonattr_noconst;
31637
+ bool should_constify = get_contract_const (contract);
31638
+ /* If we have a current class object, see if we need to consider
31639
+ it const when processing the contract condition. */
31640
+ tree current_class_ref_copy = current_class_ref;
31641
+ if (should_constify && current_class_ref_copy)
31642
+ current_class_ref = view_as_const (current_class_ref_copy);
31659
31643
31660
31644
/* Parse the condition, ensuring that parameters or the return variable
31661
31645
aren't flagged for use outside the body of a function. */
0 commit comments