From patchwork Mon Nov 1 02:07:44 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jason Merrill X-Patchwork-Id: 69747 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 8A9C1B70DA for ; Mon, 1 Nov 2010 13:07:57 +1100 (EST) Received: (qmail 25292 invoked by alias); 1 Nov 2010 02:07:54 -0000 Received: (qmail 25186 invoked by uid 22791); 1 Nov 2010 02:07:53 -0000 X-SWARE-Spam-Status: No, hits=-6.0 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_HI, SPF_HELO_PASS, TW_CX, TW_FN, TW_SF, T_RP_MATCHES_RCVD 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; Mon, 01 Nov 2010 02:07:47 +0000 Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id oA127jFd010243 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Sun, 31 Oct 2010 22:07:45 -0400 Received: from [127.0.0.1] (ovpn-113-33.phx2.redhat.com [10.3.113.33]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id oA127jfa027993 for ; Sun, 31 Oct 2010 22:07:45 -0400 Message-ID: <4CCE20F0.10405@redhat.com> Date: Sun, 31 Oct 2010 22:07:44 -0400 From: Jason Merrill User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.14) Gecko/20101020 Lightning/1.0b1 Shredder/3.0.10pre MIME-Version: 1.0 To: gcc-patches List Subject: C++0x constexpr patch #6: fix for constexpr setting on implicit default constructor with --disable-checking 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 bkoz pointed out to me that we were getting failures in the library when the compiler was built with --disable-checking; this was because the code to shortcut synthesized_method_walk for trivial functions wasn't handling constexpr properly. This patch fixes that and also avoids having to declare the implicit default constructor in order to set TYPE_HAS_CONSTEXPR_CTOR properly. Tested x86_64-pc-linux-gnu, applied to trunk. commit a37983dd24e7aa00813ba55be29ebf02c0f05e34 Author: Jason Merrill Date: Sun Oct 31 17:14:38 2010 -0400 * class.c (is_really_empty_class): Work when type is not complete. (synthesized_default_constructor_is_constexpr): New. (add_implicitly_declared_members): Use it. (type_has_constexpr_default_constructor): Likewise. * cp-tree.h: Declare it. * method.c (synthesized_method_walk): Use it. diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 50afc48..1c9fac1 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -2671,20 +2671,10 @@ add_implicitly_declared_members (tree t, if (! TYPE_HAS_USER_CONSTRUCTOR (t)) { TYPE_HAS_DEFAULT_CONSTRUCTOR (t) = 1; - if (TYPE_HAS_TRIVIAL_DFLT (t)) - { - /* A trivial default constructor is constexpr - if there is nothing to initialize. */ - if (cxx_dialect >= cxx0x && is_really_empty_class (t)) - TYPE_HAS_CONSTEXPR_CTOR (t) = 1; - CLASSTYPE_LAZY_DEFAULT_CTOR (t) = 1; - } - else if (cxx_dialect >= cxx0x) - /* We need to go ahead and declare this to set - TYPE_HAS_CONSTEXPR_CTOR. */ - lazily_declare_fn (sfk_constructor, t); - else - CLASSTYPE_LAZY_DEFAULT_CTOR (t) = 1; + CLASSTYPE_LAZY_DEFAULT_CTOR (t) = 1; + if (cxx_dialect >= cxx0x) + TYPE_HAS_CONSTEXPR_CTOR (t) + = synthesized_default_constructor_is_constexpr (t); } /* [class.ctor] @@ -4337,6 +4327,18 @@ type_has_user_provided_default_constructor (tree t) return false; } +/* Returns true iff for class T, a synthesized default constructor + would be constexpr. */ + +bool +synthesized_default_constructor_is_constexpr (tree t) +{ + /* A defaulted default constructor is constexpr + if there is nothing to initialize. */ + /* FIXME adjust for non-static data member initializers. */ + return is_really_empty_class (t); +} + /* Returns true iff class T has a constexpr default constructor. */ bool @@ -4346,6 +4348,8 @@ type_has_constexpr_default_constructor (tree t) if (!CLASS_TYPE_P (t)) return false; + if (CLASSTYPE_LAZY_DEFAULT_CTOR (t)) + return synthesized_default_constructor_is_constexpr (t); fns = get_default_ctor (t); return (fns && DECL_DECLARED_CONSTEXPR_P (fns)); } @@ -6824,13 +6828,11 @@ contains_empty_class_p (tree type) } /* Returns true if TYPE contains no actual data, just various - possible combinations of empty classes. */ + possible combinations of empty classes and possibly a vptr. */ bool is_really_empty_class (tree type) { - if (is_empty_class (type)) - return true; if (CLASS_TYPE_P (type)) { tree field; @@ -6838,6 +6840,11 @@ is_really_empty_class (tree type) tree base_binfo; int i; + /* CLASSTYPE_EMPTY_P isn't set properly until the class is actually laid + out, but we'd like to be able to check this before then. */ + if (COMPLETE_TYPE_P (type) && is_empty_class (type)) + return true; + for (binfo = TYPE_BINFO (type), i = 0; BINFO_BASE_ITERATE (binfo, i, base_binfo); ++i) if (!is_really_empty_class (BINFO_TYPE (base_binfo))) diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 7595b6f..e5ea232 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -4722,6 +4722,7 @@ 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_default_constructor (tree); +extern bool synthesized_default_constructor_is_constexpr (tree); extern bool type_has_constexpr_default_constructor (tree); extern bool type_has_virtual_destructor (tree); extern bool type_has_move_constructor (tree); diff --git a/gcc/cp/method.c b/gcc/cp/method.c index 6687c75..ca5964e 100644 --- a/gcc/cp/method.c +++ b/gcc/cp/method.c @@ -1157,7 +1157,11 @@ synthesized_method_walk (tree ctype, special_function_kind sfk, bool const_p, methods in C++0x. */ if (expected_trivial && (!copy_arg_p || cxx_dialect < cxx0x)) - return; + { + if (constexpr_p && sfk == sfk_constructor) + *constexpr_p = synthesized_default_constructor_is_constexpr (ctype); + return; + } #endif ++cp_unevaluated_operand;