Skip to content

Commit 9c05c26

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 <[email protected]>
1 parent 1d12e63 commit 9c05c26

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
@@ -2859,17 +2859,24 @@ start_function_contracts (tree fndecl)
28592859
if (POSTCONDITION_P (CONTRACT_STATEMENT (ca)))
28602860
if (tree id = POSTCONDITION_IDENTIFIER (CONTRACT_STATEMENT (ca)))
28612861
{
2862+
tree r_name = tree_strip_any_location_wrapper (id);
28622863
if (TREE_CODE (id) == PARM_DECL)
2863-
id = DECL_NAME (id);
2864-
gcc_checking_assert (id && TREE_CODE (id) == IDENTIFIER_NODE);
2865-
tree seen = lookup_name (id);
2864+
r_name = DECL_NAME (id);
2865+
gcc_checking_assert (r_name && TREE_CODE (r_name) == IDENTIFIER_NODE);
2866+
tree seen = lookup_name (r_name);
28662867
if (seen
28672868
&& TREE_CODE (seen) == PARM_DECL
28682869
&& DECL_CONTEXT (seen)
28692870
&& DECL_CONTEXT (seen) == fndecl)
28702871
{
28712872
auto_diagnostic_group d;
2872-
error_at (EXPR_LOCATION (CONTRACT_STATEMENT (ca)),
2873+
location_t id_l = location_wrapper_p (id)
2874+
? EXPR_LOCATION (id)
2875+
: DECL_SOURCE_LOCATION (id);
2876+
location_t co_l = EXPR_LOCATION (CONTRACT_STATEMENT (ca));
2877+
if (id_l != UNKNOWN_LOCATION)
2878+
co_l = make_location (id_l, get_start (co_l), get_finish (co_l));
2879+
error_at (co_l,
28732880
"contract postcondition result names must not shadow"
28742881
" function parameters");
28752882
inform (DECL_SOURCE_LOCATION (seen),

gcc/cp/parser.cc

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

3154831548
/* And its corresponding contract. */
31549+
if (identifier)
31550+
identifier.maybe_add_location_wrapper ();
3154931551
contract = grok_contract (attribute, mode, identifier, condition, loc);
3155031552
}
3155131553
else
@@ -31632,16 +31634,19 @@ void cp_parser_late_contract_condition (cp_parser *parser,
3163231634
if (TREE_CODE (condition) != DEFERRED_PARSE)
3163331635
return;
3163431636

31635-
tree identifier = NULL_TREE;
31637+
tree r_ident = NULL_TREE;
3163631638
if (TREE_CODE (contract) == POSTCONDITION_STMT)
31637-
identifier = POSTCONDITION_IDENTIFIER (contract);
31639+
r_ident = POSTCONDITION_IDENTIFIER (contract);
3163831640

3163931641
tree type = TREE_TYPE (TREE_TYPE (fn));
31640-
if (identifier)
31642+
location_t r_loc = UNKNOWN_LOCATION;
31643+
if (r_ident)
3164131644
{
31642-
/* TODO: Can we guarantee that the identifier has a location? */
31643-
location_t loc = cp_expr_location (contract);
31644-
if (!check_postcondition_result (fn, type, loc))
31645+
r_loc = EXPR_LOCATION (r_ident);
31646+
r_ident = tree_strip_any_location_wrapper (r_ident);
31647+
if (r_loc == UNKNOWN_LOCATION)
31648+
r_loc = cp_expr_location (contract);
31649+
if (!check_postcondition_result (fn, type, r_loc))
3164531650
{
3164631651
invalidate_contract (contract);
3164731652
return;
@@ -31693,16 +31698,17 @@ void cp_parser_late_contract_condition (cp_parser *parser,
3169331698
should_constify_contract = should_constify;
3169431699
/* Build a fake variable for the result identifier. */
3169531700
tree result = NULL_TREE;
31696-
if (identifier)
31701+
if (r_ident)
3169731702
{
31698-
result = make_postcondition_variable (identifier, type);
31703+
cp_expr result_id (r_ident, r_loc);
31704+
result = make_postcondition_variable (result_id, type);
3169931705
++processing_template_decl;
3170031706
}
3170131707
cp_expr parsed_condition = cp_parser_conditional_expression (parser);
3170231708
/* Commit to changes. */
3170331709
update_late_contract (contract, result, parsed_condition);
3170431710
/* Leave our temporary scope for the postcondition result. */
31705-
if (identifier)
31711+
if (r_ident)
3170631712
--processing_template_decl;
3170731713
processing_postcondition = old_pc;
3170831714
should_constify_contract = old_const;

0 commit comments

Comments
 (0)