@@ -2951,7 +2951,7 @@ struct contract_modifier {
2951
2951
};
2952
2952
2953
2953
static contract_modifier cp_parser_function_contract_modifier_opt
2954
- (cp_parser *);
2954
+ (cp_parser *, bool );
2955
2955
2956
2956
static tree cp_parser_function_contract_specifier
2957
2957
(cp_parser *);
@@ -13209,7 +13209,8 @@ cp_parser_statement (cp_parser* parser, tree in_statement_expr,
13209
13209
cp_token *token = cp_lexer_consume_token (parser->lexer);
13210
13210
location_t loc = token->location;
13211
13211
contract_modifier modifier
13212
- = cp_parser_function_contract_modifier_opt (parser);
13212
+ = cp_parser_function_contract_modifier_opt (parser,
13213
+ /*attr_mode*/false);
13213
13214
13214
13215
matching_parens parens;
13215
13216
parens.require_open (parser);
@@ -13220,27 +13221,27 @@ cp_parser_statement (cp_parser* parser, tree in_statement_expr,
13220
13221
/* Do we have an override for const-ification? */
13221
13222
bool old_flag_contracts_nonattr_noconst
13222
13223
= flag_contracts_nonattr_noconst;
13224
+
13225
+ bool should_constify = !flag_contracts_nonattr_noconst;
13223
13226
if (!modifier.error_p
13224
13227
&& (modifier.mutable_p
13225
13228
|| (flag_contracts_nonattr_const_keyword
13226
13229
&& !modifier.const_p)))
13227
- flag_contracts_nonattr_noconst = true;
13230
+ should_constify = false;
13231
+ flag_contracts_nonattr_noconst = !should_constify;
13228
13232
13229
- /* if we have a current class object, constify it before processing
13230
- * the contract condition */
13233
+ /* If we have a current class object, see if we need to consider
13234
+ it const when processing the contract condition. */
13231
13235
tree current_class_ref_copy = current_class_ref;
13232
- if (flag_contracts_nonattr
13233
- && !flag_contracts_nonattr_noconst
13234
- && current_class_ref)
13235
- current_class_ref = view_as_const (current_class_ref);
13236
+ if (should_constify && current_class_ref_copy)
13237
+ current_class_ref = view_as_const (current_class_ref_copy);
13236
13238
13237
- /* Parse the condition, ensuring that parameters or the return variable
13238
- aren't flagged for use outside the body of a function. */
13239
+ /* Parse the condition. */
13239
13240
++processing_contract_condition;
13240
13241
cp_expr condition = cp_parser_conditional_expression (parser);
13241
13242
--processing_contract_condition;
13242
13243
13243
- /* revert (any) constification of the current class object */
13244
+ /* Revert (any) constification of the current class object. */
13244
13245
current_class_ref = current_class_ref_copy;
13245
13246
13246
13247
flag_contracts_nonattr_noconst
@@ -31429,7 +31430,7 @@ cp_parser_contract_attribute_spec (cp_parser *parser, tree attribute,
31429
31430
31430
31431
/* For experimental modifiers on C++26 contracts. */
31431
31432
contract_modifier modifier
31432
- = cp_parser_function_contract_modifier_opt (parser);
31433
+ = cp_parser_function_contract_modifier_opt (parser, attr_mode );
31433
31434
31434
31435
matching_parens parens;
31435
31436
if (flag_contracts_nonattr && !attr_mode)
@@ -31485,11 +31486,6 @@ cp_parser_contract_attribute_spec (cp_parser *parser, tree attribute,
31485
31486
31486
31487
/* And its corresponding contract. */
31487
31488
contract = grok_contract (attribute, mode, identifier, condition, loc);
31488
- if (contract != error_mark_node && !modifier.error_p)
31489
- {
31490
- set_contract_mutable (contract, modifier.mutable_p);
31491
- set_contract_const (contract, modifier.const_p);
31492
- }
31493
31489
}
31494
31490
else
31495
31491
{
@@ -31505,18 +31501,21 @@ cp_parser_contract_attribute_spec (cp_parser *parser, tree attribute,
31505
31501
++processing_template_decl;
31506
31502
}
31507
31503
31504
+ 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;
31512
+ flag_contracts_nonattr_noconst = !should_constify;
31513
+
31508
31514
/* Parse the condition, ensuring that parameters or the return variable
31509
31515
aren't flagged for use outside the body of a function. */
31510
- bool old_flag_contracts_nonattr_noconst = flag_contracts_nonattr_noconst;
31511
31516
++processing_contract_condition;
31512
31517
if (postcondition_p)
31513
31518
++processing_contract_postcondition;
31514
- /* Do we have an override for const-ification? */
31515
- if (!modifier.error_p
31516
- && (modifier.mutable_p
31517
- || (flag_contracts_nonattr_const_keyword && !modifier.const_p)))
31518
- flag_contracts_nonattr_noconst = true;
31519
-
31520
31519
cp_expr condition = cp_parser_conditional_expression (parser);
31521
31520
if (postcondition_p)
31522
31521
--processing_contract_postcondition;
@@ -31535,11 +31534,6 @@ cp_parser_contract_attribute_spec (cp_parser *parser, tree attribute,
31535
31534
31536
31535
/* Build the contract. */
31537
31536
contract = grok_contract (attribute, mode, result, condition, loc);
31538
- if (contract != error_mark_node && !modifier.error_p)
31539
- {
31540
- set_contract_mutable (contract, modifier.mutable_p);
31541
- set_contract_const (contract, modifier.const_p);
31542
- }
31543
31537
/* Leave our temporary scope for the postcondition result. */
31544
31538
if (result)
31545
31539
{
@@ -31554,6 +31548,22 @@ cp_parser_contract_attribute_spec (cp_parser *parser, tree attribute,
31554
31548
return error_mark_node;
31555
31549
}
31556
31550
31551
+ if (contract != error_mark_node)
31552
+ {
31553
+ set_contract_mutable (contract, false);
31554
+ set_contract_const (contract, false);
31555
+ if (flag_contracts_nonattr && !attr_mode)
31556
+ {
31557
+ if (!modifier.error_p)
31558
+ {
31559
+ set_contract_mutable (contract, modifier.mutable_p);
31560
+ set_contract_const (contract, modifier.const_p);
31561
+ }
31562
+ else
31563
+ set_contract_const (contract, !flag_contracts_nonattr_noconst);
31564
+ }
31565
+ }
31566
+
31557
31567
return finish_contract_attribute (attribute, contract);
31558
31568
}
31559
31569
@@ -31596,12 +31606,10 @@ void cp_parser_late_contract_condition (cp_parser *parser,
31596
31606
bool mutable_p = get_contract_mutable (contract);
31597
31607
bool const_p = get_contract_const (contract);
31598
31608
bool old_flag_contracts_nonattr_noconst = flag_contracts_nonattr_noconst;
31599
- if (flag_contracts_nonattr && flag_contracts_nonattr_mutable_keyword &&
31600
- mutable_p)
31601
- flag_contracts_nonattr_noconst = 1;
31602
- if (flag_contracts_nonattr && flag_contracts_nonattr_const_keyword &&
31603
- !const_p)
31604
- flag_contracts_nonattr_noconst = 1;
31609
+ if (flag_contracts_nonattr
31610
+ && (mutable_p
31611
+ || (flag_contracts_nonattr_const_keyword && !const_p)))
31612
+ flag_contracts_nonattr_noconst = true;
31605
31613
31606
31614
/* In C++"0 contracts, 'this' is not allowed in preconditions of
31607
31615
constructors or in postconditions of destructors. Note that the
@@ -31636,7 +31644,9 @@ void cp_parser_late_contract_condition (cp_parser *parser,
31636
31644
31637
31645
/* if we have a current class object, constify it before processing
31638
31646
* the contract condition */
31639
- if (flag_contracts_nonattr && !flag_contracts_nonattr_noconst && current_class_ref)
31647
+ if (flag_contracts_nonattr
31648
+ && !flag_contracts_nonattr_noconst
31649
+ && current_class_ref)
31640
31650
current_class_ref = view_as_const (current_class_ref);
31641
31651
31642
31652
/* Parse the condition, ensuring that parameters or the return variable
@@ -31676,9 +31686,9 @@ void cp_parser_late_contract_condition (cp_parser *parser,
31676
31686
}
31677
31687
31678
31688
static contract_modifier
31679
- cp_parser_function_contract_modifier_opt (cp_parser * parser)
31689
+ cp_parser_function_contract_modifier_opt (cp_parser * parser, bool attr_mode )
31680
31690
{
31681
- if (!flag_contracts_nonattr)
31691
+ if (!flag_contracts_nonattr || attr_mode )
31682
31692
return {};
31683
31693
31684
31694
contract_modifier mod{};
0 commit comments