Patchwork C++ PATCH for c++/51675 (more constexpr unions)

login
register
mail settings
Submitter Jason Merrill
Date Feb. 8, 2012, 9:23 a.m.
Message ID <4F323EFD.5040500@redhat.com>
Download mbox | patch
Permalink /patch/140076/
State New
Headers show

Comments

Jason Merrill - Feb. 8, 2012, 9:23 a.m.
More traffic on PR 51675 demonstrates that my earlier patch didn't fix 
the whole problem.  This patch improves handling of user-defined 
constructors.

Tested x86_64-pc-linux-gnu, applying to trunk.
H.J. Lu - Aug. 21, 2012, 5:51 p.m.
On Wed, Feb 8, 2012 at 1:23 AM, Jason Merrill <jason@redhat.com> wrote:
> More traffic on PR 51675 demonstrates that my earlier patch didn't fix the
> whole problem.  This patch improves handling of user-defined constructors.
>
> Tested x86_64-pc-linux-gnu, applying to trunk.

This caused:

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54341

Patch

commit 2ebb9d76963c08ebb009a1b6eb8f576eb9e671c0
Author: Jason Merrill <jason@redhat.com>
Date:   Mon Feb 6 14:47:50 2012 -1000

    	PR c++/51675
    	* semantics.c (cx_check_missing_mem_inits): Handle unions.
    	Fix constexpr default constructor logic.

diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 9019962..5646fa7 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -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;
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-union3.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-union3.C
new file mode 100644
index 0000000..bac9cab
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-union3.C
@@ -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;