From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 24077 invoked by alias); 20 Jun 2011 14:13:55 -0000 Received: (qmail 24056 invoked by uid 22791); 20 Jun 2011 14:13:52 -0000 X-SWARE-Spam-Status: No, hits=-6.3 required=5.0 tests=AWL,BAYES_00,RCVD_IN_DNSWL_HI,SPF_HELO_PASS,TW_NV,T_RP_MATCHES_RCVD 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; Mon, 20 Jun 2011 14:13:34 +0000 Received: from int-mx01.intmail.prod.int.phx2.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id p5KEDX2W026702 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Mon, 20 Jun 2011 10:13:34 -0400 Received: from [127.0.0.1] ([10.3.113.2]) by int-mx01.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id p5KEDXA6020814 for ; Mon, 20 Jun 2011 10:13:33 -0400 Message-ID: <4DFF558D.5040402@redhat.com> Date: Mon, 20 Jun 2011 14:20:00 -0000 From: Jason Merrill User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.17) Gecko/20110428 Fedora/3.1.10-1.fc14 Lightning/1.0b2 Thunderbird/3.1.10 MIME-Version: 1.0 To: gcc-patches List Subject: C++ PATCH for c++/47080 (limits on explicit conversion operators) Content-Type: multipart/mixed; boundary="------------090905080204040102020106" Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org X-SW-Source: 2011-06/txt/msg01473.txt.bz2 This is a multi-part message in MIME format. --------------090905080204040102020106 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Content-length: 273 The PR pointed out that explicit conversion operators are more restricted than normal ones even in direct-initialization; the return type must be convertible to the target type with no more than a qualification conversion. Tested x86_64-pc-linux-gnu, applying to trunk --------------090905080204040102020106 Content-Type: text/x-patch; name="47080.patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="47080.patch" Content-length: 4275 commit 8f60db54d602164cda13a5f8c763f569b70c5e40 Author: Jason Merrill Date: Mon Jun 20 00:09:37 2011 -0400 PR c++/47080 * call.c (rejection_reason_code): Add rr_explicit_conversion. (print_z_candidate): Handle it. (explicit_conversion_rejection): New. (build_user_type_conversion_1): Reject an explicit conversion function that requires more than a qualification conversion. diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 09d73d0..e9d6e7e 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -429,6 +429,7 @@ struct candidate_warning { enum rejection_reason_code { rr_none, rr_arity, + rr_explicit_conversion, rr_arg_conversion, rr_bad_arg_conversion }; @@ -608,6 +609,16 @@ bad_arg_conversion_rejection (tree first_arg, int n_arg, tree from, tree to) return r; } +static struct rejection_reason * +explicit_conversion_rejection (tree from, tree to) +{ + struct rejection_reason *r = alloc_rejection (rr_explicit_conversion); + r->u.conversion.n_arg = 0; + r->u.conversion.from_type = from; + r->u.conversion.to_type = to; + return r; +} + /* Dynamically allocate a conversion. */ static conversion * @@ -3153,6 +3164,12 @@ print_z_candidate (const char *msgstr, struct z_candidate *candidate) case rr_bad_arg_conversion: print_conversion_rejection (loc, &r->u.bad_conversion); break; + case rr_explicit_conversion: + inform (loc, " return type %qT of explicit conversion function " + "cannot be converted to %qT with a qualification " + "conversion", r->u.conversion.from_type, + r->u.conversion.to_type); + break; case rr_none: default: /* This candidate didn't have any issues or we failed to @@ -3429,9 +3446,10 @@ build_user_type_conversion_1 (tree totype, tree expr, int flags) for (cand = candidates; cand != old_candidates; cand = cand->next) { + tree rettype = TREE_TYPE (TREE_TYPE (cand->fn)); conversion *ics = implicit_conversion (totype, - TREE_TYPE (TREE_TYPE (cand->fn)), + rettype, 0, /*c_cast_p=*/false, convflags); @@ -3453,14 +3471,23 @@ build_user_type_conversion_1 (tree totype, tree expr, int flags) if (!ics) { - tree rettype = TREE_TYPE (TREE_TYPE (cand->fn)); cand->viable = 0; cand->reason = arg_conversion_rejection (NULL_TREE, -1, rettype, totype); } + else if (DECL_NONCONVERTING_P (cand->fn) + && ics->rank > cr_exact) + { + /* 13.3.1.5: For direct-initialization, those explicit + conversion functions that are not hidden within S and + yield type T or a type that can be converted to type T + with a qualification conversion (4.4) are also candidate + functions. */ + cand->viable = -1; + cand->reason = explicit_conversion_rejection (rettype, totype); + } else if (cand->viable == 1 && ics->bad_p) { - tree rettype = TREE_TYPE (TREE_TYPE (cand->fn)); cand->viable = -1; cand->reason = bad_arg_conversion_rejection (NULL_TREE, -1, @@ -5513,7 +5540,18 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum, for (; t; t = convs->u.next) { - if (t->kind == ck_user || !t->bad_p) + if (t->kind == ck_user && t->cand->reason) + { + permerror (input_location, "invalid user-defined conversion " + "from %qT to %qT", TREE_TYPE (expr), totype); + print_z_candidate ("candidate is:", t->cand); + expr = convert_like_real (t, expr, fn, argnum, 1, + /*issue_conversion_warnings=*/false, + /*c_cast_p=*/false, + complain); + return cp_convert (totype, expr); + } + else if (t->kind == ck_user || !t->bad_p) { expr = convert_like_real (t, expr, fn, argnum, 1, /*issue_conversion_warnings=*/false, diff --git a/gcc/testsuite/g++.dg/cpp0x/explicit6.C b/gcc/testsuite/g++.dg/cpp0x/explicit6.C new file mode 100644 index 0000000..0d620be --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/explicit6.C @@ -0,0 +1,11 @@ +// PR c++/47080 +// { dg-options -std=c++0x } + +struct A { + explicit operator int(); // { dg-message "qualification conversion" } +}; + +int main() { + bool b((A())); // { dg-error "invalid user-defined" } + !A(); // { dg-error "" } +} --------------090905080204040102020106--