diff mbox

Fix PR c++/70347 (default member initializer not picked up by union)

Message ID 1458750279-4923-1-git-send-email-patrick@parcs.ath.cx
State New
Headers show

Commit Message

Patrick Palka March 23, 2016, 4:24 p.m. UTC
When performing aggregate initialization on a union we fail to take into
account the union's NSDMI (if it has one).  This patch teaches
process_init_constructor_union to consider NSDMIs.

Does this look OK to commit after bootstrap + regtest?

gcc/cp/ChangeLog:

	PR c++/70347
	* typeck.c (process_init_constructor_union): If the initializer
	is empty, use the union's NSDMI if it has one.

gcc/testsuite/ChangeLog:

	PR c++/70347
	* g++.dg/cpp1y/nsdmi-union1.C: New test.
---
 gcc/cp/typeck2.c                          | 19 ++++++++++++++++--
 gcc/testsuite/g++.dg/cpp1y/nsdmi-union1.C | 33 +++++++++++++++++++++++++++++++
 2 files changed, 50 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/cpp1y/nsdmi-union1.C

Comments

Jason Merrill March 23, 2016, 5:41 p.m. UTC | #1
OK.

Jason
diff mbox

Patch

diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c
index 2a76c96..4ab77cd 100644
--- a/gcc/cp/typeck2.c
+++ b/gcc/cp/typeck2.c
@@ -1499,9 +1499,24 @@  process_init_constructor_union (tree type, tree init,
   constructor_elt *ce;
   int len;
 
-  /* If the initializer was empty, use default zero initialization.  */
+  /* If the initializer was empty, use the union's NSDMI if it has one.
+     Otherwise use default zero initialization.  */
   if (vec_safe_is_empty (CONSTRUCTOR_ELTS (init)))
-    return 0;
+    {
+      for (tree field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
+	{
+	  if (DECL_INITIAL (field))
+	    {
+	      CONSTRUCTOR_APPEND_ELT (CONSTRUCTOR_ELTS (init),
+				      field,
+				      get_nsdmi (field, /*in_ctor=*/false));
+	      break;
+	    }
+	}
+
+      if (vec_safe_is_empty (CONSTRUCTOR_ELTS (init)))
+	return 0;
+    }
 
   len = CONSTRUCTOR_ELTS (init)->length ();
   if (len > 1)
diff --git a/gcc/testsuite/g++.dg/cpp1y/nsdmi-union1.C b/gcc/testsuite/g++.dg/cpp1y/nsdmi-union1.C
new file mode 100644
index 0000000..45b9fd0
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/nsdmi-union1.C
@@ -0,0 +1,33 @@ 
+// PR c++/70347
+// { dg-do compile { target c++14 } }
+
+union A {
+  char a;
+  long b = -42;
+};
+
+struct B {
+  union {
+    char a = 10;
+    long b;
+  };
+};
+
+A c1{};
+A c2{4};
+B c3{};
+B c4{{9}};
+
+int main() {
+  if (c1.b != -42)
+    __builtin_abort ();
+
+  if (c2.a != 4)
+    __builtin_abort ();
+
+  if (c3.a != 10)
+    __builtin_abort ();
+
+  if (c4.a != 9)
+    __builtin_abort ();
+}