From patchwork Tue May 31 12:54:56 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Carlini X-Patchwork-Id: 628227 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 3rJtkh5kb1z9t3q for ; Tue, 31 May 2016 22:55:24 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b=OpwGhNkF; 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:to:cc :from:subject:message-id:date:mime-version:content-type; q=dns; s=default; b=hRqSvf+ZghjZ/Yp+BbYc8uJUb2XYgkY4A+cjD0N2zkec6a75mb vME3I8VQIP8gWV0cnWqimLcCZClFzSfJ/mm/pxq7L1Y8ddXeFSn49p2hjon+8FKD UAjcQNgTbF0i443Ff1d4Rg8Lf48v1vEC6Cw92GwyemDBriRLNG+5f/a8k= 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:to:cc :from:subject:message-id:date:mime-version:content-type; s= default; bh=pCPqZA5x3RHqaiMvN+a0kPT2LLk=; b=OpwGhNkF82jpgWDlrT4n HakL0HH4zFWdzM5yhLYM3HKRKYK5x4ivtjsWLV2qdTa/91xAsjsKUKohyYw2/lUR 74FVbyfLNQt6lnIClswJd6Mei8sDpGbGeC2L+h9Am6NEFke0xER3El2MO+NYySJP 7UlY0+zBwFFag132/PISjTI= Received: (qmail 106183 invoked by alias); 31 May 2016 12:55:16 -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 106153 invoked by uid 89); 31 May 2016 12:55:15 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.5 required=5.0 tests=BAYES_00, KAM_ASCII_DIVIDERS, RP_MATCHES_RCVD, SPF_PASS autolearn=ham version=3.3.2 spammy=sk:!INTEGR, sk:!integr, sk:integr, sk:INTEGR 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; Tue, 31 May 2016 12:55:05 +0000 Received: from userv0021.oracle.com (userv0021.oracle.com [156.151.31.71]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id u4VCt16Y019085 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Tue, 31 May 2016 12:55:02 GMT Received: from aserv0121.oracle.com (aserv0121.oracle.com [141.146.126.235]) by userv0021.oracle.com (8.13.8/8.13.8) with ESMTP id u4VCt1Nc032647 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Tue, 31 May 2016 12:55:01 GMT Received: from abhmp0010.oracle.com (abhmp0010.oracle.com [141.146.116.16]) by aserv0121.oracle.com (8.13.8/8.13.8) with ESMTP id u4VCsw00029042; Tue, 31 May 2016 12:55:00 GMT Received: from [192.168.1.4] (/79.12.211.42) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 31 May 2016 05:54:58 -0700 To: "gcc-patches@gcc.gnu.org" Cc: Jason Merrill From: Paolo Carlini Subject: [C++ Patch] PR 71248 Message-ID: <574D89A0.70309@oracle.com> Date: Tue, 31 May 2016 14:54:56 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.7.0 MIME-Version: 1.0 X-IsSubscribed: yes Hi, the primary issue is already fixed, we don't ICE anymore, but the location of the error message is (badly) incorrect, because check_static_variable_definition doesn't use DECL_SOURCE_LOCATION. Just doing that, consistently, plus a number of additional column checks in existing testcases amounts to most of the patch. There is a subtlety though: as shown by constexpr-static8.C we have been giving redundant diagnostics about the out-of-class definitions of the erroneous in-class declarations. This is particularly evident now because we would have to get right the location of the latter too and DECL_SOURCE_LOCATION doesn't help much for those. However, I think we simply want to suppress those messages, thus the early return at the beginning of check_static_variable_definition. The latter is called only by cp_finish_decl, thus conceivably the same logic could be easily shuffled around.... Tested x86_64-linux. Thanks, Paolo. /////////////////////// /cp 2016-05-31 Paolo Carlini PR c++/71248 * decl.c (check_static_variable_definition): Use DECL_SOURCE_LOCATION to obtain correct locations; avoid redundant diagnostics on out-of-class definitions. /testsuite 2016-05-31 Paolo Carlini PR c++/71248 * g++.dg/cpp0x/pr71248.C: New. * g++.dg/cpp0x/auto7.C: Test column numbers too. * g++.dg/cpp0x/constexpr-static8.C: Likewise. * g++.dg/init/new37.C: Likewise. * g++.dg/template/static1.C: Likewise. * g++.dg/template/static2.C: Likewise. Index: cp/decl.c =================================================================== --- cp/decl.c (revision 236910) +++ cp/decl.c (working copy) @@ -8581,6 +8581,9 @@ build_ptrmem_type (tree class_type, tree member_ty static int check_static_variable_definition (tree decl, tree type) { + /* Avoid redundant diagnostics on out-of-class definitions. */ + if (!current_class_type || !TYPE_BEING_DEFINED (current_class_type)) + return 0; /* Can't check yet if we don't know the type. */ if (dependent_type_p (type)) return 0; @@ -8591,15 +8594,17 @@ check_static_variable_definition (tree decl, tree else if (cxx_dialect >= cxx11 && !INTEGRAL_OR_ENUMERATION_TYPE_P (type)) { if (!COMPLETE_TYPE_P (type)) - error ("in-class initialization of static data member %q#D of " - "incomplete type", decl); + error_at (DECL_SOURCE_LOCATION (decl), + "in-class initialization of static data member %q#D of " + "incomplete type", decl); else if (literal_type_p (type)) - permerror (input_location, + permerror (DECL_SOURCE_LOCATION (decl), "% needed for in-class initialization of " "static data member %q#D of non-integral type", decl); else - error ("in-class initialization of static data member %q#D of " - "non-literal type", decl); + error_at (DECL_SOURCE_LOCATION (decl), + "in-class initialization of static data member %q#D of " + "non-literal type", decl); return 1; } @@ -8611,17 +8616,20 @@ check_static_variable_definition (tree decl, tree required. */ if (!ARITHMETIC_TYPE_P (type) && TREE_CODE (type) != ENUMERAL_TYPE) { - error ("invalid in-class initialization of static data member " - "of non-integral type %qT", - type); + error_at (DECL_SOURCE_LOCATION (decl), + "invalid in-class initialization of static data member " + "of non-integral type %qT", + type); return 1; } else if (!CP_TYPE_CONST_P (type)) - error ("ISO C++ forbids in-class initialization of non-const " - "static member %qD", - decl); + error_at (DECL_SOURCE_LOCATION (decl), + "ISO C++ forbids in-class initialization of non-const " + "static member %qD", + decl); else if (!INTEGRAL_OR_ENUMERATION_TYPE_P (type)) - pedwarn (input_location, OPT_Wpedantic, "ISO C++ forbids initialization of member constant " + pedwarn (DECL_SOURCE_LOCATION (decl), OPT_Wpedantic, + "ISO C++ forbids initialization of member constant " "%qD of non-integral type %qT", decl, type); return 0; Index: testsuite/g++.dg/cpp0x/auto7.C =================================================================== --- testsuite/g++.dg/cpp0x/auto7.C (revision 236910) +++ testsuite/g++.dg/cpp0x/auto7.C (working copy) @@ -7,7 +7,7 @@ auto j; // { dg-error "has no initializer" } template struct A { - static auto k = 7; // { dg-error "non-const" } + static auto k = 7; // { dg-error "15:ISO C\\+\\+ forbids" } static auto l; // { dg-error "has no initializer" } auto m; // { dg-error "non-static data member declared" } }; Index: testsuite/g++.dg/cpp0x/constexpr-static8.C =================================================================== --- testsuite/g++.dg/cpp0x/constexpr-static8.C (revision 236910) +++ testsuite/g++.dg/cpp0x/constexpr-static8.C (working copy) @@ -3,6 +3,6 @@ // { dg-options "-fpermissive" } struct Foo { - static const double d = 3.14; // { dg-warning "constexpr" } + static const double d = 3.14; // { dg-warning "23:'constexpr' needed" } }; -const double Foo::d; // { dg-warning "constexpr" } +const double Foo::d; Index: testsuite/g++.dg/cpp0x/pr71248.C =================================================================== --- testsuite/g++.dg/cpp0x/pr71248.C (revision 0) +++ testsuite/g++.dg/cpp0x/pr71248.C (working copy) @@ -0,0 +1,10 @@ +// PR c++/71248 +// { dg-do compile { target c++11 } } + +struct S +{ + int a; + static int S::*typeMembers[] = { // { dg-error "20:in-class initialization" } + &S::a, + }; +}; Index: testsuite/g++.dg/init/new37.C =================================================================== --- testsuite/g++.dg/init/new37.C (revision 236910) +++ testsuite/g++.dg/init/new37.C (working copy) @@ -40,7 +40,8 @@ struct T1 { }; struct T2 { - static const double n = 2; // { dg-error "non-integral type" } + static const double n = 2; // { dg-error "23:'constexpr' needed" "" { target c++11 } } + // { dg-error "23:ISO C\\+\\+ forbids" "" { target c++98_only } 43 } }; struct T3 { Index: testsuite/g++.dg/template/static1.C =================================================================== --- testsuite/g++.dg/template/static1.C (revision 236910) +++ testsuite/g++.dg/template/static1.C (working copy) @@ -1,4 +1,6 @@ template struct A { - static const int t[1][1]={{0}}; // { dg-error "brace-enclosed|in-class" } + static const int t[1][1]={{0}}; // { dg-error "20:'constexpr' needed" "" { target c++11 } } + // { dg-error "20:invalid in-class" "" { target c++98_only } 3 } + // { dg-error "28:a brace-enclosed" "" { target c++98_only } 3 } }; Index: testsuite/g++.dg/template/static2.C =================================================================== --- testsuite/g++.dg/template/static2.C (revision 236910) +++ testsuite/g++.dg/template/static2.C (working copy) @@ -4,7 +4,9 @@ template class B { public: - static int A::* const p = P; // { dg-error "" } + static int A::* const p = P; // { dg-error "25:'constexpr' needed" "" { target c++11 } } + // { dg-error "25:invalid in-class" "" { target c++98_only } 7 } + // { dg-error "29:template parameter" "" { target c++98_only } 7 } }; class A