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.
@@ -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))
new file mode 100644
@@ -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" }