From patchwork Fri Oct 28 02:16:59 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jason Merrill X-Patchwork-Id: 122326 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 7C5EDB6F95 for ; Fri, 28 Oct 2011 13:17:24 +1100 (EST) Received: (qmail 22946 invoked by alias); 28 Oct 2011 02:17:21 -0000 Received: (qmail 22924 invoked by uid 22791); 28 Oct 2011 02:17:20 -0000 X-SWARE-Spam-Status: No, hits=-6.8 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_HI, 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, 28 Oct 2011 02:17:06 +0000 Received: from int-mx01.intmail.prod.int.phx2.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id p9S2H2ZX009650 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Thu, 27 Oct 2011 22:17:02 -0400 Received: from ns3.rdu.redhat.com (ns3.rdu.redhat.com [10.11.255.199]) by int-mx01.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id p9S2H1rZ026500; Thu, 27 Oct 2011 22:17:02 -0400 Received: from [0.0.0.0] ([10.3.113.11]) by ns3.rdu.redhat.com (8.13.8/8.13.8) with ESMTP id p9S2GxQK025812; Thu, 27 Oct 2011 22:17:00 -0400 Message-ID: <4EAA109B.3080909@redhat.com> Date: Thu, 27 Oct 2011 22:16:59 -0400 From: Jason Merrill User-Agent: Mozilla/5.0 (X11; Linux i686; rv:7.0.1) Gecko/20111001 Thunderbird/7.0.1 MIME-Version: 1.0 To: gcc-patches List CC: Gabriel Dos Reis Subject: C++ PATCH for constexpr vs. mutable 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 Recent discussion on the committee reflector pointed out issues with mutable and constexpr; this patch implements what I think is a reasonable solution. Tested x86_64-pc-linux-gnu, applying to trunk. commit 4b41346ab344632f6c22adb3d947a093cdb770ac Author: Jason Merrill Date: Thu Oct 27 14:56:21 2011 -0400 * semantics.c (cxx_eval_outermost_constant_expr): Check cp_has_mutable_p. (cxx_eval_component_reference): Check DECL_MUTABLE_P. diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index fa8ab99..d76df51 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -6680,6 +6680,12 @@ cxx_eval_component_reference (const constexpr_call *call, tree t, error ("%qE is not a constant expression", orig_whole); *non_constant_p = true; } + if (DECL_MUTABLE_P (part)) + { + if (!allow_non_constant) + error ("mutable %qD is not usable in a constant expression", part); + *non_constant_p = true; + } if (*non_constant_p) return t; FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (whole), i, field, value) @@ -7665,6 +7671,18 @@ cxx_eval_outermost_constant_expr (tree t, bool allow_non_constant) verify_constant (r, allow_non_constant, &non_constant_p); + if (TREE_CODE (t) != CONSTRUCTOR + && cp_has_mutable_p (TREE_TYPE (t))) + { + /* We allow a mutable type if the original expression was a + CONSTRUCTOR so that we can do aggregate initialization of + constexpr variables. */ + if (!allow_non_constant) + error ("%qT cannot be the type of a complete constant expression " + "because it has mutable sub-objects", TREE_TYPE (t)); + non_constant_p = true; + } + if (non_constant_p && !allow_non_constant) return error_mark_node; else if (non_constant_p && TREE_CONSTANT (t)) diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-mutable1.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-mutable1.C new file mode 100644 index 0000000..a14d611 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-mutable1.C @@ -0,0 +1,12 @@ +// { dg-options -std=c++0x } + +struct A +{ + int i; + mutable int j; +}; + +constexpr A a = { 0, 1 }; +constexpr A b = a; // { dg-error "mutable" } +constexpr int i = a.i; +constexpr int j = a.j; // { dg-error "mutable" }