From patchwork Fri Nov 17 14:09:42 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Paolo Carlini X-Patchwork-Id: 839014 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-467140-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="hwpmE/fZ"; dkim-atps=neutral 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 3ydg480q68z9s3w for ; Sat, 18 Nov 2017 01:10:15 +1100 (AEDT) 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=An3tStQzWgOg2cR8tsOmOXNwfNC3E3JzyC6KBBauK2a6K+D1zx 15oUeaK5pvhdMHOcF2UUqavHj0y05pI7unr7ELcschf6KbgE3CYmTR8Lhcmaafj8 v3t8YllUUfFUy3na1JJlK8kKBmIgtSTRWgMz8+DtPyUyHbccAJyCqv5jU= 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=BTzoH9zkgNOGFAHGCnqQMThAqUE=; b=hwpmE/fZgfwzFcPzIpHH r62aENmGPCr474eQCWe2au0j32B3W2HeZ7lxXwC/ik/78rSriHwOfjJpY3ksAZWu j7Qx0B0hyCzImXkEXfUs6wKoiThVsqzUbh5Q/fHbIWPaRoxPUY8gH0YhU25QhWrF mGyybZUTMqMjik7QF6lR+Qg= Received: (qmail 18344 invoked by alias); 17 Nov 2017 14:09:51 -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 18335 invoked by uid 89); 17 Nov 2017 14:09:50 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-14.9 required=5.0 tests=BAYES_00, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_ASCII_DIVIDERS, KAM_LAZY_DOMAIN_SECURITY, KB_WAM_FROM_NAME_SINGLEWORD, RP_MATCHES_RCVD autolearn=ham version=3.3.2 spammy= 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 ESMTP; Fri, 17 Nov 2017 14:09:49 +0000 Received: from aserv0021.oracle.com (aserv0021.oracle.com [141.146.126.233]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id vAHE9kXh000511 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 17 Nov 2017 14:09:46 GMT Received: from aserv0122.oracle.com (aserv0122.oracle.com [141.146.126.236]) by aserv0021.oracle.com (8.14.4/8.14.4) with ESMTP id vAHE9jCP015650 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 17 Nov 2017 14:09:45 GMT Received: from abhmp0005.oracle.com (abhmp0005.oracle.com [141.146.116.11]) by aserv0122.oracle.com (8.14.4/8.14.4) with ESMTP id vAHE9joA028654; Fri, 17 Nov 2017 14:09:45 GMT Received: from [192.168.1.4] (/87.19.212.40) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Fri, 17 Nov 2017 06:09:45 -0800 To: "gcc-patches@gcc.gnu.org" Cc: Jason Merrill , Nathan Sidwell From: Paolo Carlini Subject: [C++ Patch, V2] PR 82593 ("Internal compiler error: in process_init_constructor_array, at cp/typeck2.c:1294") Message-ID: <44bdbaa0-35f1-7f0c-85aa-b603939d016e@oracle.com> Date: Fri, 17 Nov 2017 15:09:42 +0100 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.4.0 MIME-Version: 1.0 X-IsSubscribed: yes Hi again, I managed to spend much more time on the issue and I'm starting a new thread with a mature - IMHO - proposal: the big thing is the use of the existing check_array_designated_initializer in process_init_constructor_array,  which calls maybe_constant_value, as we want, and covers all the ill-formed cases which I can imagine. I'm also tweaking a bit the parser to check the return value of require_potential_rvalue_constant_expression in order to avoid redundant diagnostic in some cases. Also, a couple more testcases beyond the bug report. Tested x86_64-linux. Thanks, Paolo. //////////////////////// /cp 2017-11-17 Paolo Carlini PR c++/82593 * decl.c (check_array_designated_initializer): Not static. * cp-tree.h (check_array_designated_initializer): Declare. * typeck2.c (process_init_constructor_array): Call the latter. * parser.c (cp_parser_initializer_list): Check the return value of require_potential_rvalue_constant_expression. /testsuite 2017-11-17 Paolo Carlini PR c++/82593 * g++.dg/cpp0x/desig2.C: New. * g++.dg/cpp0x/desig3.C: Likewise. * g++.dg/cpp0x/desig4.C: Likewise. Index: cp/cp-tree.h =================================================================== --- cp/cp-tree.h (revision 254858) +++ cp/cp-tree.h (working copy) @@ -6190,6 +6190,8 @@ extern bool require_deduced_type (tree, tsubst_fl extern tree finish_case_label (location_t, tree, tree); extern tree cxx_maybe_build_cleanup (tree, tsubst_flags_t); +extern bool check_array_designated_initializer (constructor_elt *, + unsigned HOST_WIDE_INT); /* in decl2.c */ extern void record_mangling (tree, bool); Index: cp/decl.c =================================================================== --- cp/decl.c (revision 254858) +++ cp/decl.c (working copy) @@ -5245,7 +5245,7 @@ grok_reference_init (tree decl, tree type, tree in initializer. If it does, an error is issued. Returns true if CE is valid, i.e., does not have a designated initializer. */ -static bool +bool check_array_designated_initializer (constructor_elt *ce, unsigned HOST_WIDE_INT index) { Index: cp/parser.c =================================================================== --- cp/parser.c (revision 254858) +++ cp/parser.c (working copy) @@ -22193,8 +22193,10 @@ cp_parser_initializer_list (cp_parser* parser, boo if (!cp_parser_parse_definitely (parser)) designator = NULL_TREE; - else if (non_const) - require_potential_rvalue_constant_expression (designator); + else if (non_const + && (!require_potential_rvalue_constant_expression + (designator))) + designator = NULL_TREE; } else designator = NULL_TREE; Index: cp/typeck2.c =================================================================== --- cp/typeck2.c (revision 254858) +++ cp/typeck2.c (working copy) @@ -1289,17 +1289,8 @@ process_init_constructor_array (tree type, tree in FOR_EACH_VEC_SAFE_ELT (v, i, ce) { - if (ce->index) - { - gcc_assert (TREE_CODE (ce->index) == INTEGER_CST); - if (compare_tree_int (ce->index, i) != 0) - { - ce->value = error_mark_node; - sorry ("non-trivial designated initializers not supported"); - } - } - else - ce->index = size_int (i); + ce->index = (check_array_designated_initializer (ce, i) + ? size_int (i) : error_mark_node); gcc_assert (ce->value); ce->value = massage_init_elt (TREE_TYPE (type), ce->value, complain); Index: testsuite/g++.dg/cpp0x/desig2.C =================================================================== --- testsuite/g++.dg/cpp0x/desig2.C (nonexistent) +++ testsuite/g++.dg/cpp0x/desig2.C (working copy) @@ -0,0 +1,23 @@ +// PR c++/82593 +// { dg-do compile { target c++11 } } +// { dg-options "" } + +enum { + INDEX1 = 0, + INDEX2 +}; + +class SomeClass { +public: + SomeClass(); +private: + struct { int field; } member[2]; +}; + +SomeClass::SomeClass() + : member({ + [INDEX1] = { .field = 0 }, + [INDEX2] = { .field = 1 } + }) +{ +} Index: testsuite/g++.dg/cpp0x/desig3.C =================================================================== --- testsuite/g++.dg/cpp0x/desig3.C (nonexistent) +++ testsuite/g++.dg/cpp0x/desig3.C (working copy) @@ -0,0 +1,21 @@ +// PR c++/82593 +// { dg-do compile { target c++11 } } +// { dg-options "" } + +const int INDEX1 = 0; +const int INDEX2 = 1; + +class SomeClass { +public: + SomeClass(); +private: + struct { int field; } member[2]; +}; + +SomeClass::SomeClass() + : member({ + [INDEX1] = { .field = 0 }, + [INDEX2] = { .field = 1 } + }) +{ +} Index: testsuite/g++.dg/cpp0x/desig4.C =================================================================== --- testsuite/g++.dg/cpp0x/desig4.C (nonexistent) +++ testsuite/g++.dg/cpp0x/desig4.C (working copy) @@ -0,0 +1,21 @@ +// PR c++/82593 +// { dg-do compile { target c++11 } } +// { dg-options "" } + +int INDEX1 = 0; +int INDEX2 = 1; + +class SomeClass { +public: + SomeClass(); +private: + struct { int field; } member[2]; +}; + +SomeClass::SomeClass() + : member({ + [INDEX1] = { .field = 0 }, // { dg-error "constant expression" } + [INDEX2] = { .field = 1 } // { dg-error "constant expression" } + }) +{ +}