Jason Merrill <ja...@redhat.com> writes: > OK.
Thanks. So here is the follow-up hardening patch that uses next_conversion instead of touching conversion::u.next directly, for better safety and maintainability. Would this be OK for next stage 1? Bootstrapped and tested on x86_64-unknown-linux-gnu against trunk. gcc/cp/ * call.c (standard_conversion, build_integral_nontype_arg_conv) (build_new_op_1, convert_like_real, is_subseq) (maybe_handle_implicit_object, maybe_handle_ref_bind, compare_ics) (joust): Use next_conversion instead of accessing fields of struct conversion directly. --- gcc/cp/call.c | 51 ++++++++++++++++++++++++++------------------------- 1 files changed, 26 insertions(+), 25 deletions(-) diff --git a/gcc/cp/call.c b/gcc/cp/call.c index dd716a4..e9e57a1 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -1323,7 +1323,7 @@ standard_conversion (tree to, tree from, tree expr, bool c_cast_p, /* Give this a better rank if it's a promotion. */ if (same_type_p (to, type_promotes_to (from)) - && conv->u.next->rank <= cr_promotion) + && next_conversion (conv)->rank <= cr_promotion) conv->rank = cr_promotion; } else if (fcode == VECTOR_TYPE && tcode == VECTOR_TYPE @@ -1333,7 +1333,7 @@ standard_conversion (tree to, tree from, tree expr, bool c_cast_p, && is_properly_derived_from (from, to)) { if (conv->kind == ck_rvalue) - conv = conv->u.next; + conv = next_conversion (conv); conv = build_conv (ck_base, to, conv); /* The derived-to-base conversion indicates the initialization of a parameter with base type from an object of a derived @@ -3696,7 +3696,7 @@ build_integral_nontype_arg_conv (tree type, tree expr, tsubst_flags_t complain) break; case ck_std: - t = conv->u.next->type; + t = next_conversion (conv)->type; if (INTEGRAL_OR_ENUMERATION_TYPE_P (t)) break; @@ -5162,7 +5162,7 @@ build_new_op_1 (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3, objects directly. */ conv = cand->convs[0]; if (conv->kind == ck_ref_bind) - conv = conv->u.next; + conv = next_conversion (conv); arg1 = convert_like (conv, arg1, complain); if (arg2) @@ -5176,14 +5176,14 @@ build_new_op_1 (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3, conv = cand->convs[1]; if (conv->kind == ck_ref_bind) - conv = conv->u.next; + conv = next_conversion (conv); arg2 = convert_like (conv, arg2, complain); } if (arg3) { conv = cand->convs[2]; if (conv->kind == ck_ref_bind) - conv = conv->u.next; + conv = next_conversion (conv); arg3 = convert_like (conv, arg3, complain); } @@ -5826,7 +5826,7 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum, break; }; - expr = convert_like_real (convs->u.next, expr, fn, argnum, + expr = convert_like_real (next_conversion (convs), expr, fn, argnum, convs->kind == ck_ref_bind ? -1 : 1, convs->kind == ck_ref_bind ? issue_conversion_warnings : false, c_cast_p, @@ -5879,7 +5879,7 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum, { tree ref_type = totype; - if (convs->bad_p && !convs->u.next->bad_p) + if (convs->bad_p && !next_conversion (convs)->bad_p) { gcc_assert (TYPE_REF_IS_RVALUE (ref_type) && real_lvalue_p (expr)); @@ -5909,7 +5909,7 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum, cp_lvalue_kind lvalue = real_lvalue_p (expr); gcc_assert (same_type_ignoring_top_level_qualifiers_p - (type, convs->u.next->type)); + (type, next_conversion (convs)->type)); if (!CP_TYPE_CONST_NON_VOLATILE_P (type) && !TYPE_REF_IS_RVALUE (ref_type)) { @@ -7439,13 +7439,13 @@ is_subseq (conversion *ics1, conversion *ics2) while (ics1->kind == ck_rvalue || ics1->kind == ck_lvalue) - ics1 = ics1->u.next; + ics1 = next_conversion (ics1); while (1) { while (ics2->kind == ck_rvalue || ics2->kind == ck_lvalue) - ics2 = ics2->u.next; + ics2 = next_conversion (ics2); if (ics2->kind == ck_user || ics2->kind == ck_ambig @@ -7458,12 +7458,12 @@ is_subseq (conversion *ics1, conversion *ics2) sequences. */ return false; - ics2 = ics2->u.next; + ics2 = next_conversion (ics2); if (ics2->kind == ics1->kind && same_type_p (ics2->type, ics1->type) - && same_type_p (ics2->u.next->type, - ics1->u.next->type)) + && same_type_p (next_conversion (ics2)->type, + next_conversion (ics1)->type)) return true; } } @@ -7511,9 +7511,9 @@ maybe_handle_implicit_object (conversion **ics) reference_type = build_reference_type (reference_type); if (t->kind == ck_qual) - t = t->u.next; + t = next_conversion (t); if (t->kind == ck_ptr) - t = t->u.next; + t = next_conversion (t); t = build_identity_conv (TREE_TYPE (t->type), NULL_TREE); t = direct_reference_binding (reference_type, t); t->this_p = 1; @@ -7532,7 +7532,7 @@ maybe_handle_ref_bind (conversion **ics) if ((*ics)->kind == ck_ref_bind) { conversion *old_ics = *ics; - *ics = old_ics->u.next; + *ics = next_conversion (old_ics); (*ics)->user_conv_p = old_ics->user_conv_p; return old_ics; } @@ -7640,11 +7640,11 @@ compare_ics (conversion *ics1, conversion *ics2) conversion *t1; conversion *t2; - for (t1 = ics1; t1->kind != ck_user; t1 = t1->u.next) + for (t1 = ics1; t1->kind != ck_user; t1 = next_conversion (t1)) if (t1->kind == ck_ambig || t1->kind == ck_aggr || t1->kind == ck_list) break; - for (t2 = ics2; t2->kind != ck_user; t2 = t2->u.next) + for (t2 = ics2; t2->kind != ck_user; t2 = next_conversion (t2)) if (t2->kind == ck_ambig || t2->kind == ck_aggr || t2->kind == ck_list) break; @@ -7689,12 +7689,12 @@ compare_ics (conversion *ics1, conversion *ics2) t1 = ics1; while (t1->kind != ck_identity) - t1 = t1->u.next; + t1 = next_conversion (t1); from_type1 = t1->type; t2 = ics2; while (t2->kind != ck_identity) - t2 = t2->u.next; + t2 = next_conversion (t2); from_type2 = t2->type; } @@ -7956,7 +7956,7 @@ compare_ics (conversion *ics1, conversion *ics2) static tree source_type (conversion *t) { - for (;; t = t->u.next) + for (;; t = next_conversion (t)) { if (t->kind == ck_user || t->kind == ck_ambig @@ -8041,6 +8041,7 @@ joust (struct z_candidate *cand1, struct z_candidate *cand2, bool warn) { conversion *t1 = cand1->convs[i + off1]; conversion *t2 = cand2->convs[i + off2]; + conversion *next_conv = next_conversion (t1); int comp = compare_ics (t1, t2); if (comp != 0) @@ -8054,11 +8055,11 @@ joust (struct z_candidate *cand1, struct z_candidate *cand2, bool warn) && TREE_CODE (t2->type) == INTEGER_TYPE && (TYPE_PRECISION (t1->type) == TYPE_PRECISION (t2->type)) - && (TYPE_UNSIGNED (t1->u.next->type) - || (TREE_CODE (t1->u.next->type) + && (TYPE_UNSIGNED (next_conv->type) + || (TREE_CODE (next_conv->type) == ENUMERAL_TYPE))) { - tree type = t1->u.next->type; + tree type = next_conv->type; tree type1, type2; struct z_candidate *w, *l; if (comp > 0) -- 1.7.6.4 -- Dodji