Skip to content

Commit

Permalink
Merge pull request gcc-mirror#56 from iains/contracts-nonattr-p2900-3…
Browse files Browse the repository at this point in the history
…-4-3

Contracts nonattr p2900 3 4 3
  • Loading branch information
villevoutilainen authored Jan 20, 2025
2 parents c252aee + 41e017f commit e5d9e45
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 1 deletion.
28 changes: 27 additions & 1 deletion gcc/cp/contracts.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2769,6 +2769,33 @@ start_function_contracts (tree decl1)
if (!handle_contracts_p (decl1))
return;

/* Check that the user did not try to shadow a function parameter with the
specified postcondition result name. */
if (flag_contracts_nonattr)
for (tree ca = DECL_CONTRACTS (decl1); ca; ca = CONTRACT_CHAIN (ca))
if (POSTCONDITION_P (CONTRACT_STATEMENT (ca)))
if (tree id = POSTCONDITION_IDENTIFIER (CONTRACT_STATEMENT (ca)))
{
if (TREE_CODE (id) == PARM_DECL)
id = DECL_NAME (id);
gcc_checking_assert (id && TREE_CODE (id) == IDENTIFIER_NODE);
tree seen = lookup_name (id);
if (seen
&& TREE_CODE (seen) == PARM_DECL
&& DECL_CONTEXT (seen)
&& DECL_CONTEXT (seen) == decl1)
{
auto_diagnostic_group d;
error_at (EXPR_LOCATION (CONTRACT_STATEMENT (ca)),
"contract postcondition result names must not shadow"
" function parameters");
inform (DECL_SOURCE_LOCATION (seen), "parameter declared here");
POSTCONDITION_IDENTIFIER (CONTRACT_STATEMENT (ca))
= error_mark_node;
CONTRACT_CONDITION (CONTRACT_STATEMENT (ca)) = error_mark_node;
}
}

/* For cdtors, we evaluate the contracts check inline. */
if (!outline_contracts_p (decl1))
return;
Expand All @@ -2778,7 +2805,6 @@ start_function_contracts (tree decl1)
/* Do we already have declarations generated ? */
if (!DECL_PRE_FN (decl1) && !DECL_POST_FN (decl1))
build_contract_function_decls (decl1);

}

/* If we have a precondition function and it's valid, call it. */
Expand Down
15 changes: 15 additions & 0 deletions gcc/cp/decl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5982,6 +5982,21 @@ start_decl (const cp_declarator *declarator,
return error_mark_node;
}

if (flag_contracts_nonattr
&& TREE_CODE (decl) == FUNCTION_DECL
&& !processing_template_decl
&& DECL_RESULT (decl)
&& is_auto (TREE_TYPE (DECL_RESULT (decl))))
for (tree contract = DECL_CONTRACTS (decl); contract;
contract = CONTRACT_CHAIN (contract))
if (POSTCONDITION_P (CONTRACT_STATEMENT (contract))
&& POSTCONDITION_IDENTIFIER (CONTRACT_STATEMENT (contract)))
{
error_at (DECL_SOURCE_LOCATION (decl),
"postconditions with deduced result name types must only"
" appear on function definitions");
return error_mark_node;
}
/* Save the DECL_INITIAL value in case it gets clobbered to assist
with attribute validation. */
initial = DECL_INITIAL (decl);
Expand Down
19 changes: 19 additions & 0 deletions gcc/testsuite/g++.dg/contracts/cpp26/p2900-3-3-4-part1.C
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// { dg-options "-std=c++26 -fcontracts -fcontracts-nonattr" }

int bad_mr_shadow (int r)
post (r: r > 5) // { dg-error "contract postcondition result names must not shadow function parameters" }
{ return r + 1; }

auto no_deduced_res_types_on_non_defs (int x) // { dg-error "postconditions with deduced result name types must only appear on function definitions" }
pre (x > 1)
post (r: r > 17);

// =====

auto f2() post (r : r > 0) // OK, type of r is deduced below.
{ return 5; }

template <typename T>
auto f3 () post (r: r > 0); // OK, postcondition instantiated with template

auto f4 () post (true); // OK, return value not named

0 comments on commit e5d9e45

Please sign in to comment.