Skip to content

Commit e5d9e45

Browse files
Merge pull request gcc-mirror#56 from iains/contracts-nonattr-p2900-3-4-3
Contracts nonattr p2900 3 4 3
2 parents c252aee + 41e017f commit e5d9e45

File tree

3 files changed

+61
-1
lines changed

3 files changed

+61
-1
lines changed

gcc/cp/contracts.cc

+27-1
Original file line numberDiff line numberDiff line change
@@ -2769,6 +2769,33 @@ start_function_contracts (tree decl1)
27692769
if (!handle_contracts_p (decl1))
27702770
return;
27712771

2772+
/* Check that the user did not try to shadow a function parameter with the
2773+
specified postcondition result name. */
2774+
if (flag_contracts_nonattr)
2775+
for (tree ca = DECL_CONTRACTS (decl1); ca; ca = CONTRACT_CHAIN (ca))
2776+
if (POSTCONDITION_P (CONTRACT_STATEMENT (ca)))
2777+
if (tree id = POSTCONDITION_IDENTIFIER (CONTRACT_STATEMENT (ca)))
2778+
{
2779+
if (TREE_CODE (id) == PARM_DECL)
2780+
id = DECL_NAME (id);
2781+
gcc_checking_assert (id && TREE_CODE (id) == IDENTIFIER_NODE);
2782+
tree seen = lookup_name (id);
2783+
if (seen
2784+
&& TREE_CODE (seen) == PARM_DECL
2785+
&& DECL_CONTEXT (seen)
2786+
&& DECL_CONTEXT (seen) == decl1)
2787+
{
2788+
auto_diagnostic_group d;
2789+
error_at (EXPR_LOCATION (CONTRACT_STATEMENT (ca)),
2790+
"contract postcondition result names must not shadow"
2791+
" function parameters");
2792+
inform (DECL_SOURCE_LOCATION (seen), "parameter declared here");
2793+
POSTCONDITION_IDENTIFIER (CONTRACT_STATEMENT (ca))
2794+
= error_mark_node;
2795+
CONTRACT_CONDITION (CONTRACT_STATEMENT (ca)) = error_mark_node;
2796+
}
2797+
}
2798+
27722799
/* For cdtors, we evaluate the contracts check inline. */
27732800
if (!outline_contracts_p (decl1))
27742801
return;
@@ -2778,7 +2805,6 @@ start_function_contracts (tree decl1)
27782805
/* Do we already have declarations generated ? */
27792806
if (!DECL_PRE_FN (decl1) && !DECL_POST_FN (decl1))
27802807
build_contract_function_decls (decl1);
2781-
27822808
}
27832809

27842810
/* If we have a precondition function and it's valid, call it. */

gcc/cp/decl.cc

+15
Original file line numberDiff line numberDiff line change
@@ -5982,6 +5982,21 @@ start_decl (const cp_declarator *declarator,
59825982
return error_mark_node;
59835983
}
59845984

5985+
if (flag_contracts_nonattr
5986+
&& TREE_CODE (decl) == FUNCTION_DECL
5987+
&& !processing_template_decl
5988+
&& DECL_RESULT (decl)
5989+
&& is_auto (TREE_TYPE (DECL_RESULT (decl))))
5990+
for (tree contract = DECL_CONTRACTS (decl); contract;
5991+
contract = CONTRACT_CHAIN (contract))
5992+
if (POSTCONDITION_P (CONTRACT_STATEMENT (contract))
5993+
&& POSTCONDITION_IDENTIFIER (CONTRACT_STATEMENT (contract)))
5994+
{
5995+
error_at (DECL_SOURCE_LOCATION (decl),
5996+
"postconditions with deduced result name types must only"
5997+
" appear on function definitions");
5998+
return error_mark_node;
5999+
}
59856000
/* Save the DECL_INITIAL value in case it gets clobbered to assist
59866001
with attribute validation. */
59876002
initial = DECL_INITIAL (decl);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// { dg-options "-std=c++26 -fcontracts -fcontracts-nonattr" }
2+
3+
int bad_mr_shadow (int r)
4+
post (r: r > 5) // { dg-error "contract postcondition result names must not shadow function parameters" }
5+
{ return r + 1; }
6+
7+
auto no_deduced_res_types_on_non_defs (int x) // { dg-error "postconditions with deduced result name types must only appear on function definitions" }
8+
pre (x > 1)
9+
post (r: r > 17);
10+
11+
// =====
12+
13+
auto f2() post (r : r > 0) // OK, type of r is deduced below.
14+
{ return 5; }
15+
16+
template <typename T>
17+
auto f3 () post (r: r > 0); // OK, postcondition instantiated with template
18+
19+
auto f4 () post (true); // OK, return value not named

0 commit comments

Comments
 (0)