@@ -31490,6 +31490,8 @@ cp_parser_contract_attribute_spec (cp_parser *parser, tree attribute,
3149031490 /*consume_paren=*/false);
3149131491
3149231492 cp_token *last = cp_lexer_peek_token (parser->lexer);
31493+ location_t end = last->location;
31494+ loc = make_location (loc, loc, end);
3149331495
3149431496 if (!attr_mode)
3149531497 parens.require_close (parser);
@@ -31500,6 +31502,8 @@ cp_parser_contract_attribute_spec (cp_parser *parser, tree attribute,
3150031502 DEFPARSE_INSTANTIATIONS (condition) = NULL;
3150131503
3150231504 /* And its corresponding contract. */
31505+ if (identifier)
31506+ identifier.maybe_add_location_wrapper ();
3150331507 contract = grok_contract (attribute, mode, identifier, condition, loc);
3150431508 }
3150531509 else
@@ -31541,6 +31545,13 @@ cp_parser_contract_attribute_spec (cp_parser *parser, tree attribute,
3154131545 /* Revert (any) constification of the current class object. */
3154231546 current_class_ref = current_class_ref_copy;
3154331547
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+
3154431555 /* For natural syntax, we eat the parens here. For the attribute
3154531556 syntax, it will be done one level up, we just need to skip to it. */
3154631557 if (!attr_mode)
@@ -31579,16 +31590,19 @@ void cp_parser_late_contract_condition (cp_parser *parser,
3157931590 if (TREE_CODE (condition) != DEFERRED_PARSE)
3158031591 return;
3158131592
31582- tree identifier = NULL_TREE;
31593+ tree r_ident = NULL_TREE;
3158331594 if (TREE_CODE (contract) == POSTCONDITION_STMT)
31584- identifier = POSTCONDITION_IDENTIFIER (contract);
31595+ r_ident = POSTCONDITION_IDENTIFIER (contract);
3158531596
3158631597 tree type = TREE_TYPE (TREE_TYPE (fn));
31587- if (identifier)
31598+ location_t r_loc = UNKNOWN_LOCATION;
31599+ if (r_ident)
3158831600 {
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))
3159231606 {
3159331607 invalidate_contract (contract);
3159431608 return;
@@ -31640,16 +31654,17 @@ void cp_parser_late_contract_condition (cp_parser *parser,
3164031654 should_constify_contract = should_constify;
3164131655 /* Build a fake variable for the result identifier. */
3164231656 tree result = NULL_TREE;
31643- if (identifier )
31657+ if (r_ident )
3164431658 {
31645- result = make_postcondition_variable (identifier, type);
31659+ cp_expr result_id (r_ident, r_loc);
31660+ result = make_postcondition_variable (result_id, type);
3164631661 ++processing_template_decl;
3164731662 }
31648- condition = cp_parser_conditional_expression (parser);
31663+ cp_expr parsed_condition = cp_parser_conditional_expression (parser);
3164931664 /* Commit to changes. */
31650- update_late_contract (contract, result, condition );
31665+ update_late_contract (contract, result, parsed_condition );
3165131666 /* Leave our temporary scope for the postcondition result. */
31652- if (identifier )
31667+ if (r_ident )
3165331668 --processing_template_decl;
3165431669 processing_postcondition = old_pc;
3165531670 should_constify_contract = old_const;
0 commit comments