]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR c++/51675 ([C++11][4.7 Regression] Cannot create constexpr unions)
authorJason Merrill <jason@redhat.com>
Wed, 8 Feb 2012 09:52:19 +0000 (04:52 -0500)
committerJason Merrill <jason@gcc.gnu.org>
Wed, 8 Feb 2012 09:52:19 +0000 (04:52 -0500)
PR c++/51675
* semantics.c (cx_check_missing_mem_inits): Handle unions.
Fix constexpr default constructor logic.

From-SVN: r184001

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

index b506f4bd055657c5a33395ab2e08048d208e9fe5..f9246e56b74be59d76b8bbe6367035b06b3e8459 100644 (file)
@@ -1,5 +1,9 @@
 2012-02-07  Jason Merrill  <jason@redhat.com>
 
+       PR c++/51675
+       * semantics.c (cx_check_missing_mem_inits): Handle unions.
+       Fix constexpr default constructor logic.
+
        PR c++/52035
        * pt.c (tsubst): Strip uninstantiated typedef.
 
index 901996248768f8550a58126d89cbcda0db316c01..5646fa7471734638471dcf86b528133147339a0e 100644 (file)
@@ -6025,13 +6025,28 @@ cx_check_missing_mem_inits (tree fun, tree body, bool complain)
   bool bad;
   tree field;
   unsigned i, nelts;
+  tree ctype;
 
   if (TREE_CODE (body) != CONSTRUCTOR)
     return false;
 
-  bad = false;
   nelts = CONSTRUCTOR_NELTS (body);
-  field = TYPE_FIELDS (DECL_CONTEXT (fun));
+  ctype = DECL_CONTEXT (fun);
+  field = TYPE_FIELDS (ctype);
+
+  if (TREE_CODE (ctype) == UNION_TYPE)
+    {
+      if (nelts == 0 && next_initializable_field (field))
+       {
+         if (complain)
+           error ("%<constexpr%> constructor for union %qT must "
+                  "initialize exactly one non-static data member", ctype);
+         return true;
+       }
+      return false;
+    }
+
+  bad = false;
   for (i = 0; i <= nelts; ++i)
     {
       tree index;
@@ -6050,8 +6065,6 @@ cx_check_missing_mem_inits (tree fun, tree body, bool complain)
          if (TREE_CODE (field) != FIELD_DECL
              || (DECL_C_BIT_FIELD (field) && !DECL_NAME (field)))
            continue;
-         if (!complain)
-           return true;
          ftype = strip_array_types (TREE_TYPE (field));
          if (type_has_constexpr_default_constructor (ftype))
            {
@@ -6062,6 +6075,8 @@ cx_check_missing_mem_inits (tree fun, tree body, bool complain)
                                   || errorcount != 0);
              continue;
            }
+         if (!complain)
+           return true;
          error ("uninitialized member %qD in %<constexpr%> constructor",
                 field);
          bad = true;
index 9f50b24ab3f1f044913b90903ce373f25fe31b97..482b4899dd13ffa07648cf3ef76e08a434711ffd 100644 (file)
@@ -1,5 +1,8 @@
 2012-02-07  Jason Merrill  <jason@redhat.com>
 
+       PR c++/51675
+       * g++.dg/cpp0x/constexpr-union3.C: New.
+
        PR c++/52035
        * g++.dg/lto/pr52035_0.C: New.
 
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-union3.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-union3.C
new file mode 100644 (file)
index 0000000..bac9cab
--- /dev/null
@@ -0,0 +1,12 @@
+// PR c++/51675
+// { dg-options -std=c++11 }
+
+union foo
+{
+  int x;
+  short y;
+
+  constexpr foo(): x(0) { }
+};
+
+constexpr foo f;