This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

C++ PATCH for constexpr vs. mutable


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 <jason@redhat.com>
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" }

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]