From patchwork Wed Oct 28 18:53:43 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jason Merrill X-Patchwork-Id: 537542 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 AC2F714076E for ; Thu, 29 Oct 2015 05:53:56 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b=ITNGnpFx; 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=yNlWzioJObNQBzBWd yXn1C7wobrdChJWtlfTG/AqRek/0u1JUyZXpWhzjbP4RrYNzEAmGtGlNTBn8DCHg 039iQHGOgV6BvGClejrX3jtVy4wYNwfAM4PuJOVkwk45EeiQlWPXUULGP7uu9vnm sDLajFXUBR9pJrRuXdqn9IJ2+M= 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=SSNOPUO4nlf10hYRia501Tk ZvK4=; b=ITNGnpFx7ZyM8JBQ6P4rKMayeYRF2W2sRltof/BS2wz1ra1wETXORns cQkhOH3oTQo++l0nv8I+mm2KrYutbD5BlJ+UxMNnc+Goc8VTWyJ/rjV7VooN1sGU ixQLhRxiL/322cwN+rog/2sc6RjtVuDT8UPFXHd8QqQa8uafdM+s= Received: (qmail 69633 invoked by alias); 28 Oct 2015 18:53:48 -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 69620 invoked by uid 89); 28 Oct 2015 18:53:47 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-3.5 required=5.0 tests=AWL, BAYES_00, RP_MATCHES_RCVD, SPF_HELO_PASS autolearn=ham version=3.3.2 X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-GCM-SHA384 encrypted) ESMTPS; Wed, 28 Oct 2015 18:53:46 +0000 Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) by mx1.redhat.com (Postfix) with ESMTPS id 6DB47A2C18; Wed, 28 Oct 2015 18:53:45 +0000 (UTC) Received: from [10.10.116.45] (ovpn-116-45.rdu2.redhat.com [10.10.116.45]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9SIrhS1026758; Wed, 28 Oct 2015 14:53:44 -0400 Subject: Re: C++ PATCH for DR 1518 (c++/54835, c++/60417) To: Ville Voutilainen , "gcc-patches@gcc.gnu.org" References: <562E3D08.8090902@redhat.com> From: Jason Merrill Message-ID: <563119B7.2060603@redhat.com> Date: Wed, 28 Oct 2015 14:53:43 -0400 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 MIME-Version: 1.0 In-Reply-To: <562E3D08.8090902@redhat.com> On 10/26/2015 10:47 AM, Jason Merrill wrote: > On 10/25/2015 09:04 PM, Ville Voutilainen wrote: >> On 25 October 2015 at 22:15, Ville Voutilainen >> wrote: >>> It seems to me that there's a discrepancy in handling explicit >>> default constructors. Based on my tests, this works: >>> >>> struct X {explicit X() {}}; >>> >>> void f(X) {} >>> >>> int main() >>> { >>> f({}); >>> } >>> >>> However, if the explicit constructor is defaulted, gcc accepts the code: >>> >>> struct X {explicit X() = default;}; >>> >>> void f(X) {} >>> >>> int main() >>> { >>> f({}); >>> } >> >> And to clarify, I'd expect both of those snippets to be rejected, but >> only the >> former is. > > The latter is accepted because the second X is an aggregate, and the > aggregate initialization bullet comes before value-initialization in 8.5.4. Further discussion on -core leads me to try changing X to be non-aggregate because of the explicit constructor. Tested x86_64-pc-linux-gnu, applying to trunk. commit 9adecc7c621fabfcdf91e3f92cf15bd2adc9d2a5 Author: Jason Merrill Date: Mon Oct 26 17:31:08 2015 -0400 DR 1518 * class.c (type_has_user_provided_or_explicit_constructor): New. (check_bases_and_members): Use it. * cp-tree.h: Declare it. diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 685b7b3..692bc44 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -5150,6 +5150,33 @@ type_has_user_provided_constructor (tree t) return false; } +/* Returns true iff class T has a user-provided constructor. */ + +bool +type_has_user_provided_or_explicit_constructor (tree t) +{ + tree fns; + + if (!CLASS_TYPE_P (t)) + return false; + + if (!TYPE_HAS_USER_CONSTRUCTOR (t)) + return false; + + /* This can happen in error cases; avoid crashing. */ + if (!CLASSTYPE_METHOD_VEC (t)) + return false; + + for (fns = CLASSTYPE_CONSTRUCTORS (t); fns; fns = OVL_NEXT (fns)) + { + tree fn = OVL_CURRENT (fns); + if (user_provided_p (fn) || DECL_NONCONVERTING_P (fn)) + return true; + } + + return false; +} + /* Returns true iff class T has a non-user-provided (i.e. implicitly declared or explicitly defaulted in the class body) default constructor. */ @@ -5735,7 +5762,8 @@ check_bases_and_members (tree t) Again, other conditions for being an aggregate are checked elsewhere. */ CLASSTYPE_NON_AGGREGATE (t) - |= (type_has_user_provided_constructor (t) || TYPE_POLYMORPHIC_P (t)); + |= (type_has_user_provided_or_explicit_constructor (t) + || TYPE_POLYMORPHIC_P (t)); /* This is the C++98/03 definition of POD; it changed in C++0x, but we retain the old definition internally for ABI reasons. */ CLASSTYPE_NON_LAYOUT_POD_P (t) diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index af2ba64..acdd71c 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -5574,6 +5574,7 @@ extern bool type_has_user_nondefault_constructor (tree); extern tree in_class_defaulted_default_constructor (tree); extern bool user_provided_p (tree); extern bool type_has_user_provided_constructor (tree); +extern bool type_has_user_provided_or_explicit_constructor (tree); extern bool type_has_non_user_provided_default_constructor (tree); extern bool vbase_has_user_provided_move_assign (tree); extern tree default_init_uninitialized_part (tree); diff --git a/gcc/testsuite/g++.dg/cpp0x/explicit10.C b/gcc/testsuite/g++.dg/cpp0x/explicit10.C index f31f856..f9f8925 100644 --- a/gcc/testsuite/g++.dg/cpp0x/explicit10.C +++ b/gcc/testsuite/g++.dg/cpp0x/explicit10.C @@ -28,12 +28,12 @@ template void g() { int main() { - f(); // { dg-bogus "required from here" } + f(); // { dg-message "required from here" } f(); // { dg-message "required from here" } f(); // { dg-message "required from here" } f(); // { dg-message "required from here" } - g(); // { dg-bogus "required from here" } + g(); // { dg-message "required from here" } g(); // { dg-message "required from here" } g(); // { dg-message "required from here" } g(); // { dg-message "required from here" }