@@ -2960,6 +2960,9 @@ static tree cp_parser_function_contract_specifier_seq
2960
2960
static void cp_parser_late_contract_condition
2961
2961
(cp_parser *, tree, tree);
2962
2962
2963
+ static bool cp_parser_should_constify_contract
2964
+ (const contract_modifier&);
2965
+
2963
2966
enum pragma_context {
2964
2967
pragma_external,
2965
2968
pragma_member,
@@ -13220,12 +13223,8 @@ cp_parser_statement (cp_parser* parser, tree in_statement_expr,
13220
13223
0);
13221
13224
13222
13225
/* Do we have an override for const-ification? */
13223
- bool should_constify = !flag_contracts_nonattr_noconst;
13224
- if (!modifier.error_p
13225
- && (modifier.mutable_p
13226
- || (flag_contracts_nonattr_const_keyword
13227
- && !modifier.const_p)))
13228
- should_constify = false;
13226
+ bool should_constify
13227
+ = cp_parser_should_constify_contract (modifier);
13229
13228
13230
13229
/* If we have a current class object, see if we need to consider
13231
13230
it const when processing the contract condition. */
@@ -31745,6 +31744,41 @@ cp_parser_function_contract_modifier_opt (cp_parser * parser)
31745
31744
return mod;
31746
31745
}
31747
31746
31747
+ /* Decide on whether this contract is const-ified, which depends on both
31748
+ the global choice (flag_contracts_nonattr_noconst) and local MODIFIER
31749
+ settings.
31750
+
31751
+ Precedence:
31752
+ 'const' keyword
31753
+ 'mutable' keyword
31754
+ -fcontracts-nonattr-noconst. */
31755
+
31756
+ static bool
31757
+ cp_parser_should_constify_contract (const contract_modifier& modifier)
31758
+ {
31759
+ /* Start with the user's base choice. */
31760
+ bool should_constify = !flag_contracts_nonattr_noconst;
31761
+
31762
+ /* We do not need to check for mutable/const conflicts that was done when
31763
+ parsing the modifier. */
31764
+
31765
+ /* Do we have an override that makes this mutable? */
31766
+ if (!modifier.error_p
31767
+ && (modifier.mutable_p
31768
+ || (flag_contracts_nonattr_const_keyword && !modifier.const_p)))
31769
+ should_constify = false;
31770
+
31771
+ /* Do we have an override that makes this const?
31772
+ This would apply when the base choice is 'no' but we have the const
31773
+ keyword applied to this specific contract. */
31774
+ if (!modifier.error_p
31775
+ && flag_contracts_nonattr_const_keyword
31776
+ && modifier.const_p)
31777
+ should_constify = true;
31778
+
31779
+ return should_constify;
31780
+ }
31781
+
31748
31782
/* Parse a natural syntax contract specifier seq.
31749
31783
31750
31784
function-contract-specifier :
@@ -31759,8 +31793,8 @@ cp_parser_function_contract_modifier_opt (cp_parser * parser)
31759
31793
31760
31794
Return void_list_node if the current token doesn't start a
31761
31795
contract specifier.
31762
-
31763
31796
*/
31797
+
31764
31798
static tree
31765
31799
cp_parser_function_contract_specifier (cp_parser *parser)
31766
31800
{
@@ -31810,11 +31844,7 @@ cp_parser_function_contract_specifier (cp_parser *parser)
31810
31844
cp_parser_require (parser, CPP_COLON, RT_COLON);
31811
31845
31812
31846
/* Do we have an override for const-ification? */
31813
- bool should_constify = !flag_contracts_nonattr_noconst;
31814
- if (!modifier.error_p
31815
- && (modifier.mutable_p
31816
- || (flag_contracts_nonattr_const_keyword && !modifier.const_p)))
31817
- should_constify = false;
31847
+ bool should_constify = cp_parser_should_constify_contract (modifier);
31818
31848
31819
31849
tree contract;
31820
31850
if (current_class_type &&
@@ -31899,7 +31929,7 @@ cp_parser_function_contract_specifier (cp_parser *parser)
31899
31929
if (!flag_contracts || !flag_contracts_nonattr)
31900
31930
{
31901
31931
error_at (loc, "P2900 contracts are only available with %<-fcontracts%>"
31902
- " and %<-fcontracts-nonattr%>");
31932
+ " and %<-fcontracts-nonattr%>");
31903
31933
return error_mark_node;
31904
31934
}
31905
31935
0 commit comments