From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 27139 invoked by alias); 27 Jan 2016 08:10:24 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Received: (qmail 27122 invoked by uid 89); 27 Jan 2016 08:10:23 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-0.9 required=5.0 tests=AWL,BAYES_00,KAM_LAZY_DOMAIN_SECURITY,RP_MATCHES_RCVD autolearn=no version=3.3.2 spammy= X-HELO: mail2-relais-roc.national.inria.fr Received: from mail2-relais-roc.national.inria.fr (HELO mail2-relais-roc.national.inria.fr) (192.134.164.83) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-GCM-SHA384 encrypted) ESMTPS; Wed, 27 Jan 2016 08:10:21 +0000 Received: from 81-64-195-101.rev.numericable.fr (HELO laptop-mg.local) ([81.64.195.101]) by mail2-relais-roc.national.inria.fr with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 27 Jan 2016 09:10:18 +0100 Date: Wed, 27 Jan 2016 08:10:00 -0000 From: Marc Glisse Reply-To: gcc-patches@gcc.gnu.org To: "H.J. Lu" cc: Jakub Jelinek , GCC Patches , Jason Merrill , Richard Biener , Markus Trippelsdorf Subject: Re: PING^1: [PATCH] Add TYPE_EMPTY_RECORD for C++ empty class In-Reply-To: Message-ID: References: <566F23AE.6070604@redhat.com> <566F2A0B.4010102@redhat.com> <56A7C8AC.8070204@redhat.com> <20160126214000.GL3017@tucnak.redhat.com> User-Agent: Alpine 2.20 (DEB 67 2015-01-07) MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII; format=flowed X-SW-Source: 2016-01/txt/msg02085.txt.bz2 On Tue, 26 Jan 2016, H.J. Lu wrote: > On Tue, Jan 26, 2016 at 1:40 PM, Jakub Jelinek wrote: >> On Tue, Jan 26, 2016 at 01:21:52PM -0800, H.J. Lu wrote: >>> Like this: >>> >>> /* Returns true if TYPE is POD for the purpose of layout and an empty >>> class or an class with empty classes. */ >>> >>> static bool >>> is_empty_record (tree type) >>> { >>> if (type == error_mark_node) >>> return false; >>> >>> if (!CLASS_TYPE_P (type)) >>> return false; >>> >>> if (CLASSTYPE_NON_LAYOUT_POD_P (type)) >>> return false; >>> >>> gcc_assert (COMPLETE_TYPE_P (type)); >>> >>> if (CLASSTYPE_EMPTY_P (type)) >>> return true; >>> >>> tree field; >>> >>> for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field)) >>> if (TREE_CODE (field) == FIELD_DECL >>> && !DECL_ARTIFICIAL (field) >>> && !is_empty_record (TREE_TYPE (field))) >>> return false; >>> >>> return true; >>> } >> >> So you say that K1 in e.g.: >> >> struct A1 {}; struct A2 {}; >> struct B1 { A1 a; A2 b; }; struct B2 { A1 a; A2 b; }; >> struct C1 { B1 a; B2 b; }; struct C2 { B1 a; B2 b; }; >> struct D1 { C1 a; C2 b; }; struct D2 { C1 a; C2 b; }; >> struct E1 { D1 a; D2 b; }; struct E2 { D1 a; D2 b; }; >> struct F1 { E1 a; E2 b; }; struct F2 { E1 a; E2 b; }; >> struct G1 { F1 a; F2 b; }; struct G2 { F1 a; F2 b; }; >> struct H1 { G1 a; G2 b; }; struct H2 { G1 a; G2 b; }; >> struct I1 { H1 a; H2 b; }; struct I2 { H1 a; H2 b; }; >> struct J1 { I1 a; I2 b; }; struct J2 { I1 a; I2 b; }; >> struct K1 { J1 a; J2 b; }; >> int v; >> __attribute__((noinline, noclone)) >> K1 foo (int a, K1 x, int b) >> { >> v = a + b; >> return x; >> } >> K1 k, m; >> void >> bar (void) >> { >> m = foo (1, k, 2); >> } >> >> is empty class? What does clang do with this? >> >> Jakub > > Revised: > > /* Returns true if TYPE is POD of one-byte or less in size for the purpose > of layout and an empty class or an class with empty classes. */ > > static bool > is_empty_record (tree type) > { > if (type == error_mark_node) > return false; > > if (!CLASS_TYPE_P (type)) > return false; > > if (CLASSTYPE_NON_LAYOUT_POD_P (type)) > return false; > > gcc_assert (COMPLETE_TYPE_P (type)); > > if (CLASSTYPE_EMPTY_P (type)) > return true; > > if (int_size_in_bytes (type) > 1) > return false; That's completely arbitrary :-( If we are defining a new ABI, I preferred your previous version (at least the idea, I didn't check the code). If we are trying to follow clang, then we need either a clear English definition from a clang developer or at least someone should check what conditions they use in the code. Trying to infer it from a couple examples sounds too fragile for an ABI decision. > tree field; > > for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field)) > if (TREE_CODE (field) == FIELD_DECL > && !DECL_ARTIFICIAL (field) > && !is_empty_record (TREE_TYPE (field))) > return false; > > return true; > } -- Marc Glisse