@@ -31490,6 +31490,8 @@ cp_parser_contract_attribute_spec (cp_parser *parser, tree attribute,
31490
31490
/*consume_paren=*/false);
31491
31491
31492
31492
cp_token *last = cp_lexer_peek_token (parser->lexer);
31493
+ location_t end = last->location;
31494
+ loc = make_location (loc, loc, end);
31493
31495
31494
31496
if (!attr_mode)
31495
31497
parens.require_close (parser);
@@ -31500,6 +31502,8 @@ cp_parser_contract_attribute_spec (cp_parser *parser, tree attribute,
31500
31502
DEFPARSE_INSTANTIATIONS (condition) = NULL;
31501
31503
31502
31504
/* And its corresponding contract. */
31505
+ if (identifier)
31506
+ identifier.maybe_add_location_wrapper ();
31503
31507
contract = grok_contract (attribute, mode, identifier, condition, loc);
31504
31508
}
31505
31509
else
@@ -31541,6 +31545,13 @@ cp_parser_contract_attribute_spec (cp_parser *parser, tree attribute,
31541
31545
/* Revert (any) constification of the current class object. */
31542
31546
current_class_ref = current_class_ref_copy;
31543
31547
31548
+ if (contract != error_mark_node)
31549
+ {
31550
+ location_t end = cp_lexer_peek_token (parser->lexer)->location;
31551
+ loc = make_location (loc, loc, end);
31552
+ SET_EXPR_LOCATION (contract, loc);
31553
+ }
31554
+
31544
31555
/* For natural syntax, we eat the parens here. For the attribute
31545
31556
syntax, it will be done one level up, we just need to skip to it. */
31546
31557
if (!attr_mode)
@@ -31579,16 +31590,19 @@ void cp_parser_late_contract_condition (cp_parser *parser,
31579
31590
if (TREE_CODE (condition) != DEFERRED_PARSE)
31580
31591
return;
31581
31592
31582
- tree identifier = NULL_TREE;
31593
+ tree r_ident = NULL_TREE;
31583
31594
if (TREE_CODE (contract) == POSTCONDITION_STMT)
31584
- identifier = POSTCONDITION_IDENTIFIER (contract);
31595
+ r_ident = POSTCONDITION_IDENTIFIER (contract);
31585
31596
31586
31597
tree type = TREE_TYPE (TREE_TYPE (fn));
31587
- if (identifier)
31598
+ location_t r_loc = UNKNOWN_LOCATION;
31599
+ if (r_ident)
31588
31600
{
31589
- /* TODO: Can we guarantee that the identifier has a location? */
31590
- location_t loc = cp_expr_location (contract);
31591
- 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))
31592
31606
{
31593
31607
invalidate_contract (contract);
31594
31608
return;
@@ -31640,16 +31654,17 @@ void cp_parser_late_contract_condition (cp_parser *parser,
31640
31654
should_constify_contract = should_constify;
31641
31655
/* Build a fake variable for the result identifier. */
31642
31656
tree result = NULL_TREE;
31643
- if (identifier )
31657
+ if (r_ident )
31644
31658
{
31645
- result = make_postcondition_variable (identifier, type);
31659
+ cp_expr result_id (r_ident, r_loc);
31660
+ result = make_postcondition_variable (result_id, type);
31646
31661
++processing_template_decl;
31647
31662
}
31648
- condition = cp_parser_conditional_expression (parser);
31663
+ cp_expr parsed_condition = cp_parser_conditional_expression (parser);
31649
31664
/* Commit to changes. */
31650
- update_late_contract (contract, result, condition );
31665
+ update_late_contract (contract, result, parsed_condition );
31651
31666
/* Leave our temporary scope for the postcondition result. */
31652
- if (identifier )
31667
+ if (r_ident )
31653
31668
--processing_template_decl;
31654
31669
processing_postcondition = old_pc;
31655
31670
should_constify_contract = old_const;
0 commit comments