re PR c++/67364 ("accessing uninitialized member" error in constexpr context)
authorJason Merrill <jason@redhat.com>
Thu, 3 Mar 2016 22:43:03 +0000 (17:43 -0500)
committerJason Merrill <jason@gcc.gnu.org>
Thu, 3 Mar 2016 22:43:03 +0000 (17:43 -0500)
PR c++/67364

* constexpr.c (cxx_eval_component_reference): Just return an empty
CONSTRUCTOR for an empty class.

From-SVN: r233945

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

index f1d51cfa481a09e8c52654ce6f218ee2781d5d5b..f2c9cd25c1bb64537773e5df908dd35c3c99f090 100644 (file)
@@ -1,3 +1,9 @@
+2016-03-03  Jason Merrill  <jason@redhat.com>
+
+       PR c++/67364
+       * constexpr.c (cxx_eval_component_reference): Just return an empty
+       CONSTRUCTOR for an empty class.
+
 2016-03-01  Jason Merrill  <jason@redhat.com>
 
        PR c++/70036
index bcb129f22c4a2154f2307c5b3d535c7dcb1a25b2..5a81469b8adab54bd33e5b9c0926407d5aeddf3c 100644 (file)
@@ -1988,11 +1988,12 @@ cxx_eval_component_reference (const constexpr_ctx *ctx, tree t,
     }
 
   if (CONSTRUCTOR_NO_IMPLICIT_ZERO (whole)
-      && !is_empty_class (TREE_TYPE (part)))
+      && !is_really_empty_class (TREE_TYPE (t)))
     {
       /* 'whole' is part of the aggregate initializer we're currently
         building; if there's no initializer for this member yet, that's an
-        error. */
+        error.  But expand_aggr_init_1 doesn't bother to initialize really
+        empty classes, so ignore them here, too.  */
       if (!ctx->quiet)
        error ("accessing uninitialized member %qD", part);
       *non_constant_p = true;
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-empty11.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-empty11.C
new file mode 100644 (file)
index 0000000..7437367
--- /dev/null
@@ -0,0 +1,17 @@
+// PR c++/67364
+// { dg-do compile { target c++11 } }
+
+template <typename Xn>
+struct element : Xn {
+  constexpr element() : Xn() { }
+};
+
+template <typename Xn>
+struct closure {
+  element<Xn> member;
+  constexpr closure() { }
+};
+
+struct empty { struct {} s; };
+constexpr closure<empty> tup{};
+constexpr empty first = tup.member;