Skip to content

Commit 6baca63

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 <[email protected]>
1 parent 451299d commit 6baca63

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
@@ -2701,18 +2701,26 @@ remap_and_emit_conditions (tree fn, tree condfn, tree_code code)
27012701
tree
27022702
finish_contract_condition (cp_expr condition)
27032703
{
2704+
if (!condition || error_operand_p (condition))
2705+
return condition;
2706+
27042707
/* Ensure we have the condition location saved in case we later need to
27052708
emit a conversion error during template instantiation and wouldn't
2706-
otherwise have it. */
2707-
if (!CAN_HAVE_LOCATION_P (condition) || EXCEPTIONAL_CLASS_P (condition))
2708-
{
2709-
condition = build1_loc (condition.get_location (), VIEW_CONVERT_EXPR,
2709+
otherwise have it. This differs from maybe_wrap_with_location in that
2710+
it allows wrappers on EXCEPTIONAL_CLASS_P which includes CONSTRUCTORs. */
2711+
if (!CAN_HAVE_LOCATION_P (condition)
2712+
&& condition.get_location () != UNKNOWN_LOCATION)
2713+
{
2714+
tree_code code
2715+
= (((CONSTANT_CLASS_P (condition) && TREE_CODE (condition) != STRING_CST)
2716+
|| (TREE_CODE (condition) == CONST_DECL && !TREE_STATIC (condition)))
2717+
? NON_LVALUE_EXPR : VIEW_CONVERT_EXPR);
2718+
condition = build1_loc (condition.get_location (), code,
27102719
TREE_TYPE (condition), condition);
27112720
EXPR_LOCATION_WRAPPER_P (condition) = true;
27122721
}
27132722

2714-
if (condition == error_mark_node
2715-
|| type_dependent_expression_p (condition))
2723+
if (type_dependent_expression_p (condition))
27162724
return condition;
27172725

27182726
return condition_conversion (condition);

gcc/cp/pt.cc

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

12071-
CONTRACT_CONDITION (r)
12072-
= tsubst_expr (CONTRACT_CONDITION (t), args, complain, in_decl);
12073-
12074-
/* The condition is converted to bool. */
12075-
CONTRACT_CONDITION (r) = finish_contract_condition (CONTRACT_CONDITION (r));
12071+
/* Contract conditions have a wider application of location wrappers than
12072+
other trees which will not work with the generic handling in tsubst_expr,
12073+
remove the wrapper here... */
12074+
location_t cond_l = EXPR_LOCATION (CONTRACT_CONDITION (t));
12075+
tree cond_t = tree_strip_any_location_wrapper (CONTRACT_CONDITION (t));
12076+
12077+
/* ... and substitute with the contained expression. */
12078+
cond_t = tsubst_expr (cond_t, args, complain, in_decl);
12079+
12080+
/* Converted to bool, if possible, and then re-apply a location wrapper
12081+
when required. */
12082+
cp_expr new_condition (cond_t, cond_l);
12083+
CONTRACT_CONDITION (r) = finish_contract_condition (new_condition);
1207612084

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

0 commit comments

Comments
 (0)