aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2011-10-27 22:18:12 -0400
committerJason Merrill <jason@gcc.gnu.org>2011-10-27 22:18:12 -0400
commit53b51666890e927604fab9dcdc0035ab4ce865e9 (patch)
tree51c2c3e1990068292adc53dc4cd35c44e7a998ae /gcc
parentfb9120e3b1bb7c508e49b49d844e4a060428d84d (diff)
downloadgcc-53b51666890e927604fab9dcdc0035ab4ce865e9.zip
gcc-53b51666890e927604fab9dcdc0035ab4ce865e9.tar.gz
gcc-53b51666890e927604fab9dcdc0035ab4ce865e9.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog6
-rw-r--r--gcc/cp/semantics.c18
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/constexpr-mutable1.C12
3 files changed, 36 insertions, 0 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index fe0665d..9791ab5 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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
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" }