@@ -13150,19 +13150,17 @@ cp_parser_statement (cp_parser* parser, tree in_statement_expr,
13150
13150
13151
13151
parens.require_close (parser);
13152
13152
/* Build the contract. */
13153
- tree contract = grok_contract (cont_assert, NULL_TREE /*mode*/,
13154
- NULL_TREE /*result*/, condition, loc);
13155
- if (contract != error_mark_node && !modifier.error_p)
13156
- {
13157
- set_contract_mutable (contract, modifier.mutable_p);
13158
- set_contract_const (contract, modifier.const_p);
13159
- }
13153
+ tree contract
13154
+ = grok_contract (cont_assert, /*mode*/NULL_TREE,
13155
+ /*result*/NULL_TREE, condition, loc);
13156
+ if (contract != error_mark_node)
13157
+ set_contract_const (contract, should_constify);
13160
13158
13161
13159
std_attrs = finish_contract_attribute (cont_assert, contract);
13162
13160
13163
13161
/* If there are errors in the contract, we do not create the
13164
- attribute tree. This assumes no attributes on
13165
- 'contract_assert' */
13162
+ attribute tree. This assumes no attributes on
13163
+ 'contract_assert'. */
13166
13164
if (std_attrs == error_mark_node)
13167
13165
std_attrs = NULL_TREE;
13168
13166
else if (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON))
@@ -31317,27 +31315,40 @@ cp_parser_contract_attribute_spec (cp_parser *parser, tree attribute,
31317
31315
if (attr_mode || identifier)
31318
31316
cp_parser_require (parser, CPP_COLON, RT_COLON);
31319
31317
31320
- /* Defer the parsing of pre/post contracts inside class definitions. */
31318
+ bool should_constify = false;
31319
+ /* When we have P2900 semantics in force.
31320
+ Do we have an override for const-ification? This applies equally to
31321
+ deferred or immediate parses. */
31322
+ if (flag_contracts_nonattr)
31323
+ {
31324
+ should_constify = !flag_contracts_nonattr_noconst;
31325
+ if (!modifier.error_p
31326
+ && (modifier.mutable_p
31327
+ || (flag_contracts_nonattr_const_keyword && !modifier.const_p)))
31328
+ should_constify = false;
31329
+ }
31330
+
31321
31331
tree contract;
31322
31332
if (!assertion_p &&
31323
31333
current_class_type &&
31324
31334
TYPE_BEING_DEFINED (current_class_type))
31325
31335
{
31326
- /* Skip until we reach an unenclose ']'. If we ran into an unnested ']'
31327
- that doesn't close the attribute, return an error and let the attribute
31328
- handling code emit an error for missing ']]'. */
31336
+ /* Defer the parsing of pre/post contracts inside class definitions. */
31329
31337
cp_token *first = cp_lexer_peek_token (parser->lexer);
31330
31338
if (attr_mode)
31331
31339
{
31340
+ /* Skip until we reach a closing token ]. */
31332
31341
cp_parser_skip_to_closing_parenthesis_1 (parser,
31333
31342
/*recovering=*/false,
31334
31343
CPP_CLOSE_SQUARE,
31335
31344
/*consume_paren=*/false);
31336
31345
if (cp_lexer_peek_token (parser->lexer)->type != CPP_CLOSE_SQUARE
31337
31346
|| cp_lexer_peek_nth_token (parser->lexer, 2)->type != CPP_CLOSE_SQUARE)
31338
31347
return error_mark_node;
31348
+ /* Otherwise the closing ]] will be consumed by the caller. */
31339
31349
}
31340
31350
else
31351
+ /* Skip until we reach a closing token ). */
31341
31352
cp_parser_skip_to_closing_parenthesis_1 (parser,
31342
31353
/*recovering=*/false,
31343
31354
CPP_CLOSE_PAREN,
@@ -31371,19 +31382,13 @@ cp_parser_contract_attribute_spec (cp_parser *parser, tree attribute,
31371
31382
}
31372
31383
31373
31384
bool old_flag_contracts_nonattr_noconst = flag_contracts_nonattr_noconst;
31374
-
31375
- /* Do we have an override for const-ification? */
31376
- bool should_constify = !flag_contracts_nonattr_noconst;
31377
- if (!modifier.error_p
31378
- && (modifier.mutable_p
31379
- || (flag_contracts_nonattr_const_keyword && !modifier.const_p)))
31380
- should_constify = false;
31385
+ /* The should_constify value should account for all the mixed flags. */
31381
31386
flag_contracts_nonattr_noconst = !should_constify;
31382
31387
31383
31388
/* If we have a current class object, see if we need to consider
31384
31389
it const when processing the contract condition. */
31385
31390
tree current_class_ref_copy = current_class_ref;
31386
- if (flag_contracts_nonattr && should_constify && current_class_ref_copy)
31391
+ if (should_constify && current_class_ref_copy)
31387
31392
current_class_ref = view_as_const (current_class_ref_copy);
31388
31393
31389
31394
/* Parse the condition, ensuring that parameters or the return variable
@@ -31425,21 +31430,9 @@ cp_parser_contract_attribute_spec (cp_parser *parser, tree attribute,
31425
31430
return error_mark_node;
31426
31431
}
31427
31432
31433
+ /* Save the decision about const-ification. */
31428
31434
if (contract != error_mark_node)
31429
- {
31430
- set_contract_mutable (contract, false);
31431
- set_contract_const (contract, false);
31432
- if (flag_contracts_nonattr && !attr_mode)
31433
- {
31434
- if (!modifier.error_p)
31435
- {
31436
- set_contract_mutable (contract, modifier.mutable_p);
31437
- set_contract_const (contract, modifier.const_p);
31438
- }
31439
- else
31440
- set_contract_const (contract, !flag_contracts_nonattr_noconst);
31441
- }
31442
- }
31435
+ set_contract_const (contract, should_constify);
31443
31436
31444
31437
return finish_contract_attribute (attribute, contract);
31445
31438
}
@@ -31480,15 +31473,7 @@ void cp_parser_late_contract_condition (cp_parser *parser,
31480
31473
++processing_template_decl;
31481
31474
}
31482
31475
31483
- bool mutable_p = get_contract_mutable (contract);
31484
- bool const_p = get_contract_const (contract);
31485
- bool old_flag_contracts_nonattr_noconst = flag_contracts_nonattr_noconst;
31486
- if (flag_contracts_nonattr
31487
- && (mutable_p
31488
- || (flag_contracts_nonattr_const_keyword && !const_p)))
31489
- flag_contracts_nonattr_noconst = true;
31490
-
31491
- /* In C++"0 contracts, 'this' is not allowed in preconditions of
31476
+ /* In C++20 contracts, 'this' is not allowed in preconditions of
31492
31477
constructors or in postconditions of destructors. Note that the
31493
31478
previous value of this variable is established by the calling function,
31494
31479
so we need to save it here. P2900 contracts allow access to members
@@ -31509,22 +31494,21 @@ void cp_parser_late_contract_condition (cp_parser *parser,
31509
31494
}
31510
31495
}
31511
31496
else
31512
- {
31513
- contract_class_ptr = NULL_TREE;
31514
- }
31497
+ contract_class_ptr = NULL_TREE;
31515
31498
31516
31499
push_unparsed_function_queues (parser);
31517
31500
31518
31501
/* Push the saved tokens onto the parser's lexer stack. */
31519
31502
cp_token_cache *tokens = DEFPARSE_TOKENS (condition);
31520
31503
cp_parser_push_lexer_for_tokens (parser, tokens);
31521
31504
31522
- /* if we have a current class object, constify it before processing
31523
- * the contract condition */
31524
- if (flag_contracts_nonattr
31525
- && !flag_contracts_nonattr_noconst
31526
- && current_class_ref)
31527
- current_class_ref = view_as_const (current_class_ref);
31505
+ bool old_flag_contracts_nonattr_noconst = flag_contracts_nonattr_noconst;
31506
+ bool should_constify = get_contract_const (contract);
31507
+ /* If we have a current class object, see if we need to consider
31508
+ it const when processing the contract condition. */
31509
+ tree current_class_ref_copy = current_class_ref;
31510
+ if (should_constify && current_class_ref_copy)
31511
+ current_class_ref = view_as_const (current_class_ref_copy);
31528
31512
31529
31513
/* Parse the condition, ensuring that parameters or the return variable
31530
31514
aren't flagged for use outside the body of a function. */
0 commit comments