Skip to content

Commit 62a9c6a

Browse files
committed
c++, contracts: Handle contract-specific location wrappers.
Contract conditions use location wrappers on more tree types than the generic code. This means that we need to take care of them when tsubst-ing, otherwise the geneic code is getting given un- expected input (and, predicatably, it does not work). This is a more general problem upstream - but "just applying wrappers" to more trees in the generic code is going to need a lot of work (it fails quite spectacularly) unrelated to contracts. Signed-off-by: Iain Sandoe <iain@sandoe.co.uk>
1 parent a325077 commit 62a9c6a

File tree

2 files changed

+27
-11
lines changed

2 files changed

+27
-11
lines changed

gcc/cp/contracts.cc

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2691,18 +2691,26 @@ remap_and_emit_conditions (tree fn, tree condfn, tree_code code)
26912691
tree
26922692
finish_contract_condition (cp_expr condition)
26932693
{
2694+
if (!condition || error_operand_p (condition))
2695+
return condition;
2696+
26942697
/* Ensure we have the condition location saved in case we later need to
26952698
emit a conversion error during template instantiation and wouldn't
2696-
otherwise have it. */
2697-
if (!CAN_HAVE_LOCATION_P (condition) || EXCEPTIONAL_CLASS_P (condition))
2698-
{
2699-
condition = build1_loc (condition.get_location (), VIEW_CONVERT_EXPR,
2699+
otherwise have it. This differs from maybe_wrap_with_location in that
2700+
it allows wrappers on EXCEPTIONAL_CLASS_P which includes CONSTRUCTORs. */
2701+
if (!CAN_HAVE_LOCATION_P (condition)
2702+
&& condition.get_location () != UNKNOWN_LOCATION)
2703+
{
2704+
tree_code code
2705+
= (((CONSTANT_CLASS_P (condition) && TREE_CODE (condition) != STRING_CST)
2706+
|| (TREE_CODE (condition) == CONST_DECL && !TREE_STATIC (condition)))
2707+
? NON_LVALUE_EXPR : VIEW_CONVERT_EXPR);
2708+
condition = build1_loc (condition.get_location (), code,
27002709
TREE_TYPE (condition), condition);
27012710
EXPR_LOCATION_WRAPPER_P (condition) = true;
27022711
}
27032712

2704-
if (condition == error_mark_node
2705-
|| type_dependent_expression_p (condition))
2713+
if (type_dependent_expression_p (condition))
27062714
return condition;
27072715

27082716
return condition_conversion (condition);

gcc/cp/pt.cc

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12057,11 +12057,19 @@ tsubst_contract (tree decl, tree t, tree args, tsubst_flags_t complain,
1205712057
/* Make the variable available for lookup. */
1205812058
register_local_specialization (newvar, oldvar);
1205912059

12060-
CONTRACT_CONDITION (r)
12061-
= tsubst_expr (CONTRACT_CONDITION (t), args, complain, in_decl);
12062-
12063-
/* The condition is converted to bool. */
12064-
CONTRACT_CONDITION (r) = finish_contract_condition (CONTRACT_CONDITION (r));
12060+
/* Contract conditions have a wider application of location wrappers than
12061+
other trees which will not work with the generic handling in tsubst_expr,
12062+
remove the wrapper here... */
12063+
location_t cond_l = EXPR_LOCATION (CONTRACT_CONDITION (t));
12064+
tree cond_t = tree_strip_any_location_wrapper (CONTRACT_CONDITION (t));
12065+
12066+
/* ... and substitute with the contained expression. */
12067+
cond_t = tsubst_expr (cond_t, args, complain, in_decl);
12068+
12069+
/* Converted to bool, if possible, and then re-apply a location wrapper
12070+
when required. */
12071+
cp_expr new_condition (cond_t, cond_l);
12072+
CONTRACT_CONDITION (r) = finish_contract_condition (new_condition);
1206512073

1206612074
/* And the comment. */
1206712075
/* TODO : this does not do anything at the moment. The CONTRACT_COMMENT is

0 commit comments

Comments
 (0)