From patchwork Thu Apr 7 21:41:58 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jason Merrill X-Patchwork-Id: 90236 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 155C8B6F44 for ; Fri, 8 Apr 2011 07:42:08 +1000 (EST) Received: (qmail 28253 invoked by alias); 7 Apr 2011 21:42:06 -0000 Received: (qmail 28177 invoked by uid 22791); 7 Apr 2011 21:42:05 -0000 X-SWARE-Spam-Status: No, hits=-6.3 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_HI, SPF_HELO_PASS, 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; Thu, 07 Apr 2011 21:41:59 +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 p37Lfx0a030754 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Thu, 7 Apr 2011 17:41:59 -0400 Received: from [127.0.0.1] (ovpn-113-53.phx2.redhat.com [10.3.113.53]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id p37LfwmM003758 for ; Thu, 7 Apr 2011 17:41:59 -0400 Message-ID: <4D9E2FA6.1010205@redhat.com> Date: Thu, 07 Apr 2011 17:41:58 -0400 From: Jason Merrill User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.15) Gecko/20110307 Fedora/3.1.9-0.39.b3pre.fc14 Lightning/1.0b2 Thunderbird/3.1.9 MIME-Version: 1.0 To: gcc-patches List Subject: C++/c-common PATCH to conversion from scoped enum to bool (part of 48450) 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 PR 48450 has to do with SFINAE bugs, but one of them turns out to be a different sort of bug: we were failing to convert from a non-constant value of scoped enum type to bool, because that conversion was doing a != 0, which requires an implicit conversion to int. So now we explicitly convert to the underlying integral type first, and prevent c-common from helpfully removing it again. Tested x86_64-pc-linux-gnu, applying to trunk. commit 87823d7d9dab304517871340e7b3aba6b73afe16 Author: Jason Merrill Date: Tue Apr 5 15:02:14 2011 -0400 PR c++/48450 * c-family/c-common.c (c_common_truthvalue_conversion): Don't ignore conversion from C++0x scoped enum. * cp/cvt.c (ocp_convert): Handle converting scoped enum to bool. diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c index 1252b18..e0acfea 100644 --- a/gcc/c-family/c-common.c +++ b/gcc/c-family/c-common.c @@ -3939,16 +3939,25 @@ c_common_truthvalue_conversion (location_t location, tree expr) } CASE_CONVERT: - /* Don't cancel the effect of a CONVERT_EXPR from a REFERENCE_TYPE, - since that affects how `default_conversion' will behave. */ - if (TREE_CODE (TREE_TYPE (expr)) == REFERENCE_TYPE - || TREE_CODE (TREE_TYPE (TREE_OPERAND (expr, 0))) == REFERENCE_TYPE) - break; - /* If this is widening the argument, we can ignore it. */ - if (TYPE_PRECISION (TREE_TYPE (expr)) - >= TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (expr, 0)))) - return c_common_truthvalue_conversion (location, - TREE_OPERAND (expr, 0)); + { + tree totype = TREE_TYPE (expr); + tree fromtype = TREE_TYPE (TREE_OPERAND (expr, 0)); + + /* Don't cancel the effect of a CONVERT_EXPR from a REFERENCE_TYPE, + since that affects how `default_conversion' will behave. */ + if (TREE_CODE (totype) == REFERENCE_TYPE + || TREE_CODE (fromtype) == REFERENCE_TYPE) + break; + /* Don't strip a conversion from C++0x scoped enum, since they + don't implicitly convert to other types. */ + if (TREE_CODE (fromtype) == ENUMERAL_TYPE + && ENUM_IS_SCOPED (fromtype)) + break; + /* If this isn't narrowing the argument, we can ignore it. */ + if (TYPE_PRECISION (totype) >= TYPE_PRECISION (fromtype)) + return c_common_truthvalue_conversion (location, + TREE_OPERAND (expr, 0)); + } break; case MODIFY_EXPR: diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c index 8ab0001..290b926 100644 --- a/gcc/cp/cvt.c +++ b/gcc/cp/cvt.c @@ -727,7 +727,13 @@ ocp_convert (tree type, tree expr, int convtype, int flags) return error_mark_node; } if (code == BOOLEAN_TYPE) - return cp_truthvalue_conversion (e); + { + /* We can't implicitly convert a scoped enum to bool, so convert + to the underlying type first. */ + if (SCOPED_ENUM_P (intype) && (convtype & CONV_STATIC)) + e = convert (ENUM_UNDERLYING_TYPE (intype), e); + return cp_truthvalue_conversion (e); + } converted = fold_if_not_in_template (convert_to_integer (type, e)); diff --git a/gcc/testsuite/g++.dg/cpp0x/enum9.C b/gcc/testsuite/g++.dg/cpp0x/enum9.C new file mode 100644 index 0000000..10e510b --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/enum9.C @@ -0,0 +1,5 @@ +// { dg-options -std=c++0x } + +enum class E { }; +E f(); +bool b2 = static_cast(f());