From patchwork Fri Sep 7 19:38:17 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jason Merrill X-Patchwork-Id: 182437 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]) by ozlabs.org (Postfix) with SMTP id 9D7052C008F for ; Sat, 8 Sep 2012 05:38:39 +1000 (EST) Comment: DKIM? See http://www.dkim.org DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d=gcc.gnu.org; s=default; x=1347651519; h=Comment: DomainKey-Signature:Received:Received:Received:Received:Received: Message-ID:Date:From:User-Agent:MIME-Version:To:CC:Subject: References:In-Reply-To:Content-Type:Mailing-List:Precedence: List-Id:List-Unsubscribe:List-Archive:List-Post:List-Help:Sender: Delivered-To; bh=UZ6nBClTivGZ2yXL+LKbc+h08lg=; b=i8r20jXjycEQ00y T6eguyRXyI6Jnf0BKXnHPJYDr2cxI56eAz3BBLcCkwOXgPNaQKCM69+zEUI9VHw0 I6dFHraIQUOtdzlYHXhM64irauWxHm6WaUyAnrnc+jpvM9wQ9g4anN8MK0Ilt2mt 3uab0Z8v7NRG0Kl3yglIp26SS2i0= Comment: DomainKeys? See http://antispam.yahoo.com/domainkeys DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=default; d=gcc.gnu.org; h=Received:Received:X-SWARE-Spam-Status:X-Spam-Check-By:Received:Received:Received:Message-ID:Date:From:User-Agent:MIME-Version:To:CC:Subject:References:In-Reply-To:Content-Type:Mailing-List:Precedence:List-Id:List-Unsubscribe:List-Archive:List-Post:List-Help:Sender:Delivered-To; b=SXEbbMf21M0QmJrPRaLWYUVsaoaC4Bav0JFFNx+YFYxzjaofIWLlDnmqREqwJw T6T7cGHAqnZf2PHjyXOMF1oLiibtRSpkRikZhINeqK83AfrzzMHKrewTpa67wsDc d/zirB2wUHF45fPCPgbk2ya4c3pcsPMB2RNgDrOcAsJnc=; Received: (qmail 19018 invoked by alias); 7 Sep 2012 19:38:36 -0000 Received: (qmail 19007 invoked by uid 22791); 7 Sep 2012 19:38:35 -0000 X-SWARE-Spam-Status: No, hits=-7.1 required=5.0 tests=AWL, BAYES_00, KHOP_RCVD_UNTRUST, KHOP_THREADED, RCVD_IN_DNSWL_HI, RCVD_IN_HOSTKARMA_W, RP_MATCHES_RCVD, SPF_HELO_PASS X-Spam-Check-By: sourceware.org Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Fri, 07 Sep 2012 19:38:19 +0000 Received: from int-mx12.intmail.prod.int.phx2.redhat.com (int-mx12.intmail.prod.int.phx2.redhat.com [10.5.11.25]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id q87JcIN7015544 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Fri, 7 Sep 2012 15:38:19 -0400 Received: from [10.3.113.162] (ovpn-113-162.phx2.redhat.com [10.3.113.162]) by int-mx12.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id q87JcHPS007220; Fri, 7 Sep 2012 15:38:18 -0400 Message-ID: <504A4D29.9060104@redhat.com> Date: Fri, 07 Sep 2012 15:38:17 -0400 From: Jason Merrill User-Agent: Mozilla/5.0 (X11; Linux i686; rv:15.0) Gecko/20120828 Thunderbird/15.0 MIME-Version: 1.0 To: Matthias Klose CC: gcc-patches List Subject: Re: C++ PATCH for c++/54341, c++/54253 (constexpr and virtual functions) References: <5048C356.6000701@redhat.com> <504A21BC.9030507@ubuntu.com> In-Reply-To: <504A21BC.9030507@ubuntu.com> 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 On 09/07/2012 12:33 PM, Matthias Klose wrote: > thanks for the fix. looked at backporting this for 4.7. Is it really necessary > to use C++ only syntax for this kind of patches, which are a candidate for 4.7? It's not necessary to use this syntax, but even code that uses the VEC macros would need to be different between 4.7 and 4.8. Here's a 4.7 version: commit a983881a0bcf570c9325f3c0d5d848ef07c1aec4 Author: Jason Merrill Date: Wed Sep 5 22:26:43 2012 -0400 PR c++/54341 PR c++/54253 * semantics.c (sort_constexpr_mem_initializers): New. (build_constexpr_constructor_member_initializers): Use it. (cx_check_missing_mem_inits): Skip artificial fields. * init.c (expand_aggr_init_1): Don't zero out a class with no data. diff --git a/gcc/cp/init.c b/gcc/cp/init.c index 2829c28..fe5d040 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -1736,8 +1736,10 @@ expand_aggr_init_1 (tree binfo, tree true_exp, tree exp, tree init, int flags, that's value-initialization. */ if (init == void_type_node) { - /* If no user-provided ctor, we need to zero out the object. */ - if (!type_has_user_provided_constructor (type)) + /* If the type has data but no user-provided ctor, we need to zero + out the object. */ + if (!type_has_user_provided_constructor (type) + && !is_really_empty_class (type)) { tree field_size = NULL_TREE; if (exp != true_exp && CLASSTYPE_AS_BASE (type) != type) diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 36ad72f..1dd1e32 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -5876,6 +5876,37 @@ check_constexpr_ctor_body (tree last, tree list) return ok; } +/* VEC is a vector of constructor elements built up for the base and member + initializers of a constructor for TYPE. They need to be in increasing + offset order, which they might not be yet if TYPE has a primary base + which is not first in the base-clause. */ + +static VEC(constructor_elt,gc) * +sort_constexpr_mem_initializers (tree type, VEC(constructor_elt,gc) *vec) +{ + tree pri = CLASSTYPE_PRIMARY_BINFO (type); + constructor_elt elt; + int i; + + if (pri == NULL_TREE + || pri == BINFO_BASE_BINFO (TYPE_BINFO (type), 0)) + return vec; + + /* Find the element for the primary base and move it to the beginning of + the vec. */ + pri = BINFO_TYPE (pri); + for (i = 1; ; ++i) + if (TREE_TYPE (VEC_index (constructor_elt, vec, i)->index) == pri) + break; + + elt = *VEC_index (constructor_elt, vec, i); + for (; i > 0; --i) + VEC_replace (constructor_elt, vec, i, + VEC_index (constructor_elt, vec, i-1)); + VEC_replace (constructor_elt, vec, 0, &elt); + return vec; +} + /* Build compile-time evalable representations of member-initializer list for a constexpr constructor. */ @@ -5932,6 +5963,7 @@ build_constexpr_constructor_member_initializers (tree type, tree body) return body; } } + vec = sort_constexpr_mem_initializers (type, vec); return build_constructor (type, vec); } else @@ -6050,14 +6082,16 @@ cx_check_missing_mem_inits (tree fun, tree body, bool complain) { index = CONSTRUCTOR_ELT (body, i)->index; /* Skip base and vtable inits. */ - if (TREE_CODE (index) != FIELD_DECL) + if (TREE_CODE (index) != FIELD_DECL + || DECL_ARTIFICIAL (index)) continue; } for (; field != index; field = DECL_CHAIN (field)) { tree ftype; if (TREE_CODE (field) != FIELD_DECL - || (DECL_C_BIT_FIELD (field) && !DECL_NAME (field))) + || (DECL_C_BIT_FIELD (field) && !DECL_NAME (field)) + || DECL_ARTIFICIAL (field)) continue; ftype = strip_array_types (TREE_TYPE (field)); if (type_has_constexpr_default_constructor (ftype)) diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-virtual2.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-virtual2.C new file mode 100644 index 0000000..86040a3 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-virtual2.C @@ -0,0 +1,24 @@ +// PR c++/54341 +// { dg-do compile { target c++11 } } + +template +struct enable_shared_from_this +{ + constexpr enable_shared_from_this(); // { dg-warning "used but never defined" } + +private: + int mem; +}; + +class VTableClass { +public: + virtual void someVirtualMethod() { } +}; + +class SomeClass : public enable_shared_from_this< SomeClass >, public +VTableClass { }; + +SomeClass* createInstance() +{ + return new SomeClass; +} diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-virtual3.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-virtual3.C new file mode 100644 index 0000000..de446bc --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-virtual3.C @@ -0,0 +1,42 @@ +// PR c++/54253 +// { dg-do compile { target c++11 } } + +namespace A { + class Base { + int x; + public: + constexpr Base(int x) : x(x) {} + }; + + class Base2 { + public: + virtual void fun() {} + }; + + class Derived : public Base2, public Base { + public: + constexpr Derived() : Base2(), Base(5) {} + }; + + constexpr Derived der; +} + +namespace B { + class Base { + int x; + public: + constexpr Base() : x(5) {} + }; + + class Base2 { + public: + virtual void fun() {} + }; + + class Derived : public Base, public Base2 { + public: + constexpr Derived() {} + }; + + constexpr Derived der; +}