semantics.c (cxx_eval_outermost_constant_expr): Check cp_has_mutable_p.

* semantics.c (cxx_eval_outermost_constant_expr): Check
	cp_has_mutable_p.
	(cxx_eval_component_reference): Check DECL_MUTABLE_P.

From-SVN: r180590
This commit is contained in:
Jason Merrill 2011-10-27 22:18:12 -04:00 committed by Jason Merrill
parent fb9120e3b1
commit 53b5166689
3 changed files with 36 additions and 0 deletions

View File

@ -1,3 +1,9 @@
2011-10-27 Jason Merrill <jason@redhat.com>
* semantics.c (cxx_eval_outermost_constant_expr): Check
cp_has_mutable_p.
(cxx_eval_component_reference): Check DECL_MUTABLE_P.
2011-10-27 Roberto Agostino Vitillo <ravitillo@lbl.gov>
PR c++/30066

View File

@ -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))

View File

@ -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" }