From: Jason Merrill Date: Fri, 28 Oct 2011 02:18:12 +0000 (-0400) Subject: semantics.c (cxx_eval_outermost_constant_expr): Check cp_has_mutable_p. X-Git-Tag: releases/gcc-4.7.0~2754 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=53b51666890e927604fab9dcdc0035ab4ce865e9;p=thirdparty%2Fgcc.git 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 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index fe0665d83064..9791ab5d3b25 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2011-10-27 Jason Merrill + + * 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 PR c++/30066 diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index fa8ab9914c3f..d76df5156b44 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 000000000000..a14d611cee82 --- /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" }