From patchwork Thu Jul 28 15:55:05 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Paolo Carlini X-Patchwork-Id: 653803 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]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3s0bzk2x8fz9t1P for ; Fri, 29 Jul 2016 01:55:29 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b=i3mkIec9; dkim-atps=neutral DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :subject:to:references:cc:from:message-id:date:mime-version :in-reply-to:content-type; q=dns; s=default; b=vzcPcXrza4GV9aJDW RKf+PzHSH2NmvLbonnBv6ShDP4k82T9QkmXcyi9UJ7GuRPgU5SePe4/ad6/J7IvQ twCIRb7Ox2i9TdRI2cqb1VHhznKb9CA7TwyqX1iv7pCx3umd4RUyIyF3uQmiMLrw yGb7dR0fmpf540DjaybxXgcqlY= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :subject:to:references:cc:from:message-id:date:mime-version :in-reply-to:content-type; s=default; bh=U2RnLekblYo27m3G/NMAtPE pc1E=; b=i3mkIec9+8IbfhElBosIUlpKwFA023VpVDQWjDCXbszZlpmiq2Sqxup zYp/M6sAH/vbdSi58+unH8KdA3ATT9uH+cYeqXJr0oLZZnCzhC+OBROE7XX+RaQI s5pjgker8zZ0qZKebYWfjy3gAUPvDYjjjwfSIgUgbubkYRYvanuA= Received: (qmail 33609 invoked by alias); 28 Jul 2016 15:55:23 -0000 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 Received: (qmail 33599 invoked by uid 89); 28 Jul 2016 15:55:22 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.4 required=5.0 tests=BAYES_00, KAM_ASCII_DIVIDERS, RP_MATCHES_RCVD, SPF_PASS autolearn=ham version=3.3.2 spammy=H*M:6e63, quality, our X-HELO: aserp1040.oracle.com Received: from aserp1040.oracle.com (HELO aserp1040.oracle.com) (141.146.126.69) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-GCM-SHA384 encrypted) ESMTPS; Thu, 28 Jul 2016 15:55:12 +0000 Received: from aserv0022.oracle.com (aserv0022.oracle.com [141.146.126.234]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id u6SFt9cT013253 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Thu, 28 Jul 2016 15:55:09 GMT Received: from aserv0121.oracle.com (aserv0121.oracle.com [141.146.126.235]) by aserv0022.oracle.com (8.13.8/8.13.8) with ESMTP id u6SFt9GQ006158 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Thu, 28 Jul 2016 15:55:09 GMT Received: from abhmp0015.oracle.com (abhmp0015.oracle.com [141.146.116.21]) by aserv0121.oracle.com (8.13.8/8.13.8) with ESMTP id u6SFt827009276; Thu, 28 Jul 2016 15:55:08 GMT Received: from [192.168.1.4] (/79.46.212.215) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Thu, 28 Jul 2016 08:55:08 -0700 Subject: Re: [C++ RFC/Patch] PR c++/71665 To: Jason Merrill References: <5773E0DC.9080105@oracle.com> <22f2aee0-29d3-1c18-3871-291f08be4984@oracle.com> <11b0a778-116d-3249-f39a-75c022df4718@oracle.com> Cc: gcc-patches List From: Paolo Carlini Message-ID: <78408ffa-6e63-6d7e-8a59-e2bcfffdb0ad@oracle.com> Date: Thu, 28 Jul 2016 17:55:05 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.2 MIME-Version: 1.0 In-Reply-To: X-IsSubscribed: yes Hi, On 28/07/2016 16:28, Jason Merrill wrote: > On Thu, Jul 28, 2016 at 7:48 AM, Paolo Carlini wrote: >> Ah sorry, I missed the *type* bit. The below passes testing on x86_64-linux. >> I don't think we need to check the type again after cxx_constant_value?!? > No, we don't. The patch is OK. > >> While finally spending a decent amount of time on this issue I noticed that >> current clang appears to enforce integral or *unscoped* enumeration type and >> tweaking our code in the obvious way doesn't cause regressions, we of course >> reject earlier (ie, not as "could not convert ‘(E)1’ from ‘E’ to ‘unsigned >> int’") in build_enumerator snippets like: >> >> enum class E { e = 1 }; >> >> class A >> { >> enum { a = E::e }; >> }; > Sure, that change could improve diagnostic quality a bit. Thanks Jason. Then I'm regression testing again the below and I mean to commit it later today. Thanks again, Paolo. ///////////////////// /cp 2016-07-28 Paolo Carlini PR c++/71665 * decl.c (build_enumerator): Check the type of the enumerator before calling cxx_constant_value. /testsuite 2016-07-28 Paolo Carlini PR c++/71665 * g++.dg/cpp0x/pr71665-1.C: New. * g++.dg/cpp0x/pr71665-2.C: Likewise. * g++.dg/cpp0x/enum29.C: Adjust dg-error string. * g++.dg/ext/label10.C: Likewise. * g++.dg/parse/constant5.C: Likewise. Index: cp/decl.c =================================================================== --- cp/decl.c (revision 238822) +++ cp/decl.c (working copy) @@ -13587,15 +13587,24 @@ build_enumerator (tree name, tree value, tree enum if (value != NULL_TREE) { - value = cxx_constant_value (value); - - if (TREE_CODE (value) != INTEGER_CST - || ! INTEGRAL_OR_ENUMERATION_TYPE_P (TREE_TYPE (value))) + if (! INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P + (TREE_TYPE (value))) { - error ("enumerator value for %qD is not an integer constant", - name); + error ("enumerator for %qD must have integral or " + "unscoped enumeration type", name); value = NULL_TREE; } + else + { + value = cxx_constant_value (value); + + if (TREE_CODE (value) != INTEGER_CST) + { + error ("enumerator value for %qD is not an integer " + "constant", name); + value = NULL_TREE; + } + } } } Index: testsuite/g++.dg/cpp0x/enum29.C =================================================================== --- testsuite/g++.dg/cpp0x/enum29.C (revision 238822) +++ testsuite/g++.dg/cpp0x/enum29.C (working copy) @@ -38,7 +38,7 @@ enum E0 { e0 = X0() }; enum E1 { e1 = X1() }; enum E2 { e2 = X2() }; enum E3 { e3 = X3() }; -enum E4 { e4 = X4() }; // { dg-error "integer constant" } +enum E4 { e4 = X4() }; // { dg-error "integral" } enum E5 { e5 = X5() }; // { dg-error "ambiguous" } enum F0 : int { f0 = X0() }; Index: testsuite/g++.dg/cpp0x/pr71665-1.C =================================================================== --- testsuite/g++.dg/cpp0x/pr71665-1.C (revision 0) +++ testsuite/g++.dg/cpp0x/pr71665-1.C (working copy) @@ -0,0 +1,8 @@ +// PR c++/71665 +// { dg-do compile { target c++11 } } + +class A +{ + int f (); + enum { a = f }; // { dg-error "enumerator" } +}; Index: testsuite/g++.dg/cpp0x/pr71665-2.C =================================================================== --- testsuite/g++.dg/cpp0x/pr71665-2.C (revision 0) +++ testsuite/g++.dg/cpp0x/pr71665-2.C (working copy) @@ -0,0 +1,8 @@ +// PR c++/71665 +// { dg-do compile { target c++11 } } + +class A +{ + enum class E { e = 1 }; + enum { a = E::e }; // { dg-error "integral or unscoped enumeration" } +}; Index: testsuite/g++.dg/ext/label10.C =================================================================== --- testsuite/g++.dg/ext/label10.C (revision 238822) +++ testsuite/g++.dg/ext/label10.C (working copy) @@ -4,7 +4,7 @@ template struct A { - enum { M = && N }; // { dg-error "referenced outside|cannot appear in|not an integer constant" } + enum { M = && N }; // { dg-error "referenced outside|cannot appear in|integral" } }; A<0> a; @@ -12,6 +12,6 @@ A<0> a; void foo () { __label__ P; - enum { O = && P }; // { dg-error "cannot appear in|not an integer constant" } + enum { O = && P }; // { dg-error "cannot appear in|integral" } P:; } Index: testsuite/g++.dg/parse/constant5.C =================================================================== --- testsuite/g++.dg/parse/constant5.C (revision 238822) +++ testsuite/g++.dg/parse/constant5.C (working copy) @@ -1,7 +1,7 @@ // { dg-options "-std=c++98 -pedantic-errors" } enum E { - a = 24.2, // { dg-error "constant" } + a = 24.2, // { dg-error "integral|constant" } b = (int)3.7, c = int(4.2), d = (int)(4.2 + 3.7), // { dg-error "constant" }