Skip to content

Commit 108128d

Browse files
committed
c++, contracts: Improve postcondition locations.
We should now point to the postcondition var if relevant: 3 | post (r: r > 5) | ~~~~~~^~~~~~~~~ We now apply a wrapper when deferring parses - so that the identifier can be re-created in the actual parse. We also check for this in the relevant places. Signed-off-by: Iain Sandoe <iain@sandoe.co.uk>
1 parent e233158 commit 108128d

File tree

2 files changed

+26
-13
lines changed

2 files changed

+26
-13
lines changed

gcc/cp/contracts.cc

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2849,17 +2849,24 @@ start_function_contracts (tree fndecl)
28492849
if (POSTCONDITION_P (CONTRACT_STATEMENT (ca)))
28502850
if (tree id = POSTCONDITION_IDENTIFIER (CONTRACT_STATEMENT (ca)))
28512851
{
2852+
tree r_name = tree_strip_any_location_wrapper (id);
28522853
if (TREE_CODE (id) == PARM_DECL)
2853-
id = DECL_NAME (id);
2854-
gcc_checking_assert (id && TREE_CODE (id) == IDENTIFIER_NODE);
2855-
tree seen = lookup_name (id);
2854+
r_name = DECL_NAME (id);
2855+
gcc_checking_assert (r_name && TREE_CODE (r_name) == IDENTIFIER_NODE);
2856+
tree seen = lookup_name (r_name);
28562857
if (seen
28572858
&& TREE_CODE (seen) == PARM_DECL
28582859
&& DECL_CONTEXT (seen)
28592860
&& DECL_CONTEXT (seen) == fndecl)
28602861
{
28612862
auto_diagnostic_group d;
2862-
error_at (EXPR_LOCATION (CONTRACT_STATEMENT (ca)),
2863+
location_t id_l = location_wrapper_p (id)
2864+
? EXPR_LOCATION (id)
2865+
: DECL_SOURCE_LOCATION (id);
2866+
location_t co_l = EXPR_LOCATION (CONTRACT_STATEMENT (ca));
2867+
if (id_l != UNKNOWN_LOCATION)
2868+
co_l = make_location (id_l, get_start (co_l), get_finish (co_l));
2869+
error_at (co_l,
28632870
"contract postcondition result names must not shadow"
28642871
" function parameters");
28652872
inform (DECL_SOURCE_LOCATION (seen),

gcc/cp/parser.cc

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -31502,6 +31502,8 @@ cp_parser_contract_attribute_spec (cp_parser *parser, tree attribute,
3150231502
DEFPARSE_INSTANTIATIONS (condition) = NULL;
3150331503

3150431504
/* And its corresponding contract. */
31505+
if (identifier)
31506+
identifier.maybe_add_location_wrapper ();
3150531507
contract = grok_contract (attribute, mode, identifier, condition, loc);
3150631508
}
3150731509
else
@@ -31588,16 +31590,19 @@ void cp_parser_late_contract_condition (cp_parser *parser,
3158831590
if (TREE_CODE (condition) != DEFERRED_PARSE)
3158931591
return;
3159031592

31591-
tree identifier = NULL_TREE;
31593+
tree r_ident = NULL_TREE;
3159231594
if (TREE_CODE (contract) == POSTCONDITION_STMT)
31593-
identifier = POSTCONDITION_IDENTIFIER (contract);
31595+
r_ident = POSTCONDITION_IDENTIFIER (contract);
3159431596

3159531597
tree type = TREE_TYPE (TREE_TYPE (fn));
31596-
if (identifier)
31598+
location_t r_loc = UNKNOWN_LOCATION;
31599+
if (r_ident)
3159731600
{
31598-
/* TODO: Can we guarantee that the identifier has a location? */
31599-
location_t loc = cp_expr_location (contract);
31600-
if (!check_postcondition_result (fn, type, loc))
31601+
r_loc = EXPR_LOCATION (r_ident);
31602+
r_ident = tree_strip_any_location_wrapper (r_ident);
31603+
if (r_loc == UNKNOWN_LOCATION)
31604+
r_loc = cp_expr_location (contract);
31605+
if (!check_postcondition_result (fn, type, r_loc))
3160131606
{
3160231607
invalidate_contract (contract);
3160331608
return;
@@ -31649,16 +31654,17 @@ void cp_parser_late_contract_condition (cp_parser *parser,
3164931654
should_constify_contract = should_constify;
3165031655
/* Build a fake variable for the result identifier. */
3165131656
tree result = NULL_TREE;
31652-
if (identifier)
31657+
if (r_ident)
3165331658
{
31654-
result = make_postcondition_variable (identifier, type);
31659+
cp_expr result_id (r_ident, r_loc);
31660+
result = make_postcondition_variable (result_id, type);
3165531661
++processing_template_decl;
3165631662
}
3165731663
cp_expr parsed_condition = cp_parser_conditional_expression (parser);
3165831664
/* Commit to changes. */
3165931665
update_late_contract (contract, result, parsed_condition);
3166031666
/* Leave our temporary scope for the postcondition result. */
31661-
if (identifier)
31667+
if (r_ident)
3166231668
--processing_template_decl;
3166331669
processing_postcondition = old_pc;
3166431670
should_constify_contract = old_const;

0 commit comments

Comments
 (0)