re PR c++/46873 ([C++0x] ICE: in build_data_member_initialization, at cp/semantics...
authorJason Merrill <jason@redhat.com>
Mon, 13 Dec 2010 20:46:58 +0000 (15:46 -0500)
committerJason Merrill <jason@gcc.gnu.org>
Mon, 13 Dec 2010 20:46:58 +0000 (15:46 -0500)
PR c++/46873
PR c++/46877
* semantics.c (build_data_member_initialization): Handle
cv-qualified data member.

From-SVN: r167770

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

index caea47e404bb7896e7fb8be866c1ef111361f0b7..3ca26973c87a774b8a0f0f0886ceb9b289b8c41f 100644 (file)
@@ -1,3 +1,10 @@
+2010-12-13  Jason Merrill  <jason@redhat.com>
+
+       PR c++/46873
+       PR c++/46877
+       * semantics.c (build_data_member_initialization): Handle
+       cv-qualified data member.
+
 2010-12-13  Jan Hubicka  <jh@suse.cz>
 
        PR middle-end/45388
index 1b3bfa33919eb5d2cb18a642ca0a2615a5abe4d1..27e2982a98c392fef3c3c7199f66ce53864f9dd5 100644 (file)
@@ -5483,49 +5483,43 @@ build_data_member_initialization (tree t, VEC(constructor_elt,gc) **vec)
     {
       member = TREE_OPERAND (t, 0);
       init = unshare_expr (TREE_OPERAND (t, 1));
-      if (TREE_CODE (member) == INDIRECT_REF)
-       {
-         tree op = TREE_OPERAND (member, 0);
-         STRIP_NOPS (op);
-         gcc_assert (TREE_CODE (op) == ADDR_EXPR);
-         op = TREE_OPERAND (op, 0);
-         if (TREE_CODE (op) == COMPONENT_REF)
-           /* Initializing a cv-qualified member; we just looked through
-              the const_cast.  */
-           member = op;
-         else
-           {
-             /* Initializing an empty base; just skip it.  */
-             gcc_assert (is_empty_class (TREE_TYPE (member)));
-             return true;
-           }
-       }
     }
   else
     {
-      tree memtype;
       gcc_assert (TREE_CODE (t) == CALL_EXPR);
       member = CALL_EXPR_ARG (t, 0);
-      memtype = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (member)));
-      if (TREE_CODE (member) == NOP_EXPR)
+      /* We don't use build_cplus_new here because it complains about
+        abstract bases.  Leaving the call unwrapped means that it has the
+        wrong type, but cxx_eval_constant_expression doesn't care.  */
+      init = unshare_expr (t);
+    }
+  if (TREE_CODE (member) == INDIRECT_REF)
+    member = TREE_OPERAND (member, 0);
+  if (TREE_CODE (member) == NOP_EXPR)
+    {
+      tree op = member;
+      STRIP_NOPS (op);
+      if (TREE_CODE (op) == ADDR_EXPR)
        {
-         /* We don't put out anything for an empty base.  */
-         gcc_assert (is_empty_class (memtype));
-         /* But if the constructor used isn't constexpr, leave in the call
-            so we complain later.  */
-         if (potential_constant_expression (t, tf_none))
-           return true;
+         gcc_assert (same_type_ignoring_top_level_qualifiers_p
+                     (TREE_TYPE (TREE_TYPE (op)),
+                      TREE_TYPE (TREE_TYPE (member))));
+         /* Initializing a cv-qualified member; we need to look through
+            the const_cast.  */
+         member = op;
        }
       else
        {
-         gcc_assert (TREE_CODE (member) == ADDR_EXPR);
-         member = TREE_OPERAND (member, 0);
+         /* We don't put out anything for an empty base.  */
+         gcc_assert (is_empty_class (TREE_TYPE (TREE_TYPE (member))));
+         /* But if the initializer isn't constexpr, leave it in so we
+            complain later.  */
+         if (potential_constant_expression (init, tf_none))
+           return true;
        }
-      /* We don't use build_cplus_new here because it complains about
-        abstract bases.  T has the wrong type, but
-        cxx_eval_constant_expression doesn't care.  */
-      init = unshare_expr (t);
     }
+  if (TREE_CODE (member) == ADDR_EXPR)
+    member = TREE_OPERAND (member, 0);
   if (TREE_CODE (member) == COMPONENT_REF)
     member = TREE_OPERAND (member, 1);
   CONSTRUCTOR_APPEND_ELT (*vec, member, init);
index 165be16f4c409c5533acf47e94a0e0e1f995f942..a9ed2f84c7779c19b446e4bd5aa3909c5309c0e5 100644 (file)
@@ -1,3 +1,10 @@
+2010-12-13  Jason Merrill  <jason@redhat.com>
+
+       PR c++/46873
+       PR c++/46877
+       * g++.dg/cpp0x/constexpr-ctor4.C: New.
+       * g++.dg/cpp0x/constexpr-ctor5.C: New.
+
 2010-12-13  Janus Weil  <janus@gcc.gnu.org>
 
        PR fortran/46201
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-ctor4.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-ctor4.C
new file mode 100644 (file)
index 0000000..397b4b0
--- /dev/null
@@ -0,0 +1,15 @@
+// PR c++/46873
+// { dg-options -std=c++0x }
+
+struct S
+{
+  int i:1;
+};
+
+struct T
+{
+  const S s;
+  constexpr T (S a = S ()) : s (a) { }
+};
+
+T t;
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-ctor5.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-ctor5.C
new file mode 100644 (file)
index 0000000..36b0178
--- /dev/null
@@ -0,0 +1,30 @@
+// PR c++/46877
+// { dg-options -std=c++0x }
+
+struct new_allocator
+{
+  constexpr new_allocator ();
+};
+
+struct string
+{
+  constexpr string ()
+  {
+  }
+  new_allocator a;
+};
+
+struct pair
+{
+  const string first;
+  constexpr pair ()
+  {
+  }
+};
+
+constexpr
+new_allocator::new_allocator ()
+{
+}
+
+pair p;