From patchwork Thu Dec 15 10:40:59 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dodji Seketeli X-Patchwork-Id: 131559 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id E4AEC1007D6 for ; Thu, 15 Dec 2011 21:41:23 +1100 (EST) Received: (qmail 20259 invoked by alias); 15 Dec 2011 10:41:21 -0000 Received: (qmail 20248 invoked by uid 22791); 15 Dec 2011 10:41:20 -0000 X-SWARE-Spam-Status: No, hits=-4.8 required=5.0 tests=AWL, BAYES_00, RP_MATCHES_RCVD, SPF_HELO_PASS, TW_NV X-Spam-Check-By: sourceware.org Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Thu, 15 Dec 2011 10:41:03 +0000 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id pBFAf25M001363 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Thu, 15 Dec 2011 05:41:02 -0500 Received: from localhost (ovpn-116-27.ams2.redhat.com [10.36.116.27]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id pBFAf0pB022859 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Thu, 15 Dec 2011 05:41:02 -0500 Received: by localhost (Postfix, from userid 500) id BF5A529C13B; Thu, 15 Dec 2011 11:40:59 +0100 (CET) From: Dodji Seketeli To: Jason Merrill Cc: GCC Patches Subject: Re: [PATCH] PR c++/51475 - ICE with invalid initializer-list References: <4EE90095.50208@redhat.com> <4EE92403.6030906@redhat.com> X-URL: http://www.redhat.com Date: Thu, 15 Dec 2011 11:40:59 +0100 In-Reply-To: <4EE92403.6030906@redhat.com> (Jason Merrill's message of "Wed, 14 Dec 2011 17:32:35 -0500") Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.2 (gnu/linux) MIME-Version: 1.0 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Jason Merrill writes: > On 12/14/2011 03:41 PM, Dodji Seketeli wrote: >> @@ -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))) > > I don't think we want to hoist that up so far; we're only interested > in the next conversion if a lot of other checks pass. Let's just do > the mechanical transformation again here. OK with that change. OK. Here is the final patch, undergoing bootstrap and testing on x86_64-unknown-linux-gnu against trunk. From: Dodji Seketeli Date: Wed, 14 Dec 2011 18:04:37 +0100 Subject: [PATCH] Use next_conversion for better safety 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/ChangeLog | 8 ++++++++ gcc/cp/call.c | 50 +++++++++++++++++++++++++------------------------- 2 files changed, 33 insertions(+), 25 deletions(-) diff --git a/gcc/cp/call.c b/gcc/cp/call.c index dd716a4..317a17f 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 @@ -8054,11 +8054,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_conversion (t1)->type) + || (TREE_CODE (next_conversion (t1)->type) == ENUMERAL_TYPE))) { - tree type = t1->u.next->type; + tree type = next_conversion (t1)->type; tree type1, type2; struct z_candidate *w, *l; if (comp > 0)