Patchwork C++ PATCH for c++/51675 (DR 1359, constexpr union)

login
register
mail settings
Submitter Jason Merrill
Date Jan. 2, 2012, 5:52 p.m.
Message ID <4F01EEC8.6030807@redhat.com>
Download mbox | patch
Permalink /patch/133889/
State New
Headers show

Comments

Jason Merrill - Jan. 2, 2012, 5:52 p.m.
DR 1359 points out that the rules for constexpr constructors require all 
data members to be initialized, which is wrong for unions.  This patch 
implements the obvious resolution.

Tested x86_64-pc-linux-gnu, applying to trunk.

Patch

commit 82927de9eb3327c2e65be4f56aec991e36c44fa9
Author: Jason Merrill <jason@redhat.com>
Date:   Mon Jan 2 00:40:02 2012 -0500

    	PR c++/51675
    	* method.c (walk_field_subobs): Don't check for uninitialized
    	fields in a union.
    	(synthesized_method_walk): Check here.

diff --git a/gcc/cp/method.c b/gcc/cp/method.c
index 8101f8a..cf2a713 100644
--- a/gcc/cp/method.c
+++ b/gcc/cp/method.c
@@ -1063,7 +1063,8 @@  walk_field_subobs (tree fields, tree fnname, special_function_kind sfk,
 	  /* For an implicitly-defined default constructor to be constexpr,
 	     every member must have a user-provided default constructor or
 	     an explicit initializer.  */
-	  if (constexpr_p && !CLASS_TYPE_P (mem_type))
+	  if (constexpr_p && !CLASS_TYPE_P (mem_type)
+	      && TREE_CODE (DECL_CONTEXT (field)) != UNION_TYPE)
 	    {
 	      *constexpr_p = false;
 	      if (msg)
@@ -1208,12 +1209,19 @@  synthesized_method_walk (tree ctype, special_function_kind sfk, bool const_p,
      resolution, so a constructor can be trivial even if it would otherwise
      call a non-trivial constructor.  */
   if (expected_trivial
-      && !diag
       && (!copy_arg_p || cxx_dialect < cxx0x))
     {
       if (constexpr_p && sfk == sfk_constructor)
-	*constexpr_p = trivial_default_constructor_is_constexpr (ctype);
-      return;
+	{
+	  bool cx = trivial_default_constructor_is_constexpr (ctype);
+	  *constexpr_p = cx;
+	  if (diag && !cx && TREE_CODE (ctype) == UNION_TYPE)
+	    /* A trivial constructor doesn't have any NSDMI.  */
+	    inform (input_location, "defaulted default constructor does "
+		    "not initialize any non-static data member");
+	}
+      if (!diag)
+	return;
     }
 
   ++cp_unevaluated_operand;
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-union2.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-union2.C
new file mode 100644
index 0000000..0bf2aa7
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-union2.C
@@ -0,0 +1,18 @@ 
+// PR c++/51675
+// { dg-options -std=c++0x }
+
+union foo
+{
+  int x = 0;
+  short y;
+
+  constexpr foo() = default;
+};
+
+union bar
+{
+  int x;
+  short y;
+
+  constexpr bar() = default;	// { dg-error "constexpr" }
+};