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

* constexpr.c (cxx_eval_component_reference): Further tweak.

From-SVN: r233982

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

index 08c25189649926414d0d5923901aee6d5e6165f0..4db438b8eab5526d040a67ded097e3371a127c3c 100644 (file)
@@ -1,5 +1,8 @@
 2016-03-04  Jason Merrill  <jason@redhat.com>
 
+       PR c++/67364
+       * constexpr.c (cxx_eval_component_reference): Further tweak.
+
        * constexpr.c (struct constexpr_ctx): Add save_exprs field.
        (cxx_eval_loop_expr): Discard SAVE_EXPR values before looping.
        (cxx_eval_constant_expression) [SAVE_EXPR]: Add it to the set.
index 4fadc0fd5078dcfd99e090e1efa8beda4bbeb11d..d308175cb5f0b78305790a51e02ed94e9284095f 100644 (file)
@@ -1990,13 +1990,16 @@ cxx_eval_component_reference (const constexpr_ctx *ctx, tree t,
       return t;
     }
 
-  if (CONSTRUCTOR_NO_IMPLICIT_ZERO (whole)
-      && !is_really_empty_class (TREE_TYPE (t)))
+  /* We only create a CONSTRUCTOR for a subobject when we modify it, so empty
+     classes never get represented; throw together a value now.  */
+  if (is_really_empty_class (TREE_TYPE (t)))
+    return build_constructor (TREE_TYPE (t), NULL);
+
+  if (CONSTRUCTOR_NO_IMPLICIT_ZERO (whole))
     {
       /* 'whole' is part of the aggregate initializer we're currently
         building; if there's no initializer for this member yet, that's an
-        error.  But expand_aggr_init_1 doesn't bother to initialize really
-        empty classes, so ignore them here, too.  */
+        error.  */
       if (!ctx->quiet)
        error ("accessing uninitialized member %qD", part);
       *non_constant_p = true;
diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-empty2.C b/gcc/testsuite/g++.dg/cpp1y/constexpr-empty2.C
new file mode 100644 (file)
index 0000000..2acfa98
--- /dev/null
@@ -0,0 +1,27 @@
+// { dg-do compile { target c++14 } }
+
+struct A
+{
+  constexpr A(int) { }
+};
+
+struct B: A {
+  constexpr B(int i): A(i) { }
+  constexpr B(const B& b): A(b) { }
+};
+
+struct C {
+  B b;
+  constexpr C(int i): b(i) { }
+  constexpr C(const C&c): b(c.b) {}
+};
+
+constexpr int f()
+{
+  C b1{42};
+  C b2{b1};
+  b2.b;
+  return 42;
+}
+
+constexpr int i = f();