OSDN Git Service

* semantics.c (cxx_eval_outermost_constant_expr): Check
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 28 Oct 2011 02:18:12 +0000 (02:18 +0000)
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 28 Oct 2011 02:18:12 +0000 (02:18 +0000)
cp_has_mutable_p.
(cxx_eval_component_reference): Check DECL_MUTABLE_P.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@180590 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/cp/ChangeLog
gcc/cp/semantics.c
gcc/testsuite/g++.dg/cpp0x/constexpr-mutable1.C [new file with mode: 0644]

index fe0665d..9791ab5 100644 (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
index fa8ab99..d76df51 100644 (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))
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-mutable1.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-mutable1.C
new file mode 100644 (file)
index 0000000..a14d611
--- /dev/null
@@ -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" }