Skip to content

Commit f9100e8

Browse files
Merge pull request gcc-mirror#90 from iains/contracts-nonattr-factor-and-update-constify-rules
c++, contracts: Factor constify rules and update.
2 parents 911414e + be025c0 commit f9100e8

File tree

3 files changed

+55
-13
lines changed

3 files changed

+55
-13
lines changed

gcc/cp/parser.cc

Lines changed: 43 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2960,6 +2960,9 @@ static tree cp_parser_function_contract_specifier_seq
29602960
static void cp_parser_late_contract_condition
29612961
(cp_parser *, tree, tree);
29622962

2963+
static bool cp_parser_should_constify_contract
2964+
(const contract_modifier&);
2965+
29632966
enum pragma_context {
29642967
pragma_external,
29652968
pragma_member,
@@ -13220,12 +13223,8 @@ cp_parser_statement (cp_parser* parser, tree in_statement_expr,
1322013223
0);
1322113224

1322213225
/* 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);
1322913228

1323013229
/* If we have a current class object, see if we need to consider
1323113230
it const when processing the contract condition. */
@@ -31745,6 +31744,41 @@ cp_parser_function_contract_modifier_opt (cp_parser * parser)
3174531744
return mod;
3174631745
}
3174731746

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+
3174831782
/* Parse a natural syntax contract specifier seq.
3174931783

3175031784
function-contract-specifier :
@@ -31759,8 +31793,8 @@ cp_parser_function_contract_modifier_opt (cp_parser * parser)
3175931793

3176031794
Return void_list_node if the current token doesn't start a
3176131795
contract specifier.
31762-
3176331796
*/
31797+
3176431798
static tree
3176531799
cp_parser_function_contract_specifier (cp_parser *parser)
3176631800
{
@@ -31810,11 +31844,7 @@ cp_parser_function_contract_specifier (cp_parser *parser)
3181031844
cp_parser_require (parser, CPP_COLON, RT_COLON);
3181131845

3181231846
/* 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);
3181831848

3181931849
tree contract;
3182031850
if (current_class_type &&
@@ -31899,7 +31929,7 @@ cp_parser_function_contract_specifier (cp_parser *parser)
3189931929
if (!flag_contracts || !flag_contracts_nonattr)
3190031930
{
3190131931
error_at (loc, "P2900 contracts are only available with %<-fcontracts%>"
31902-
" and %<-fcontracts-nonattr%>");
31932+
" and %<-fcontracts-nonattr%>");
3190331933
return error_mark_node;
3190431934
}
3190531935

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// { dg-options "-std=c++2b -fcontracts -fcontracts-nonattr -fcontracts-nonattr-const-keyword -fcontracts-nonattr-noconst " }
2+
3+
// this is mutable because we have const keywords and it is not marked const.
4+
// fcontracts-nonattr-noconst is ignored.
5+
void good (int x) pre (x++ > 1) {}
6+
7+
// this is const
8+
// again, -fcontracts-nonattr-noconst is ignored
9+
void bad (int x) pre const (x++ > 1) {} // { dg-error {increment of read-only location '\(const int\)x'} }
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
// { dg-options "-std=c++2b -fcontracts -fcontracts-nonattr -fcontracts-nonattr-noconst" }
2+
3+
void good (int x) pre (x++ > 1) {} // should not be an error.

0 commit comments

Comments
 (0)