Skip to content

Commit 5c59f09

Browse files
committed
c++, contracts: Some tweaks to the handling of mutable/const modifiers.
Mainly factoring some things and making sure we do not try to parse them in attribute mode. However, we also try to pick a default fallback for the case that the user tries to specify both mutable and const (which is to do the default selected). Signed-off-by: Iain Sandoe <[email protected]>
1 parent 9b90a99 commit 5c59f09

File tree

1 file changed

+49
-39
lines changed

1 file changed

+49
-39
lines changed

gcc/cp/parser.cc

Lines changed: 49 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -2951,7 +2951,7 @@ struct contract_modifier {
29512951
};
29522952

29532953
static contract_modifier cp_parser_function_contract_modifier_opt
2954-
(cp_parser *);
2954+
(cp_parser *, bool);
29552955

29562956
static tree cp_parser_function_contract_specifier
29572957
(cp_parser *);
@@ -13209,7 +13209,8 @@ cp_parser_statement (cp_parser* parser, tree in_statement_expr,
1320913209
cp_token *token = cp_lexer_consume_token (parser->lexer);
1321013210
location_t loc = token->location;
1321113211
contract_modifier modifier
13212-
= cp_parser_function_contract_modifier_opt (parser);
13212+
= cp_parser_function_contract_modifier_opt (parser,
13213+
/*attr_mode*/false);
1321313214

1321413215
matching_parens parens;
1321513216
parens.require_open (parser);
@@ -13220,27 +13221,27 @@ cp_parser_statement (cp_parser* parser, tree in_statement_expr,
1322013221
/* Do we have an override for const-ification? */
1322113222
bool old_flag_contracts_nonattr_noconst
1322213223
= flag_contracts_nonattr_noconst;
13224+
13225+
bool should_constify = !flag_contracts_nonattr_noconst;
1322313226
if (!modifier.error_p
1322413227
&& (modifier.mutable_p
1322513228
|| (flag_contracts_nonattr_const_keyword
1322613229
&& !modifier.const_p)))
13227-
flag_contracts_nonattr_noconst = true;
13230+
should_constify = false;
13231+
flag_contracts_nonattr_noconst = !should_constify;
1322813232

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. */
1323113235
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);
1323613238

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. */
1323913240
++processing_contract_condition;
1324013241
cp_expr condition = cp_parser_conditional_expression (parser);
1324113242
--processing_contract_condition;
1324213243

13243-
/* revert (any) constification of the current class object */
13244+
/* Revert (any) constification of the current class object. */
1324413245
current_class_ref = current_class_ref_copy;
1324513246

1324613247
flag_contracts_nonattr_noconst
@@ -31429,7 +31430,7 @@ cp_parser_contract_attribute_spec (cp_parser *parser, tree attribute,
3142931430

3143031431
/* For experimental modifiers on C++26 contracts. */
3143131432
contract_modifier modifier
31432-
= cp_parser_function_contract_modifier_opt (parser);
31433+
= cp_parser_function_contract_modifier_opt (parser, attr_mode);
3143331434

3143431435
matching_parens parens;
3143531436
if (flag_contracts_nonattr && !attr_mode)
@@ -31485,11 +31486,6 @@ cp_parser_contract_attribute_spec (cp_parser *parser, tree attribute,
3148531486

3148631487
/* And its corresponding contract. */
3148731488
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-
}
3149331489
}
3149431490
else
3149531491
{
@@ -31505,18 +31501,21 @@ cp_parser_contract_attribute_spec (cp_parser *parser, tree attribute,
3150531501
++processing_template_decl;
3150631502
}
3150731503

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+
3150831514
/* Parse the condition, ensuring that parameters or the return variable
3150931515
aren't flagged for use outside the body of a function. */
31510-
bool old_flag_contracts_nonattr_noconst = flag_contracts_nonattr_noconst;
3151131516
++processing_contract_condition;
3151231517
if (postcondition_p)
3151331518
++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-
3152031519
cp_expr condition = cp_parser_conditional_expression (parser);
3152131520
if (postcondition_p)
3152231521
--processing_contract_postcondition;
@@ -31535,11 +31534,6 @@ cp_parser_contract_attribute_spec (cp_parser *parser, tree attribute,
3153531534

3153631535
/* Build the contract. */
3153731536
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-
}
3154331537
/* Leave our temporary scope for the postcondition result. */
3154431538
if (result)
3154531539
{
@@ -31554,6 +31548,22 @@ cp_parser_contract_attribute_spec (cp_parser *parser, tree attribute,
3155431548
return error_mark_node;
3155531549
}
3155631550

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+
3155731567
return finish_contract_attribute (attribute, contract);
3155831568
}
3155931569

@@ -31596,12 +31606,10 @@ void cp_parser_late_contract_condition (cp_parser *parser,
3159631606
bool mutable_p = get_contract_mutable (contract);
3159731607
bool const_p = get_contract_const (contract);
3159831608
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;
3160531613

3160631614
/* In C++"0 contracts, 'this' is not allowed in preconditions of
3160731615
constructors or in postconditions of destructors. Note that the
@@ -31636,7 +31644,9 @@ void cp_parser_late_contract_condition (cp_parser *parser,
3163631644

3163731645
/* if we have a current class object, constify it before processing
3163831646
* 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)
3164031650
current_class_ref = view_as_const (current_class_ref);
3164131651

3164231652
/* Parse the condition, ensuring that parameters or the return variable
@@ -31676,9 +31686,9 @@ void cp_parser_late_contract_condition (cp_parser *parser,
3167631686
}
3167731687

3167831688
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)
3168031690
{
31681-
if (!flag_contracts_nonattr)
31691+
if (!flag_contracts_nonattr || attr_mode)
3168231692
return {};
3168331693

3168431694
contract_modifier mod{};

0 commit comments

Comments
 (0)