From patchwork Fri Apr 29 16:21:08 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Carlini X-Patchwork-Id: 616894 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 3qxJq86z5lz9t3t for ; Sat, 30 Apr 2016 02:21: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=arKOhu3s; 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:from:message-id:date:mime-version :in-reply-to:content-type; q=dns; s=default; b=FZ5gOLor0+PhfH0rD pAPH9jvT044qT6AU6HW5o13P4D9klhiPgpfwCDTGiFdAyNxQjKqB4Krb74s8jlTo f51j7BpwvYxuPfe+px2fs7LGG9vMHqEt20/HXU9vhdvyrMzoWLrLo5jFbr9sjbRk l8tKId8mJDaV5T3MhOjyb00oc4= 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:from:message-id:date:mime-version :in-reply-to:content-type; s=default; bh=jbbTcTg6fTqJj0eIh4loGNV mAlE=; b=arKOhu3sY0ht7sKZUFW4ojkwTeZA7ZfuDaDg2JwDxeNWm8UiprKtHaG P0RRzCbP++IscQ6IZlhQqMd45PIAFIImbueIY6d4Wp6Pyp5xfyMomTSpuFW5pcSO HjeZ2wuEQUFwd0N9CxHK38xml8jE9YJgb9P7d3NVC30CZgh2zpeE= Received: (qmail 128476 invoked by alias); 29 Apr 2016 16:21: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 128463 invoked by uid 89); 29 Apr 2016 16:21:16 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.1 required=5.0 tests=BAYES_00, KAM_ASCII_DIVIDERS, RP_MATCHES_RCVD, SPF_PASS autolearn=ham version=3.3.2 spammy=Something, 362013 X-HELO: userp1040.oracle.com Received: from userp1040.oracle.com (HELO userp1040.oracle.com) (156.151.31.81) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-GCM-SHA384 encrypted) ESMTPS; Fri, 29 Apr 2016 16:21:14 +0000 Received: from userv0022.oracle.com (userv0022.oracle.com [156.151.31.74]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id u3TGLC3B004883 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 29 Apr 2016 16:21:12 GMT Received: from userv0121.oracle.com (userv0121.oracle.com [156.151.31.72]) by userv0022.oracle.com (8.14.4/8.13.8) with ESMTP id u3TGLBH4016563 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Fri, 29 Apr 2016 16:21:12 GMT Received: from abhmp0017.oracle.com (abhmp0017.oracle.com [141.146.116.23]) by userv0121.oracle.com (8.13.8/8.13.8) with ESMTP id u3TGLB1n007718; Fri, 29 Apr 2016 16:21:11 GMT Received: from [192.168.1.4] (/87.11.217.155) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Fri, 29 Apr 2016 09:21:11 -0700 Subject: Re: [C++ Patch] PR 66644 To: Jason Merrill , "gcc-patches@gcc.gnu.org" References: <572267EF.1060200@oracle.com> <57228472.8090005@redhat.com> <5722A870.5040403@oracle.com> <57236870.5030709@redhat.com> From: Paolo Carlini Message-ID: <572389F4.6000103@oracle.com> Date: Fri, 29 Apr 2016 18:21:08 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.7.0 MIME-Version: 1.0 In-Reply-To: <57236870.5030709@redhat.com> X-IsSubscribed: yes Hi, On 29/04/2016 15:58, Jason Merrill wrote: > On 04/28/2016 08:18 PM, Paolo Carlini wrote: >> else if (ANON_AGGR_TYPE_P (type)) >> { >> - tree fields; >> - >> - for (fields = TYPE_FIELDS (type); fields; fields = DECL_CHAIN >> (fields)) >> + for (tree fields = TYPE_FIELDS (type); fields; >> + fields = DECL_CHAIN (fields)) >> if (TREE_CODE (fields) == FIELD_DECL && !DECL_C_BIT_FIELD (field)) >> - check_field_decl (fields, t, cant_have_const_ctor, >> - no_const_asn_ref, any_default_members); >> + any_default_members_field |= check_field_decl (fields, t, >> + cant_have_const_ctor, >> + no_const_asn_ref, >> + any_default_members); > > The logic here seems convoluted. I guess we don't need to handle > anonymous structs and unions differently here because we'll call > check_field_decls for the anonymous union itself, and complain then? > In that case, instead of passing down any_default_members at all, can > we just pass it up and complain in check_field_decls? Indeed. Code reworked along these lines becomes even comprehensible ;) Something as simple as the below passes testing.... Thanks, Paolo. //////////////////////////// Index: cp/class.c =================================================================== --- cp/class.c (revision 235643) +++ cp/class.c (working copy) @@ -139,7 +139,7 @@ static int count_fields (tree); static int add_fields_to_record_type (tree, struct sorted_fields_type*, int); static void insert_into_classtype_sorted_fields (tree, tree, int); static bool check_bitfield_decl (tree); -static void check_field_decl (tree, tree, int *, int *, int *); +static bool check_field_decl (tree, tree, int *, int *); static void check_field_decls (tree, tree *, int *, int *); static tree *build_base_field (record_layout_info, tree, splay_tree, tree *); static void build_base_fields (record_layout_info, splay_tree, tree *); @@ -3541,14 +3541,14 @@ check_bitfield_decl (tree field) enclosing type T. Issue any appropriate messages and set appropriate flags. */ -static void +static bool check_field_decl (tree field, tree t, int* cant_have_const_ctor, - int* no_const_asn_ref, - int* any_default_members) + int* no_const_asn_ref) { tree type = strip_array_types (TREE_TYPE (field)); + bool any_default_members = false; /* In C++98 an anonymous union cannot contain any fields which would change the settings of CANT_HAVE_CONST_CTOR and friends. */ @@ -3558,12 +3558,12 @@ check_field_decl (tree field, structs. So, we recurse through their fields here. */ else if (ANON_AGGR_TYPE_P (type)) { - tree fields; - - for (fields = TYPE_FIELDS (type); fields; fields = DECL_CHAIN (fields)) + for (tree fields = TYPE_FIELDS (type); fields; + fields = DECL_CHAIN (fields)) if (TREE_CODE (fields) == FIELD_DECL && !DECL_C_BIT_FIELD (field)) - check_field_decl (fields, t, cant_have_const_ctor, - no_const_asn_ref, any_default_members); + any_default_members |= check_field_decl (fields, t, + cant_have_const_ctor, + no_const_asn_ref); } /* Check members with class type for constructors, destructors, etc. */ @@ -3620,13 +3620,11 @@ check_field_decl (tree field, check_abi_tags (t, field); if (DECL_INITIAL (field) != NULL_TREE) - { - /* `build_class_init_list' does not recognize - non-FIELD_DECLs. */ - if (TREE_CODE (t) == UNION_TYPE && *any_default_members != 0) - error ("multiple fields in union %qT initialized", t); - *any_default_members = 1; - } + /* `build_class_init_list' does not recognize + non-FIELD_DECLs. */ + any_default_members = true; + + return any_default_members; } /* Check the data members (both static and non-static), class-scoped @@ -3662,7 +3660,7 @@ check_field_decls (tree t, tree *access_decls, tree *field; tree *next; bool has_pointers; - int any_default_members; + bool any_default_members; int cant_pack = 0; int field_access = -1; @@ -3672,7 +3670,7 @@ check_field_decls (tree t, tree *access_decls, has_pointers = false; /* Assume none of the members of this class have default initializations. */ - any_default_members = 0; + any_default_members = false; for (field = &TYPE_FIELDS (t); *field; field = next) { @@ -3867,11 +3865,16 @@ check_field_decls (tree t, tree *access_decls, /* We set DECL_C_BIT_FIELD in grokbitfield. If the type and width are valid, we'll also set DECL_BIT_FIELD. */ - if (! DECL_C_BIT_FIELD (x) || ! check_bitfield_decl (x)) - check_field_decl (x, t, - cant_have_const_ctor_p, - no_const_asn_ref_p, - &any_default_members); + if ((! DECL_C_BIT_FIELD (x) || ! check_bitfield_decl (x)) + && check_field_decl (x, t, + cant_have_const_ctor_p, + no_const_asn_ref_p)) + { + if (any_default_members + && TREE_CODE (t) == UNION_TYPE) + error ("multiple fields in union %qT initialized", t); + any_default_members = true; + } /* Now that we've removed bit-field widths from DECL_INITIAL, anything left in DECL_INITIAL is an NSDMI that makes the class Index: testsuite/g++.dg/cpp0x/nsdmi-anon-struct1.C =================================================================== --- testsuite/g++.dg/cpp0x/nsdmi-anon-struct1.C (revision 0) +++ testsuite/g++.dg/cpp0x/nsdmi-anon-struct1.C (working copy) @@ -0,0 +1,48 @@ +// PR c++/66644 +// { dg-do compile { target c++11 } } +// { dg-options "-Wno-pedantic" } + +struct test1 +{ + union + { + struct { char a=0, b=0; }; + char buffer[16]; + }; +}; + +struct test2 +{ + union + { + struct { char a=0, b; }; + char buffer[16]; + }; +}; + +struct test3 +{ + union + { + struct { char a, b; } test2{0,0}; + char buffer[16]; + }; +}; + +struct test4 +{ + union + { // { dg-error "multiple fields" } + struct { char a=0, b=0; }; + struct { char c=0, d; }; + }; +}; + +struct test5 +{ + union + { + union { char a=0, b=0; }; // { dg-error "multiple fields" } + char buffer[16]; + }; +};